crypto-client
Version:
An unified client for all cryptocurrency exchanges.
253 lines (252 loc) • 9.64 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDepositAddresses = exports.getWithdrawalFees = exports.queryBalance = exports.queryAllBalances = exports.queryOpenOrder = exports.queryOrder = exports.cancelOrder = exports.placeOrder = exports.initilize = void 0;
// forked from https://github.com/WhaleEx/API/blob/master/sample/nodejs/whaleex-api.js
const assert_1 = require("assert");
const axios_1 = __importDefault(require("axios"));
const crypto_pair_1 = require("crypto-pair");
const eos_token_info_1 = require("eos-token-info");
const config_1 = require("../config");
const util_1 = require("../util");
// import debug from '../util/debug';
const whaleex_sign_1 = require("../util/whaleex_sign");
const WHALEEX_ACCOUNT = 'whaleextrust';
const URL_PREFIX = 'https://api.whaleex.com/BUSINESS';
async function getGlobalIds(remark = '0') {
const path = '/api/v1/order/globalIds';
const params = whaleex_sign_1.signData('GET', path, { remark, size: 100 });
const response = await axios_1.default.get(`${URL_PREFIX}${path}?${params}`);
assert_1.strict.equal(response.status, 200);
assert_1.strict.equal(response.data.returnCode, '0');
return response.data.result;
}
const ID_CACHE = { remark: '0', list: [], lastTimestamp: Date.now() };
async function getIdFromCache() {
const now = Date.now();
// IDs expire after 5 minutes, so update them per 3 minutes
if (ID_CACHE.list.length === 0 || now - ID_CACHE.lastTimestamp >= 3 * 60 * 1000) {
const { remark, list } = await getGlobalIds(ID_CACHE.remark);
ID_CACHE.remark = remark;
ID_CACHE.list = list;
ID_CACHE.lastTimestamp = now;
}
return ID_CACHE.list.pop();
}
async function initilize(apiKey, userId) {
assert_1.strict.ok(apiKey);
assert_1.strict.ok(userId);
config_1.USER_CONFIG.WHALEEX_API_KEY = apiKey;
config_1.USER_CONFIG.WHALEEX_USER_ID = userId;
const { remark, list } = await getGlobalIds(ID_CACHE.remark);
ID_CACHE.remark = remark;
ID_CACHE.list = list;
ID_CACHE.lastTimestamp = Date.now();
}
exports.initilize = initilize;
async function placeOrder(market, price, quantity, sell) {
try {
assert_1.strict.ok(market);
assert_1.strict.ok(config_1.USER_CONFIG.WHALEEX_API_KEY, 'APIKey is empty');
assert_1.strict.ok(config_1.USER_CONFIG.eosAccount);
assert_1.strict.ok(config_1.USER_CONFIG.eosPrivateKey);
const [priceStr, quantityStr] = util_1.convertPriceAndQuantityToStrings(market, price, quantity, sell);
const path = '/api/v1/order/orders/place';
let orderId;
for (let i = 0; i < 3; i += 1) {
if (orderId instanceof Error || orderId === undefined) {
// eslint-disable-next-line no-await-in-loop
orderId = await getIdFromCache().catch((e) => {
return e;
});
}
}
if (orderId instanceof Error)
return orderId;
if (orderId === undefined)
return new Error(`orderId is undefined`);
const order = {
orderId,
amount: quantityStr,
price: priceStr,
symbol: market.id,
type: sell ? 'sell-limit' : 'buy-limit',
};
let baseToken = market.base;
if (baseToken === 'MYKEY')
baseToken = 'KEY';
const symbolObj = {
baseToken,
quoteToken: market.quote,
basePrecision: market.precision.base,
quotePrecision: market.precision.quote,
baseContract: market.info.baseContract,
quoteContract: market.info.quoteContract,
};
const params = whaleex_sign_1.signDataOrder(order, symbolObj);
const response = await axios_1.default.post(`${URL_PREFIX}${path}?${params}`, order, {
transformResponse: (resp) => {
return JSON.parse(resp.replace(/"result":(\d+)/g, '"result":"$1"'));
},
responseType: 'json',
}).catch((e) => {
return e;
});
if (response instanceof Error)
return response;
assert_1.strict.equal(response.status, 200);
if (response.data.returnCode === '0') {
assert_1.strict.equal(typeof response.data.result, 'string');
return response.data.result;
}
return new Error(JSON.stringify({ price: priceStr, quantity: quantityStr, data: response.data }));
}
catch (e) {
return e;
}
}
exports.placeOrder = placeOrder;
async function cancelOrder(orderId) {
assert_1.strict.ok(config_1.USER_CONFIG.WHALEEX_API_KEY);
assert_1.strict.ok(config_1.USER_CONFIG.eosAccount);
assert_1.strict.ok(config_1.USER_CONFIG.eosPrivateKey);
const path = `/api/v1/order/orders/${orderId}/submitcancel`;
const params = whaleex_sign_1.signData('POST', path);
const response = await axios_1.default.post(`${URL_PREFIX}${path}?${params}`);
return response.status === 200 && response.data.returnCode === '0';
}
exports.cancelOrder = cancelOrder;
async function queryOrder(orderId) {
assert_1.strict.ok(config_1.USER_CONFIG.WHALEEX_API_KEY);
const path = `/api/v1/order/orders/${orderId}`;
const params = whaleex_sign_1.signData('GET', path);
const response = await axios_1.default.get(`${URL_PREFIX}${path}?${params}`);
assert_1.strict.equal(response.status, 200);
if (response.data.returnCode === '0') {
return response.data.result;
}
return undefined;
}
exports.queryOrder = queryOrder;
// for debug only
async function queryOpenOrder(sell = false) {
const path = '/api/v1/order/openOrders';
const params = whaleex_sign_1.signData('GET', path, { side: sell ? 'sell' : 'buy' });
const response = await axios_1.default.get(`${URL_PREFIX}${path}?${params}`);
assert_1.strict.equal(response.status, 200);
if (response.data.returnCode === '0') {
return response.data.result.content;
}
return undefined;
}
exports.queryOpenOrder = queryOpenOrder;
async function queryAllBalances(all = false) {
const path = '/api/v1/assets';
const params = whaleex_sign_1.signData('GET', path);
const response = await axios_1.default.get(`${URL_PREFIX}${path}?${params}`).catch((e) => {
return e;
});
if (response instanceof Error)
return response;
assert_1.strict.equal(response.status, 200);
if (response.data.returnCode !== '0') {
return {};
}
const arr = response.data.result.list.content;
const result = {};
arr.forEach((x) => {
const symbol = crypto_pair_1.normalizeSymbol(x.currency, 'WhaleEx');
result[symbol] = all ? parseFloat(x.totalAmount) : parseFloat(x.availableAmount);
});
return result;
}
exports.queryAllBalances = queryAllBalances;
async function queryBalance(symbol) {
const path = `/api/v1/asset/${symbol}`;
const params = whaleex_sign_1.signData('GET', path);
const response = await axios_1.default.get(`${URL_PREFIX}${path}?${params}`);
assert_1.strict.equal(response.status, 200);
if (response.data.returnCode !== '0') {
return 0;
}
assert_1.strict.equal(symbol, response.data.result.currency);
const total = parseFloat(response.data.result.total);
const frozen = parseFloat(response.data.result.frozen);
assert_1.strict(total >= frozen);
return total - frozen;
}
exports.queryBalance = queryBalance;
function getWithdrawalFees(symbols) {
const result = {};
symbols.forEach((symbol) => {
if (eos_token_info_1.getTokenInfo(symbol === 'MYKEY' ? 'KEY' : symbol) === undefined)
return;
result[symbol] = {};
result[symbol].EOS = {
symbol,
platform: 'EOS',
fee: 0,
min: 0,
};
});
const config = {
EOS: {
EOS: {
symbol: 'EOS',
platform: 'EOS',
fee: 0,
min: 0,
},
},
ETH: {
ETH: {
symbol: 'ETH',
platform: 'ETH',
fee: 0.005,
min: 0,
},
},
USDT: {
ERC20: {
symbol: 'USDT',
platform: 'ERC20',
fee: 1,
min: 0,
},
EOS: {
symbol: 'USDT',
platform: 'EOS',
fee: 0,
min: 0,
},
OMNI: {
symbol: 'USDT',
platform: 'OMNI',
fee: 0,
min: 0,
},
},
};
return Object.assign(result, config);
}
exports.getWithdrawalFees = getWithdrawalFees;
function getDepositAddresses(symbols) {
assert_1.strict.ok(config_1.USER_CONFIG.WHALEEX_API_KEY, 'WHALEEX_API_KEY is empty');
assert_1.strict.ok(config_1.USER_CONFIG.WHALEEX_USER_ID, 'WHALEEX_USER_ID is empty');
const result = {};
symbols.forEach((symbol) => {
if (eos_token_info_1.getTokenInfo(symbol === 'MYKEY' ? 'KEY' : symbol) === undefined)
return;
result[symbol] = {};
result[symbol].EOS = {
symbol,
platform: 'EOS',
address: WHALEEX_ACCOUNT,
memo: config_1.USER_CONFIG.WHALEEX_USER_ID,
};
});
return result;
}
exports.getDepositAddresses = getDepositAddresses;