Comparing version 0.24.0 to 0.25.0
@@ -19,2 +19,3 @@ import { Account, Network, SwapControllerService, SwapControllerServiceEvents, SwapControllerServiceSwapToReceiveArgs, SwapControllerServiceSwapToUseArgs, Token } from 'blockchain-service-swap'; | ||
private recalculateSwapArguments; | ||
private clearFields; | ||
private get lastAmountChange(); | ||
@@ -21,0 +22,0 @@ private set lastAmountChange(value); |
@@ -170,16 +170,10 @@ "use strict"; | ||
return; | ||
if (this.lastAmountChange === 'amountToReceive') { | ||
if (!this.amountToReceive) | ||
return; | ||
const { amountToUse, maximumSelling, liquidityProviderFee, priceImpact, priceInverse } = FlamingoSwapHelper_1.FlamingoSwapHelper.getSwapOut({ | ||
if (this.lastAmountChange === 'amountToReceive' && this.amountToReceive) { | ||
const { amountToUse, maximumSelling, liquidityProviderFee, priceImpact, priceInverse } = FlamingoSwapHelper_1.FlamingoSwapHelper.getSwapFields({ | ||
network: __classPrivateFieldGet(this, _FlamingoSwapControllerService_network, "f"), | ||
amountOut: this.amountToReceive, | ||
assetInHash: this.tokenToUse.hash, | ||
assetInName: this.tokenToUse.symbol, | ||
assetOutHash: this.tokenToReceive.hash, | ||
assetOutName: this.tokenToReceive.symbol, | ||
decimalsIn: this.tokenToUse.decimals, | ||
decimalsOut: this.tokenToReceive.decimals, | ||
reserveIn: this.reservesToUse, | ||
reserveOut: this.reservesToReceive, | ||
amountToReceive: this.amountToReceive, | ||
tokenToUse: this.tokenToUse, | ||
tokenToReceive: this.tokenToReceive, | ||
reservesToUse: this.reservesToUse, | ||
reservesToReceive: this.reservesToReceive, | ||
slippage: this.slippage, | ||
@@ -193,19 +187,13 @@ }); | ||
this.priceInverse = priceInverse; | ||
this.routes = []; | ||
this.routes = []; // TODO: It will be implemented in Swap Multi Invoke issue | ||
return; | ||
} | ||
if (this.lastAmountChange === 'amountToUse') { | ||
if (!this.amountToUse) | ||
return; | ||
const { amountToReceive, minimumReceived, liquidityProviderFee, priceImpact, priceInverse } = FlamingoSwapHelper_1.FlamingoSwapHelper.getSwapIn({ | ||
if (this.lastAmountChange === 'amountToUse' && this.amountToUse) { | ||
const { amountToReceive, minimumReceived, liquidityProviderFee, priceImpact, priceInverse } = FlamingoSwapHelper_1.FlamingoSwapHelper.getSwapFields({ | ||
network: __classPrivateFieldGet(this, _FlamingoSwapControllerService_network, "f"), | ||
amountIn: this.amountToUse, | ||
assetInHash: this.tokenToUse.hash, | ||
assetOutHash: this.tokenToReceive.hash, | ||
assetInName: this.tokenToUse.symbol, | ||
assetOutName: this.tokenToReceive.symbol, | ||
decimalsIn: this.tokenToUse.decimals, | ||
decimalsOut: this.tokenToReceive.decimals, | ||
reserveIn: this.reservesToUse, | ||
reserveOut: this.reservesToReceive, | ||
amountToUse: this.amountToUse, | ||
tokenToUse: this.tokenToUse, | ||
tokenToReceive: this.tokenToReceive, | ||
reservesToUse: this.reservesToUse, | ||
reservesToReceive: this.reservesToReceive, | ||
slippage: this.slippage, | ||
@@ -219,5 +207,16 @@ }); | ||
this.priceInverse = priceInverse; | ||
this.routes = []; | ||
this.routes = []; // TODO: It will be implemented in Swap Multi Invoke issue | ||
return; | ||
} | ||
this.clearFields(); | ||
} | ||
clearFields() { | ||
this.amountToUse = null; | ||
this.amountToReceive = null; | ||
this.minimumReceived = null; | ||
this.maximumSelling = null; | ||
this.liquidityProviderFee = null; | ||
this.priceImpact = null; | ||
this.priceInverse = null; | ||
} | ||
// Getters and setters | ||
@@ -224,0 +223,0 @@ get lastAmountChange() { |
@@ -8,29 +8,15 @@ import BigNumber from 'bignumber.js'; | ||
}; | ||
type TGetAmountArgs = { | ||
reserveIn: BigNumber; | ||
reserveOut: BigNumber; | ||
}; | ||
type TGetAmountInArgs = { | ||
amountOut: BigNumber; | ||
} & TGetAmountArgs; | ||
type TGetAmountOutArgs = { | ||
amountIn: BigNumber; | ||
} & TGetAmountArgs; | ||
type TGetSwapArgs = { | ||
decimalsIn: number; | ||
decimalsOut: number; | ||
assetInName: string; | ||
assetOutName: string; | ||
assetInHash: string; | ||
assetOutHash: string; | ||
reserveIn: string; | ||
reserveOut: string; | ||
tokenToUse: Token; | ||
tokenToReceive: Token; | ||
reservesToUse: string; | ||
reservesToReceive: string; | ||
slippage: number; | ||
network: Network; | ||
}; | ||
type TGetSwapInArgs = { | ||
amountIn: string; | ||
type TGetSwapToUseArgs = { | ||
amountToUse: string; | ||
} & TGetSwapArgs; | ||
type TGetSwapOutArgs = { | ||
amountOut: string; | ||
type TGetSwapToReceiveArgs = { | ||
amountToReceive: string; | ||
} & TGetSwapArgs; | ||
@@ -43,22 +29,9 @@ export declare class FlamingoSwapHelper { | ||
static readonly FEE_RATE: BigNumber; | ||
static getAmountOut({ amountIn, reserveIn, reserveOut }: TGetAmountOutArgs): BigNumber | null; | ||
static getAmountIn({ amountOut, reserveIn, reserveOut }: TGetAmountInArgs): BigNumber | null; | ||
static getSwapIn({ amountIn, decimalsIn, decimalsOut, assetInName, assetOutName, assetInHash, assetOutHash, reserveIn, reserveOut, slippage, network, }: TGetSwapInArgs): { | ||
static getSwapFields(params: TGetSwapToUseArgs | TGetSwapToReceiveArgs): { | ||
amountToReceive: string; | ||
amountIn: string; | ||
route: { | ||
assetInName: string; | ||
reserveIn: BigNumber; | ||
assetOutName: string; | ||
reserveOut: BigNumber; | ||
}[]; | ||
amountOut: string; | ||
amountOutMin: string; | ||
minimumReceived: string; | ||
reserveIn: string; | ||
reserveOut: string; | ||
assetInName: string; | ||
assetOutName: string; | ||
amountToReceiveOverrode: string; | ||
amountToUse: string; | ||
amountToUseOverrode: string; | ||
fee: string; | ||
tolerance: string; | ||
liquidityProviderFee: string; | ||
midPrice: string; | ||
@@ -68,33 +41,8 @@ price: string; | ||
priceInverse: string; | ||
liquidityProviderFee: string; | ||
}; | ||
static getSwapOut({ amountOut, decimalsIn, decimalsOut, assetInName, assetOutName, assetInHash, assetOutHash, reserveIn, reserveOut, slippage, network, }: TGetSwapOutArgs): { | ||
amountToUse: string; | ||
amountOut: string; | ||
route: { | ||
assetInName: string; | ||
reserveIn: BigNumber; | ||
assetOutName: string; | ||
reserveOut: BigNumber; | ||
}[]; | ||
amountIn: string; | ||
amountInMax: string; | ||
maximumSelling: string; | ||
reserveIn: string; | ||
reserveOut: string; | ||
assetInName: string; | ||
assetOutName: string; | ||
fee: string; | ||
tolerance: string; | ||
midPrice: string; | ||
price: string; | ||
priceImpact: string; | ||
priceInverse: string; | ||
liquidityProviderFee: string; | ||
minimumReceived: string | null; | ||
maximumSelling: string | null; | ||
}; | ||
private static getSwapInData; | ||
private static getSwapOutData; | ||
private static createTradeData; | ||
private static overrideDecimals; | ||
private static overrideSymbol; | ||
private static overrideToken; | ||
private static overrideAmountInput; | ||
@@ -101,0 +49,0 @@ private static overrideAmountToDisplay; |
@@ -10,100 +10,53 @@ "use strict"; | ||
class FlamingoSwapHelper { | ||
static getAmountOut({ amountIn, reserveIn, reserveOut }) { | ||
if (!reserveIn.gt(this.BN_0) || !reserveOut.gt(this.BN_0)) { | ||
throw new Error('amount and reserve should be positive number'); | ||
static getSwapFields(params) { | ||
const reservesToUseBn = new bignumber_js_1.default(params.reservesToUse); | ||
const reservesToReceiveBn = new bignumber_js_1.default(params.reservesToReceive); | ||
if (reservesToUseBn.lt(this.BN_0) || reservesToReceiveBn.lt(this.BN_0)) { | ||
throw new Error('Reserve should be positive number'); | ||
} | ||
if (!amountIn.gt(this.BN_0)) { | ||
return null; | ||
let amountToUseFormatted; | ||
let amountToReceiveFormatted; | ||
let maximumSelling = null; | ||
let minimumReceived = null; | ||
const slippageFormatted = new bignumber_js_1.default(params.slippage * 10).shiftedBy(-3); | ||
if ('amountToReceive' in params) { | ||
amountToReceiveFormatted = this.overrideAmountInput(params.network, params.amountToReceive, params.tokenToReceive); | ||
amountToUseFormatted = reservesToUseBn | ||
.times(amountToReceiveFormatted) | ||
.times(this.BN_1000) | ||
.idiv(reservesToReceiveBn.minus(amountToReceiveFormatted).times(this.BN_997)) | ||
.plus(this.BN_1); | ||
minimumReceived = amountToUseFormatted.shiftedBy(-params.tokenToReceive.decimals).toFixed(); | ||
} | ||
const amountInWithFee = amountIn.times(this.BN_997); | ||
return amountInWithFee.times(reserveOut).idiv(reserveIn.times(this.BN_1000).plus(amountInWithFee)); | ||
} | ||
static getAmountIn({ amountOut, reserveIn, reserveOut }) { | ||
if (!reserveIn.gt(this.BN_0) || !reserveOut.gt(this.BN_0)) { | ||
throw new Error('amount and reserve should be positive number'); | ||
else { | ||
amountToUseFormatted = this.overrideAmountInput(params.network, params.amountToUse, params.tokenToUse); | ||
const amountToUseWithFee = amountToUseFormatted.times(this.BN_997); | ||
amountToReceiveFormatted = amountToUseFormatted | ||
.times(amountToUseWithFee) | ||
.times(params.reservesToReceive) | ||
.idiv(reservesToUseBn.times(this.BN_1000).plus(amountToUseWithFee)); | ||
maximumSelling = amountToUseFormatted.times(this.BN_1.plus(slippageFormatted)).dp(0).toFixed(); | ||
} | ||
if (!amountOut.gt(this.BN_0) || !amountOut.lt(reserveOut)) { | ||
return null; | ||
} | ||
return reserveIn | ||
.times(amountOut) | ||
.times(this.BN_1000) | ||
.idiv(reserveOut.minus(amountOut).times(this.BN_997)) | ||
.plus(this.BN_1); | ||
} | ||
static getSwapIn({ amountIn, decimalsIn, decimalsOut, assetInName, assetOutName, assetInHash, assetOutHash, reserveIn, reserveOut, slippage, network, }) { | ||
const reserveInBn = new bignumber_js_1.default(reserveIn); | ||
const reserveOutBn = new bignumber_js_1.default(reserveOut); | ||
const amountInFormatted = this.overrideAmountInput(network, amountIn, assetInHash, decimalsIn); | ||
const swapInData = this.getSwapInData({ | ||
amountIn: amountInFormatted, | ||
decimalsOut, | ||
decimalsIn, | ||
originalAssetInName: assetInName, | ||
originalAssetOutName: assetOutName, | ||
originalAssetInHash: assetInHash, | ||
originalAssetOutHash: assetOutHash, | ||
reserveIn: reserveInBn, | ||
reserveOut: reserveOutBn, | ||
slippage, | ||
}); | ||
const amountToReceive = this.overrideAmountToDisplay(network, swapInData.amountOut, assetOutHash, decimalsOut); | ||
return Object.assign(Object.assign({}, swapInData), { amountToReceive, amountIn: amountInFormatted.toFixed() }); | ||
} | ||
static getSwapOut({ amountOut, decimalsIn, decimalsOut, assetInName, assetOutName, assetInHash, assetOutHash, reserveIn, reserveOut, slippage, network, }) { | ||
const reserveInBn = new bignumber_js_1.default(reserveIn); | ||
const reserveOutBn = new bignumber_js_1.default(reserveOut); | ||
const amountOutFormatted = this.overrideAmountInput(network, amountOut, assetOutHash, decimalsOut); | ||
const swapOutData = this.getSwapOutData({ | ||
amountOut: amountOutFormatted, | ||
decimalsIn, | ||
decimalsOut, | ||
originalAssetInName: assetInName, | ||
originalAssetOutName: assetOutName, | ||
originalAssetInHash: assetInHash, | ||
originalAssetOutHash: assetOutHash, | ||
reserveIn: reserveInBn, | ||
reserveOut: reserveOutBn, | ||
slippage, | ||
}); | ||
const amountToUse = this.overrideAmountToDisplay(network, swapOutData.amountIn, assetInHash, decimalsIn); | ||
return Object.assign(Object.assign({}, swapOutData), { amountToUse, amountOut: amountOutFormatted.toFixed() }); | ||
} | ||
static getSwapInData({ amountIn, decimalsIn, decimalsOut, originalAssetInName, originalAssetOutName, reserveIn, reserveOut, slippage, }) { | ||
var _a; | ||
const assetInName = this.overrideSymbol(originalAssetInName); | ||
const assetOutName = this.overrideSymbol(originalAssetOutName); | ||
const amountOut = (_a = this.getAmountOut({ | ||
amountIn, | ||
reserveIn, | ||
reserveOut, | ||
})) !== null && _a !== void 0 ? _a : new bignumber_js_1.default(0); | ||
const route = [ | ||
{ | ||
assetInName, | ||
reserveIn, | ||
assetOutName, | ||
reserveOut, | ||
assetToUseSymbol: this.overrideToken(params.network, params.tokenToUse).symbol, | ||
reservesToReceive: reservesToReceiveBn, | ||
assetToReceiveSymbol: this.overrideToken(params.network, params.tokenToReceive).symbol, | ||
reservesToUse: reservesToUseBn, | ||
}, | ||
]; | ||
const { fee, price, priceImpact, midPrice } = this.createTradeData({ | ||
amountIn, | ||
amountOut, | ||
amountToReceive: amountToReceiveFormatted, | ||
amountToUse: amountToUseFormatted, | ||
route, | ||
}); | ||
const slippageFormatted = new bignumber_js_1.default(slippage * 10).shiftedBy(-3); | ||
const amountOutMin = amountOut.times(this.BN_1.minus(slippageFormatted)).dp(0); | ||
const priceInverse = this.BN_1.div(price); | ||
const diffDecimals = decimalsIn - decimalsOut; | ||
const diffDecimals = params.tokenToUse.decimals - params.tokenToReceive.decimals; | ||
return { | ||
route, | ||
amountOut: amountOut.toFixed(), | ||
amountOutMin: amountOutMin.toFixed(), | ||
minimumReceived: amountOutMin.shiftedBy(-decimalsOut).toFixed(), | ||
reserveIn: reserveIn.toFixed(), | ||
reserveOut: reserveOut.toFixed(), | ||
assetInName, | ||
assetOutName, | ||
amountToReceive: amountToReceiveFormatted.toFixed(), | ||
amountToReceiveOverrode: this.overrideAmountToDisplay(params.network, amountToReceiveFormatted.toString(), params.tokenToReceive), | ||
amountToUse: amountToUseFormatted.toFixed(), | ||
amountToUseOverrode: this.overrideAmountToDisplay(params.network, amountToUseFormatted.toFixed(), params.tokenToUse), | ||
fee: fee.toFixed(), | ||
tolerance: slippageFormatted.toFixed(), | ||
liquidityProviderFee: fee.shiftedBy(-8).plus(this.BN_0).toFixed(4), | ||
midPrice: midPrice.toFixed(), | ||
@@ -113,54 +66,12 @@ price: price.toFixed(), | ||
priceInverse: isFinite(Number(priceInverse)) ? priceInverse.multipliedBy(Math.pow(10, diffDecimals)).toFixed() : '0', | ||
liquidityProviderFee: fee.shiftedBy(-8).plus(this.BN_0).toFixed(4), | ||
}; | ||
} | ||
static getSwapOutData({ amountOut, decimalsIn, decimalsOut, originalAssetInName, originalAssetOutName, reserveIn, reserveOut, slippage, }) { | ||
var _a; | ||
const assetInName = this.overrideSymbol(originalAssetInName); | ||
const assetOutName = this.overrideSymbol(originalAssetOutName); | ||
const amountIn = (_a = this.getAmountIn({ | ||
amountOut, | ||
reserveIn, | ||
reserveOut, | ||
})) !== null && _a !== void 0 ? _a : new bignumber_js_1.default(0); | ||
const route = [ | ||
{ | ||
assetInName, | ||
reserveIn, | ||
assetOutName, | ||
reserveOut, | ||
}, | ||
]; | ||
const { fee, price, priceImpact, midPrice } = this.createTradeData({ | ||
amountIn, | ||
amountOut, | ||
route, | ||
}); | ||
const diffDecimals = decimalsIn - decimalsOut; | ||
const slippageFormatted = new bignumber_js_1.default(slippage * 10).shiftedBy(-3); | ||
const amountInMax = amountIn.times(this.BN_1.plus(slippageFormatted)).dp(0); | ||
const priceInverse = this.BN_1.div(price); | ||
return { | ||
route, | ||
amountIn: amountIn.toFixed(), | ||
amountInMax: amountInMax.toFixed(), | ||
maximumSelling: amountInMax.shiftedBy(-decimalsIn).toFixed(), | ||
reserveIn: reserveIn.toFixed(), | ||
reserveOut: reserveOut.toFixed(), | ||
assetInName, | ||
assetOutName, | ||
fee: fee.toFixed(), | ||
tolerance: slippageFormatted.toFixed(), | ||
midPrice: midPrice.toFixed(), | ||
price: price.toFixed(), | ||
priceImpact: isFinite(Number(priceImpact)) ? priceImpact.shiftedBy(2).toFixed(4) : '0', | ||
priceInverse: isFinite(Number(priceInverse)) ? priceInverse.multipliedBy(Math.pow(10, diffDecimals)).toFixed() : '0', | ||
liquidityProviderFee: fee.shiftedBy(-8).plus(this.BN_0).toFixed(4), | ||
minimumReceived, | ||
maximumSelling, | ||
}; | ||
} | ||
static createTradeData({ amountIn, amountOut, route }) { | ||
const fee = amountIn.minus(route.reduce((acc) => acc.times(this.BN_1.minus(this.FEE_RATE)), amountIn)); | ||
const price = amountIn.div(amountOut); | ||
static createTradeData({ amountToUse, amountToReceive, route }) { | ||
const fee = amountToUse.minus(route.reduce((acc) => acc.times(this.BN_1.minus(this.FEE_RATE)), amountToUse)); | ||
const price = amountToUse.div(amountToReceive); | ||
const midPrice = route.reduce((acc, item) => acc.times(item.reserveIn).div(item.reserveOut), this.BN_1); | ||
const priceImpact = price.minus(midPrice).div(price).minus(fee.div(amountIn)); | ||
const priceImpact = price.minus(midPrice).div(price).minus(fee.div(amountToUse)); | ||
return { | ||
@@ -173,22 +84,21 @@ fee, | ||
} | ||
static overrideDecimals(network, scriptHash, decimals) { | ||
const neoToken = constants_1.TOKENS[network.type].find(token => token.hash === scriptHash); | ||
if (!neoToken) { | ||
return decimals; | ||
static overrideToken(network, token) { | ||
const neoScriptHash = constants_1.SWAP_SCRIPT_HASHES_BY_NETWORK_TYPE[network.type].neo; | ||
const isNeoToken = this.normalizeHash(token.hash) === this.normalizeHash(neoScriptHash); | ||
if (!isNeoToken) { | ||
return token; | ||
} | ||
const isNeoToken = this.normalizeHash(scriptHash) === this.normalizeHash(neoToken.hash); | ||
const BNEO_DECIMALS = 8; | ||
return isNeoToken ? BNEO_DECIMALS : decimals; | ||
const bneoToken = constants_1.TOKENS[network.type].find(token => token.hash === constants_1.SWAP_SCRIPT_HASHES_BY_NETWORK_TYPE[network.type].bneo); | ||
if (!bneoToken) | ||
throw new Error('Bneo token not found'); | ||
return bneoToken; | ||
} | ||
static overrideSymbol(symbol) { | ||
return symbol === 'NEO' ? 'BNEO' : symbol; | ||
static overrideAmountInput(network, amount, token) { | ||
const tokenOverrode = this.overrideToken(network, token); | ||
return new bignumber_js_1.default(amount).shiftedBy(tokenOverrode.decimals); | ||
} | ||
static overrideAmountInput(network, amount, assetHash, decimals) { | ||
const decimalsOverride = this.overrideDecimals(network, assetHash, decimals); | ||
return new bignumber_js_1.default(amount).shiftedBy(decimalsOverride); | ||
static overrideAmountToDisplay(network, amount, token) { | ||
const tokenOverrode = this.overrideToken(network, token); | ||
return new bignumber_js_1.default(amount).shiftedBy(-tokenOverrode.decimals).toFixed(); | ||
} | ||
static overrideAmountToDisplay(network, amount, assetHash, decimals) { | ||
const decimalsOverride = this.overrideDecimals(network, assetHash, decimals); | ||
return new bignumber_js_1.default(amount).shiftedBy(-decimalsOverride).toFixed(); | ||
} | ||
static normalizeHash(hash) { | ||
@@ -195,0 +105,0 @@ return hash.startsWith('0x') ? hash.slice(2) : hash; |
{ | ||
"name": "bs-neo3", | ||
"version": "0.24.0", | ||
"version": "0.25.0", | ||
"main": "dist/index.js", | ||
@@ -5,0 +5,0 @@ "types": "dist/index.d.ts", |
97537
1992