UNPKG

bitcore-wallet-service

Version:
381 lines 13.7 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Utils = void 0; const CWC = __importStar(require("crypto-wallet-core")); const lodash_1 = __importDefault(require("lodash")); const config_1 = __importDefault(require("../../config")); const logger_1 = require("../logger"); const constants_1 = require("./constants"); const $ = require('preconditions').singleton(); const bitcore = require('bitcore-lib'); const crypto = bitcore.crypto; const secp256k1 = require('secp256k1'); const Bitcore = require('bitcore-lib'); const Bitcore_ = { btc: Bitcore, bch: require('bitcore-lib-cash'), doge: require('bitcore-lib-doge'), ltc: require('bitcore-lib-ltc') }; exports.Utils = { isObject(obj) { return obj && typeof obj === 'object' && !Array.isArray(obj); }, isNumber(val) { return val != null && !isNaN(val); }, isNumberish(val) { return exports.Utils.isNumber(val) || typeof val === 'bigint'; }, getMissingFields(obj, args) { args = args || []; if (!Array.isArray(args)) args = [args]; if (!exports.Utils.isObject(obj)) return args; const missing = args.filter(arg => !obj.hasOwnProperty(arg)); return missing; }, strip(number) { return parseFloat(number.toPrecision(12)); }, hashMessage(text, noReverse) { $.checkArgument(text); const buf = Buffer.from(text); let ret = crypto.Hash.sha256sha256(buf); if (!noReverse) { ret = new bitcore.encoding.BufferReader(ret).readReverse(); } return ret; }, verifyMessage(message, signature, publicKey) { $.checkArgument(message); const flattenedMessage = Array.isArray(message) ? message.join(',') : message; const hash = exports.Utils.hashMessage(flattenedMessage, true); const sig = exports.Utils._tryImportSignature(signature); if (!sig) { return false; } const publicKeyBuffer = exports.Utils._tryImportPublicKey(publicKey); if (!publicKeyBuffer) { return false; } return exports.Utils._tryVerifyMessage(hash, sig, publicKeyBuffer); }, _tryImportPublicKey(publicKey) { let publicKeyBuffer = publicKey; try { if (!Buffer.isBuffer(publicKey)) { publicKeyBuffer = Buffer.from(publicKey, 'hex'); } return publicKeyBuffer; } catch (e) { logger_1.logger.error('_tryImportPublicKey encountered an error: %o', e); return false; } }, _tryImportSignature(signature) { try { let signatureBuffer = signature; if (!Buffer.isBuffer(signature)) { signatureBuffer = Buffer.from(signature, 'hex'); } return secp256k1.signatureImport(signatureBuffer); } catch (e) { logger_1.logger.error('_tryImportSignature encountered an error: %o', e); return false; } }, _tryVerifyMessage(hash, sig, publicKeyBuffer) { try { return secp256k1.ecdsaVerify(sig, hash, publicKeyBuffer); } catch (e) { logger_1.logger.error('_tryVerifyMessage encountered an error: %o', e); return false; } }, formatAmount(satoshis, unit, opts) { const UNITS = Object.entries(CWC.Constants.UNITS).reduce((units, [currency, currencyConfig]) => { units[currency] = { toSatoshis: currencyConfig.toSatoshis, maxDecimals: currencyConfig.short.maxDecimals, minDecimals: currencyConfig.short.minDecimals }; return units; }, {}); $.shouldBeNumber(satoshis); function addSeparators(nStr, thousands, decimal, minDecimals) { nStr = nStr.replace('.', decimal); const x = nStr.split(decimal); let x0 = x[0]; let x1 = x[1]; x1 = lodash_1.default.dropRightWhile(x1, (n, i) => { return n == '0' && i >= minDecimals; }).join(''); const x2 = x.length > 1 ? decimal + x1 : ''; x0 = x0.replace(/\B(?=(\d{3})+(?!\d))/g, thousands); return x0 + x2; } opts = opts || {}; if (!UNITS[unit] && !opts.decimals && !opts.toSatoshis) { return Number(satoshis).toLocaleString(); } const u = Object.assign({}, UNITS[unit], opts); var decimals = opts.decimals ? opts.decimals : u; var toSatoshis = opts.toSatoshis ? opts.toSatoshis : u.toSatoshis; const amount = (satoshis / toSatoshis).toFixed(decimals.maxDecimals); return addSeparators(amount, opts.thousandsSeparator || ',', opts.decimalSeparator || '.', decimals.minDecimals); }, formatAmountInBtc(amount) { return (exports.Utils.formatAmount(amount, 'btc', { minDecimals: 8, maxDecimals: 8 }) + 'btc'); }, formatUtxos(utxos) { if (!utxos?.length) return 'none'; return utxos.map(i => { const amount = exports.Utils.formatAmountInBtc(i.satoshis); const confirmations = i.confirmations ? i.confirmations + 'c' : 'u'; return amount + '/' + confirmations; }).join(', '); }, formatRatio(ratio) { return (ratio * 100).toFixed(4) + '%'; }, formatSize(size) { return (size / 1000).toFixed(4) + 'kB'; }, parseVersion(version) { const v = {}; if (!version) return null; let x = version.split('-'); if (x.length != 2) { v.agent = version; return v; } v.agent = ['bwc', 'bws'].includes(x[0]) ? 'bwc' : x[0]; x = x[1].split('.'); v.major = x[0] ? parseInt(x[0]) : null; v.minor = x[1] ? parseInt(x[1]) : null; v.patch = x[2] ? parseInt(x[2]) : null; return v; }, parseAppVersion(agent) { const v = {}; if (!agent) return null; agent = agent.toLowerCase(); let w; w = agent.indexOf('copay'); if (w >= 0) { v.app = 'copay'; } else { w = agent.indexOf('bitpay'); if (w >= 0) { v.app = 'bitpay'; } else { v.app = 'other'; return v; } } const version = agent.substr(w + v.app.length); const x = version.split('.'); v.major = x[0] ? parseInt(x[0].replace(/\D/g, '')) : null; v.minor = x[1] ? parseInt(x[1]) : null; v.patch = x[2] ? parseInt(x[2]) : null; return v; }, getIpFromReq(req) { if (req.headers) { if (req.headers['x-forwarded-for']) return req.headers['x-forwarded-for'].split(',')[0]; if (req.headers['x-real-ip']) return req.headers['x-real-ip'].split(',')[0]; } if (req.ip) return req.ip; if (req.connection && req.connection.remoteAddress) return req.connection.remoteAddress; return ''; }, checkValueInCollection(value, collection) { if (typeof value !== 'string') return false; return Object.values(collection).includes(value); }, getAddressCoin(address) { try { new Bitcore_['btc'].Address(address); return 'btc'; } catch (e) { try { new Bitcore_['bch'].Address(address); return 'bch'; } catch (e) { try { new Bitcore_['doge'].Address(address); return 'doge'; } catch (e) { try { new Bitcore_['ltc'].Address(address); return 'ltc'; } catch (e) { return; } } } } }, translateAddress(address, coin) { const origCoin = exports.Utils.getAddressCoin(address); const origAddress = new Bitcore_[origCoin].Address(address); const origObj = origAddress.toObject(); const result = Bitcore_[coin].Address.fromObject(origObj); return coin == 'bch' ? result.toLegacyAddress() : result.toString(); }, compareNetworks(network1, network2, chain) { network1 = network1 ? exports.Utils.getNetworkName(chain, network1.toLowerCase()) : null; network2 = network2 ? exports.Utils.getNetworkName(chain, network2.toLowerCase()) : null; if (network1 == network2) return true; if (config_1.default.allowRegtest && ['testnet', 'regtest'].includes(exports.Utils.getNetworkType(network1)) && ['testnet', 'regtest'].includes(exports.Utils.getNetworkType(network2))) return true; return false; }, getNetworkName(chain, network) { const aliases = constants_1.Constants.NETWORK_ALIASES[chain]; if (aliases && aliases[network]) { return aliases[network]; } return network; }, getGenericName(network) { if (network === 'mainnet') return 'livenet'; const isTestnet = !!Object.keys(constants_1.Constants.NETWORK_ALIASES).find(key => constants_1.Constants.NETWORK_ALIASES[key].testnet === network); if (isTestnet) return 'testnet'; return network; }, getNetworkType(network) { if (['mainnet', 'livenet'].includes(network)) { return 'mainnet'; } if (network === 'regtest') { return 'regtest'; } return 'testnet'; }, castToBool(input) { input = input?.toString(); if (input?.toLowerCase() === 'true' || input == '1') { return true; } return false; }, sortAsc(arr, ...keys) { function transformVals(val1, val2) { if (val1 === undefined) { val1 = '\uFFFF'; } else if (val1 === null || val1 === false || val1.toString() === 'NaN') { val1 = '0'; } else if (val1 === true) { val1 = '1'; } if (val2 === undefined) { val2 = '\uFFFF'; } else if (val2 === null || val2 === false || val2.toString() === 'NaN') { val2 = '0'; } else if (val2 === true) { val2 = '1'; } return [Buffer.from(val1.toString()), Buffer.from(val2.toString())]; } ; if (!keys.length) { return arr.sort((a, b) => { const [_a, _b] = transformVals(a, b); return _a.compare(_b); }); } else if (keys.length === 1 && !Array.isArray(keys[0])) { return arr.sort((a, b) => { const [_a, _b] = transformVals(a[keys[0]], b[keys[0]]); return _a.compare(_b); }); } return arr.sort((a, b) => { let aVal = ''; let bVal = ''; for (let k of keys) { const [aTemp, bTemp] = transformVals(Array.isArray(k) ? k.reduce((val, key) => val[key], a) : a[k], Array.isArray(k) ? k.reduce((val, key) => val[key], b) : b[k]); aVal += aTemp.toString(); bVal += bTemp.toString(); } return Buffer.from(aVal).compare(Buffer.from(bVal)); }); }, sortDesc(arr, ...keys) { return exports.Utils.sortAsc(arr, ...keys).reverse(); }, fromPairs(input) { return input.reduce((map, [k, v]) => { map[k] = v; return map; }, {}); }, difference(arr1, arr2) { if (!Array.isArray(arr1)) return []; if (!Array.isArray(arr2)) arr2 = null; return arr1.filter(x => !arr2?.includes(x)); } }; //# sourceMappingURL=utils.js.map