nerve-sdk-js
Version:
nerve nerve-js nerve-sdk nerve-js-sdk
1,575 lines (1,291 loc) • 61.6 kB
JavaScript
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
var sdk = require('../api/sdk');
var util = require('../test/api/util');
var cryptos = require("crypto");
var BigNumber = require('bignumber.js');
var nerve = require('../index');
function inputsOrOutputsOfSwapAddLiquidity(_x, _x2, _x3, _x4, _x5) {
return _inputsOrOutputsOfSwapAddLiquidity.apply(this, arguments);
}
function _inputsOrOutputsOfSwapAddLiquidity() {
_inputsOrOutputsOfSwapAddLiquidity = _asyncToGenerator(function* (fromAddress, to, tokenAmountA, tokenAmountB, pairAddress) {
var balanceA = yield util.getNulsBalance(fromAddress, tokenAmountA.chainId, tokenAmountA.assetId);
var balanceB = yield util.getNulsBalance(fromAddress, tokenAmountB.chainId, tokenAmountB.assetId);
var inputs = [{
address: fromAddress,
amount: tokenAmountA.amount,
assetsChainId: tokenAmountA.chainId,
assetsId: tokenAmountA.assetId,
nonce: balanceA.data.nonce,
locked: 0
}, {
address: fromAddress,
amount: tokenAmountB.amount,
assetsChainId: tokenAmountB.chainId,
assetsId: tokenAmountB.assetId,
nonce: balanceB.data.nonce,
locked: 0
}];
var outputs = [{
address: pairAddress,
amount: tokenAmountA.amount,
assetsChainId: tokenAmountA.chainId,
assetsId: tokenAmountA.assetId,
locked: 0
}, {
address: pairAddress,
amount: tokenAmountB.amount,
assetsChainId: tokenAmountB.chainId,
assetsId: tokenAmountB.assetId,
locked: 0
}];
return {
success: true,
data: {
inputs: inputs,
outputs: outputs
}
};
});
return _inputsOrOutputsOfSwapAddLiquidity.apply(this, arguments);
}
function inputsOrOutputsOfStableAddLiquidityOrTrade(_x6, _x7, _x8, _x9, _x10) {
return _inputsOrOutputsOfStableAddLiquidityOrTrade.apply(this, arguments);
}
function _inputsOrOutputsOfStableAddLiquidityOrTrade() {
_inputsOrOutputsOfStableAddLiquidityOrTrade = _asyncToGenerator(function* (fromAddress, to, tokenAmounts, feeTo, feeTokenAmount) {
var inputs = [];
var outputs = [];
var hasFee = false;
if (feeTo && feeTokenAmount) {
hasFee = true;
}
var length = tokenAmounts.length;
for (var i = 0; i < length; i++) {
var tokenAmount = tokenAmounts[i];
var balance = yield util.getNulsBalance(fromAddress, tokenAmount.chainId, tokenAmount.assetId);
inputs.push({
address: fromAddress,
amount: tokenAmount.amount,
assetsChainId: tokenAmount.chainId,
assetsId: tokenAmount.assetId,
nonce: balance.data.nonce,
locked: 0
});
var fromAmount = new BigNumber(tokenAmount.amount);
if (hasFee && tokenAmount.chainId == feeTokenAmount.chainId && tokenAmount.assetId == feeTokenAmount.assetId) {
fromAmount = fromAmount.minus(new BigNumber(feeTokenAmount.amount));
outputs.push({
address: feeTo,
amount: feeTokenAmount.amount,
assetsChainId: tokenAmount.chainId,
assetsId: tokenAmount.assetId,
locked: 0
});
}
outputs.push({
address: to,
amount: fromAmount.toFixed(),
assetsChainId: tokenAmount.chainId,
assetsId: tokenAmount.assetId,
locked: 0
});
}
return {
success: true,
data: {
inputs: inputs,
outputs: outputs
}
};
});
return _inputsOrOutputsOfStableAddLiquidityOrTrade.apply(this, arguments);
}
function int32ToBytes(x) {
return Buffer.concat([Buffer.from([0xFF & x]), Buffer.from([0xFF & x >> 8]), Buffer.from([0xFF & x >> 16]), Buffer.from([0xFF & x >> 24])]);
}
function containsCurrency(currentPathArray, token) {
var length = currentPathArray.length;
for (var i = 0; i < length; i++) {
var pair = currentPathArray[i];
if (swap.tokenEquals(pair.token0, token) || swap.tokenEquals(pair.token1, token)) {
return true;
}
}
return false;
}
function getAmountOutForBestTrade(amountIn, reserveIn, reserveOut, feeRate) {
if (typeof feeRate === 'undefined') {
feeRate = 3;
}
var _amountIn = new BigNumber(amountIn);
if (_amountIn.isLessThanOrEqualTo(0)) {
return new BigNumber('0');
}
var _reserveIn = new BigNumber(reserveIn);
var _reserveOut = new BigNumber(reserveOut);
if (_reserveIn.isLessThanOrEqualTo(0) || _reserveOut.isLessThanOrEqualTo(0)) {
return new BigNumber('0');
} // let amountInWithFee = _amountIn.times(997);
var amountInWithFee = _amountIn.times(1000 - feeRate);
var numerator = amountInWithFee.times(_reserveOut);
var denominator = _reserveIn.times(1000).plus(amountInWithFee);
var amountOut = numerator.dividedToIntegerBy(denominator);
return amountOut;
}
function getAmountInForBestTrade(amountOut, reserveIn, reserveOut, feeRate) {
if (typeof feeRate === 'undefined') {
feeRate = 3;
}
var _amountOut = new BigNumber(amountOut);
if (_amountOut.isLessThanOrEqualTo(0)) {
return new BigNumber('0');
}
var _reserveIn = new BigNumber(reserveIn);
var _reserveOut = new BigNumber(reserveOut);
if (_reserveOut.isLessThanOrEqualTo(_amountOut) || _reserveIn.isLessThanOrEqualTo(0) || _reserveOut.isLessThanOrEqualTo(0)) {
return new BigNumber('0');
}
var numerator = _reserveIn.times(_amountOut).times(1000); // let denominator = _reserveOut.minus(_amountOut).times(997);
var denominator = _reserveOut.minus(_amountOut).times(1000 - feeRate);
var amountIn = numerator.dividedToIntegerBy(denominator).plus(1);
return amountIn;
}
function calcBestTradeExactIn(chainId, pairs, tokenAmountIn, tokenOut, currentPathArray, wholeTradeArray, orginTokenAmountIn, maxPairSize, stableGroupArray) {
var tokenIn = tokenAmountIn.token;
var length = pairs.length;
var tokens = swap.tokenSort(tokenIn, tokenOut);
var subIndex = -1;
for (var i = 0; i < length; i++) {
var pair = pairs[i];
if (swap.tokenEquals(pair.token0, tokens[0]) && swap.tokenEquals(pair.token1, tokens[1])) {
subIndex = i;
break;
}
}
if (subIndex != -1) {
var _pair = pairs[subIndex];
var reserves = swap.getReserves(tokenIn, tokenOut, _pair);
var reserveIn = new BigNumber(reserves[0]);
var reserveOut = new BigNumber(reserves[1]);
var amountOut = getAmountOutForBestTrade(tokenAmountIn.amount, reserveIn, reserveOut, reserves[2]);
var tokenAmountOut = swap.tokenAmount(tokenOut.chainId, tokenOut.assetId, amountOut);
wholeTradeArray.push({
path: [_pair],
tokenAmountIn: orginTokenAmountIn,
tokenAmountOut: tokenAmountOut
});
pairs = pairs.slice(0, subIndex).concat(pairs.slice(subIndex + 1, length));
} // pair去重,检查交易对中是否有多个相同组下的普通token和稳定币token 筛选机制,留下一个,留下稳定币token在Pair池中数量最多的
if (stableGroupArray) {
pairs = deduplicationGroupPair(pairs, stableGroupArray);
}
var trades = realBestTradeExactIn(chainId, pairs, tokenAmountIn, tokenOut, currentPathArray, wholeTradeArray, orginTokenAmountIn, 0, maxPairSize, stableGroupArray);
if (trades.length == 0) return {};
trades.sort(function (a, b) {
return b.tokenAmountOut.amount.minus(a.tokenAmountOut.amount);
});
var trade = trades[0];
if (trade.tokenAmountOut.amount.isEqualTo(0)) return {};
return trade;
}
function deduplicationGroupPair(pairs, stableGroupArray) {
var resultPairs = [];
var groupPairMap = {};
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i];
var stableInfo = swap.checkStableToken(pair.token0, stableGroupArray);
if (stableInfo.success) {
var array = groupPairMap[swap.tokenStr(stableInfo.lpToken) + "-" + swap.tokenStr(pair.token1)];
if (!array) {
array = [];
}
pair.stableToken = pair.token0;
pair.stableTokenReserve = pair.reserve0;
pair.stableTokenDecimals = stableInfo['groupCoin'][swap.tokenStr(pair.token0)].decimals;
array.push(pair);
} else {
stableInfo = swap.checkStableToken(pair.token1, stableGroupArray);
if (stableInfo.success) {
var _array = groupPairMap[swap.tokenStr(stableInfo.lpToken) + "-" + swap.tokenStr(pair.token0)];
if (!_array) {
_array = [];
groupPairMap[swap.tokenStr(stableInfo.lpToken) + "-" + swap.tokenStr(pair.token0)] = _array;
}
pair.stableToken = pair.token1;
pair.stableTokenReserve = pair.reserve1;
pair.stableTokenDecimals = stableInfo['groupCoin'][swap.tokenStr(pair.token1)].decimals;
_array.push(pair);
} else {
resultPairs.push(pair);
}
}
}
var keys = Object.keys(groupPairMap);
if (keys.length > 0) {
for (var _i = 0; _i < keys.length; _i++) {
var key = keys[_i]; // console.log('============key', key);
var _array2 = groupPairMap[key];
if (_array2.length == 0) continue;
if (_array2.length == 1) {
resultPairs.push(_array2[0]);
} else {
// 留下一个,留下稳定币token在Pair池中数量最多的
var index = 0;
var maxReserve = new BigNumber('0');
for (var j = 0; j < _array2.length; j++) {
var _pair2 = _array2[j];
var currentReserve = new BigNumber(_pair2.stableTokenReserve).times(new BigNumber('10').pow(18 - _pair2.stableTokenDecimals)); // console.log('token', swap.tokenStr(pair.stableToken), 'currentReserve', currentReserve.toFixed());
if (currentReserve.isGreaterThan(maxReserve)) {
maxReserve = currentReserve;
index = j;
}
}
resultPairs.push(_array2[index]);
}
}
}
return resultPairs;
}
function makeStableLinkPair(tokenA, tokenB, amountA, amountB) {
var array = swap.tokenSort(tokenA, tokenB);
var token0 = array[0];
var result = swap.tokenEquals(tokenA, token0) ? swap.pair(tokenA, tokenB, amountA, amountB, 0) : swap.pair(tokenB, tokenA, amountB, amountA, 0);
return result;
}
function realBestTradeExactIn(chainId, pairs, tokenAmountIn, out, currentPathArray, wholeTradeArray, orginTokenAmountIn, depth, maxPairSize, stableGroupArray) {
// console.log('-------------', 'pairs', JSON.stringify(pairs), 'depth', depth);
var length = pairs.length;
for (var i = 0; i < length; i++) {
var pair = pairs[i]; // console.log('pair', JSON.stringify(pair), 'depth', depth);
var linkPair = void 0;
var tokenIn = tokenAmountIn.token;
if (!swap.tokenEquals(pair.token0, tokenIn) && !swap.tokenEquals(pair.token1, tokenIn)) {
// add for link +
if (stableGroupArray) {
var stableResult = isGroupStable(pair.token0, tokenAmountIn.token, stableGroupArray);
if (stableResult.success) {
linkPair = makeStableLinkPair(pair.token0, tokenAmountIn.token, '0', '0');
linkPair.groupCoin = stableResult.groupCoin;
tokenIn = pair.token0;
} else {
stableResult = isGroupStable(pair.token1, tokenAmountIn.token, stableGroupArray);
if (stableResult.success) {
linkPair = makeStableLinkPair(pair.token1, tokenAmountIn.token, '0', '0');
linkPair.groupCoin = stableResult.groupCoin;
tokenIn = pair.token1;
} else {
continue;
}
} // add for link -
} else {
continue;
}
}
var tokenOut = swap.tokenEquals(pair.token0, tokenIn) ? pair.token1 : pair.token0;
if (containsCurrency(currentPathArray, tokenOut)) continue; // 计算tokenOutAmount
var amountIn = tokenAmountIn.amount; // add for link +
if (linkPair) {
// 检查稳定币池是否有足够的金额
var linkIn = linkPair['groupCoin'][swap.tokenStr(tokenAmountIn.token)];
var linkOut = linkPair['groupCoin'][swap.tokenStr(tokenIn)];
var linkAmountOut = new BigNumber(amountIn).times(new BigNumber('10').pow(linkOut.decimals)).div(new BigNumber('10').pow(linkIn.decimals));
if (new BigNumber(linkOut.balance).isLessThan(linkAmountOut)) {
amountIn = '0';
} else {
amountIn = linkAmountOut.toFixed();
}
} // add for link -
var reserves = swap.getReserves(tokenIn, tokenOut, pair);
var reserveIn = new BigNumber(reserves[0]);
var reserveOut = new BigNumber(reserves[1]);
if (reserveIn.isEqualTo(0) || reserveOut.isEqualTo(0)) continue;
var amountOut = getAmountOutForBestTrade(amountIn, reserveIn, reserveOut, reserves[2]);
if (swap.tokenEquals(tokenOut, out)) {
var cloneCurrentPathArray = currentPathArray.slice(); // add for link +
if (linkPair) {
cloneCurrentPathArray.push(linkPair);
} // add for link -
cloneCurrentPathArray.push(pair);
var tokenAmountOut = swap.tokenAmount(tokenOut.chainId, tokenOut.assetId, amountOut);
wholeTradeArray.push({
path: cloneCurrentPathArray,
tokenAmountIn: orginTokenAmountIn,
tokenAmountOut: tokenAmountOut
});
} else if (depth < maxPairSize - 1 && length > 1) {
var _cloneCurrentPathArray = currentPathArray.slice(); // add for link +
if (linkPair) {
_cloneCurrentPathArray.push(linkPair);
} // add for link -
_cloneCurrentPathArray.push(pair);
var subPairs = pairs.slice(0, i);
subPairs = subPairs.concat(pairs.slice(i + 1, length));
realBestTradeExactIn(chainId, subPairs, swap.tokenAmount(tokenOut.chainId, tokenOut.assetId, amountOut), out, _cloneCurrentPathArray, wholeTradeArray, orginTokenAmountIn, depth + 1, maxPairSize, stableGroupArray);
}
}
return wholeTradeArray;
}
function calcBestTradeExactOut(chainId, pairs, _in, tokenAmountOut, currentPathArray, wholeTradeArray, orginTokenAmountOut, maxPairSize, stableGroupArray) {
var tokenOut = tokenAmountOut.token;
var length = pairs.length;
var tokens = swap.tokenSort(_in, tokenOut);
var subIndex = -1;
for (var i = 0; i < length; i++) {
var pair = pairs[i];
if (swap.tokenEquals(pair.token0, tokens[0]) && swap.tokenEquals(pair.token1, tokens[1])) {
subIndex = i;
break;
}
}
if (subIndex != -1) {
var _pair3 = pairs[subIndex];
var reserves = swap.getReserves(_in, tokenOut, _pair3);
var reserveIn = new BigNumber(reserves[0]);
var reserveOut = new BigNumber(reserves[1]);
var amountIn = getAmountInForBestTrade(tokenAmountOut.amount, reserveIn, reserveOut, reserves[2]);
var tokenAmountIn = swap.tokenAmount(_in.chainId, _in.assetId, amountIn);
wholeTradeArray.push({
path: [_pair3],
tokenAmountIn: tokenAmountIn,
tokenAmountOut: orginTokenAmountOut
});
pairs = pairs.slice(0, subIndex).concat(pairs.slice(subIndex + 1, length));
} // pair去重,检查交易对中是否有多个相同组下的普通token和稳定币token 筛选机制,留下一个,留下稳定币token在Pair池中数量最多的
if (stableGroupArray) {
pairs = deduplicationGroupPair(pairs, stableGroupArray);
}
var trades = realBestTradeExactOut(chainId, pairs, _in, tokenAmountOut, currentPathArray, wholeTradeArray, orginTokenAmountOut, 0, maxPairSize, stableGroupArray);
if (trades.length == 0) return {};
trades.sort(function (a, b) {
return a.tokenAmountIn.amount.minus(b.tokenAmountIn.amount);
});
for (var _i2 = 0; _i2 < trades.length; _i2++) {
var trade = trades[_i2];
if (trade.tokenAmountIn.amount.isEqualTo(0)) continue;
return trade;
}
return {};
}
function realBestTradeExactOut(chainId, pairs, _in, tokenAmountOut, currentPathArray, wholeTradeArray, orginTokenAmountOut, depth, maxPairSize, stableGroupArray) {
var length = pairs.length;
for (var i = 0; i < length; i++) {
var pair = pairs[i];
var linkPair = void 0;
var currentOut = tokenAmountOut.token;
if (!swap.tokenEquals(pair.token0, currentOut) && !swap.tokenEquals(pair.token1, currentOut)) {
// add for link +
if (stableGroupArray) {
var stableResult = isGroupStable(pair.token0, tokenAmountOut.token, stableGroupArray);
if (stableResult.success) {
linkPair = makeStableLinkPair(pair.token0, tokenAmountOut.token, '0', '0');
linkPair.groupCoin = stableResult.groupCoin;
currentOut = pair.token0;
} else {
stableResult = isGroupStable(pair.token1, tokenAmountOut.token, stableGroupArray);
if (stableResult.success) {
linkPair = makeStableLinkPair(pair.token1, tokenAmountOut.token, '0', '0');
linkPair.groupCoin = stableResult.groupCoin;
currentOut = pair.token1;
} else {
continue;
}
} // add for link -
} else {
continue;
}
}
var currentIn = swap.tokenEquals(pair.token0, currentOut) ? pair.token1 : pair.token0;
if (containsCurrency(currentPathArray, currentIn)) continue; // 计算tokenInAmount
var amountOut = tokenAmountOut.amount; // add for link +
if (linkPair) {
// 检查稳定币池是否有足够的金额
var linkIn = linkPair['groupCoin'][swap.tokenStr(currentOut)];
var linkOut = linkPair['groupCoin'][swap.tokenStr(tokenAmountOut.token)];
var linkAmountIn = new BigNumber(amountOut).times(new BigNumber('10').pow(linkIn.decimals)).div(new BigNumber('10').pow(linkOut.decimals));
if (new BigNumber(linkOut.balance).isLessThan(amountOut)) {
amountOut = '0';
} else {
amountOut = linkAmountIn.toFixed();
}
} // add for link -
var reserves = swap.getReserves(currentIn, currentOut, pair);
var reserveIn = new BigNumber(reserves[0]);
var reserveOut = new BigNumber(reserves[1]);
if (reserveIn.isEqualTo(0) || reserveOut.isEqualTo(0)) continue;
var amountIn = getAmountInForBestTrade(amountOut, reserveIn, reserveOut, reserves[2]);
if (swap.tokenEquals(currentIn, _in)) {
var cloneCurrentPathArray = currentPathArray.slice(); // add for link +
if (linkPair) {
cloneCurrentPathArray.push(linkPair);
} // add for link -
cloneCurrentPathArray.push(pair);
var tokenAmountIn = swap.tokenAmount(currentIn.chainId, currentIn.assetId, amountIn);
wholeTradeArray.push({
path: cloneCurrentPathArray,
tokenAmountIn: tokenAmountIn,
tokenAmountOut: orginTokenAmountOut
});
} else if (depth < maxPairSize - 1 && length > 1) {
var _cloneCurrentPathArray2 = currentPathArray.slice(); // add for link +
if (linkPair) {
_cloneCurrentPathArray2.push(linkPair);
} // add for link -
_cloneCurrentPathArray2.push(pair);
var subPairs = pairs.slice(0, i);
subPairs = subPairs.concat(pairs.slice(i + 1, length));
realBestTradeExactOut(chainId, subPairs, _in, swap.tokenAmount(currentIn.chainId, currentIn.assetId, amountIn), _cloneCurrentPathArray2, wholeTradeArray, orginTokenAmountOut, depth + 1, maxPairSize, stableGroupArray);
}
}
return wholeTradeArray;
}
function isGroupStable(tokenA, tokenB, stableGroupArray) {
var result = {
success: false
};
var length = stableGroupArray.length;
for (var i = 0; i < length; i++) {
var info = stableGroupArray[i];
if (info['groupCoin'][swap.tokenStr(tokenA)] && info['groupCoin'][swap.tokenStr(tokenB)]) {
result.success = true;
result.address = info.address;
result.lpToken = swap.parseTokenStr(info.lpToken);
result.groupCoin = info.groupCoin;
return result;
}
}
return result;
}
function getCumulativeAmountsOfStableSwap(amounts, coins) {
var result = new BigNumber('0');
if (!amounts) {
return result;
}
var length = amounts.length;
var amount;
var exponent;
for (var i = 0; i < length; i++) {
amount = new BigNumber(amounts[i]);
exponent = 18 - Number(coins[i].decimals);
if (exponent == 0) {
result = result.plus(amount);
} else {
result = result.plus(amount.shiftedBy(exponent));
}
}
return result;
}
var swap = {
/**
* 当前时间,单位秒
* @returns {number}
*/
currentTime() {
var times = new Date().valueOf();
return Number(times.toString().substr(0, times.toString().length - 3)); //交易时间
},
/**
*
* 组装一个token的json对象
*/
token(chainId, assetId) {
return {
chainId: chainId,
assetId: assetId
};
},
/**
* @param amount 资产数量
* @returns {{amount: *, chainId: *, assetId: *}}
*/
tokenAmount(chainId, assetId, amount) {
var token = this.token(chainId, assetId);
return {
chainId: chainId,
assetId: assetId,
amount: amount,
token: token
};
},
/**
* 按`chainId`和`assetId`排序两个token
*/
tokenSort(token0, token1) {
var positiveSequence = token0.chainId < token1.chainId || token0.chainId == token1.chainId && token0.assetId < token1.assetId;
if (positiveSequence) {
return [token0, token1];
}
return [token1, token0];
},
tokenStr(token) {
return token.chainId + '-' + token.assetId;
},
parseTokenStr(tokenStr) {
var split = tokenStr.split("-");
return {
chainId: Number(split[0].trim()),
assetId: Number(split[1].trim())
};
},
/**
* 根据token计算swap交易对地址
*/
getStringPairAddress(chainId, token0, token1) {
var array = this.tokenSort(token0, token1);
var all = Buffer.concat([cryptos.createHash('sha256').update(int32ToBytes(array[0].chainId)).digest(), cryptos.createHash('sha256').update(int32ToBytes(array[0].assetId)).digest(), cryptos.createHash('sha256').update(int32ToBytes(array[1].chainId)).digest(), cryptos.createHash('sha256').update(int32ToBytes(array[1].assetId)).digest()]);
var prefix = null;
if (5 === chainId) {
prefix = 'TNVT';
} else if (9 === chainId) {
prefix = "NERVE";
}
return sdk.getStringAddressBase(chainId, 4, null, cryptos.createHash('sha256').update(all).digest(), prefix);
},
/**
*
* 比较两个token是否相同
*/
tokenEquals(tokenA, tokenB) {
return tokenA.chainId == tokenB.chainId && tokenA.assetId == tokenB.assetId;
},
/**
*
* 组装一个交易对的json对象
*/
pair(token0, token1, reserve0, reserve1, feeRate) {
if (typeof feeRate === 'undefined') {
feeRate = 3;
}
return {
token0: token0,
token1: token1,
reserve0: reserve0,
reserve1: reserve1,
feeRate: feeRate
};
},
/**
*
* 根据指定的token,返回相应顺序的流动性数量
*/
getReserves(tokenA, tokenB, pair) {
var array = this.tokenSort(tokenA, tokenB);
var token0 = array[0];
var result = this.tokenEquals(tokenA, token0) ? [pair.reserve0, pair.reserve1, pair.feeRate] : [pair.reserve1, pair.reserve0, pair.feeRate];
return result;
},
/**
* 检查`token`是否为稳定币池中的token
* @param token
* @param stableGroupArray
*/
checkStableToken(token, stableGroupArray) {
var result = {
success: false
};
var length = stableGroupArray.length;
for (var i = 0; i < length; i++) {
var info = stableGroupArray[i];
if (info['groupCoin'][this.tokenStr(token)]) {
result.success = true;
result.address = info.address;
result.lpToken = this.parseTokenStr(info.lpToken);
result.groupCoin = info.groupCoin;
return result;
}
}
return result;
},
/**
* 计算最优交易路径
*/
bestTradeExactIn(chainId, pairs, tokenAmountIn, tokenOut, maxPairSize, stableGroupArray) {
var trade = calcBestTradeExactIn(chainId, pairs, tokenAmountIn, tokenOut, [], [], tokenAmountIn, maxPairSize, stableGroupArray);
if (!trade.path) return trade;
var tokenIn = trade.tokenAmountIn.token;
var amountIn = new BigNumber(trade.tokenAmountIn.amount);
var tokenPath = [tokenIn];
var path = trade.path;
var length = path.length;
var _1 = new BigNumber(1);
var _1000 = new BigNumber(1000);
var _rate = _1;
for (var i = 0; i < length; i++) {
var pair = path[i];
var token0 = pair.token0;
var token1 = pair.token1;
if (this.tokenEquals(tokenIn, token0)) {
tokenPath.push(token1);
tokenIn = token1;
} else {
tokenPath.push(token0);
tokenIn = token0;
}
_rate = _rate.multipliedBy(_1.minus(new BigNumber(pair.feeRate).div(_1000)));
}
_rate = _1.minus(_rate);
var pathFee = amountIn.multipliedBy(_rate);
trade.path = tokenPath;
trade.pathFee = pathFee.toFixed(0);
return trade;
},
/**
* 计算最优交易路径
*/
bestTradeExactOut(chainId, pairs, tokenIn, tokenAmountOut, maxPairSize, stableGroupArray) {
var trade = calcBestTradeExactOut(chainId, pairs, tokenIn, tokenAmountOut, [], [], tokenAmountOut, maxPairSize, stableGroupArray);
if (!trade.path) return trade;
var tokenOut = tokenAmountOut.token;
var tokenPath = [tokenOut];
var path = trade.path;
var length = path.length;
var _tokenTmp = tokenOut;
var _1 = new BigNumber(1);
var _1000 = new BigNumber(1000);
var _rate = _1;
for (var i = 0; i < length; i++) {
var pair = path[i];
var token0 = pair.token0;
var token1 = pair.token1;
if (swap.tokenEquals(_tokenTmp, token0)) {
tokenPath.push(token1);
_tokenTmp = token1;
} else {
tokenPath.push(token0);
_tokenTmp = token0;
}
_rate = _rate.multipliedBy(_1.minus(new BigNumber(pair.feeRate).div(_1000)));
}
_rate = _1.minus(_rate);
var pathFee = trade.tokenAmountIn.amount.multipliedBy(_rate);
var tokenPathArray = tokenPath.reverse();
trade.path = tokenPathArray;
trade.pathFee = pathFee.toFixed(0);
return trade;
},
/**
*
* 计算移除流动性可获得的资产数量
*/
calRemoveLiquidity(liquidity, tokenA, tokenB, pair) {
var _liquidity = new BigNumber(liquidity);
var reserves = this.getReserves(tokenA, tokenB, pair);
var reserveA = reserves[0];
var reserveB = reserves[1];
var totalSupply = new BigNumber(pair.totalSupply); // 可赎回的资产
var amountA = _liquidity.times(reserveA).dividedToIntegerBy(totalSupply);
var amountB = _liquidity.times(reserveB).dividedToIntegerBy(totalSupply);
if (amountA.isLessThanOrEqualTo(0) || amountB.isLessThanOrEqualTo(0)) {
// INSUFFICIENT_LIQUIDITY_BURNED
throw "sw_0014";
}
return {
amountA: amountA,
amountB: amountB
};
},
/**
* 根据交易对中其中一个币种,计算另外一个币种可添加的流动性
*/
quote(amountA, reserveA, reserveB) {
var _amountA = new BigNumber(amountA);
if (_amountA.isLessThanOrEqualTo(0)) {
// INSUFFICIENT_AMOUNT
throw "sw_0002";
}
var _reserveA = new BigNumber(reserveA);
var _reserveB = new BigNumber(reserveB);
if (_reserveA.isLessThanOrEqualTo(0) || _reserveB.isLessThanOrEqualTo(0)) {
// INSUFFICIENT_LIQUIDITY
throw "sw_0003";
}
return _amountA.times(_reserveB).dividedToIntegerBy(_reserveA);
},
/**
* 根据卖出数量,计算可买进的数量
*/
getAmountOut(amountIn, reserveIn, reserveOut, feeRate) {
if (typeof feeRate === 'undefined') {
feeRate = 3;
}
var _amountIn = new BigNumber(amountIn);
if (_amountIn.isLessThanOrEqualTo(0)) {
// INSUFFICIENT_INPUT_AMOUNT
throw "sw_0004";
}
var _reserveIn = new BigNumber(reserveIn);
var _reserveOut = new BigNumber(reserveOut);
if (_reserveIn.isLessThanOrEqualTo(0) || _reserveOut.isLessThanOrEqualTo(0)) {
// INSUFFICIENT_LIQUIDITY
throw "sw_0003";
} // let amountInWithFee = _amountIn.times(997);
var amountInWithFee = _amountIn.times(1000 - feeRate);
var numerator = amountInWithFee.times(_reserveOut);
var denominator = _reserveIn.times(1000).plus(amountInWithFee);
var amountOut = numerator.dividedToIntegerBy(denominator);
return amountOut;
},
/**
* 根据买进数量,计算可卖出数量
*/
getAmountIn(amountOut, reserveIn, reserveOut, feeRate) {
if (typeof feeRate === 'undefined') {
feeRate = 3;
}
var _amountOut = new BigNumber(amountOut);
if (_amountOut.isLessThanOrEqualTo(0)) {
// INSUFFICIENT_OUTPUT_AMOUNT
throw "sw_0005";
}
var _reserveIn = new BigNumber(reserveIn);
var _reserveOut = new BigNumber(reserveOut);
if (_reserveOut.isLessThanOrEqualTo(_amountOut) || _reserveIn.isLessThanOrEqualTo(0) || _reserveOut.isLessThanOrEqualTo(0)) {
// INSUFFICIENT_LIQUIDITY
throw "sw_0003";
}
var numerator = _reserveIn.times(_amountOut).times(1000); // let denominator = _reserveOut.minus(_amountOut).times(997);
var denominator = _reserveOut.minus(_amountOut).times(1000 - feeRate);
var amountIn = numerator.dividedToIntegerBy(denominator).plus(1);
return amountIn;
},
/**
*
* 根据卖出数量,计算可买进的数量
*/
getAmountsOut(amountIn, tokenPathArray, pairsArray) {
var pathLength = tokenPathArray.length;
if (pathLength < 1 || pathLength > 100) {
// INVALID_PATH
throw "sw_0006";
}
var amounts = new Array(pathLength);
amounts[0] = amountIn;
var reserveIn;
var reserveOut;
for (var i = 0; i < pathLength - 1; i++) {
var reserves = this.getReserves(tokenPathArray[i], tokenPathArray[i + 1], pairsArray[i]);
reserveIn = reserves[0];
reserveOut = reserves[1];
amounts[i + 1] = this.getAmountOut(amounts[i], reserveIn, reserveOut, reserves[2]);
}
return amounts;
},
/**
*
* 根据买进数量,计算可卖出数量
*/
getAmountsIn(amountOut, tokenPathArray, pairsArray) {
var pathLength = tokenPathArray.length;
if (pathLength < 1 || pathLength > 100) {
// INVALID_PATH
throw "sw_0006";
}
var amounts = new Array(pathLength);
amounts[pathLength - 1] = amountOut;
var reserveIn;
var reserveOut;
for (var i = pathLength - 1; i > 0; i--) {
var reserves = this.getReserves(tokenPathArray[i - 1], tokenPathArray[i], pairsArray[i - 1]);
reserveIn = reserves[0];
reserveOut = reserves[1];
amounts[i - 1] = this.getAmountIn(amounts[i], reserveIn, reserveOut, reserves[2]);
}
return amounts;
},
/**
*
* 根据交易数量,计算当前流动池数量和交易后的流动池数量
*/
getAmountsReserves(amounts, tokenPathArray, pairsArray) {
var pathLength = tokenPathArray.length;
if (pathLength < 1 || pathLength > 100) {
// INVALID_PATH
throw "sw_0006";
}
var amountIn = amounts[0];
var amountOut = amounts[amounts.length - 1];
var reserves = this.getReserves(tokenPathArray[0], tokenPathArray[1], pairsArray[0]);
var reserveIn = new BigNumber(reserves[0]);
var _reserveIn = reserveIn.plus(amountIn);
var reserveOut;
if (pathLength < 3) {
reserveOut = new BigNumber(reserves[1]);
} else {
reserves = this.getReserves(tokenPathArray[pathLength - 2], tokenPathArray[pathLength - 1], pairsArray[pathLength - 2]);
reserveOut = new BigNumber(reserves[1]);
}
var _reserveOut = reserveOut.minus(amountOut);
return [reserveIn, reserveOut, _reserveIn, _reserveOut];
},
/**
*
* 根据交易数量计算价格影响
*
* 计算规则:
* 原始池: reserveIn, reserveOut
* 交易后的池: _reserveIn, _reserveOut
* 原始价格: reserveOut / reserveIn
* 交易后的价格: _reserveOut / _reserveIn
* 结果 = (原始价格 - 交易后的价格).abs() / 原始价格
*/
getPriceImpact(amounts, tokenPathArray, pairsArray) {
var array = this.getAmountsReserves(amounts, tokenPathArray, pairsArray);
var reserveIn = array[0];
var reserveOut = array[1];
var _reserveIn = array[2];
var _reserveOut = array[3];
var priceImpact = new BigNumber(1).minus(new BigNumber(_reserveOut.times(reserveIn).shiftedBy(78).div(_reserveIn.times(reserveOut)).toFixed(78)).shiftedBy(-78)).abs();
return priceImpact;
},
/**
* 组装交易: swap创建交易对
*
* @param fromAddress 用户地址
* @param tokenA 资产A的类型,示例:nerve.swap.token(5,1)
* @param tokenB 资产B的类型,示例:nerve.swap.token(5,6)
* @param remark 交易备注
* @returns 交易序列化hex字符串
*/
swapCreatePair(fromAddress, tokenA, tokenB, remark) {
return _asyncToGenerator(function* () {
var transferInfo = {
fromAddress: fromAddress,
toAddress: fromAddress,
fee: 0,
assetsChainId: nerve.chainId(),
assetsId: 1,
amount: 0
};
var balance = yield util.getNulsBalance(transferInfo.fromAddress, transferInfo.assetsChainId, transferInfo.assetsId);
var inOrOutputs = yield util.inputsOrOutputs(transferInfo, balance.data);
if (!inOrOutputs.success) {
throw "inputs、outputs组装错误";
}
var tAssemble = nerve.transactionAssemble(inOrOutputs.data.inputs, inOrOutputs.data.outputs, remark, 61, {
tokenA: tokenA,
tokenB: tokenB
}); //获取hash
var hash = yield tAssemble.getHash();
var txhex = tAssemble.txSerialize().toString("hex");
return {
hash: hash.toString('hex'),
hex: txhex
};
})();
},
/**
* 组装交易: swap添加流动性
*
* @param fromAddress 用户地址
* @param tokenAmountA 添加的资产A的数量,示例:nerve.swap.tokenAmount(5, 1, "140000000000")
* @param tokenAmountB 添加的资产B的数量,示例:nerve.swap.tokenAmount(5, 6, "100000000")
* @param amountAMin 资产A最小添加值
* @param amountBMin 资产B最小添加值
* @param deadline 过期时间,示例:nerve.swap.currentTime() + 300 (5分钟/300秒以后)
* @param to 流动性份额接收地址
* @param remark 交易备注
* @returns 交易序列化hex字符串
*/
swapAddLiquidity(fromAddress, tokenAmountA, tokenAmountB, amountAMin, amountBMin, deadline, to, remark) {
var _this = this;
return _asyncToGenerator(function* () {
var pairAddress = _this.getStringPairAddress(nerve.chainId(), tokenAmountA, tokenAmountB);
var inOrOutputs = yield inputsOrOutputsOfSwapAddLiquidity(fromAddress, to, tokenAmountA, tokenAmountB, pairAddress);
if (!inOrOutputs.success) {
throw "inputs、outputs组装错误";
}
var tAssemble = nerve.transactionAssemble(inOrOutputs.data.inputs, inOrOutputs.data.outputs, remark, 64, {
tokenA: tokenAmountA,
tokenB: tokenAmountB,
to: to,
deadline: deadline,
amountAMin: amountAMin,
amountBMin: amountBMin
}); //获取hash
var hash = yield tAssemble.getHash();
var txhex = tAssemble.txSerialize().toString("hex");
return {
hash: hash.toString('hex'),
hex: txhex
};
})();
},
/**
* 组装交易: swap移除流动性
*
* @param fromAddress 用户地址
* @param tokenAmountLP 移除的资产LP的数量,示例:nerve.swap.tokenAmount(5, 18, "2698778989")
* @param tokenAmountAMin 资产A最小移除值,示例:nerve.swap.tokenAmount(5, 1, "140000000000")
* @param tokenAmountBMin 资产B最小移除值,示例:nerve.swap.tokenAmount(5, 6, "100000000")
* @param deadline 过期时间,示例:nerve.swap.currentTime() + 300 (5分钟/300秒以后)
* @param to 移除流动性份额接收地址
* @param remark 交易备注
* @returns 交易序列化hex字符串
*/
swapRemoveLiquidity(fromAddress, tokenAmountLP, tokenAmountAMin, tokenAmountBMin, deadline, to, remark) {
var _this2 = this;
return _asyncToGenerator(function* () {
var pairAddress = _this2.getStringPairAddress(nerve.chainId(), tokenAmountAMin, tokenAmountBMin);
var transferInfo = {
fromAddress: fromAddress,
toAddress: pairAddress,
fee: 0,
assetsChainId: tokenAmountLP.chainId,
assetsId: tokenAmountLP.assetId,
amount: tokenAmountLP.amount
};
var balance = yield util.getNulsBalance(transferInfo.fromAddress, transferInfo.assetsChainId, transferInfo.assetsId);
var inOrOutputs = yield util.inputsOrOutputs(transferInfo, balance.data);
if (!inOrOutputs.success) {
throw "inputs、outputs组装错误";
}
var tAssemble = nerve.transactionAssemble(inOrOutputs.data.inputs, inOrOutputs.data.outputs, remark, 65, {
tokenA: tokenAmountAMin,
tokenB: tokenAmountBMin,
to: to,
deadline: deadline,
amountAMin: tokenAmountAMin.amount,
amountBMin: tokenAmountBMin.amount
}); //获取hash
var hash = yield tAssemble.getHash();
var txhex = tAssemble.txSerialize().toString("hex");
return {
hash: hash.toString('hex'),
hex: txhex
};
})();
},
/**
* 组装交易: swap币币交易
*
* @param fromAddress 用户地址
* @param amountIn 卖出的资产数量
* @param tokenPath 币币交换资产路径,路径中最后一个资产,是用户要买进的资产,
* 如卖A买B: [A, B] or [A, C, B],
* 示例: [nerve.swap.token(5, 1), nerve.swap.token(5, 6)]
* @param amountOutMin 最小买进的资产数量
* @param feeTo 交易手续费取出一部分给指定的接收地址
* @param deadline 过期时间,示例:nerve.swap.currentTime() + 300 (5分钟/300秒以后)
* @param to 资产接收地址
* @param remark 交易备注
* @returns 交易序列化hex字符串
*/
swapTrade(fromAddress, amountIn, tokenPath, amountOutMin, feeTo, deadline, to, remark) {
var _this3 = this;
return _asyncToGenerator(function* () {
if (feeTo == null) {
feeTo = '';
}
var firstTokenIn = tokenPath[0];
var pairAddress = _this3.getStringPairAddress(nerve.chainId(), firstTokenIn, tokenPath[1]);
var transferInfo = {
fromAddress: fromAddress,
toAddress: pairAddress,
fee: 0,
assetsChainId: firstTokenIn.chainId,
assetsId: firstTokenIn.assetId,
amount: amountIn
};
var balance = yield util.getNulsBalance(transferInfo.fromAddress, transferInfo.assetsChainId, transferInfo.assetsId);
var inOrOutputs = yield util.inputsOrOutputs(transferInfo, balance.data);
if (!inOrOutputs.success) {
throw "inputs、outputs组装错误";
}
var tAssemble = nerve.transactionAssemble(inOrOutputs.data.inputs, inOrOutputs.data.outputs, remark, 63, {
amountOutMin: amountOutMin,
to: to,
feeTo: feeTo,
deadline: deadline,
tokenPath: tokenPath
}); //获取hash
var hash = yield tAssemble.getHash();
var txhex = tAssemble.txSerialize().toString("hex");
return {
hash: hash.toString('hex'),
hex: txhex
};
})();
},
/**
* 组装交易: swap币币交易(聚合稳定币池)
*
* @param fromAddress 用户地址
* @param amountIn 卖出的资产数量
* @param tokenPath 币币交换资产路径,路径中最后一个资产,是用户要买进的资产,
* 如卖A买B: [A, B] or [A, C, B],
* 示例: [nerve.swap.token(5, 1), nerve.swap.token(5, 6)]
* @param amountOutMin 最小买进的资产数量
* @param feeTo 交易手续费取出一部分给指定的接收地址
* @param deadline 过期时间,示例:nerve.swap.currentTime() + 300 (5分钟/300秒以后)
* @param to 资产接收地址
* @param stableGroupArray 支持的稳定币池信息
* @param remark 交易备注
* @returns 交易序列化hex字符串
*/
swapTradeWithCombinedStable(fromAddress, amountIn, tokenPath, amountOutMin, feeTo, deadline, to, stableGroupArray, remark) {
var _this4 = this;
return _asyncToGenerator(function* () {
if (feeTo == null) {
feeTo = '';
}
var firstTokenIn = tokenPath[0];
var secondTokenIn = tokenPath[1]; // 检查前两个币是否稳定币池
var pairAddress;
var group = isGroupStable(firstTokenIn, secondTokenIn, stableGroupArray);
if (group.success) {
pairAddress = group.address;
}
if (!pairAddress) {
// 普通交易对
pairAddress = _this4.getStringPairAddress(nerve.chainId(), firstTokenIn, secondTokenIn);
}
var transferInfo = {
fromAddress: fromAddress,
toAddress: pairAddress,
fee: 0,
assetsChainId: firstTokenIn.chainId,
assetsId: firstTokenIn.assetId,
amount: amountIn
};
var balance = yield util.getNulsBalance(transferInfo.fromAddress, transferInfo.assetsChainId, transferInfo.assetsId);
var inOrOutputs = yield util.inputsOrOutputs(transferInfo, balance.data);
if (!inOrOutputs.success) {
throw "inputs、outputs组装错误";
}
var tAssemble = nerve.transactionAssemble(inOrOutputs.data.inputs, inOrOutputs.data.outputs, remark, 63, {
amountOutMin: amountOutMin,
to: to,
feeTo: feeTo,
deadline: deadline,
tokenPath: tokenPath
}); //获取hash
var hash = yield tAssemble.getHash();
var txhex = tAssemble.txSerialize().toString("hex");
return {
hash: hash.toString('hex'),
hex: txhex
};
})();
},
/**
* 组装交易: stable-swap创建交易对
*
* @param fromAddress 用户地址
* @param coins 资产类型列表,示例:[nerve.swap.token(5, 6), nerve.swap.token(5, 9), nerve.swap.token(5, 7), nerve.swap.token(5, 8)]
* @param symbol LP名称(选填)
* @param remark 交易备注
* @returns 交易序列化hex字符串
*/
stableSwapCreatePair(fromAddress, coins, symbol, remark) {
return _asyncToGenerator(function* () {
var transferInfo = {
fromAddress: fromAddress,
toAddress: fromAddress,
fee: 0,
assetsChainId: nerve.chainId(),
assetsId: 1,
amount: 0
};
var balance = yield util.getNulsBalance(transferInfo.fromAddress, transferInfo.chainId, transferInfo.assetId);
var inOrOutputs = yield util.inputsOrOutputs(transferInfo, balance.data);
if (!inOrOutputs.success) {
throw "inputs、outputs组装错误";
}
var tAssemble = nerve.transactionAssemble(inOrOutputs.data.inputs, inOrOutputs.data.outputs, remark, 71, {
coins: coins,
symbol: symbol
}); //获取hash
var hash = yield tAssemble.getHash();
var txhex = tAssemble.txSerialize().toString("hex");
return {
hash: hash.toString('hex'),
hex: txhex
};
})();
},
/**
* 组装交易: stable-swap添加流动性
*
* @param fromAddress 用户地址
* @param stablePairAddress 交易对地址
* @param tokenAmounts 添加的资产数量列表,示例:[swap.tokenAmount(5, 6, "60000000000"), swap.tokenAmount(5, 7, "700000000"), swap.tokenAmount(5, 8, "800000000"), swap.tokenAmount(5, 9, "900000000")]
* @param deadline 过期时间,示例:nerve.swap.currentTime() + 300 (5分钟/300秒以后)
* @param to 流动性份额接收地址
* @param remark 交易备注
* @returns 交易序列化hex字符串
*/
stableSwapAddLiquidity(fromAddress, stablePairAddress, tokenAmounts, deadline, to, remark) {
return _asyncToGenerator(function* () {
var inOrOutputs = yield inputsOrOutputsOfStableAddLiquidityOrTrade(fromAddress, stablePairAddress, tokenAmounts);
if (!inOrOutputs.success) {
throw "inputs、outputs组装错误";
}
var tAssemble = nerve.transactionAssemble(inOrOutputs.data.inputs, inOrOutputs.data.outputs, remark, 73, {
to: to
}); //获取hash
var hash = yield tAssemble.getHash();
var txhex = tAssemble.txSerialize().toString("hex");
return {
hash: hash.toString('hex'),
hex: txhex
};
})();
},
/**
* 组装交易: stable-swap移除流动性
*
* @param fromAddress 用户地址
* @param stablePairAddress 交易对地址
* @param tokenAmountLP 移除的资产LP的数量,示例:nerve.swap.tokenAmount(5, 18, "2698778989")
* @param receiveOrderIndexs 按币种索引顺序接收资产,示例:[4, 2, 3, 1]
* @param deadline 过期时间,示例:nerve.swap.currentTime() + 300 (5分钟/300秒以后)
* @param to 移除流动性份额接收地址
* @param remark 交易备注
* @returns 交易序列化hex字符串
*/
stableSwapRemoveLiquidity(fromAddress, stablePairAddress, tokenAmountLP, receiveOrderIndexs, deadline, to, remark) {
return _asyncToGenerator(function* () {
var pairAddress = stablePairAddress;
var transferInfo = {
fromAddress: fromAddress,
toAddress: pairAddress,
fee: 0,
assetsChainId: tokenAmountLP.chainId,
assetsId: tokenAmountLP.assetId,
amount: tokenAmountLP.amount
};
var balance = yield util.getNulsBalance(transferInfo.fromAddress, transferInfo.assetsChainId, transferInfo.assetsId);
var inOrOutputs = yield util.inputsOrOutputs(transferInfo, balance.data);
if (!inOrOutputs.success) {
throw "inputs、outputs组装错误";
}
var tAssemble = nerve.transactionAssemble(inOrOutputs.data.inputs, inOrOutputs.data.outputs, remark, 74, {
indexs: Buffer.from(receiveOrderIndexs),
to: to
}); //获取hash
var hash = yield tAssemble.getHash();
var txhex = tAssemble.txSerialize().toString("hex");
return {
hash: hash.toString('hex'),
hex: txhex
};
})();
},
/**
* 组装交易:StableSwap币币交易
*
* @param fromAddress 用户地址
* @param stablePairAddress 交易对地址
* @param amountIns 卖出的资产数量列表,示例:[nerve.swap.tokenAmount(5, 6, "600000000"), nerve.swap.tokenAmount(5, 9, "90000000")]
* @param tokenOutIndex 买进的资产索引,示例:3
* @param feeTo 交易手续费接收地址
* @param deadline 过期时间,示例:nerve.swap.currentTime() + 300 (5分钟/300秒以后)
* @param to 资产接收地址
* @param remark 交易备注
* @param feeTokenAmount 交易手续费,示例:nerve.swap.tokenAmount(5, 6, "6000000")
* @returns 交易序列化hex字符串
*/
stableSwapTrade(fromAddress, stablePairAddress, amountIns, tokenOutIndex, feeTo, deadline, to, remark, feeTokenAmount) {
return _asyncToGenerator(function* () {
var inOrOutputs = yield inputsOrOutputsOfStableAddLiquidityOrTrade(fromAddress, stablePairAddress, amountIns, feeTo, feeTokenAmount);
if (!inOrOutputs.success) {
throw "inputs、outputs组装错误";
}
if (feeTo == null) {
feeTo = '';
}
var tAssemble = nerve.transactionAssemble(inOrOutputs.data.inputs, inOrOutputs.data.outputs, remark, 72, {
to: to,
tokenOutIndex: Buffer.from([tokenOutIndex]),
feeTo: feeTo
}); //获取hash
var hash = yield tAssemble.getHash();
var txhex = tAssemble.txSerialize().toString("hex");
return {
hash: hash.toString('hex'),
hex: txhex
};
})();
},
/**
* 组装交易: stable-lp-swap-trade
*
* @param fromAddress 用户地址
* @param stablePairAddress 稳定币交易对地址
* @param amountIn 卖出的资产数量
* @param tokenPath 币币交换资产路径,路径中最后一个资产,是用户要买进的资产,
* 如卖A买B: [A, stableLp, B] or [A, stableLp, C, B],
* 示例: [nerve.swap.token(5, 1), nerve.swap.token(5, 6)...]
* @param amountOutMin 最小买进的资产数量
* @param feeTo 交易手续费取出一部分给指定的接收地址
* @param deadline 过期时间,示例:nerve.swap.currentTime() + 300 (5分钟/300秒以后)
* @param to 流动性份额接收地址
* @param remark 交易备注
* @returns 交易序列化hex字符串
*/
stableLpSwapTrade(fromAddress, stablePairAddress, amountIn, tokenPath, amountOutMin, feeTo, deadline, to, remark) {
var _this5 = this;
return _asyncToGenerator(function* () {
if (feeTo == null) {
feeTo = '';
}
var tokenIn = tokenPath[0];
var tokenAmountIn = _this5.tokenAmount(tokenIn.chainId, tokenIn.assetId, amountIn);
var inOrOutputs = yield inputsOrOutputsOfStableAddLiquidityOrTrade(fromAddress, stablePairAddress, [tokenAmountIn]);
if (!inOrOutputs.success) {
throw "inputs、outputs组装错误";
}
var tAssemble = nerve.transactionAssemble(inOrOutputs.data.inputs, inOrOutputs.data.outputs, remark, 77, {
amountOutMin: amountOutMin,
to: to,
feeTo: feeTo,
deadline: deadline,
tokenPath: tokenPath
}); //获取hash
var hash = yield tAssemble.getHash();
var txhex = tAssemble.txSerialize().toString("hex");
return {
hash: hash.toString('hex'),
hex: txhex
};
})();
},
/**
* 组装交易: swap交易聚合稳定币撤销流动性交易
*
* @param fromAddress 用户地址
* @param amountIn 卖出的资产数量
* @param tokenPath 币币交换资产路径,路径中最后一个资产,是用户要买进的资产,
* 如卖A买B: [A, B] or [A, C, B],
* 示例: [nerve.swap.token(5, 1), nerve.swap.token(5, 6)]
* @param amountOutMin 最小买进的资产数量
* @param feeTo 交易手续费取出一部分给指定的接收地址
* @param deadline 过期时间,示例:nerve.swap.currentTime() + 300 (5分钟/300秒以后)
* @param to 资产接收地址
* @param targetToken 撤销稳定币流动性换出的资产
* @param remark 交易备注
* @returns 交易序列化hex字符串
*/
swapTradeStableRemoveLp(fromAddress, amountIn, tokenPath, amountOutMin, feeTo, deadline, to, targetToken, remark) {
var _this6 = this;
return _asyncToGenerator(function* () {
if (feeTo == null) {
feeTo = '';
}
var firstTokenIn = tokenPath[0];
var pairAddress = _this6.getStringPairAddress(nerve.chainId(), firstTokenIn, tokenPath[1]);
var transferInfo = {
fromAddress: fromAddress,
toAddress: pairAddress,
fee: 0,
assetsChainId: firstTokenIn.chainId,
assetsId: firstTokenIn.assetId,
amount: amountIn
};
var balance = yield util.getNulsBalance(transferInfo.fromAddress, transferInfo.assetsChainId, transferInfo.assetsId);
var inOrOutputs = yield util.inputsOrOutputs(transferInfo, balance.data);
if (!inOrOutputs.success) {
throw "inputs、outputs组装错误";
}
var tAssemble = nerve.transactionAssemble(inOrOutputs.data.inputs, inOrOutput