UNPKG

crypto-client

Version:

An unified client for all cryptocurrency exchanges.

179 lines (178 loc) 6.33 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.signDataOrder = exports.signData = exports.sort = exports.signOrder = exports.getKeys = void 0; // forked from https://github.com/WhaleEx/API/blob/master/sample/nodejs/whaleex-sign.js const assert_1 = require("assert"); const crypto_1 = __importDefault(require("crypto")); const eos_utils_1 = require("eos-utils"); const eosjs_ecc_1 = require("eosjs-ecc"); const long_1 = __importDefault(require("long")); const mathjs_1 = require("mathjs"); const config_1 = require("../config"); const math = mathjs_1.create(mathjs_1.all, { number: 'BigNumber', precision: 64, }); const WHALEEX_EOS_ACCOUNT = 'whaleexchang'; function defaultHandler(params) { return Object.assign({ timestamp: Date.now(), APIKey: config_1.USER_CONFIG.WHALEEX_API_KEY, pk: eosjs_ecc_1.privateToPublic(config_1.USER_CONFIG.eosPrivateKey) }, params); } const HANDLER = { '/api/v1/order/orders': defaultHandler, '/api/auth/pk/status': (params) => { return Object.assign({ pk: eosjs_ecc_1.privateToPublic(config_1.USER_CONFIG.eosPrivateKey) }, params); }, '/api/v1/order/matchresults': defaultHandler, default: defaultHandler, }; // Pack all kinds of data into a binary buffer. class Packer { constructor() { this.buf = Buffer.alloc(0); } updateStr(str) { this.buf = Buffer.concat([this.buf, Buffer.from(str)]); return this; } updateInt8(i) { const tmp = Buffer.alloc(1); tmp.writeInt8(i, 0); this.buf = Buffer.concat([this.buf, tmp]); return this; } updateInt16(i) { const tmp = Buffer.alloc(2); tmp.writeInt16LE(i, 0); this.buf = Buffer.concat([this.buf, tmp]); return this; } updateInt32(i) { const tmp = Buffer.alloc(4); tmp.writeInt32LE(i, 0); this.buf = Buffer.concat([this.buf, tmp]); return this; } updateInt64(str) { const long = long_1.default.fromString(str, 10); this.buf = Buffer.concat([this.buf, Buffer.from(long.toBytesLE())]); return this; } finalize() { return this.buf; } clear() { this.buf = Buffer.alloc(0); } } function getHandle(path) { return HANDLER[path] || HANDLER.default; } function getHash() { return crypto_1.default.createHash('sha256'); } function multiply(m, n, decimal, ceil = false) { const result = math.evaluate(`${m} * ${n} * ${10 ** decimal}`); if (ceil) { return String(Math.ceil(result)); } return String(result).split('.')[0]; } function getKeys() { assert_1.strict.ok(config_1.USER_CONFIG.eosPrivateKey); assert_1.strict.ok(config_1.USER_CONFIG.WHALEEX_API_KEY); return { privateKey: config_1.USER_CONFIG.eosPrivateKey, publicKey: eosjs_ecc_1.privateToPublic(config_1.USER_CONFIG.eosPrivateKey), APIKey: config_1.USER_CONFIG.WHALEEX_API_KEY, }; } exports.getKeys = getKeys; function signOrder(post, timestamp, symbolObj) { const { baseToken = 'IQ', quoteToken = 'EOS', basePrecision = 3, quotePrecision = eos_utils_1.EOS_QUANTITY_PRECISION, baseContract, quoteContract, } = symbolObj; // "IQ/EOS for example" const pack = new Packer(); pack .updateStr(config_1.USER_CONFIG.eosAccount) .updateStr(WHALEEX_EOS_ACCOUNT) .updateInt64(post.orderId.toString()) .updateInt32(Math.floor(timestamp / 1000)); const price = parseFloat(post.price); const quantity = parseFloat(post.amount); if (post.type === 'buy-limit') { pack .updateStr(quoteContract) .updateStr(quoteToken) .updateInt64(multiply(price, quantity, quotePrecision, true)) .updateStr(baseContract) .updateStr(baseToken) .updateInt64(multiply(1, quantity, basePrecision)); } if (post.type === 'sell-limit') { pack .updateStr(baseContract) .updateStr(baseToken) .updateInt64(multiply(1, quantity, basePrecision)) .updateStr(quoteContract) .updateStr(quoteToken) .updateInt64(multiply(price, quantity, quotePrecision)); } if (post.type === 'buy-market') { pack .updateStr(quoteContract) .updateStr(quoteToken) .updateInt64(multiply(1, quantity, quotePrecision)) .updateStr(baseContract) .updateStr(baseToken) .updateInt64('0'); } if (post.type === 'sell-market') { pack .updateStr(baseContract) .updateStr(baseToken) .updateInt64(multiply(1, quantity, basePrecision)) .updateStr(quoteContract) .updateStr(quoteToken) .updateInt64('0'); } pack.updateInt16(10).updateInt16(10); const buf = pack.finalize(); const hashData = getHash().update(buf).digest('hex'); const { privateKey } = getKeys(); const sig = eosjs_ecc_1.signHash(hashData, privateKey); return sig; } exports.signOrder = signOrder; function sort(params) { const sb = []; // String buffer const keys = Object.keys(params).sort(); keys.forEach((key) => { sb.push(`${key}=${params[key]}`); }); return sb.join('&'); } exports.sort = sort; function signData(method, path, params = {}) { const { privateKey } = getKeys(); // console.log("signData", method, path, params); const paramsStr = sort(getHandle(path)(params)); const data = `${method.toUpperCase()}\napi.whaleex.com\n${path}\n${encodeURIComponent(paramsStr)}`; const signature = eosjs_ecc_1.sign(data, privateKey); return `${paramsStr}&Signature=${signature}`; } exports.signData = signData; function signDataOrder(order, symbolObj) { const { APIKey, publicKey } = getKeys(); const map = { APIKey: APIKey, timestamp: Date.now(), pk: publicKey, orderId: order.orderId, }; const paramsText = sort(map); const signature = signOrder(order, map.timestamp, symbolObj); return `${paramsText}&Signature=${signature}`; } exports.signDataOrder = signDataOrder;