-
Notifications
You must be signed in to change notification settings - Fork 8
/
index.js
100 lines (98 loc) · 3.07 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
require('dotenv').config()
const config = require('./bitserve.json')
const express = require('express')
const bitqueryd = require('bitqueryd')
const PQueue = require('p-queue')
const ip = require('ip')
const app = express()
const rateLimit = require("express-rate-limit")
const cors = require("cors")
const concurrency = ((config.concurrency && config.concurrency.aggregate) ? config.concurrency.aggregate : 3)
const queue = new PQueue({concurrency: concurrency})
var db
app.set('view engine', 'ejs')
app.use(express.static('public'))
// create rate limiter for API endpoint,ß bypass whitelisted IPs
var whitelist = []
if (process.env.whitelist) {
whitelist = process.env.whitelist.split(',')
}
app.use(cors())
app.enable("trust proxy")
const limiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute window
max: 60, // 60 requests per windowMs
handler: function(req, res, /*next*/) {
res.format({
json: function() {
res.status(500).json({
error: "Too many requests. Limits are 60 requests per minute."
})
}
})
},
skip: function (req, /*res*/) {
if (whitelist.includes(req.ip)) {
return true
}
return false
}
})
app.get(/^\/q\/(.+)/, cors(), limiter, async function(req, res) {
var encoded = req.params[0];
let r = JSON.parse(new Buffer(encoded, "base64").toString());
if (r.q && r.q.aggregate) {
// add to aggregate queue
console.log("# Aggregate query. Adding to queue", queue.size)
queue.add(async function() {
// regular read
let result = await db.read(r)
if (config.log) {
console.log("query = ", r)
console.log("response = ", result)
}
console.log("Done", queue.size-1)
res.json(result)
})
} else {
// regular read
let result = await db.read(r)
if (config.log) {
console.log("query = ", r)
console.log("response = ", result)
}
res.json(result)
}
})
app.get(/^\/explorer\/(.+)/, function(req, res) {
let encoded = req.params[0]
let decoded = Buffer.from(encoded, 'base64').toString()
res.render('explorer', { code: decoded })
});
app.get('/explorer', function (req, res) {
res.render('explorer', { code: JSON.stringify(config.query, null, 2) })
});
app.get('/', function(req, res) {
res.redirect('/explorer')
});
var run = async function() {
db = await bitqueryd.init({
url: (config.url ? config.url : process.env.url),
timeout: config.timeout,
name: config.name
})
app.listen(config.port, () => {
console.log("######################################################################################");
console.log("#")
console.log("# BITSERVE: BitDB Microservice")
console.log("# Serving Bitcoin through HTTP...")
console.log("#")
console.log(`# Explorer: ${ip.address()}:${config.port}/explorer`);
console.log(`# API Endpoint: ${ip.address()}:${config.port}/q`);
console.log("#")
console.log("# Learn more at https://docs.bitdb.network")
console.log("#")
console.log("######################################################################################");
})
}
run()