UNPKG

insight-via-api

Version:

A Viacoin blockchain REST and web socket API service for Viacore Node.

232 lines (190 loc) 6.11 kB
'use strict'; var bitcore = require('viacore-lib'); var async = require('async'); var TxController = require('./transactions'); var Common = require('./common'); function AddressController(node) { this.node = node; this.txController = new TxController(node); this.common = new Common({log: this.node.log}); } AddressController.prototype.show = function(req, res) { var self = this; var options = { noTxList: parseInt(req.query.noTxList) }; if (req.query.from && req.query.to) { options.from = parseInt(req.query.from); options.to = parseInt(req.query.to); } this.getAddressSummary(req.addr, options, function(err, data) { if(err) { return self.common.handleErrors(err, res); } res.jsonp(data); }); }; AddressController.prototype.balance = function(req, res) { this.addressSummarySubQuery(req, res, 'balanceSat'); }; AddressController.prototype.totalReceived = function(req, res) { this.addressSummarySubQuery(req, res, 'totalReceivedSat'); }; AddressController.prototype.totalSent = function(req, res) { this.addressSummarySubQuery(req, res, 'totalSentSat'); }; AddressController.prototype.unconfirmedBalance = function(req, res) { this.addressSummarySubQuery(req, res, 'unconfirmedBalanceSat'); }; AddressController.prototype.addressSummarySubQuery = function(req, res, param) { var self = this; this.getAddressSummary(req.addr, {}, function(err, data) { if(err) { return self.common.handleErrors(err, res); } res.jsonp(data[param]); }); }; AddressController.prototype.getAddressSummary = function(address, options, callback) { this.node.getAddressSummary(address, options, function(err, summary) { if(err) { return callback(err); } var transformed = { addrStr: address, balance: summary.balance / 1e8, balanceSat: summary.balance, totalReceived: summary.totalReceived / 1e8, totalReceivedSat: summary.totalReceived, totalSent: summary.totalSpent / 1e8, totalSentSat: summary.totalSpent, unconfirmedBalance: summary.unconfirmedBalance / 1e8, unconfirmedBalanceSat: summary.unconfirmedBalance, unconfirmedTxApperances: summary.unconfirmedAppearances, // misspelling - ew txApperances: summary.appearances, // yuck transactions: summary.txids }; callback(null, transformed); }); }; AddressController.prototype.checkAddr = function(req, res, next) { req.addr = req.params.addr; this.check(req, res, next, [req.addr]); }; AddressController.prototype.checkAddrs = function(req, res, next) { if(req.body.addrs) { req.addrs = req.body.addrs.split(','); } else { req.addrs = req.params.addrs.split(','); } this.check(req, res, next, req.addrs); }; AddressController.prototype.check = function(req, res, next, addresses) { var self = this; if(!addresses.length || !addresses[0]) { return self.common.handleErrors({ message: 'Must include address', code: 1 }, res); } for(var i = 0; i < addresses.length; i++) { try { var a = new bitcore.Address(addresses[i]); } catch(e) { return self.common.handleErrors({ message: 'Invalid address: ' + e.message, code: 1 }, res); } } next(); }; AddressController.prototype.utxo = function(req, res) { var self = this; this.node.getAddressUnspentOutputs(req.addr, {}, function(err, utxos) { if(err) { return self.common.handleErrors(err, res); } else if (!utxos.length) { return res.jsonp([]); } res.jsonp(utxos.map(self.transformUtxo.bind(self))); }); }; AddressController.prototype.multiutxo = function(req, res) { var self = this; this.node.getAddressUnspentOutputs(req.addrs, true, function(err, utxos) { if(err && err.code === -5) { return res.jsonp([]); } else if(err) { return self.common.handleErrors(err, res); } res.jsonp(utxos.map(self.transformUtxo.bind(self))); }); }; AddressController.prototype.transformUtxo = function(utxoArg) { var utxo = { address: utxoArg.address, txid: utxoArg.txid, vout: utxoArg.outputIndex, scriptPubKey: utxoArg.script, amount: utxoArg.satoshis / 1e8, satoshis: utxoArg.satoshis }; if (utxoArg.height && utxoArg.height > 0) { utxo.height = utxoArg.height; utxo.confirmations = this.node.services.bitcoind.height - utxoArg.height + 1; } else { utxo.confirmations = 0; } if (utxoArg.timestamp) { utxo.ts = utxoArg.timestamp; } return utxo; }; AddressController.prototype._getTransformOptions = function(req) { return { noAsm: parseInt(req.query.noAsm) ? true : false, noScriptSig: parseInt(req.query.noScriptSig) ? true : false, noSpent: parseInt(req.query.noSpent) ? true : false }; }; AddressController.prototype.multitxs = function(req, res, next) { var self = this; var options = { from: parseInt(req.query.from) || parseInt(req.body.from) || 0 }; options.to = parseInt(req.query.to) || parseInt(req.body.to) || parseInt(options.from) + 10; self.node.getAddressHistory(req.addrs, options, function(err, result) { if(err) { return self.common.handleErrors(err, res); } var transformOptions = self._getTransformOptions(req); self.transformAddressHistoryForMultiTxs(result.items, transformOptions, function(err, items) { if (err) { return self.common.handleErrors(err, res); } res.jsonp({ totalItems: result.totalCount, from: options.from, to: Math.min(options.to, result.totalCount), items: items }); }); }); }; AddressController.prototype.transformAddressHistoryForMultiTxs = function(txinfos, options, callback) { var self = this; var items = txinfos.map(function(txinfo) { return txinfo.tx; }).filter(function(value, index, self) { return self.indexOf(value) === index; }); async.map( items, function(item, next) { self.txController.transformTransaction(item, options, next); }, callback ); }; module.exports = AddressController;