evernode-js-client 0.5.0 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
package/src/defaults.js DELETED
@@ -1,21 +0,0 @@
1
- const DefaultValues = {
2
- registryAddress: 'raaFre81618XegCrzTzVotAmarBcqNSAvK',
3
- rippledServer: 'wss://hooks-testnet-v2.xrpl-labs.com',
4
- xrplApi: null,
5
- stateIndexId: 'evernodeindex'
6
- }
7
-
8
- class Defaults {
9
- static set(newDefaults) {
10
- Object.assign(DefaultValues, newDefaults)
11
- }
12
-
13
- static get() {
14
- return { ...DefaultValues };
15
- }
16
- }
17
-
18
- module.exports = {
19
- DefaultValues,
20
- Defaults
21
- }
package/src/eccrypto.js DELETED
@@ -1,258 +0,0 @@
1
- // Code taken from https://github.com/bitchan/eccrypto/blob/master/browser.js
2
- // We are using this code file directly because the full eccrypto library causes a conflict with
3
- // tiny-secp256k1 used by xrpl libs during ncc/webpack build.
4
-
5
- var EC = require("elliptic").ec;
6
- var ec = new EC("secp256k1");
7
- var browserCrypto = global.crypto || global.msCrypto || {};
8
- var subtle = browserCrypto.subtle || browserCrypto.webkitSubtle;
9
-
10
- var nodeCrypto = require('crypto');
11
-
12
- const EC_GROUP_ORDER = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 'hex');
13
- const ZERO32 = Buffer.alloc(32, 0);
14
-
15
- function assert(condition, message) {
16
- if (!condition) {
17
- throw new Error(message || "Assertion failed");
18
- }
19
- }
20
-
21
- function isScalar(x) {
22
- return Buffer.isBuffer(x) && x.length === 32;
23
- }
24
-
25
- function isValidPrivateKey(privateKey) {
26
- if (!isScalar(privateKey)) {
27
- return false;
28
- }
29
- return privateKey.compare(ZERO32) > 0 && // > 0
30
- privateKey.compare(EC_GROUP_ORDER) < 0; // < G
31
- }
32
-
33
- // Compare two buffers in constant time to prevent timing attacks.
34
- function equalConstTime(b1, b2) {
35
- if (b1.length !== b2.length) {
36
- return false;
37
- }
38
- var res = 0;
39
- for (var i = 0; i < b1.length; i++) {
40
- res |= b1[i] ^ b2[i]; // jshint ignore:line
41
- }
42
- return res === 0;
43
- }
44
-
45
- /* This must check if we're in the browser or
46
- not, since the functions are different and does
47
- not convert using browserify */
48
- function randomBytes(size) {
49
- var arr = new Uint8Array(size);
50
- if (typeof browserCrypto.getRandomValues === 'undefined') {
51
- return Buffer.from(nodeCrypto.randomBytes(size));
52
- } else {
53
- browserCrypto.getRandomValues(arr);
54
- }
55
- return Buffer.from(arr);
56
- }
57
-
58
- function sha512(msg) {
59
- return new Promise(function (resolve) {
60
- var hash = nodeCrypto.createHash('sha512');
61
- var result = hash.update(msg).digest();
62
- resolve(new Uint8Array(result));
63
- });
64
- }
65
-
66
- function getAes(op) {
67
- return function (iv, key, data) {
68
- return new Promise(function (resolve) {
69
- if (subtle) {
70
- var importAlgorithm = { name: "AES-CBC" };
71
- var keyp = subtle.importKey("raw", key, importAlgorithm, false, [op]);
72
- return keyp.then(function (cryptoKey) {
73
- var encAlgorithm = { name: "AES-CBC", iv: iv };
74
- return subtle[op](encAlgorithm, cryptoKey, data);
75
- }).then(function (result) {
76
- resolve(Buffer.from(new Uint8Array(result)));
77
- });
78
- } else {
79
- if (op === 'encrypt') {
80
- var cipher = nodeCrypto.createCipheriv('aes-256-cbc', key, iv);
81
- let firstChunk = cipher.update(data);
82
- let secondChunk = cipher.final();
83
- resolve(Buffer.concat([firstChunk, secondChunk]));
84
- }
85
- else if (op === 'decrypt') {
86
- var decipher = nodeCrypto.createDecipheriv('aes-256-cbc', key, iv);
87
- let firstChunk = decipher.update(data);
88
- let secondChunk = decipher.final();
89
- resolve(Buffer.concat([firstChunk, secondChunk]));
90
- }
91
- }
92
- });
93
- };
94
- }
95
-
96
- var aesCbcEncrypt = getAes("encrypt");
97
- var aesCbcDecrypt = getAes("decrypt");
98
-
99
- function hmacSha256Sign(key, msg) {
100
- return new Promise(function (resolve) {
101
- var hmac = nodeCrypto.createHmac('sha256', Buffer.from(key));
102
- hmac.update(msg);
103
- var result = hmac.digest();
104
- resolve(result);
105
- });
106
- }
107
-
108
- function hmacSha256Verify(key, msg, sig) {
109
- return new Promise(function (resolve) {
110
- var hmac = nodeCrypto.createHmac('sha256', Buffer.from(key));
111
- hmac.update(msg);
112
- var expectedSig = hmac.digest();
113
- resolve(equalConstTime(expectedSig, sig));
114
- });
115
- }
116
-
117
- /**
118
- * Generate a new valid private key. Will use the window.crypto or window.msCrypto as source
119
- * depending on your browser.
120
- * @return {Buffer} A 32-byte private key.
121
- * @function
122
- */
123
- exports.generatePrivate = function () {
124
- var privateKey = randomBytes(32);
125
- while (!isValidPrivateKey(privateKey)) {
126
- privateKey = randomBytes(32);
127
- }
128
- return privateKey;
129
- };
130
-
131
- var getPublic = exports.getPublic = function (privateKey) {
132
- // This function has sync API so we throw an error immediately.
133
- assert(privateKey.length === 32, "Bad private key");
134
- assert(isValidPrivateKey(privateKey), "Bad private key");
135
- // XXX(Kagami): `elliptic.utils.encode` returns array for every
136
- // encoding except `hex`.
137
- return Buffer.from(ec.keyFromPrivate(privateKey).getPublic("arr"));
138
- };
139
-
140
- /**
141
- * Get compressed version of public key.
142
- */
143
- var getPublicCompressed = exports.getPublicCompressed = function (privateKey) { // jshint ignore:line
144
- assert(privateKey.length === 32, "Bad private key");
145
- assert(isValidPrivateKey(privateKey), "Bad private key");
146
- // See https://github.com/wanderer/secp256k1-node/issues/46
147
- let compressed = true;
148
- return Buffer.from(ec.keyFromPrivate(privateKey).getPublic(compressed, "arr"));
149
- };
150
-
151
- // NOTE(Kagami): We don't use promise shim in Browser implementation
152
- // because it's supported natively in new browsers (see
153
- // <http://caniuse.com/#feat=promises>) and we can use only new browsers
154
- // because of the WebCryptoAPI (see
155
- // <http://caniuse.com/#feat=cryptography>).
156
- exports.sign = function (privateKey, msg) {
157
- return new Promise(function (resolve) {
158
- assert(privateKey.length === 32, "Bad private key");
159
- assert(isValidPrivateKey(privateKey), "Bad private key");
160
- assert(msg.length > 0, "Message should not be empty");
161
- assert(msg.length <= 32, "Message is too long");
162
- resolve(Buffer.from(ec.sign(msg, privateKey, { canonical: true }).toDER()));
163
- });
164
- };
165
-
166
- exports.verify = function (publicKey, msg, sig) {
167
- return new Promise(function (resolve, reject) {
168
- assert(publicKey.length === 65 || publicKey.length === 33, "Bad public key");
169
- if (publicKey.length === 65) {
170
- assert(publicKey[0] === 4, "Bad public key");
171
- }
172
- if (publicKey.length === 33) {
173
- assert(publicKey[0] === 2 || publicKey[0] === 3, "Bad public key");
174
- }
175
- assert(msg.length > 0, "Message should not be empty");
176
- assert(msg.length <= 32, "Message is too long");
177
- if (ec.verify(msg, sig, publicKey)) {
178
- resolve(null);
179
- } else {
180
- reject(new Error("Bad signature"));
181
- }
182
- });
183
- };
184
-
185
- var derive = exports.derive = function (privateKeyA, publicKeyB) {
186
- return new Promise(function (resolve) {
187
- assert(Buffer.isBuffer(privateKeyA), "Bad private key");
188
- assert(Buffer.isBuffer(publicKeyB), "Bad public key");
189
- assert(privateKeyA.length === 32, "Bad private key");
190
- assert(isValidPrivateKey(privateKeyA), "Bad private key");
191
- assert(publicKeyB.length === 65 || publicKeyB.length === 33, "Bad public key");
192
- if (publicKeyB.length === 65) {
193
- assert(publicKeyB[0] === 4, "Bad public key");
194
- }
195
- if (publicKeyB.length === 33) {
196
- assert(publicKeyB[0] === 2 || publicKeyB[0] === 3, "Bad public key");
197
- }
198
- var keyA = ec.keyFromPrivate(privateKeyA);
199
- var keyB = ec.keyFromPublic(publicKeyB);
200
- var Px = keyA.derive(keyB.getPublic()); // BN instance
201
- resolve(Buffer.from(Px.toArray()));
202
- });
203
- };
204
-
205
- exports.encrypt = function (publicKeyTo, msg, opts) {
206
- opts = opts || {};
207
- // Tmp variables to save context from flat promises;
208
- var iv, ephemPublicKey, ciphertext, macKey;
209
- return new Promise(function (resolve) {
210
- var ephemPrivateKey = opts.ephemPrivateKey || randomBytes(32);
211
- // There is a very unlikely possibility that it is not a valid key
212
- while (!isValidPrivateKey(ephemPrivateKey)) {
213
- ephemPrivateKey = opts.ephemPrivateKey || randomBytes(32);
214
- }
215
- ephemPublicKey = getPublic(ephemPrivateKey);
216
- resolve(derive(ephemPrivateKey, publicKeyTo));
217
- }).then(function (Px) {
218
- return sha512(Px);
219
- }).then(function (hash) {
220
- iv = opts.iv || randomBytes(16);
221
- var encryptionKey = hash.slice(0, 32);
222
- macKey = hash.slice(32);
223
- return aesCbcEncrypt(iv, encryptionKey, msg);
224
- }).then(function (data) {
225
- ciphertext = data;
226
- var dataToMac = Buffer.concat([iv, ephemPublicKey, ciphertext]);
227
- return hmacSha256Sign(macKey, dataToMac);
228
- }).then(function (mac) {
229
- return {
230
- iv: iv,
231
- ephemPublicKey: ephemPublicKey,
232
- ciphertext: ciphertext,
233
- mac: mac,
234
- };
235
- });
236
- };
237
-
238
- exports.decrypt = function (privateKey, opts) {
239
- // Tmp variable to save context from flat promises;
240
- var encryptionKey;
241
- return derive(privateKey, opts.ephemPublicKey).then(function (Px) {
242
- return sha512(Px);
243
- }).then(function (hash) {
244
- encryptionKey = hash.slice(0, 32);
245
- var macKey = hash.slice(32);
246
- var dataToMac = Buffer.concat([
247
- opts.iv,
248
- opts.ephemPublicKey,
249
- opts.ciphertext
250
- ]);
251
- return hmacSha256Verify(macKey, dataToMac, opts.mac);
252
- }).then(function (macGood) {
253
- assert(macGood, "Bad MAC");
254
- return aesCbcDecrypt(opts.iv, encryptionKey, opts.ciphertext);
255
- }).then(function (msg) {
256
- return Buffer.from(new Uint8Array(msg));
257
- });
258
- };
@@ -1,41 +0,0 @@
1
- const eccrypto = require('./eccrypto') // Using local copy of the eccrypto code file.
2
-
3
- class EncryptionHelper {
4
- // Offsets of the properties in the encrypted buffer.
5
- static ivOffset = 65;
6
- static macOffset = this.ivOffset + 16;
7
- static ciphertextOffset = this.macOffset + 32;
8
- static contentFormat = 'base64';
9
- static keyFormat = 'hex';
10
-
11
- static async encrypt(publicKey, json, options = {}) {
12
- // For the encryption library, both keys and data should be buffers.
13
- const encrypted = await eccrypto.encrypt(Buffer.from(publicKey, this.keyFormat), Buffer.from(JSON.stringify(json)), options);
14
- // Concat all the properties of the encrypted object to a single buffer.
15
- const result = Buffer.concat([encrypted.ephemPublicKey, encrypted.iv, encrypted.mac, encrypted.ciphertext]).toString(this.contentFormat);
16
- return result;
17
- }
18
-
19
- static async decrypt(privateKey, encrypted) {
20
- // Extract the buffer from the string and prepare encrypt object from buffer offsets for decryption.
21
- const encryptedBuf = Buffer.from(encrypted, this.contentFormat);
22
- const encryptedObj = {
23
- ephemPublicKey: encryptedBuf.slice(0, this.ivOffset),
24
- iv: encryptedBuf.slice(this.ivOffset, this.macOffset),
25
- mac: encryptedBuf.slice(this.macOffset, this.ciphertextOffset),
26
- ciphertext: encryptedBuf.slice(this.ciphertextOffset)
27
- }
28
-
29
- const decrypted = await eccrypto.decrypt(Buffer.from(privateKey, this.keyFormat).slice(1), encryptedObj)
30
- .catch(err => console.log(err));
31
-
32
- if (!decrypted)
33
- return null;
34
-
35
- return JSON.parse(decrypted.toString());
36
- }
37
- }
38
-
39
- module.exports = {
40
- EncryptionHelper
41
- }
@@ -1,45 +0,0 @@
1
- class EventEmitter {
2
- constructor() {
3
- this.handlers = {};
4
- }
5
-
6
- on(event, handler) {
7
- if (!this.handlers[event])
8
- this.handlers[event] = [];
9
- this.handlers[event].push({
10
- once: false,
11
- func: handler
12
- });
13
- }
14
-
15
- once(event, handler) {
16
- if (!this.handlers[event])
17
- this.handlers[event] = [];
18
- this.handlers[event].push({
19
- once: true,
20
- func: handler
21
- });
22
- }
23
-
24
- off(event, handler = null) {
25
- if (this.handlers[event]) {
26
- if (handler)
27
- this.handlers[event] = this.handlers[event].filter(h => h !== handler);
28
- else
29
- delete this.handlers[event];
30
- }
31
- }
32
-
33
- emit(event, value, error = null) {
34
- if (this.handlers[event]) {
35
- this.handlers[event].forEach(handler => handler.func(value, error));
36
-
37
- // Rmove all handlers marked as 'once'.
38
- this.handlers[event] = this.handlers[event].filter(h => !h.once);
39
- }
40
- }
41
- }
42
-
43
- module.exports = {
44
- EventEmitter
45
- }
@@ -1,103 +0,0 @@
1
- const EvernodeConstants = {
2
- EVR: 'EVR',
3
- NFT_PREFIX_HEX: '657672686F7374', // evrhost
4
- LEASE_NFT_PREFIX_HEX: '6576726C65617365', // evrlease
5
- HOOK_NAMESPACE: '01EAF09326B4911554384121FF56FA8FECC215FDDE2EC35D9E59F2C53EC665A0'
6
- }
7
-
8
- const MemoTypes = {
9
- ACQUIRE_LEASE: 'evnAcquireLease',
10
- ACQUIRE_SUCCESS: 'evnAcquireSuccess',
11
- ACQUIRE_ERROR: 'evnAcquireError',
12
- ACQUIRE_REF: 'evnAcquireRef',
13
- HOST_REG: 'evnHostReg',
14
- HOST_DEREG: 'evnHostDereg',
15
- HOST_UPDATE_INFO: 'evnHostUpdateReg',
16
- HEARTBEAT: 'evnHeartbeat',
17
- HOST_POST_DEREG: 'evnHostPostDereg',
18
- EXTEND_LEASE: 'evnExtendLease',
19
- EXTEND_SUCCESS: 'evnExtendSuccess',
20
- EXTEND_ERROR: 'evnExtendError',
21
- EXTEND_REF: 'evnExtendRef',
22
- REGISTRY_INIT: 'evnInitialize',
23
- REFUND: 'evnRefund',
24
- REFUND_REF: 'evnRefundRef',
25
- DEAD_HOST_PRUNE: 'evnDeadHostPrune'
26
- }
27
-
28
- const MemoFormats = {
29
- TEXT: 'text/plain',
30
- JSON: 'text/json',
31
- BASE64: 'base64',
32
- HEX: 'hex'
33
- }
34
-
35
- const ErrorCodes = {
36
- ACQUIRE_ERR: 'ACQUIRE_ERR',
37
- EXTEND_ERR: 'EXTEND_ERR'
38
- }
39
-
40
- const ErrorReasons = {
41
- TRANSACTION_FAILURE: 'TRANSACTION_FAILURE',
42
- NO_OFFER: 'NO_OFFER',
43
- NO_NFT: 'NO_NFT',
44
- INTERNAL_ERR: 'INTERNAL_ERR',
45
- TIMEOUT: 'TIMEOUT',
46
- HOST_INVALID: 'HOST_INVALID',
47
- HOST_INACTIVE: 'HOST_INACTIVE',
48
- NO_STATE_KEY: 'NO_STATE_KEY'
49
- }
50
-
51
- // All keys are prefixed with 'EVR' (0x455652)
52
- // Config keys sub-prefix: 0x01
53
- const HookStateKeys = {
54
- // Configuration.
55
- EVR_ISSUER_ADDR: "4556520100000000000000000000000000000000000000000000000000000001",
56
- FOUNDATION_ADDR: "4556520100000000000000000000000000000000000000000000000000000002",
57
- MOMENT_SIZE: "4556520100000000000000000000000000000000000000000000000000000003",
58
- MINT_LIMIT: "4556520100000000000000000000000000000000000000000000000000000004",
59
- FIXED_REG_FEE: "4556520100000000000000000000000000000000000000000000000000000005",
60
- HOST_HEARTBEAT_FREQ: "4556520100000000000000000000000000000000000000000000000000000006",
61
- PURCHASER_TARGET_PRICE: "4556520100000000000000000000000000000000000000000000000000000007",
62
- LEASE_ACQUIRE_WINDOW: "4556520100000000000000000000000000000000000000000000000000000008",
63
- REWARD_CONFIGURATION: "4556520100000000000000000000000000000000000000000000000000000009",
64
- MAX_TOLERABLE_DOWNTIME: "455652010000000000000000000000000000000000000000000000000000000A",
65
-
66
- // Singleton
67
- HOST_COUNT: "4556523200000000000000000000000000000000000000000000000000000000",
68
- MOMENT_BASE_IDX: "4556523300000000000000000000000000000000000000000000000000000000",
69
- HOST_REG_FEE: "4556523400000000000000000000000000000000000000000000000000000000",
70
- MAX_REG: "4556523500000000000000000000000000000000000000000000000000000000",
71
- REWARD_INFO: "4556523600000000000000000000000000000000000000000000000000000000",
72
-
73
- // Prefixes
74
- PREFIX_HOST_TOKENID: "45565202",
75
- PREFIX_HOST_ADDR: "45565203",
76
- }
77
-
78
- const EvernodeEvents = {
79
- HostRegistered: "HostRegistered",
80
- HostDeregistered: "HostDeregistered",
81
- HostPostDeregistered: "HostPostDeregistered",
82
- AcquireLease: "AcquireLease",
83
- AcquireSuccess: "AcquireSuccess",
84
- AcquireError: "AcquireError",
85
- Heartbeat: "Heartbeat",
86
- ExtendLease: "ExtendLease",
87
- ExtendSuccess: "ExtendSuccess",
88
- ExtendError: "ExtendError",
89
- HostRegUpdated: "HostRegUpdated",
90
- HostReRegistered: "HostReRegistered",
91
- RegistryInitialized: "RegistryInitialized",
92
- DeadHostPrune: "DeadHostPrune"
93
- }
94
-
95
- module.exports = {
96
- EvernodeConstants,
97
- MemoTypes,
98
- MemoFormats,
99
- ErrorCodes,
100
- ErrorReasons,
101
- HookStateKeys,
102
- EvernodeEvents
103
- }
@@ -1,14 +0,0 @@
1
- const { EvernodeConstants } = require('./evernode-common');
2
-
3
- class EvernodeHelpers {
4
- static async getLeaseOffers(xrplAcc) {
5
- const hostNfts = (await xrplAcc.getNfts()).filter(nft => nft.URI.startsWith(EvernodeConstants.LEASE_NFT_PREFIX_HEX));
6
- const hostTokenIDs = hostNfts.map(nft => nft.NFTokenID);
7
- const nftOffers = (await xrplAcc.getNftOffers())?.filter(offer => (offer.Flags == 1 && hostTokenIDs.includes(offer.NFTokenID))); // Filter only sell offers
8
- return nftOffers;
9
- }
10
- }
11
-
12
- module.exports = {
13
- EvernodeHelpers
14
- }