diff --git a/api/app.js b/api/app.js new file mode 100644 index 00000000..3ca81b93 --- /dev/null +++ b/api/app.js @@ -0,0 +1,41 @@ +'use strict'; + +var cors = require('cors') +var express = require('express'); +var compress = require('compression'); +var bodyParser = require('body-parser'); + +var routes = require('./routes'); + +function init(backend) { + var app = express(); + + // parse POST data + app.use(cors()); + app.use(compress()); + app.use(bodyParser.json()); + app.use(bodyParser.urlencoded({ extended: false })); + + // install routes + app.use('/', routes(backend)); + + // catch 404 and forward to error handler + app.use(function(req, res, next) { + var err = new Error('Not Found'); + err.status = 404; + next(err); + }); + + // production error handler + app.use(function(err, req, res, next) { + res.status(err.status || 500); + res.send({ + message: err.message, + error: {} + }); + }); + + return app; +} + +module.exports = init; diff --git a/api/bin/www b/api/bin/www new file mode 100755 index 00000000..55d52e15 --- /dev/null +++ b/api/bin/www @@ -0,0 +1,99 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var API = require('../app'); +var http = require('http'); + +/** + * Init api with backing services + */ + +var Node = { + status: 'live', + nodes: 123 +} +var app = new API(Node); + +/** + * Get port from environment and store in Express. + */ + +var port = normalizePort(process.env.PORT || '8000'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +var server = http.createServer(app); + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + console.log('Listening on ' + bind); +} diff --git a/api/routes/index.js b/api/routes/index.js new file mode 100644 index 00000000..645f8d9f --- /dev/null +++ b/api/routes/index.js @@ -0,0 +1,20 @@ +'use strict'; + +var express = require('express'); +var router = express.Router(); + +function initRouter(backend) { + var v1 = require('./v1')(backend); + var v2 = require('./v2')(backend); + + router.use('/v1', v1); + router.use('/v2', v2); + + router.get('/', function(req, res, next) { + res.send('bitcore node api'); + }); + + return router; +} + +module.exports = initRouter; diff --git a/api/routes/v1.js b/api/routes/v1.js new file mode 100644 index 00000000..bfcaabf3 --- /dev/null +++ b/api/routes/v1.js @@ -0,0 +1,50 @@ +'use strict'; + +var express = require('express'); + +function initRouter(backend) { + var router = express.Router(); + + function mockResponse(req, res, next) { + res.send('This is a mocked response. Backed service is: ' + backend.status); + } + + router.get('/blocks', mockResponse); + router.get('/block/:blockHash', mockResponse); + router.get('/block-index/:height', mockResponse); + + // Transaction routes + router.get('/tx/:txid', mockResponse); + router.get('/txs', mockResponse); + router.post('/tx/send', mockResponse); + + // Address routes + router.get('/addr/:addr', mockResponse); + router.get('/addr/:addr/utxo', mockResponse); + router.get('/addrs/:addrs/utxo', mockResponse); + router.post('/addrs/utxo', mockResponse); + router.get('/addrs/:addrs/txs', mockResponse); + router.post('/addrs/txs', mockResponse); + + // Address property routes + router.get('/addr/:addr/balance', mockResponse); + router.get('/addr/:addr/totalReceived', mockResponse); + router.get('/addr/:addr/totalSent', mockResponse); + router.get('/addr/:addr/unconfirmedBalance', mockResponse); + + // Status route + router.get('/status', mockResponse); + router.get('/sync', mockResponse); + router.get('/peer', mockResponse); + + // Currency + router.get('/currency', mockResponse); + + // Address routes + router.get('/messages/verify', mockResponse); + router.post('/messages/verify', mockResponse); + + return router; +} + +module.exports = initRouter; diff --git a/api/routes/v2.js b/api/routes/v2.js new file mode 100644 index 00000000..b6e51377 --- /dev/null +++ b/api/routes/v2.js @@ -0,0 +1,15 @@ +'use strict'; + +var express = require('express'); + +function initRouter(backend) { + var router = express.Router(); + + router.get('/blocks', function(req, res, next) { + res.send('blocks v2 ' + backend.nodes); + }); + + return router; +} + +module.exports = initRouter; diff --git a/package.json b/package.json index 957d0d66..20437458 100644 --- a/package.json +++ b/package.json @@ -52,8 +52,10 @@ "buffertools": "*", "commander": "^2.3.0", "config": "^1.12.0", + "compression": "^1.4.1", + "cors": "^2.5.3", "cron": "^1.0.4", - "express": "~3.4.7", + "express": "4.11.1", "glob": "*", "js-yaml": "^3.2.7", "leveldown": "~0.10.0",