Skip to content
4 changes: 4 additions & 0 deletions lib/addresses.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ AddressController.prototype.show = function(req, res) {
});
};

AddressController.prototype.listUnspent = function(req, res){
this.listUnspent(req, res);
}

AddressController.prototype.balance = function(req, res) {
this.addressSummarySubQuery(req, res, 'balanceSat');
};
Expand Down
1 change: 1 addition & 0 deletions lib/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var LRU = require('lru-cache');
var Common = require('./common');

function BlockController(options) {

var self = this;
this.node = options.node;

Expand Down
19 changes: 19 additions & 0 deletions lib/governance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict';

var Common = require('./common');

function GovernanceController(node) {
this.node = node;
this.common = new Common({log: this.node.log});
}

GovernanceController.prototype.getSuperBlockBudget = function (req, res) {
var self = this;
var blockindex = req.params.blockindex || 0;
this.node.services.bitcoind.getSuperBlockBudget(blockindex,function (err, result) {
if(err) { return self.common.handleErrors(err, res);}
res.jsonp(result);
})
}
module.exports = GovernanceController;

158 changes: 158 additions & 0 deletions lib/govobject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
'use strict';

var Common = require('./common');

function GovObjectController(node) {
this.node = node;
this.common = new Common({log: this.node.log});
}

GovObjectController.prototype.submit = function (req, res) {
var self = this;

var parentHash = req.body.parentHash || (function(){throw new Error('missing parentHash')}());
var revision = req.body.revision || (function(){throw new Error('missing revision')}());
var time = req.body.time || (function(){throw new Error('missing time')}())
var dataHex = req.body.dataHex || (function(){throw new Error('missing dataHex')}());
var feeTxId = req.body.feeTxId || (function(){throw new Error('missing feeTxId')}());

this.node.services.bitcoind.govObjectSubmit(parentHash, revision, time, dataHex, feeTxId, function(err, result) {
if(err) { return self.common.handleErrors(err, res);}
res.jsonp(result)
});
}

GovObjectController.prototype.list = function(req, res) {
var options = {
type:1//by default display proposal
};
if (req.params.filter) {
if (req.params.filter === 'proposal') options.type = 1;
if (req.params.filter === 'trigger') options.type = 2;
}

this.govObjectList(options, function(err, result) {
var govObjectList = {gobjects: result}
if (err) {
return self.common.handleErrors(err, res);
}

res.jsonp(govObjectList);
});

};

GovObjectController.prototype.govObjectList = function(options, callback) {
this.node.services.bitcoind.govObjectList(options, function(err, result) {
if (err) {
return callback(err);
}
callback(null, result);
});

};


GovObjectController.prototype.show = function(req, res) {
var self = this;
var options = {};

this.getHash(req.hash, function(err, data) {
if(err) {
return self.common.handleErrors(err, res);
}

res.jsonp(data);
});

};

GovObjectController.prototype.getHash = function(hash, callback) {

this.node.services.bitcoind.govObjectHash(hash, function(err, result) {
if (err) {
return callback(err);
}

callback(null, result);
});

};

/**
* Verifies that the GovObject Hash provided is valid.
*
* @param req
* @param res
* @param next
*/
GovObjectController.prototype.validateHash = function(req, res, next) {
req.hash = req.params.hash;
this.isValidHash(req, res, next, [req.hash]);
};

GovObjectController.prototype.isValidHash = function(req, res, next, hash) {
// TODO: Implement some type of validation
if(hash) next();
};


GovObjectController.prototype.govObjectCheck = function(req, res) {
var self = this;
var hexdata = req.params.hexdata;

this.node.services.bitcoind.govObjectCheck(hexdata, function(err, result) {
if (err) {
return self.common.handleErrors(err, res);
}
res.jsonp(result);
});
};

GovObjectController.prototype.getInfo = function (req, res) {
var self = this;
this.node.services.bitcoind.govObjectInfo(function (err, result) {
if(err) { return self.common.handleErrors(err, res);}
res.jsonp(result);
})
}

GovObjectController.prototype.getCount = function (req, res) {
var self = this;
this.node.services.bitcoind.govCount(function (err, result) {
if(err) { return self.common.handleErrors(err, res);}
res.jsonp(result);
})
}

GovObjectController.prototype.govObjectVotes = function (req, res) {
var self = this;
var govHash = req.params.hash;

this.node.services.bitcoind.getVotes(govHash, function (err, result) {
if(err) { return self.common.handleErrors(err, res);}
res.jsonp(result);
})
}

GovObjectController.prototype.govObjectCurrentVotes = function (req, res) {
var self = this;
var govHash = req.params.hash;

this.node.services.bitcoind.getCurrentVotes(govHash, function (err, result) {
if(err) { return self.common.handleErrors(err, res);}
res.jsonp(result);
})
}

GovObjectController.prototype.govObjectDeserialize = function (req, res) {
var self = this;
var hexdata = req.params.hexdata;

this.node.services.dashd.govObjectDeserialize(hexdata, function (err, result) {
if(err) { return self.common.handleErrors(err, res);}
res.jsonp(result);
})
}
module.exports = GovObjectController;

30 changes: 30 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ var inherits = require('util').inherits;
var BlockController = require('./blocks');
var TxController = require('./transactions');
var AddressController = require('./addresses');
var GovObjectController = require('./govobject');
var GovernanceController = require('./governance');
var ChartController = require('./charts');
var StatusController = require('./status');
var MessagesController = require('./messages');
var MasternodesController = require('./masternodes');
var UtilsController = require('./utils');
var CurrencyController = require('./currency');
var RateLimiter = require('./ratelimiter');
Expand Down Expand Up @@ -212,6 +215,33 @@ InsightAPI.prototype.setupRoutes = function(app) {
app.get('/addr/:addr/totalSent', this.cacheShort(), addresses.checkAddr.bind(addresses), addresses.totalSent.bind(addresses));
app.get('/addr/:addr/unconfirmedBalance', this.cacheShort(), addresses.checkAddr.bind(addresses), addresses.unconfirmedBalance.bind(addresses));

//Governance Routes
var govObject = new GovObjectController(this.node);
app.post('/gobject/submit', this.cacheShort(), govObject.submit.bind(govObject));
app.get('/gobject/list', this.cacheShort(), govObject.list.bind(govObject));
app.get('/gobject/list/:filter', this.cacheShort(), govObject.list.bind(govObject));
app.get('/gobject/get/:hash', this.cacheShort(), govObject.validateHash.bind(govObject), govObject.show.bind(govObject));
app.get('/gobject/check/:hexdata', this.cacheShort(), govObject.govObjectCheck.bind(govObject));
app.get('/gobject/info', this.cacheShort(), govObject.getInfo.bind(govObject));
app.get('/gobject/count', this.cacheShort(), govObject.getCount.bind(govObject));
app.get('/gobject/deserialize/:hexdata', this.cacheShort(), govObject.govObjectDeserialize.bind(govObject));
app.get('/gobject/votes/current/:hash', this.cacheShort(), govObject.govObjectCurrentVotes.bind(govObject));
app.get('/gobject/votes/:hash', this.cacheShort(), govObject.govObjectVotes.bind(govObject));

var governance = new GovernanceController(this.node);
app.get('/governance/budget/:blockindex', this.cacheShort(), governance.getSuperBlockBudget.bind(governance));

//Masternodes
var masternodes = new MasternodesController(this.node);
app.get('/masternodes/list', this.cacheShort(), masternodes.list.bind
(masternodes));
var masternodeByRank = new MasternodesController(this.node);
app.get('/masternodes/listbyrank', this.cacheShort(), masternodes.listByRank.bind(masternodeByRank));
app.get('/masternodes/validate/:payee', this.cacheShort(), masternodes.validate.bind(masternodes));

var createMasternode = new MasternodesController(this.node);
app.get('/masternodes/create', this.cacheShort(), masternodes.startAll.bind(createMasternode));

// Chart routes
var chartOptions = {
node: this.node,
Expand Down
131 changes: 131 additions & 0 deletions lib/masternodes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
'use strict';

var Common = require('./common');
var bitcore = require('bitcore-lib-anon');
var _ = bitcore.deps._;

function MasternodeController(node) {
this.node = node;
this.common = new Common({log: this.node.log});
}

MasternodeController.prototype.list = function(req, res) {
var self = this;
this.getMNList(function(err, result) {
if (err) {
return self.common.handleErrors(err, res);
}
res.jsonp(result);
});
};

MasternodeController.prototype.listByRank = function(req, res) {
var self = this;
this.getListMasternodes(function(err, result) {
if (err) {
return self.common.handleErrors(err, res);
}
res.jsonp(result);

});
};

MasternodeController.prototype.validate = function (req, res, next) {
var payeeAddr = req.params.payee;
//We first validate that the payee address is valid
var self = this;
if(!payeeAddr || payeeAddr.length!=34 ) {
return self.common.handleErrors({
message: 'Must include a valid format address',
code: 1
}, res);
}

try {
var a = new bitcore.Address(payeeAddr);
} catch(e) {
return self.common.handleErrors({
message: 'Invalid address: ' + e.message,
code: 1
}, res);
}


//After having valide addr, we get the MNList
this.getMNList(function(err, mnList){
if(err){
return self.common.handleErrors(err, res);
}

var filteredMnList = mnList.filter(function(elem){
return elem.payee === payeeAddr;
});

if(!filteredMnList || !filteredMnList[0]){
return res.jsonp({valid:false, payee:payeeAddr});
}
var mn = filteredMnList[0];
mn.valid = false;

if(!mn.hasOwnProperty('payee') ||
mn.hasOwnProperty('vin')){
var vin = mn.vin.split('-');
var txid = vin[0];
var voutindex = vin[1];

self.node.getDetailedTransaction(txid, function(err, transaction) {
if (err && err.code === -5) {
return self.common.handleErrors(null, res);
} else if(err) {
return self.common.handleErrors(err, res);
}
if(transaction.outputs && transaction.outputs[voutindex]){
var txvout = transaction.outputs[voutindex]
if(txvout.satoshis===100000000000 &&
txvout.spentTxId===undefined &&
txvout.spentHeight===undefined &&
txvout.spentIndex===undefined){
mn.valid = true;
res.jsonp(mn)
}else{
res.jsonp(mn)
}
}
});
}
})
};

MasternodeController.prototype.getMNList = function(callback) {
this.node.services.bitcoind.getMNList(function(err, result){

var MNList = {masternodes: result } || {masternodes:[]};
if (err) {
return callback(err);
}
callback(null,MNList);
});
};

MasternodeController.prototype.getListMasternodes = function(callback) {
this.node.services.bitcoind.getListMasternodes(function(err, result){
var MNList = {masternodesByRank: result } || {masternodesByRank:[]};
if (err) {
return callback(err);
}
callback(null,MNList);
});
};

MasternodeController.prototype.startAll = function(req, res) {
this.node.services.bitcoind.startAll(function(err,result){

if(err){
return callback(err);
}
// callback(null, result);
res.jsonp(result);
});
}

module.exports = MasternodeController;
Loading