-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkyte.js
More file actions
127 lines (108 loc) · 3.77 KB
/
Copy pathkyte.js
File metadata and controls
127 lines (108 loc) · 3.77 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
const axios = require('axios');
const crypto = require('crypto');
const jwt = require('jsonwebtoken'); // Ensure you have the correct import
class KyteClient {
constructor(publicKey, privateKey, kyteAccount, kyteIdentifier, kyteEndpoint, kyteAppId) {
this.publicKey = publicKey;
this.privateKey = privateKey;
this.kyteAccount = kyteAccount;
this.kyteIdentifier = kyteIdentifier;
this.kyteEndpoint = kyteEndpoint;
this.kyteAppId = kyteAppId;
this.sessionToken = '0';
this.transactionToken = '0';
this.usernameField = 'email';
this.passwordField = 'password';
}
encode(data) {
return Buffer.from(data, 'utf-8').toString('base64');
}
hmacSha256(data, key) {
const hmac = crypto.createHmac('sha256', key);
hmac.update(data);
return hmac.digest();
}
bytesToHex(bytes) {
return Array.from(bytes, byte => ('0' + byte.toString(16)).slice(-2)).join('');
}
async getIdentity(timestamp) {
const identityStr = `${this.publicKey}%${this.sessionToken}%${timestamp}%${this.kyteAccount}`;
return encodeURIComponent(this.encode(identityStr));
}
async getSignature(epoch) {
const key1 = this.hmacSha256(this.transactionToken, Buffer.from(this.privateKey, 'utf-8'));
const key2 = this.hmacSha256(this.kyteIdentifier, key1);
return this.bytesToHex(this.hmacSha256(epoch, key2));
}
async request(method, model, field, value, data, headers = {}) {
const formatter = new Intl.DateTimeFormat('en-US', {
timeZone: 'UTC',
weekday: 'short',
day: '2-digit',
month: 'short',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
});
const epoch = Math.floor(Date.now() / 1000).toString();
const timestamp = formatter.format(new Date());
const signature = await this.getSignature(epoch);
const identity = await this.getIdentity(timestamp);
let endpoint = `${this.kyteEndpoint}/${model}`;
if (field && value) {
endpoint += `/${field}/${value}`;
}
const config = {
method,
url: endpoint,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'x-kyte-signature': signature,
'x-kyte-identity': identity,
...headers
},
data: data ? JSON.stringify(data) : undefined
};
if (this.kyteAppId) {
config.headers['x-kyte-appid'] = this.kyteAppId;
}
const response = await axios(config);
if (response.status !== 200) {
throw new Error(`HTTP Error: ${response.status} - ${response.data}`);
}
if (!response.data.session || !response.data.token) {
throw new Error('Failed to retrieve sessionToken or transactionToken');
}
this.sessionToken = response.data.session;
this.transactionToken = response.data.token;
return response.data;
}
async post(model, data, headers) {
return await this.request('post', model, null, null, data, headers);
}
async put(model, field, value, data, headers) {
return await this.request('put', model, field, value, data, headers);
}
async get(model, field, value, headers) {
return await this.request('get', model, field, value, null, headers);
}
async delete(model, field, value, headers) {
return await this.request('delete', model, field, value, null, headers);
}
async createSession(username, password) {
const data = {};
data[this.usernameField] = username;
data[this.passwordField] = password;
const result = await this.post('Session', data);
if (!result.session || !result.token) {
throw new Error('Failed to retrieve sessionToken or transactionToken');
}
this.sessionToken = result.session;
this.transactionToken = result.token;
return result;
}
}
module.exports = KyteClient;