@onekeyfe/blockchain-link
Version:
High-level javascript interface for blockchain communication
321 lines (320 loc) • 11.5 kB
JavaScript
;
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;