evernode-js-client 0.4.51 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- package/.eslintrc.json +14 -0
- package/LICENSE +21 -0
- package/README.md +26 -0
- package/clean-pkg.sh +4 -0
- package/npm-readme.md +4 -0
- package/package.json +16 -1
- package/remove-versions.sh +10 -0
- package/src/clients/base-evernode-client.js +567 -0
- package/src/clients/host-client.js +357 -0
- package/src/clients/registry-client.js +52 -0
- package/src/clients/tenant-client.js +264 -0
- package/src/defaults.js +21 -0
- package/src/eccrypto.js +258 -0
- package/src/encryption-helper.js +41 -0
- package/src/event-emitter.js +45 -0
- package/src/evernode-common.js +103 -0
- package/src/evernode-helpers.js +14 -0
- package/src/firestore/firestore-handler.js +309 -0
- package/src/index.js +37 -0
- package/src/state-helpers.js +283 -0
- package/src/transaction-helper.js +62 -0
- package/src/util-helpers.js +48 -0
- package/src/xfl-helpers.js +130 -0
- package/src/xrpl-account.js +473 -0
- package/src/xrpl-api.js +275 -0
- package/src/xrpl-common.js +17 -0
- package/test/package-lock.json +884 -0
- package/test/package.json +9 -0
- package/test/test.js +379 -0
- package/index.js +0 -15129
package/src/defaults.js
ADDED
@@ -0,0 +1,21 @@
|
|
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
ADDED
@@ -0,0 +1,258 @@
|
|
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
|
+
};
|
@@ -0,0 +1,41 @@
|
|
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
|
+
}
|
@@ -0,0 +1,45 @@
|
|
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
|
+
}
|
@@ -0,0 +1,103 @@
|
|
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
|
+
}
|
@@ -0,0 +1,14 @@
|
|
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
|
+
}
|