forked from MetaMask/eth-faucet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
137 lines (114 loc) · 3.52 KB
/
Copy pathserver.js
File metadata and controls
137 lines (114 loc) · 3.52 KB
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const MASCARA_SUPPORT = process.env.MASCARA_SUPPORT
const PORT = process.env.PORT || 9000
const express = require('express')
const Browserify = require('browserify')
const envify = require('envify/custom')
const bodyParser = require('body-parser')
const cors = require('cors')
const RateLimit = require('express-rate-limit')
const EthQuery = require('ethjs-query')
const BN = require('bn.js')
const ethUtil = require('ethereumjs-util')
const config = require('./get-config')
const rpcWrapperEngine = require('./index.js')
const regularPageCode = require('fs').readFileSync('./index.html', 'utf-8')
const mascaraPageCode = require('fs').readFileSync('./zero.html', 'utf-8')
const pageCode = MASCARA_SUPPORT ? mascaraPageCode : regularPageCode
const ETHER = 1e18
const faucetAmountWei = (1 * ETHER)
console.log('Acting as faucet for address:', config.address)
// Lazy nonce tracking fix:
// Force an exit after ten minutes (docker will trigger a restart)
setTimeout(() => {
console.log('Restarting for better nonce tracking')
process.exit()
}, 10 * 60 * 1000)
//
// create engine
//
// ProviderEngine based caching layer, with fallback to geth
var engine = rpcWrapperEngine({
rpcUrl: config.rpcOrigin,
addressHex: config.address,
privateKey: ethUtil.toBuffer(config.privateKey),
})
var ethQuery = new EthQuery(engine)
// prepare app bundle
var browserify = Browserify()
// inject faucet address
browserify.transform(envify({
FAUCET_ADDRESS: config.address,
}))
// build app
browserify.add('./app.js')
browserify.bundle(function(err, bundle){
if (err) throw err
var appCode = bundle.toString()
startServer(appCode)
})
//
// create webserver
//
function startServer(appCode) {
const app = express()
app.use(cors())
app.use(bodyParser.text({ type: '*/*' }))
// serve app
app.get('/', deliverPage)
app.get('/index.html', deliverPage)
app.get('/app.js', deliverApp)
// send ether
app.enable('trust proxy')
// add IP-based rate limiting
app.post('/', new RateLimit({
// 15 minutes
windowMs: 15*60*1000,
// limit each IP to N requests per windowMs
max: 200,
// disable delaying - full speed until the max limit is reached
delayMs: 0,
}))
// the fauceting request
app.post('/', function(req, res){
// parse request
var targetAddress = req.body
if (targetAddress.slice(0,2) !== '0x') {
targetAddress = '0x'+targetAddress
}
if (targetAddress.length !== 42) {
return didError(new Error('Address parse failure - '+targetAddress))
}
// check for greediness
ethQuery.getBalance(targetAddress, 'pending').then(function(balance){
var balanceTooFull = balance.gt(new BN('10000000000000000000', 10))
if (balanceTooFull) return didError(new Error('User is greedy.'))
// send value
ethQuery.sendTransaction({
to: targetAddress,
from: config.address,
value: faucetAmountWei,
data: '',
}).then(function(result){
console.log('sent tx:', result)
res.send(result)
}).catch(didError)
}).catch(didError)
function didError(err){
console.error(err.stack)
res.status(500).json({ error: err.message })
}
function invalidRequest(){
res.status(400).json({ error: 'Not a valid request.' })
}
})
app.listen(PORT, function(){
console.log('ethereum rpc listening on', PORT)
console.log('and proxying to', config.rpcOrigin)
})
function deliverPage(req, res){
res.status(200).send(pageCode)
}
function deliverApp(req, res){
res.status(200).send(appCode)
}
}