Manuel Aráoz
10 years ago
7 changed files with 1 additions and 275 deletions
@ -1,36 +0,0 @@ |
|||
title: Insight Explorer |
|||
description: Provides an interface to fetch information about the state of the blockchain from a trusted Insight server. |
|||
--- |
|||
# Insight |
|||
|
|||
## Description |
|||
|
|||
`bitcore.transport.explorers.Insight` is a simple agent to perform queries to an Insight blockchain explorer. The default servers are `https://insight.bitpay.com` and `https://test-insight.bitpay.com`, hosted by BitPay Inc. You can (and we strongly suggest you do) run your own insight server. For more information, head to https://github.com/bitpay/insight-api |
|||
|
|||
There are currently two methods implemented (the API will grow as features are requested): `getUnspentUtxos` and `broadcast`. |
|||
|
|||
### Retrieving Unspent UTXOs for an Address (or set of) |
|||
|
|||
```javascript |
|||
var insight = new Insight(); |
|||
insight.getUnspentUtxos('1Bitcoin...', function(err, utxos) { |
|||
if (err) { |
|||
// Handle errors... |
|||
} else { |
|||
// Maybe use the UTXOs to create a transaction |
|||
} |
|||
}); |
|||
``` |
|||
|
|||
### Broadcasting a Transaction |
|||
|
|||
```javascript |
|||
var insight = new Insight(); |
|||
insight.broadcast(tx, function(err, returnedTxId) { |
|||
if (err) { |
|||
// Handle errors... |
|||
} else { |
|||
// Mark the transaction as broadcasted |
|||
} |
|||
}); |
|||
``` |
@ -1,3 +0,0 @@ |
|||
module.exports = { |
|||
Insight: require('./insight') |
|||
}; |
@ -1,115 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
var $ = require('../../util/preconditions'); |
|||
var _ = require('lodash'); |
|||
|
|||
var Address = require('../../address'); |
|||
var JSUtil = require('../../util/js'); |
|||
var Networks = require('../../networks'); |
|||
var Transaction = require('../../transaction'); |
|||
var UnspentOutput = Transaction.UnspentOutput; |
|||
|
|||
var request = require('request'); |
|||
|
|||
/** |
|||
* Allows the retrieval of information regarding the state of the blockchain |
|||
* (and broadcasting of transactions) from/to a trusted Insight server. |
|||
* @param {string=} url the url of the Insight server |
|||
* @param {Network=} network whether to use livenet or testnet |
|||
* @constructor |
|||
*/ |
|||
function Insight(url, network) { |
|||
if (!url && !network) { |
|||
return new Insight(Networks.defaultNetwork); |
|||
} |
|||
if (Networks.get(url)) { |
|||
network = Networks.get(url); |
|||
if (network === Networks.livenet) { |
|||
url = 'https://insight.bitpay.com'; |
|||
} else { |
|||
url = 'https://test-insight.bitpay.com'; |
|||
} |
|||
} |
|||
JSUtil.defineImmutable(this, { |
|||
url: url, |
|||
network: Networks.get(network) || Networks.defaultNetwork |
|||
}); |
|||
return this; |
|||
} |
|||
|
|||
/** |
|||
* @callback Insight.GetUnspentUtxosCallback |
|||
* @param {Error} err |
|||
* @param {Array.UnspentOutput} utxos |
|||
*/ |
|||
|
|||
/** |
|||
* Retrieve a list of unspent outputs associated with an address or set of addresses |
|||
* @param {Address|string|Array.Address|Array.string} addresses |
|||
* @param {GetUnspentUtxosCallback} callback |
|||
*/ |
|||
Insight.prototype.getUnspentUtxos = function(addresses, callback) { |
|||
$.checkArgument(_.isFunction(callback)); |
|||
if (!_.isArray(addresses)) { |
|||
addresses = [addresses]; |
|||
} |
|||
addresses = _.map(addresses, function(address) { return new Address(address); }); |
|||
|
|||
this.requestPost('/api/addrs/utxo', { |
|||
addrs: _.map(addresses, function(address) { return address.toString(); }).join(',') |
|||
}, function(err, res, unspent) { |
|||
if (err || res.statusCode !== 200) { |
|||
return callback(err || res); |
|||
} |
|||
unspent = _.map(unspent, UnspentOutput); |
|||
|
|||
return callback(null, unspent); |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* @callback Insight.BroadcastCallback |
|||
* @param {Error} err |
|||
* @param {string} txid |
|||
*/ |
|||
|
|||
/** |
|||
* Broadcast a transaction to the bitcoin network |
|||
* @param {transaction|string} transaction |
|||
* @param {BroadcastCallback} callback |
|||
*/ |
|||
Insight.prototype.broadcast = function(transaction, callback) { |
|||
$.checkArgument(JSUtil.isHexa(transaction) || transaction instanceof Transaction); |
|||
$.checkArgument(_.isFunction(callback)); |
|||
if (transaction instanceof Transaction) { |
|||
transaction = transaction.serialize(); |
|||
} |
|||
|
|||
this.requestPost('/api/tx/send', { |
|||
rawtx: transaction |
|||
}, function(err, res, body) { |
|||
if (err || res.statusCode !== 200) { |
|||
return callback(err || body); |
|||
} |
|||
return callback(null, body ? body.txid : null); |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Internal function to make a post request to the server |
|||
* @param {string} path |
|||
* @param {?} data |
|||
* @param {function} callback |
|||
* @private |
|||
*/ |
|||
Insight.prototype.requestPost = function(path, data, callback) { |
|||
$.checkArgument(_.isString(path)); |
|||
$.checkArgument(_.isFunction(callback)); |
|||
request({ |
|||
method: 'POST', |
|||
url: this.url + path, |
|||
json: data |
|||
}, callback); |
|||
}; |
|||
|
|||
module.exports = Insight; |
@ -1,6 +0,0 @@ |
|||
/** |
|||
* @namespace Transport |
|||
*/ |
|||
module.exports = { |
|||
explorers: require('./explorers') |
|||
}; |
@ -1,108 +0,0 @@ |
|||
'use strict'; |
|||
|
|||
var sinon = require('sinon'); |
|||
var should = require('chai').should(); |
|||
var expect = require('chai').expect; |
|||
var bitcore = require('../../..'); |
|||
|
|||
var Insight = bitcore.transport.explorers.Insight; |
|||
var Address = bitcore.Address; |
|||
var Transaction = bitcore.Transaction; |
|||
var Networks = bitcore.Networks; |
|||
|
|||
describe('Insight', function() { |
|||
|
|||
describe('instantiation', function() { |
|||
it('can be created without any parameters', function() { |
|||
var insight = new Insight(); |
|||
should.exist(insight.url); |
|||
should.exist(insight.network); |
|||
if (insight.network === Networks.livenet) { |
|||
insight.url.should.equal('https://insight.bitpay.com'); |
|||
} else if (insight.network === Networks.testnet) { |
|||
insight.url.should.equal('https://test-insight.bitpay.com'); |
|||
} |
|||
}); |
|||
it('can be created providing just a network', function() { |
|||
var insight = new Insight(Networks.testnet); |
|||
insight.url.should.equal('https://test-insight.bitpay.com'); |
|||
insight.network.should.equal(Networks.testnet); |
|||
}); |
|||
it('can be created with a custom url', function() { |
|||
var url = 'https://localhost:1234'; |
|||
var insight = new Insight(url); |
|||
insight.url.should.equal(url); |
|||
}); |
|||
it('can be created with a custom url and network', function() { |
|||
var url = 'https://localhost:1234'; |
|||
var insight = new Insight(url, Networks.testnet); |
|||
insight.url.should.equal(url); |
|||
insight.network.should.equal(Networks.testnet); |
|||
}); |
|||
it('defaults to defaultNetwork on a custom url', function() { |
|||
var insight = new Insight('https://localhost:1234'); |
|||
insight.network.should.equal(Networks.defaultNetwork); |
|||
}); |
|||
}); |
|||
|
|||
describe('getting unspent utxos', function() { |
|||
var insight = new Insight(); |
|||
var address = '371mZyMp4t6uVtcEr4DAAbTZyby9Lvia72'; |
|||
beforeEach(function() { |
|||
insight.requestPost = sinon.stub(); |
|||
insight.requestPost.onFirstCall().callsArgWith(2, null, {statusCode: 200}); |
|||
}); |
|||
it('can receive an address', function(callback) { |
|||
insight.getUnspentUtxos(new Address(address), callback); |
|||
}); |
|||
it('can receive a address as a string', function(callback) { |
|||
insight.getUnspentUtxos(address, callback); |
|||
}); |
|||
it('can receive an array of addresses', function(callback) { |
|||
insight.getUnspentUtxos([address, new Address(address)], callback); |
|||
}); |
|||
it('errors if server is not available', function(callback) { |
|||
insight.requestPost.onFirstCall().callsArgWith(2, 'Unable to connect'); |
|||
insight.getUnspentUtxos(address, function(error) { |
|||
expect(error).to.equal('Unable to connect'); |
|||
callback(); |
|||
}); |
|||
}); |
|||
it('errors if server returns errorcode', function(callback) { |
|||
insight.requestPost.onFirstCall().callsArgWith(2, null, {statusCode: 400}); |
|||
insight.getUnspentUtxos(address, function(error) { |
|||
expect(error).to.deep.equal({statusCode: 400}); |
|||
callback(); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
describe('broadcasting a transaction', function() { |
|||
var insight = new Insight(); |
|||
var tx = require('../../data/tx_creation.json')[0][7]; |
|||
beforeEach(function() { |
|||
insight.requestPost = sinon.stub(); |
|||
insight.requestPost.onFirstCall().callsArgWith(2, null, {statusCode: 200}); |
|||
}); |
|||
it('accepts a raw transaction', function(callback) { |
|||
insight.broadcast(tx, callback); |
|||
}); |
|||
it('accepts a transaction model', function(callback) { |
|||
insight.broadcast(new Transaction(tx), callback); |
|||
}); |
|||
it('errors if server is not available', function(callback) { |
|||
insight.requestPost.onFirstCall().callsArgWith(2, 'Unable to connect'); |
|||
insight.broadcast(tx, function(error) { |
|||
expect(error).to.equal('Unable to connect'); |
|||
callback(); |
|||
}); |
|||
}); |
|||
it('errors if server returns errorcode', function(callback) { |
|||
insight.requestPost.onFirstCall().callsArgWith(2, null, {statusCode: 400}, 'error'); |
|||
insight.broadcast(tx, function(error) { |
|||
expect(error).to.equal('error'); |
|||
callback(); |
|||
}); |
|||
}); |
|||
}); |
|||
}); |
Loading…
Reference in new issue