UNPKG

@onekeyfe/blockchain-link

Version:

High-level javascript interface for blockchain communication

321 lines (320 loc) 11.5 kB
"use strict"; var __assign = (this && this.__assign) || function () { __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; }; return __assign.apply(this, arguments); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.transformAccountUtxo = exports.transformAccountInfo = exports.transformAddresses = exports.transformTokenInfo = exports.transformTransaction = exports.filterTokenTransfers = exports.filterTargets = exports.transformServerInfo = void 0; var bignumber_js_1 = __importDefault(require("bignumber.js")); var transformServerInfo = function (payload) { return { name: payload.name, shortcut: payload.shortcut, testnet: payload.testnet, version: payload.version, decimals: payload.decimals, blockHeight: payload.bestHeight, blockHash: payload.bestHash, }; }; exports.transformServerInfo = transformServerInfo; var filterTargets = function (addresses, targets) { if (typeof addresses === 'string') { addresses = [addresses]; } if (!addresses || !Array.isArray(addresses) || !targets || !Array.isArray(targets)) return []; var all = addresses.map(function (a) { if (typeof a === 'string') return a; if (typeof a === 'object' && typeof a.address === 'string') return a.address; return null; }); return targets.filter(function (t) { if (t && Array.isArray(t.addresses)) { return t.addresses.filter(function (a) { return all.indexOf(a) >= 0; }).length > 0; } return false; }); }; exports.filterTargets = filterTargets; var filterTokenTransfers = function (addresses, transfers) { if (typeof addresses === 'string') { addresses = [addresses]; } if (!addresses || !Array.isArray(addresses) || !transfers || !Array.isArray(transfers)) return []; var all = addresses.map(function (a) { if (typeof a === 'string') return a; if (typeof a === 'object' && typeof a.address === 'string') return a.address; return null; }); return transfers .filter(function (tr) { if (tr && typeof tr === 'object') { return (tr.from && all.indexOf(tr.from) >= 0) || (tr.to && all.indexOf(tr.to) >= 0); } return false; }) .map(function (tr) { var incoming = tr.from && all.indexOf(tr.from) >= 0; var outgoing = tr.to && all.indexOf(tr.to) >= 0; var type = 'unknown'; if (incoming && outgoing) { type = 'self'; } else { if (incoming) { type = 'sent'; } if (outgoing) { type = 'recv'; } } return { type: type, name: tr.name, symbol: tr.symbol, address: tr.token, decimals: tr.decimals || 0, amount: tr.value, from: tr.from, to: tr.to, }; }); }; exports.filterTokenTransfers = filterTokenTransfers; var transformTarget = function (target, incoming) { return { n: target.n || 0, addresses: target.addresses, isAddress: target.isAddress, amount: target.value, coinbase: target.coinbase, isAccountTarget: incoming.includes(target) ? true : undefined, }; }; var sumVinVout = function (vinVout, initialValue, operation) { if (initialValue === void 0) { initialValue = '0'; } if (operation === void 0) { operation = 'sum'; } var sum = vinVout.reduce(function (bn, v) { if (typeof v.value !== 'string') return bn; return operation === 'sum' ? bn.plus(v.value) : bn.minus(v.value); }, new bignumber_js_1.default(initialValue)); return sum.toString(); }; var transformTransaction = function (descriptor, addresses, tx) { var myAddresses = addresses ? addresses.change.concat(addresses.used, addresses.unused) : [descriptor]; var vinLength = Array.isArray(tx.vin) ? tx.vin.length : 0; var voutLength = Array.isArray(tx.vout) ? tx.vout.length : 0; var outgoing = exports.filterTargets(myAddresses, tx.vin); var incoming = exports.filterTargets(myAddresses, tx.vout); var internal = addresses ? exports.filterTargets(addresses.change, tx.vout) : []; var tokens = exports.filterTokenTransfers(myAddresses, tx.tokenTransfers); var type; var targets = []; var amount = tx.value; var totalInput = sumVinVout(vinLength ? tx.vin : []); var totalOutput = sumVinVout(voutLength ? tx.vout : []); if (outgoing.length === 0 && incoming.length === 0 && tokens.length === 0) { type = 'unknown'; } else if (vinLength > 0 && voutLength > 0 && outgoing.length === vinLength && incoming.length === voutLength) { type = 'self'; targets = tx.vout.filter(function (o) { return internal.indexOf(o) < 0; }); amount = tx.fees; } else if (outgoing.length === 0 && (incoming.length > 0 || tokens.length > 0)) { type = 'recv'; amount = '0'; if (incoming.length > 0) { targets = incoming; amount = sumVinVout(incoming, amount); } } else { type = 'sent'; if (tokens.length === 0 && voutLength) { targets = tx.vout.filter(function (o) { return internal.indexOf(o) < 0; }); } if (tx.ethereumSpecific) { amount = tokens.length > 0 || tx.ethereumSpecific.status === 0 ? tx.fees : tx.value; } else if (voutLength) { var myInputsSum = sumVinVout(outgoing, '0'); amount = sumVinVout(incoming, myInputsSum, 'reduce'); } } var rbf; if (vinLength) { tx.vin.forEach(function (vin) { if (typeof vin.sequence === 'number' && vin.sequence < 0xffffffff - 1) { rbf = true; } }); } var fee = tx.fees; if (tx.ethereumSpecific && !tx.ethereumSpecific.gasUsed) { fee = new bignumber_js_1.default(tx.ethereumSpecific.gasPrice) .times(tx.ethereumSpecific.gasLimit) .toString(); } return { type: type, txid: tx.txid, blockTime: tx.blockTime, blockHeight: tx.blockHeight, blockHash: tx.blockHash, amount: amount, fee: fee, targets: targets.filter(function (t) { return typeof t === 'object'; }).map(function (t) { return transformTarget(t, incoming); }), tokens: tokens, rbf: rbf, ethereumSpecific: tx.ethereumSpecific, details: { vin: tx.vin, vout: tx.vout, size: typeof tx.hex === 'string' ? tx.hex.length / 2 : 0, totalInput: totalInput ? totalInput.toString() : '0', totalOutput: totalOutput ? totalOutput.toString() : '0', }, }; }; exports.transformTransaction = transformTransaction; var transformTokenInfo = function (tokens) { if (!tokens || !Array.isArray(tokens)) return undefined; var info = tokens.reduce(function (arr, t) { if (t.type !== 'ERC20') return arr; return arr.concat([ { type: t.type, name: t.name, symbol: t.symbol, address: t.contract, balance: t.balance, decimals: t.decimals || 0, }, ]); }, []); return info.length > 0 ? info : undefined; }; exports.transformTokenInfo = transformTokenInfo; var transformAddresses = function (tokens) { if (!tokens || !Array.isArray(tokens)) return undefined; var addresses = tokens.reduce(function (arr, t) { if (t.type !== 'XPUBAddress') return arr; return arr.concat([ { address: t.name, path: t.path, transfers: t.transfers, balance: t.balance, sent: t.totalSent, received: t.totalReceived, }, ]); }, []); if (addresses.length < 1) return undefined; var internal = addresses.filter(function (a) { return a.path.split('/')[4] === '1'; }); var external = addresses.filter(function (a) { return internal.indexOf(a) < 0; }); return { change: internal, used: external.filter(function (a) { return a.transfers > 0; }), unused: external.filter(function (a) { return a.transfers === 0; }), }; }; exports.transformAddresses = transformAddresses; var transformAccountInfo = function (payload) { var page; if (typeof payload.page === 'number') { page = { index: payload.page, size: payload.itemsOnPage, total: payload.totalPages, }; } var misc = {}; if (typeof payload.nonce === 'string') { misc.nonce = payload.nonce; } if (payload.erc20Contract) { var token = exports.transformTokenInfo([ __assign(__assign({}, payload.erc20Contract), { type: payload.erc20Contract.type || 'ERC20' }), ]); if (token) { var erc20Contract = token[0]; misc.erc20Contract = erc20Contract; } } if (Object.keys(misc).length < 1) { misc = undefined; } var descriptor = payload.address; var addresses = exports.transformAddresses(payload.tokens); var tokens = exports.transformTokenInfo(payload.tokens); var unconfirmed = new bignumber_js_1.default(payload.unconfirmedBalance); var availableBalance = !unconfirmed.isNaN() && !unconfirmed.isZero() ? unconfirmed.plus(payload.balance).toString() : payload.balance; var empty = payload.txs === 0 && payload.unconfirmedTxs === 0 && new bignumber_js_1.default(availableBalance).isZero(); return { descriptor: descriptor, balance: payload.balance, availableBalance: availableBalance, empty: empty, tokens: tokens, addresses: addresses, history: { total: payload.txs, tokens: typeof payload.nonTokenTxs === 'number' ? payload.txs - payload.nonTokenTxs : undefined, unconfirmed: payload.unconfirmedTxs, transactions: payload.transactions ? payload.transactions.map(function (t) { return exports.transformTransaction(descriptor, addresses, t); }) : undefined, }, misc: misc, page: page, }; }; exports.transformAccountInfo = transformAccountInfo; var transformAccountUtxo = function (payload) { return payload.map(function (utxo) { return ({ txid: utxo.txid, vout: utxo.vout, amount: utxo.value, blockHeight: utxo.height, address: utxo.address, path: utxo.path, confirmations: utxo.confirmations, coinbase: utxo.coinbase, }); }); }; exports.transformAccountUtxo = transformAccountUtxo;