-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvalidateSignature.js
More file actions
103 lines (91 loc) · 2.94 KB
/
validateSignature.js
File metadata and controls
103 lines (91 loc) · 2.94 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
const { Requester, Validator } = require('@chainlink/external-adapter')
const { default: axios } = require('axios')
var eccryptoJS = require('eccrypto-js');
var EC = require('elliptic').ec;
var ec = new EC('p256');
// Define custom parameters to be used by the adapter.
// Extra parameters can be stated in the extra object,
// with a Boolean value indicating whether or not they
// should be required.
const customParams = {
pubKey: ['pubKey', 'publicKey'],
signature: ['sig', 'signature'],
getNonceUrl: ['getNonceUrl', 'getNonce'],
deleteNonceUrl: ['deleteNonceUrl', 'delNonceUrl'],
endpoint: false
}
const validateSignature = async (input, callback) => {
// The Validator helps you validate the Chainlink request data
const validator = new Validator(callback, input, customParams)
const jobRunID = validator.validated.id;
const pubKey = validator.validated.data.pubKey;
const signature = validator.validated.data.signature;
const getNonceUrl = validator.validated.data.getNonceUrl;
const deleteNonceUrl = validator.validated.data.deleteNonceUrl;
const noncesResp = await axios.get(getNonceUrl)
console.log('fetched nonces');
try {
const nonces = noncesResp.data.nonces;
let validNonce = '';
console.log(nonces);
let foundValidNonce = false;
for (const nonce of nonces) {
console.log(nonce);
const msg = Buffer.from(nonce.toString());
const hash = await eccryptoJS.sha256(msg);
const public = ec.keyFromPublic(pubKey, 'hex');
const isVerified = public.verify(hash, signature)
if (isVerified) {
foundValidNonce = true;
validNonce = nonce;
console.log('found valid nonce');
break;
}
console.log('did not find valid nonce');
}
// TODO: fix & uncomment
if (foundValidNonce && deleteNonceUrl)
await axios.delete(deleteNonceUrl + `&nonce=${validNonce}`);
callback(200, {
jobRunID,
data: {
isValid: foundValidNonce
}
});
} catch (error) {
callback(500, {
jobRunID,
data: {
isValid: false
}
})
};
}
// This is a wrapper to allow the function to work with
// GCP Functions
exports.gcpservice = (req, res) => {
validateSignature(req.body, (statusCode, data) => {
res.status(statusCode).send(data)
})
}
// This is a wrapper to allow the function to work with
// AWS Lambda
exports.handler = (event, context, callback) => {
validateSignature(event, (statusCode, data) => {
callback(null, data)
})
}
// This is a wrapper to allow the function to work with
// newer AWS Lambda implementations
exports.handlerv2 = (event, context, callback) => {
validateSignature(JSON.parse(event.body), (statusCode, data) => {
callback(null, {
statusCode: statusCode,
body: JSON.stringify(data),
isBase64Encoded: false
})
})
}
// This allows the function to be exported for testing
// or for running in express
module.exports.validateSignature = validateSignature