tokenlon-sdk
Version:
imToken Tokenlon API for node
182 lines • 10.1 kB
JavaScript
;
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
var _ = require("lodash");
var constants_1 = require("../constants");
var helper_1 = require("./helper");
var math_1 = require("./math");
var format_1 = require("./format");
var types_1 = require("../types");
var _0x_js_1 = require("0x.js");
var sign_1 = require("./sign");
var assert_1 = require("./assert");
var pair_1 = require("./pair");
// generate a dex order without salt by simple order
exports.generateDexOrderWithoutSalt = function (params) {
var simpleOrder = params.simpleOrder, pair = params.pair, config = params.config;
var base = pair.base, quote = pair.quote;
var side = simpleOrder.side, price = simpleOrder.price, amount = simpleOrder.amount, expirationUnixTimestampSec = simpleOrder.expirationUnixTimestampSec;
var isBuy = side === 'BUY';
var baseTokenAmountUnit = amount;
var quoteTokenAmountUnit = math_1.toBN(price).times(amount);
return {
maker: helper_1.lowerCase(config.wallet.address),
taker: helper_1.lowerCase(constants_1.ETH_CONTRACT),
makerTokenAmount: isBuy ? format_1.fromUnitToDecimalBN(quoteTokenAmountUnit, quote.decimal) : format_1.fromUnitToDecimalBN(baseTokenAmountUnit, base.decimal),
takerTokenAmount: isBuy ? format_1.fromUnitToDecimalBN(baseTokenAmountUnit, base.decimal) : format_1.fromUnitToDecimalBN(quoteTokenAmountUnit, quote.decimal),
makerTokenAddress: helper_1.lowerCase(isBuy ? quote.contractAddress : base.contractAddress),
takerTokenAddress: helper_1.lowerCase(isBuy ? base.contractAddress : quote.contractAddress),
// 智能合约上的判断 因此 expirationUnixTimestampSec 为必填项 未设置情况下设置到明年今日
// if(block.timestamp >= order.expirationTimestampInSec) {
// LogError(uint8(Errors.ORDER_EXPIRED), order.orderHash);
// return 0;
// }
expirationUnixTimestampSec: math_1.toBN(expirationUnixTimestampSec || helper_1.getTimestamp() + 86400 * 365),
exchangeContractAddress: helper_1.lowerCase(config.zeroEx.exchangeContractAddress),
feeRecipient: constants_1.FEE_RECIPIENT,
// TODO setting fees
makerFee: math_1.toBN(0),
takerFee: math_1.toBN(0),
};
};
// use 0x.js and privateKey's personal sign, to generate a dex order
exports.getSignedOrder = function (orderWithoutSalt, config) {
var order = __assign({}, orderWithoutSalt, { salt: _0x_js_1.ZeroEx.generatePseudoRandomSalt() });
var hash = _0x_js_1.ZeroEx.getOrderHashHex(order);
return __assign({}, order, { ecSignature: sign_1.personalECSignHex(config.wallet.privateKey, hash) });
};
var translateValueHelper = function (obj, check, operate) {
var result = {};
_.keys(obj).forEach(function (key) {
var v = obj[key];
result[key] = check(v) ? operate(v) : v;
});
return result;
};
// translate a dex order with bigNumber to string
exports.orderBNToString = function (order) {
var result = {};
result = translateValueHelper(order, math_1.isBigNumber, function (v) { return v.toString(); });
return result;
};
exports.orderStringToBN = function (order) {
var result = {};
var check = function (v) { return _.isString(v) && !v.startsWith('0x'); };
result = translateValueHelper(order, check, math_1.toBN);
return result;
};
exports.getAmountTotal = function (params) {
var order = params.order, pair = params.pair;
var base = pair.base, quote = pair.quote, precision = pair.precision;
var formatPrice = format_1.formatNumHelper(precision);
var makerTokenAddress = order.makerTokenAddress, makerTokenAmount = order.makerTokenAmount, takerTokenAddress = order.takerTokenAddress, takerTokenAmount = order.takerTokenAmount;
var isBuy = helper_1.helpCompareStr(base.contractAddress, takerTokenAddress) && helper_1.helpCompareStr(quote.contractAddress, makerTokenAddress);
var baseTokenAmountBN = isBuy ? format_1.fromDecimalToUnit(takerTokenAmount, base.decimal) : format_1.fromDecimalToUnit(makerTokenAmount, base.decimal);
var amountTotal = math_1.toBN(formatPrice(baseTokenAmountBN.toString(), false)).toNumber();
return amountTotal;
};
// translate dex order to simple order, for us to check which order we want to fill
exports.getSimpleOrder = function (params) {
var order = params.order, pair = params.pair, amountRemaining = params.amountRemaining;
var base = pair.base, quote = pair.quote, precision = pair.precision;
var formatPrice = format_1.formatNumHelper(precision);
var expirationUnixTimestampSec = order.expirationUnixTimestampSec, makerTokenAddress = order.makerTokenAddress, makerTokenAmount = order.makerTokenAmount, takerTokenAddress = order.takerTokenAddress, takerTokenAmount = order.takerTokenAmount;
var isBuy = helper_1.helpCompareStr(base.contractAddress, takerTokenAddress) && helper_1.helpCompareStr(quote.contractAddress, makerTokenAddress);
var side = isBuy ? 'BUY' : 'SELL';
var baseTokenAmountBN = isBuy ? format_1.fromDecimalToUnit(takerTokenAmount, base.decimal) : format_1.fromDecimalToUnit(makerTokenAmount, base.decimal);
var quoteTokenAmountBN = isBuy ? format_1.fromDecimalToUnit(makerTokenAmount, quote.decimal) : format_1.fromDecimalToUnit(takerTokenAmount, quote.decimal);
var amountRemainingBN = amountRemaining && math_1.toBN(amountRemaining).lt(baseTokenAmountBN) ? math_1.toBN(amountRemaining) : baseTokenAmountBN;
var price = math_1.toBN(formatPrice(quoteTokenAmountBN.dividedBy(baseTokenAmountBN).toString(), false)).toNumber();
var amount = math_1.toBN(formatPrice(amountRemainingBN.toString(), false)).toNumber();
return {
side: side,
price: price,
amount: amount,
expirationUnixTimestampSec: math_1.toBN(expirationUnixTimestampSec).toNumber(),
};
};
exports.getSimpleOrderWithBaseQuoteBySignedOrder = function (order, pairs) {
var pair = pair_1.getPairBySignedOrder(order, pairs);
var simpleOrder = exports.getSimpleOrder({
order: order,
pair: pair,
});
return __assign({ base: pair.base.symbol.toUpperCase(), quote: pair.quote.symbol.toUpperCase() }, simpleOrder);
};
exports.translateOrderBookToSimple = function (params) {
var orderbookItems = params.orderbookItems, pair = params.pair, wallet = params.wallet;
return orderbookItems.map(function (item) {
var amountRemaining = item.amountRemaining, payload = item.payload;
return __assign({}, exports.getSimpleOrder({
pair: pair,
order: payload,
amountRemaining: amountRemaining,
}), { amountTotal: exports.getAmountTotal({ pair: pair, order: payload }), isMaker: !!wallet && helper_1.helpCompareStr(wallet.address, payload.maker), rawOrder: JSON.stringify(payload) });
});
};
// fill order need to change side
// if is buy, then maker token is weth, so we use quote decimal
exports.getFillTakerTokenAmountBN = function (side, amount, price, pair) {
return side === 'SELL' ? format_1.fromUnitToDecimalBN(amount, pair.base.decimal) : format_1.fromUnitToDecimalBN(math_1.toBN(amount).times(price).toNumber(), pair.quote.decimal);
};
exports.getFillTakerTokenAmountBNByUpToOrders = function (side, amount, simpleOrders, pair) {
if (side === 'SELL') {
return format_1.fromUnitToDecimalBN(amount, pair.base.decimal);
}
var remainedAmountBN = math_1.toBN(amount);
var takerTokenAmountBN = math_1.toBN(0);
simpleOrders.some(function (so) {
var orderPrice = so.price;
var orderAmount = so.amount;
// if base amount is too large, then set takerTokenAmount as orders quote amounts
if (remainedAmountBN.gt(math_1.toBN(orderAmount))) {
takerTokenAmountBN = takerTokenAmountBN.plus(exports.getFillTakerTokenAmountBN('BUY', orderAmount, orderPrice, pair));
remainedAmountBN = remainedAmountBN.minus(math_1.toBN(orderAmount));
// // if orders quote amount larger then base amount, then set takerTokenAmount as calculated amount
}
else {
takerTokenAmountBN = takerTokenAmountBN.plus(exports.getFillTakerTokenAmountBN('BUY', remainedAmountBN, orderPrice, pair));
return true;
}
});
return takerTokenAmountBN;
};
exports.getOrderFillRequest = function (params, pairs) {
var rawOrder = params.rawOrder, price = params.price, amount = params.amount, side = params.side, base = params.base, quote = params.quote;
assert_1.assert.isValidrawOrder(rawOrder);
assert_1.assert.isValidBaseQuote(params, pairs);
var order = JSON.parse(rawOrder);
var isBuy = side === 'BUY';
var pair = pair_1.getPairByContractAddress(isBuy ? {
base: order.makerTokenAddress,
quote: order.takerTokenAddress,
} : {
base: order.takerTokenAddress,
quote: order.makerTokenAddress,
}, pairs);
if (!helper_1.helpCompareStr(pair.base.symbol, base) || !helper_1.helpCompareStr(pair.quote.symbol, quote)) {
throw helper_1.newError(types_1.TokenlonError.UnsupportedPair);
}
assert_1.assert.isValidSimpleOrder(params, pair.precision);
var simpleOrder = exports.getSimpleOrder({
order: order,
pair: pair,
});
var formatPrice = format_1.formatNumHelper(pair.precision);
if (formatPrice(simpleOrder.price, false) !== formatPrice(price, false)) {
throw helper_1.newError(types_1.TokenlonError.InvalidPriceWithToBeFilledOrder);
}
var takerTokenAmountBN = exports.getFillTakerTokenAmountBN(side, amount, price, pair);
return {
signedOrder: exports.orderStringToBN(order),
takerTokenFillAmount: takerTokenAmountBN,
};
};
//# sourceMappingURL=dex.js.map