xud
Version:
Exchange Union Daemon
257 lines • 9.17 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseResponseBody = exports.getDefaultBackupDir = exports.toEip55Address = exports.uint8ArrayToHex = exports.hexToUint8Array = exports.base64ToHex = exports.sortOrders = exports.convertKvpArrayToKvps = exports.setObjectToMap = exports.removeUndefinedProps = exports.setTimeoutPromise = exports.isPlainObject = exports.derivePairId = exports.ms = exports.checkDecimalPlaces = exports.groupBy = exports.getPublicMethods = exports.deepMerge = exports.getTsString = exports.isEmptyObject = exports.isObject = exports.getExternalIp = void 0;
const http_1 = __importDefault(require("http"));
// @ts-ignore
const keccak_1 = __importDefault(require("keccak"));
const moment_1 = __importDefault(require("moment"));
const os_1 = __importDefault(require("os"));
const path_1 = __importDefault(require("path"));
const util_1 = require("util");
const errors_1 = __importDefault(require("../p2p/errors"));
const MAX_DECIMAL_PLACES = 12;
/**
* Gets the external IP of the node.
*/
exports.getExternalIp = () => {
return new Promise((resolve, reject) => {
http_1.default.get('http://ipv4.icanhazip.com/', (res) => {
let body = '';
res.on('data', (chunk) => {
body += chunk;
});
res.on('end', () => {
// Removes new line at the end of the string
body = body.trimRight();
resolve(body);
});
res.on('error', (err) => {
reject(errors_1.default.EXTERNAL_IP_UNRETRIEVABLE(err));
});
}).on('error', (err) => {
reject(errors_1.default.EXTERNAL_IP_UNRETRIEVABLE(err));
});
});
};
/**
* Check whether a variable is a non-array object
*/
exports.isObject = (val) => {
return (val && typeof val === 'object' && !Array.isArray(val));
};
/**
* Check whether a variable is an empty object
*/
exports.isEmptyObject = (val) => {
return exports.isObject(val) && Object.keys(val).length === 0;
};
/** Get the current date in the given dateFormat, if not provided formats with `YYYY-MM-DD hh:mm:ss.sss`.
*/
exports.getTsString = (dateFormat) => moment_1.default().format(dateFormat || 'YYYY-MM-DD hh:mm:ss.sss');
/**
* Recursively merge properties from different sources into a target object, overriding any
* existing properties.
* @param target the destination object to merge into.
* @param sources the sources objects to copy from.
*/
exports.deepMerge = (target, ...sources) => {
if (!sources.length)
return target;
const source = sources.shift();
if (exports.isObject(target) && exports.isObject(source)) {
Object.keys(source).forEach((key) => {
if (exports.isObject(source[key])) {
if (!target[key])
Object.assign(target, { [key]: {} });
exports.deepMerge(target[key], source[key]);
}
else if (source[key] !== undefined) {
Object.assign(target, { [key]: source[key] });
}
});
}
return exports.deepMerge(target, ...sources);
};
/**
* Get all methods from an object whose name doesn't start with an underscore.
*/
exports.getPublicMethods = (obj) => {
const ret = {};
Object.getOwnPropertyNames(Object.getPrototypeOf(obj)).forEach((name) => {
const func = obj[name];
if ((func instanceof Function) && name !== 'constructor' && !name.startsWith('_')) {
ret[name] = func;
}
});
return ret;
};
exports.groupBy = (arr, keyGetter) => {
const ret = {};
arr.forEach((item) => {
const key = keyGetter(item);
const group = ret[key];
if (!group) {
ret[key] = [item];
}
else {
group.push(item);
}
});
return ret;
};
/** Returns true if number has more than MAX_DECIMAL_PLACES, false otherwise. */
exports.checkDecimalPlaces = (digits) => {
const fixed = Number(digits.toFixed(MAX_DECIMAL_PLACES));
return fixed < digits;
};
/**
* Get current time in unix time (milliseconds).
*/
exports.ms = () => {
return Date.now();
};
/**
* Convert a pair's base currency and quote currency to a ticker symbol pair id.
*/
exports.derivePairId = (pair) => {
return `${pair.baseCurrency}/${pair.quoteCurrency}`;
};
/**
* A simplified copy of lodash's isPlainObject;
*
* A plain object is;
* - prototype should be [object Object]
* - shouldn't be null
* - its type should be 'object' (does extra check because typeof null == object)
*
* Examples;
* isPlainObject(new Foo); => false
* isPlainObject([1, 2, 3]); => false
* isPlainObject({ 'x': 0, 'y': 0 }); => true
* isPlainObject(Object.create(null)); => true
*/
exports.isPlainObject = (obj) => {
if (typeof obj !== 'object' || obj === null || Object.prototype.toString.call(obj) !== '[object Object]') {
return false;
}
if (Object.getPrototypeOf(obj) === null) {
return true;
}
let proto = obj;
while (Object.getPrototypeOf(proto) !== null) {
proto = Object.getPrototypeOf(proto);
}
return Object.getPrototypeOf(obj) === proto;
};
/** A promisified wrapper for the NodeJS `setTimeout` method. */
exports.setTimeoutPromise = util_1.promisify(setTimeout);
exports.removeUndefinedProps = (typedObj) => {
const obj = typedObj;
Object.keys(obj).forEach((key) => {
if (obj[key] === undefined) {
delete obj[key];
}
else if (typeof obj[key] === 'object') {
exports.removeUndefinedProps(obj[key]);
}
});
return obj;
};
exports.setObjectToMap = (obj, map) => {
for (const key in obj) {
if (obj[key] !== undefined) {
map.set(key, obj[key]);
}
}
};
/**
* Converts an array of key value pair arrays into an object with the key value pairs.
*/
exports.convertKvpArrayToKvps = (kvpArray) => {
const kvps = {};
kvpArray.forEach((kvp) => {
kvps[kvp[0]] = kvp[1];
});
return kvps;
};
exports.sortOrders = (orders, isBuy) => {
return orders.sort((a, b) => {
if (a.price === b.price) {
return a.createdAt - b.createdAt;
}
return isBuy
? a.price - b.price
: b.price - a.price;
});
};
exports.base64ToHex = (b64) => {
return Buffer.from(b64, 'base64').toString('hex');
};
exports.hexToUint8Array = (hex) => {
return Uint8Array.from(Buffer.from(hex, 'hex'));
};
exports.uint8ArrayToHex = (uint8) => {
return Buffer.from(uint8).toString('hex');
};
/**
* Converts input to EIP55 format.
* Prints the ith digit in uppercase if it's a letter and the 4*ith bit of the hash of the lowercase hexadecimal address is 1
* otherwise prints it in lowercase.
* Example: '0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359' is converted to '0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359'
*/
exports.toEip55Address = (address) => {
const lowercaseAddress = address.toLowerCase().replace('0x', '');
const hash = keccak_1.default('keccak256').update(lowercaseAddress).digest('hex');
let ret = '0x';
for (let i = 0; i < lowercaseAddress.length; i += 1) {
if (parseInt(hash[i], 16) >= 8) {
ret += lowercaseAddress[i].toUpperCase();
}
else {
ret += lowercaseAddress[i];
}
}
return ret;
};
exports.getDefaultBackupDir = () => {
switch (os_1.default.platform()) {
case 'win32':
return path_1.default.join(process.env.LOCALAPPDATA, 'Xud Backup');
default:
return path_1.default.join(process.env.HOME, '.xud-backup');
}
};
/**
* A utility function to parse the payload from an http response.
*/
function parseResponseBody(res) {
return __awaiter(this, void 0, void 0, function* () {
res.setEncoding('utf8');
return new Promise((resolve, reject) => {
let body = '';
res.on('data', (chunk) => {
body += chunk;
});
res.on('end', () => {
resolve(JSON.parse(body));
});
res.on('error', (err) => {
reject(err);
});
});
});
}
exports.parseResponseBody = parseResponseBody;
//# sourceMappingURL=utils.js.map