forked from smartcontractkit/cryptocompare-vwap-adapter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
142 lines (131 loc) · 3.64 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
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
138
139
140
141
142
const request = require('request-promise')
const createRequest = async (input, callback) => {
const coin = input.data.coin || 'AMPL'
const options = {
url: 'https://min-api.cryptocompare.com/data/pricehistorical',
qs: {
api_key: process.env.API_KEY,
tryConversion: false,
calculationType: 'VolFVolT'
},
json: true
}
const markets = await getMarkets(coin)
if (badResponse(markets)) {
return callback(500, {
jobRunID: input.id,
error: 'Coin not found',
status: 'errored',
statusCode: 500
})
}
const rawResults = await queryMarkets(coin, markets, options)
if (badResponse(rawResults)) {
return callback(500, {
jobRunID: input.id,
error: 'Could not query markets',
status: 'errored',
statusCode: 500
})
}
const conversions = await getConversions(coin, rawResults, options)
const vwap = calculateResults(coin, rawResults, conversions)
const allData = {
markets: markets,
results: rawResults,
conversions: conversions,
result: vwap
}
callback(200, {
jobRunID: input.id,
data: allData,
result: vwap,
statusCode: 200
})
}
const badResponse = (obj) => {
if (Object.keys(obj).length === 0 && obj.constructor === Object) return true
if (obj.Response == 'Error') return true
return false
}
// Get all the markets for a given coin
const getMarkets = async (coin) => {
const allMarkets = await request({
url: 'https://min-api.cryptocompare.com/data/pair/mapping/fsym',
qs: {
api_key: process.env.API_KEY,
fsym: coin
},
json: true
})
return allMarkets.Data
}
// Get the rate for each market of a given coin
const queryMarkets = async (coin, markets, options) => {
const tsymsArr = []
for (let i = 0; i < markets.length; i++) {
tsymsArr.push(markets[i].tsym)
}
const tsymsSet = [...new Set(tsymsArr)] // remove duplicates
let tsyms = ""
for (let i = 0; i < tsymsSet.length; i++) {
if (tsyms.length < 27) {
tsyms += tsymsSet[i] + ","
}
}
tsyms = tsyms.slice(0, -1)
options.qs.fsym = coin
options.qs.tsyms = tsyms
return await request(options)
}
// Get the rate in USD for non-USD markets
const getConversions = async (coin, markets, options) => {
const conversions = []
const keys = Object.keys(markets[coin])
for (let i = 0; i < keys.length; i++) {
if (keys[i].toLowerCase() !== 'usd') {
options.qs.fsym = keys[i]
options.qs.tsyms = 'USD'
conversions.push(await request(options))
}
}
return conversions
}
// Get the VWAP of all markets converted to USD
const calculateResults = (coin, rawResults, conversions) => {
const prices = []
const keys = Object.keys(rawResults[coin])
for (let i = 0; i < keys.length; i++) {
if (keys[i].toLowerCase() !== 'usd') {
const conversion = conversions.find(c => c[keys[i]])
const price = +rawResults[coin][keys[i]] * +conversion[keys[i]].USD
prices.push(price)
} else {
prices.push(+rawResults[coin][keys[i]])
}
}
return average(prices)
}
const average = (prices) => {
return prices.reduce((a, b) => a + b, 0) / prices.length
}
exports.gcpservice = (req, res) => {
createRequest(req.body, (statusCode, data) => {
res.status(statusCode).send(data)
})
}
exports.handler = (event, context, callback) => {
createRequest(event, (statusCode, data) => {
callback(null, data)
})
}
exports.handlerv2 = (event, context, callback) => {
createRequest(JSON.parse(event.body), (statusCode, data) => {
callback(null, {
statusCode: statusCode,
body: JSON.stringify(data),
isBase64Encoded: false
})
})
}
module.exports.createRequest = createRequest