-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
64 lines (61 loc) · 2.16 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
import { STATUS_CODES } from 'node:http'
import assert from 'node:assert'
import Sentry from '@sentry/node'
/**
*
* @param {import('node:http').IncomingMessage} req
* @param {import('node:http').ServerResponse} res
* @param {string} apiKey
* @param {typeof fetch} fetch
*/
const handler = async (req, res, apiKey, fetch) => {
// The origin is the electron app. The origin depends on how we run the app.
// - via `npm start` -> origin is http://localhost:3000
// - packaged -> origin is app://-
// Unfortunately, Access-Control-Allow-Origin supports only a single value (single origin)
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
// > Only a single origin can be specified. If the server supports clients from multiple origins,
// > it must return the origin for the specific client making the request.
if (req.headers.origin === 'http://localhost:3000') {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000')
} else {
res.setHeader('Access-Control-Allow-Origin', 'app://-')
}
const address = req.url.split('/')[1].trim()
const fetchRes = await fetch(
`https://public.chainalysis.com/api/v1/address/${address}`,
{
headers: {
'X-API-Key': apiKey,
accept: 'application/json'
}
}
)
assert(fetchRes.ok, `Chainalysis API status ${fetchRes.status}`)
const body = await fetchRes.json()
if (typeof body !== 'object' || body === null || !Array.isArray(body.identifications)) {
const err = new Error('Invalid Chainalysis response')
err.body = body
throw err
}
res.statusCode = body.identifications.length > 0 ? 403 : 200
res.end(STATUS_CODES[res.statusCode])
}
export const createHandler = ({
apiKey,
fetch = globalThis.fetch,
logger
}) => (req, res) => {
const start = new Date()
logger.request(`${req.method} ${req.url} ...`)
handler(req, res, apiKey, fetch)
.catch(err => {
logger.error(err)
Sentry.captureException(err)
res.statusCode = 500
res.end('Internal Server Error')
})
.then(() => {
logger.request(`${req.method} ${req.url} ${res.statusCode} (${new Date() - start}ms)`)
})
}