2015-03-30 11:34:05 -07:00
'use strict' ;
var _ = require ( 'lodash' ) ;
var $ = require ( 'preconditions' ) . singleton ( ) ;
var log = require ( 'npmlog' ) ;
log . debug = log . verbose ;
var Explorers = require ( 'bitcore-explorers' ) ;
var request = require ( 'request' ) ;
2015-03-30 12:57:55 -07:00
var io = require ( 'socket.io-client' ) ;
2015-03-30 11:34:05 -07:00
2015-06-10 07:49:52 -07:00
var PROVIDERS = {
'insight' : {
'livenet' : 'https://insight.bitpay.com:443' ,
'testnet' : 'https://test-insight.bitpay.com:443' ,
} ,
} ;
2015-03-30 11:34:05 -07:00
2015-03-30 16:16:51 -07:00
function BlockChainExplorer ( opts ) {
2015-03-30 11:34:05 -07:00
$ . checkArgument ( opts ) ;
2015-06-10 07:49:52 -07:00
this . provider = opts . provider || 'insight' ;
this . network = opts . network || 'livenet' ;
$ . checkState ( PROVIDERS [ this . provider ] , 'Provider ' + this . provider + ' not supported' ) ;
$ . checkState ( PROVIDERS [ this . provider ] [ this . network ] , 'Network ' + this . network + ' not supported' ) ;
this . url = opts . url || PROVIDERS [ this . provider ] [ this . network ] ;
switch ( this . provider ) {
default :
2015-03-30 11:34:05 -07:00
case 'insight' :
2015-06-10 07:49:52 -07:00
var explorer = new Explorers . Insight ( this . url , this . network ) ;
explorer . getTransaction = _ . bind ( getTransactionInsight , explorer , this . url ) ;
explorer . getTransactions = _ . bind ( getTransactionsInsight , explorer , this . url ) ;
explorer . getAddressActivity = _ . bind ( getAddressActivityInsight , explorer , this . url ) ;
explorer . initSocket = _ . bind ( initSocketInsight , explorer , this . url ) ;
2015-03-31 08:04:02 -07:00
return explorer ;
2015-03-30 11:34:05 -07:00
} ;
} ;
2015-06-10 07:49:52 -07:00
BlockChainExplorer . prototype . getConnectionInfo = function ( ) {
return this . provider + ' (' + this . network + ') @ ' + this . url ;
} ;
2015-05-28 08:50:58 -07:00
function getTransactionInsight ( url , txid , cb ) {
var url = url + '/api/tx/' + txid ;
var args = {
method : "GET" ,
url : url ,
} ;
request ( args , function ( err , res , tx ) {
if ( err || res . statusCode != 200 ) return cb ( err || res ) ;
return cb ( null , tx ) ;
} ) ;
} ;
2015-03-31 12:26:46 -07:00
function getTransactionsInsight ( url , addresses , from , to , cb ) {
var qs = [ ] ;
if ( _ . isNumber ( from ) ) qs . push ( 'from=' + from ) ;
if ( _ . isNumber ( to ) ) qs . push ( 'to=' + to ) ;
var url = url + '/api/addrs/txs' + ( qs . length > 0 ? '?' + qs . join ( '&' ) : '' ) ;
2015-04-18 02:55:24 -07:00
var args = {
2015-03-30 11:34:05 -07:00
method : "POST" ,
2015-03-31 12:26:46 -07:00
url : url ,
2015-03-30 11:34:05 -07:00
json : {
addrs : [ ] . concat ( addresses ) . join ( ',' )
2015-04-18 02:55:24 -07:00
} ,
} ;
request ( args , function ( err , res , txs ) {
2015-03-30 11:34:05 -07:00
if ( err || res . statusCode != 200 ) return cb ( err || res ) ;
2015-04-06 11:13:30 -07:00
// NOTE: Whenever Insight breaks communication with bitcoind, it returns invalid data but no error code.
2015-04-18 02:55:24 -07:00
if ( ! _ . isArray ( txs ) || ( txs . length != _ . compact ( txs ) . length ) ) return cb ( new Error ( 'Could not retrieve transactions from blockchain. Request was:' + JSON . stringify ( args ) ) ) ;
2015-04-06 13:41:04 -07:00
2015-04-06 09:29:02 -07:00
return cb ( null , txs ) ;
2015-03-30 11:34:05 -07:00
} ) ;
} ;
2015-04-01 12:42:12 -07:00
function getAddressActivityInsight ( url , addresses , cb ) {
2015-04-15 09:23:30 -07:00
getTransactionsInsight ( url , addresses , null , null , function ( err , result ) {
2015-03-31 12:26:46 -07:00
if ( err ) return cb ( err ) ;
2015-04-15 09:23:30 -07:00
return cb ( null , result && result . length > 0 ) ;
2015-03-31 12:26:46 -07:00
} ) ;
} ;
2015-03-30 12:57:55 -07:00
function initSocketInsight ( url ) {
2015-05-07 11:04:32 -07:00
var socket = io . connect ( url , {
'reconnection' : true ,
} ) ;
2015-03-30 12:57:55 -07:00
return socket ;
} ;
2015-03-30 16:16:51 -07:00
module . exports = BlockChainExplorer ;