evernode-js-client 0.5.13 → 0.5.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,396 +0,0 @@
1
- const codec = require('ripple-address-codec');
2
- const { Buffer } = require('buffer');
3
- const { HookStateKeys, EvernodeConstants } = require('./evernode-common');
4
- const { XflHelpers } = require('./xfl-helpers');
5
- const crypto = require("crypto");
6
-
7
- const NFTOKEN_PREFIX = '00000000';
8
-
9
- const EPOCH_OFFSET = 0;
10
- const SAVED_MOMENT_OFFSET = 1;
11
- const PREV_MOMENT_ACTIVE_HOST_COUNT_OFFSET = 5;
12
- const CUR_MOMENT_ACTIVE_HOST_COUNT_OFFSET = 9;
13
- const EPOCH_POOL_OFFSET = 13;
14
-
15
- const EPOCH_COUNT_OFFSET = 0;
16
- const FIRST_EPOCH_REWARD_QUOTA_OFFSET = 1;
17
- const EPOCH_REWARD_AMOUNT_OFFSET = 5;
18
- const REWARD_START_MOMENT_OFFSET = 9;
19
-
20
- const TRANSIT_IDX_OFFSET = 0;
21
- const TRANSIT_MOMENT_SIZE_OFFSET = 8;
22
- const TRANSIT_MOMENT_TYPE_OFFSET = 10;
23
-
24
- const MOMENT_BASE_POINT_OFFSET = 0;
25
- const MOMENT_AT_TRANSITION_OFFSET = 8;
26
- const MOMENT_TYPE_OFFSET = 12;
27
-
28
- const HOST_TOKEN_ID_OFFSET = 0;
29
- const HOST_COUNTRY_CODE_OFFSET = 32;
30
- const HOST_RESERVED_OFFSET = 34;
31
- const HOST_DESCRIPTION_OFFSET = 42;
32
- const HOST_REG_LEDGER_OFFSET = 68;
33
- const HOST_REG_FEE_OFFSET = 76;
34
- const HOST_TOT_INS_COUNT_OFFSET = 84;
35
- const HOST_ACT_INS_COUNT_OFFSET = 88;
36
- const HOST_HEARTBEAT_LEDGER_IDX_OFFSET = 92;
37
- const HOST_VERSION_OFFSET = 100;
38
- const HOST_REG_TIMESTAMP_OFFSET = 103;
39
- const HOST_TRANSFER_FLAG_OFFSET = 111;
40
-
41
- const HOST_ADDRESS_OFFSET = 0;
42
- const HOST_CPU_MODEL_NAME_OFFSET = 20;
43
- const HOST_CPU_COUNT_OFFSET = 60;
44
- const HOST_CPU_SPEED_OFFSET = 62;
45
- const HOST_CPU_MICROSEC_OFFSET = 64;
46
- const HOST_RAM_MB_OFFSET = 68;
47
- const HOST_DISK_MB_OFFSET = 72;
48
- const HOST_EMAIL_ADDRESS_OFFSET = 76;
49
-
50
- const PREV_HOST_ADDRESS_OFFSET = 0;
51
- const TRANSFER_LEDGER_IDX_OFFSET = 20;
52
- const TRANSFERRED_NFT_ID_OFFSET = 28;
53
-
54
- const STATE_KEY_TYPES = {
55
- TOKEN_ID: 2,
56
- HOST_ADDR: 3,
57
- TRANSFEREE_ADDR: 4
58
- }
59
-
60
- const MOMENT_TYPES = {
61
- LEDGER: 0,
62
- TIMESTAMP: 1
63
- }
64
-
65
- const TRANSFER_STATES = {
66
- NO_TRANSFER: 0,
67
- HAS_A_TRANSFER: 1
68
- }
69
-
70
- const EVERNODE_PREFIX = 'EVR';
71
- const HOST_ADDR_KEY_ZERO_COUNT = 8;
72
- const TRANSFEREE_ADDR_KEY_ZERO_COUNT = 8;
73
- const HOOK_STATE_LEDGER_TYPE_PREFIX = 118; // Decimal value of ASCII 'v'
74
- const PENDING_TRANSFER = 1;
75
- const HOST_EMAIL_ADDRESS_LEN = 40;
76
-
77
- class StateHelpers {
78
- static StateTypes = {
79
- TOKEN_ID: 'tokenId',
80
- HOST_ADDR: 'hostAddr',
81
- SIGLETON: 'singleton',
82
- CONFIGURATION: 'configuration',
83
- TRANSFEREE_ADDR: 'transfereeAddr'
84
- }
85
-
86
- static timeLines = {
87
- SEC: "SEC"
88
- }
89
-
90
- static getStateData(states, key) {
91
- const state = states.find(s => key === s.key);
92
- if (!state)
93
- return null;
94
-
95
- return state.data;
96
- }
97
-
98
- static decodeHostAddressState(stateKeyBuf, stateDataBuf) {
99
- let data = {
100
- address: codec.encodeAccountID(stateKeyBuf.slice(12)),
101
- nfTokenId: stateDataBuf.slice(HOST_TOKEN_ID_OFFSET, HOST_COUNTRY_CODE_OFFSET).toString('hex').toUpperCase(),
102
- countryCode: stateDataBuf.slice(HOST_COUNTRY_CODE_OFFSET, HOST_RESERVED_OFFSET).toString(),
103
- description: stateDataBuf.slice(HOST_DESCRIPTION_OFFSET, HOST_REG_LEDGER_OFFSET).toString().replace(/\0/g, ''),
104
- registrationLedger: Number(stateDataBuf.readBigUInt64BE(HOST_REG_LEDGER_OFFSET)),
105
- registrationFee: Number(stateDataBuf.readBigUInt64BE(HOST_REG_FEE_OFFSET)),
106
- maxInstances: stateDataBuf.readUInt32BE(HOST_TOT_INS_COUNT_OFFSET),
107
- activeInstances: stateDataBuf.readUInt32BE(HOST_ACT_INS_COUNT_OFFSET),
108
- lastHeartbeatIndex: Number(stateDataBuf.readBigUInt64BE(HOST_HEARTBEAT_LEDGER_IDX_OFFSET)),
109
- version: `${stateDataBuf.readUInt8(HOST_VERSION_OFFSET)}.${stateDataBuf.readUInt8(HOST_VERSION_OFFSET + 1)}.${stateDataBuf.readUInt8(HOST_VERSION_OFFSET + 2)}`,
110
- isATransferer: (stateDataBuf.length > HOST_TRANSFER_FLAG_OFFSET && (stateDataBuf.readUInt8(HOST_TRANSFER_FLAG_OFFSET) === PENDING_TRANSFER)) ? TRANSFER_STATES.HAS_A_TRANSFER : TRANSFER_STATES.NO_TRANSFER
111
- }
112
- if (stateDataBuf.length > HOST_REG_TIMESTAMP_OFFSET)
113
- data.registrationTimestamp = Number(stateDataBuf.readBigUInt64BE(HOST_REG_TIMESTAMP_OFFSET));
114
- return data;
115
- }
116
-
117
- static decodeTokenIdState(stateDataBuf) {
118
- return {
119
- address: codec.encodeAccountID(stateDataBuf.slice(HOST_ADDRESS_OFFSET, HOST_CPU_MODEL_NAME_OFFSET)),
120
- cpuModelName: stateDataBuf.slice(HOST_CPU_MODEL_NAME_OFFSET, HOST_CPU_COUNT_OFFSET).toString().replace(/\x00+$/, ''), // Remove trailing \x00 characters.
121
- cpuCount: stateDataBuf.readUInt16BE(HOST_CPU_COUNT_OFFSET),
122
- cpuMHz: stateDataBuf.readUInt16BE(HOST_CPU_SPEED_OFFSET),
123
- cpuMicrosec: stateDataBuf.readUInt32BE(HOST_CPU_MICROSEC_OFFSET),
124
- ramMb: stateDataBuf.readUInt32BE(HOST_RAM_MB_OFFSET),
125
- diskMb: stateDataBuf.readUInt32BE(HOST_DISK_MB_OFFSET),
126
- email: (stateDataBuf.length > HOST_EMAIL_ADDRESS_OFFSET ?
127
- stateDataBuf.slice(HOST_EMAIL_ADDRESS_OFFSET, HOST_EMAIL_ADDRESS_OFFSET + HOST_EMAIL_ADDRESS_LEN).toString().toString().replace(/\0/g, '') :
128
- "")
129
- }
130
- }
131
-
132
-
133
- static decodeTransfereeAddrState(stateKeyBuf, stateDataBuf) {
134
- const prevHostClassicAddress = codec.encodeAccountID(stateDataBuf.slice(PREV_HOST_ADDRESS_OFFSET, TRANSFER_LEDGER_IDX_OFFSET));
135
- return {
136
- futureOwnerAddress: codec.encodeAccountID(stateKeyBuf.slice(12)),
137
- prevHostAddressKey: this.generateHostAddrStateKey(prevHostClassicAddress),
138
- prevHostAddress: prevHostClassicAddress,
139
- transferLedgerIdx: Number(stateDataBuf.readBigUInt64BE(TRANSFER_LEDGER_IDX_OFFSET)),
140
- transferredNfTokenId: stateDataBuf.slice(TRANSFERRED_NFT_ID_OFFSET, 60).toString('hex').toUpperCase()
141
- }
142
- }
143
-
144
- static decodeStateData(stateKey, stateData) {
145
- const hexKey = stateKey.toString('hex').toUpperCase();
146
- if (Buffer.from(HookStateKeys.PREFIX_HOST_ADDR, 'hex').compare(stateKey, 0, 4) === 0) {
147
- return {
148
- type: this.StateTypes.HOST_ADDR,
149
- key: hexKey,
150
- ...this.decodeHostAddressState(stateKey, stateData)
151
- }
152
- }
153
- else if (Buffer.from(HookStateKeys.PREFIX_HOST_TOKENID, 'hex').compare(stateKey, 0, 4) === 0) {
154
- // Generate the address state key.
155
- const addressKeyBuf = Buffer.alloc(32, 0);
156
- Buffer.from(HookStateKeys.PREFIX_HOST_ADDR, 'hex').copy(addressKeyBuf);
157
- stateData.copy(addressKeyBuf, 12, HOST_ADDRESS_OFFSET, HOST_CPU_MODEL_NAME_OFFSET)
158
- return {
159
- type: this.StateTypes.TOKEN_ID,
160
- key: hexKey,
161
- addressKey: addressKeyBuf.toString('hex').toUpperCase(),
162
- ...this.decodeTokenIdState(stateData)
163
- }
164
- }
165
- else if (Buffer.from(HookStateKeys.PREFIX_TRANSFEREE_ADDR, 'hex').compare(stateKey, 0, 4) === 0) {
166
- return {
167
- type: this.StateTypes.TRANSFEREE_ADDR,
168
- key: hexKey,
169
- ...this.decodeTransfereeAddrState(stateKey, stateData)
170
- }
171
- }
172
- else if (Buffer.from(HookStateKeys.HOST_COUNT, 'hex').compare(stateKey) === 0) {
173
- return {
174
- type: this.StateTypes.SIGLETON,
175
- key: hexKey,
176
- value: stateData.readUInt32BE()
177
- }
178
- }
179
- else if (Buffer.from(HookStateKeys.MOMENT_BASE_INFO, 'hex').compare(stateKey) === 0) {
180
- return {
181
- type: this.StateTypes.SIGLETON,
182
- key: hexKey,
183
- value: {
184
- baseIdx: Number(stateData.readBigUInt64BE(MOMENT_BASE_POINT_OFFSET)),
185
- baseTransitionMoment: stateData.length > MOMENT_AT_TRANSITION_OFFSET ? stateData.readUInt32BE(MOMENT_AT_TRANSITION_OFFSET) : 0,
186
- momentType: (stateData.length <= MOMENT_TYPE_OFFSET || stateData.readUInt8(MOMENT_TYPE_OFFSET) === MOMENT_TYPES.LEDGER) ? 'ledger' : 'timestamp'
187
- }
188
- }
189
- }
190
- else if (Buffer.from(HookStateKeys.HOST_REG_FEE, 'hex').compare(stateKey) === 0 || Buffer.from(HookStateKeys.MAX_REG, 'hex').compare(stateKey) === 0) {
191
- return {
192
- type: this.StateTypes.SIGLETON,
193
- key: hexKey,
194
- value: Number(stateData.readBigUInt64BE())
195
- }
196
- }
197
- else if (Buffer.from(HookStateKeys.EVR_ISSUER_ADDR, 'hex').compare(stateKey) === 0 || Buffer.from(HookStateKeys.FOUNDATION_ADDR, 'hex').compare(stateKey) === 0) {
198
- return {
199
- type: this.StateTypes.CONFIGURATION,
200
- key: hexKey,
201
- value: codec.encodeAccountID(stateData)
202
- }
203
- }
204
- else if (Buffer.from(HookStateKeys.MOMENT_SIZE, 'hex').compare(stateKey) === 0 ||
205
- Buffer.from(HookStateKeys.HOST_HEARTBEAT_FREQ, 'hex').compare(stateKey) === 0 ||
206
- Buffer.from(HookStateKeys.LEASE_ACQUIRE_WINDOW, 'hex').compare(stateKey) === 0) {
207
- return {
208
- type: this.StateTypes.CONFIGURATION,
209
- key: hexKey,
210
- value: stateData.readUInt16BE()
211
- }
212
- }
213
- else if (Buffer.from(HookStateKeys.MINT_LIMIT, 'hex').compare(stateKey) === 0 || Buffer.from(HookStateKeys.FIXED_REG_FEE, 'hex').compare(stateKey) === 0) {
214
- return {
215
- type: this.StateTypes.CONFIGURATION,
216
- key: hexKey,
217
- value: Number(stateData.readBigUInt64BE())
218
- }
219
- }
220
- else if (Buffer.from(HookStateKeys.PURCHASER_TARGET_PRICE, 'hex').compare(stateKey) === 0) {
221
- const xfl = stateData.readBigInt64BE(0);
222
- const val = XflHelpers.toString(xfl);
223
- return {
224
- type: this.StateTypes.CONFIGURATION,
225
- key: hexKey,
226
- value: val
227
- }
228
- }
229
- else if (Buffer.from(HookStateKeys.REWARD_CONFIGURATION, 'hex').compare(stateKey) === 0) {
230
- return {
231
- type: this.StateTypes.CONFIGURATION,
232
- key: hexKey,
233
- value: {
234
- epochCount: stateData.readUInt8(EPOCH_COUNT_OFFSET),
235
- firstEpochRewardQuota: stateData.readUInt32BE(FIRST_EPOCH_REWARD_QUOTA_OFFSET),
236
- epochRewardAmount: stateData.readUInt32BE(EPOCH_REWARD_AMOUNT_OFFSET),
237
- rewardStartMoment: stateData.readUInt32BE(REWARD_START_MOMENT_OFFSET)
238
- }
239
- }
240
- }
241
- else if (Buffer.from(HookStateKeys.REWARD_INFO, 'hex').compare(stateKey) === 0) {
242
- return {
243
- type: this.StateTypes.SIGLETON,
244
- key: hexKey,
245
- value: {
246
- epoch: stateData.readUInt8(EPOCH_OFFSET),
247
- savedMoment: stateData.readUInt32BE(SAVED_MOMENT_OFFSET),
248
- prevMomentActiveHostCount: stateData.readUInt32BE(PREV_MOMENT_ACTIVE_HOST_COUNT_OFFSET),
249
- curMomentActiveHostCount: stateData.readUInt32BE(CUR_MOMENT_ACTIVE_HOST_COUNT_OFFSET),
250
- epochPool: XflHelpers.toString(stateData.readBigInt64BE(EPOCH_POOL_OFFSET))
251
- }
252
- }
253
- }
254
- else if (Buffer.from(HookStateKeys.MAX_TOLERABLE_DOWNTIME, 'hex').compare(stateKey) === 0) {
255
- return {
256
- type: this.StateTypes.CONFIGURATION,
257
- key: hexKey,
258
- value: stateData.readUInt16BE()
259
- }
260
- }
261
- else if (Buffer.from(HookStateKeys.MOMENT_TRANSIT_INFO, 'hex').compare(stateKey) === 0) {
262
- Buffer.alloc(1).readUInt8()
263
- return {
264
- type: this.StateTypes.CONFIGURATION,
265
- key: hexKey,
266
- value: {
267
- transitionIndex: Number(stateData.readBigInt64BE(TRANSIT_IDX_OFFSET)),
268
- momentSize: stateData.readUInt16BE(TRANSIT_MOMENT_SIZE_OFFSET),
269
- momentType: stateData.readUInt8(TRANSIT_MOMENT_TYPE_OFFSET) === MOMENT_TYPES.LEDGER ? 'ledger' : 'timestamp'
270
- }
271
- }
272
- }
273
- else if (Buffer.from(HookStateKeys.MAX_TRX_EMISSION_FEE, 'hex').compare(stateKey) === 0) {
274
- return {
275
- type: this.StateTypes.CONFIGURATION,
276
- key: hexKey,
277
- value: Number(stateData.readBigUInt64BE())
278
- }
279
- }
280
- else
281
- throw { type: 'Validation Error', message: 'Invalid state key.' };
282
- }
283
-
284
- static decodeStateKey(stateKey) {
285
- const hexKey = stateKey.toString('hex').toUpperCase();
286
- if (Buffer.from(HookStateKeys.PREFIX_HOST_ADDR, 'hex').compare(stateKey, 0, 4) === 0) {
287
- return {
288
- key: hexKey,
289
- type: this.StateTypes.HOST_ADDR
290
- };
291
- }
292
- else if (Buffer.from(HookStateKeys.PREFIX_HOST_TOKENID, 'hex').compare(stateKey, 0, 4) === 0) {
293
- return {
294
- key: hexKey,
295
- type: this.StateTypes.TOKEN_ID
296
- };
297
- }
298
- else if (Buffer.from(HookStateKeys.PREFIX_TRANSFEREE_ADDR, 'hex').compare(stateKey, 0, 4) === 0) {
299
- return {
300
- key: hexKey,
301
- type: this.StateTypes.TRANSFEREE_ADDR
302
- };
303
- }
304
- else if (Buffer.from(HookStateKeys.HOST_COUNT, 'hex').compare(stateKey) === 0 ||
305
- Buffer.from(HookStateKeys.MOMENT_BASE_INFO, 'hex').compare(stateKey) === 0 ||
306
- Buffer.from(HookStateKeys.HOST_REG_FEE, 'hex').compare(stateKey) === 0 ||
307
- Buffer.from(HookStateKeys.MAX_REG, 'hex').compare(stateKey) === 0 ||
308
- Buffer.from(HookStateKeys.REWARD_INFO, 'hex').compare(stateKey) === 0) {
309
- return {
310
- key: hexKey,
311
- type: this.STATE_TYPES.SIGLETON
312
- };
313
- }
314
- else if (Buffer.from(HookStateKeys.EVR_ISSUER_ADDR, 'hex').compare(stateKey) === 0 ||
315
- Buffer.from(HookStateKeys.FOUNDATION_ADDR, 'hex').compare(stateKey) === 0 ||
316
- Buffer.from(HookStateKeys.MOMENT_SIZE, 'hex').compare(stateKey) === 0 ||
317
- Buffer.from(HookStateKeys.PURCHASER_TARGET_PRICE, 'hex').compare(stateKey) === 0 ||
318
- Buffer.from(HookStateKeys.HOST_HEARTBEAT_FREQ, 'hex').compare(stateKey) ||
319
- Buffer.from(HookStateKeys.MINT_LIMIT, 'hex').compare(stateKey) === 0 ||
320
- Buffer.from(HookStateKeys.FIXED_REG_FEE, 'hex').compare(stateKey) === 0 ||
321
- Buffer.from(HookStateKeys.LEASE_ACQUIRE_WINDOW, 'hex').compare(stateKey) === 0 ||
322
- Buffer.from(HookStateKeys.REWARD_CONFIGURATION, 'hex').compare(stateKey) === 0 ||
323
- Buffer.from(HookStateKeys.MAX_TOLERABLE_DOWNTIME, 'hex').compare(stateKey) === 0 ||
324
- Buffer.from(HookStateKeys.MOMENT_TRANSIT_INFO, 'hex').compare(stateKey) === 0 ||
325
- Buffer.from(HookStateKeys.MAX_TRX_EMISSION_FEE, 'hex').compare(stateKey) === 0) {
326
- return {
327
- key: hexKey,
328
- type: this.STATE_TYPES.CONFIGURATION
329
- };
330
- }
331
- else
332
- throw { type: 'Validation Error', message: 'Invalid state key.' };
333
- }
334
-
335
- static generateTokenIdStateKey(nfTokenId) {
336
- // 1 byte - Key Type.
337
- let buf = Buffer.allocUnsafe(1);
338
- buf.writeUInt8(STATE_KEY_TYPES.TOKEN_ID);
339
-
340
- const nfTokenIdBuf = Buffer.from(nfTokenId, "hex");
341
- const stateKeyBuf = (Buffer.concat([Buffer.from(EVERNODE_PREFIX, "utf-8"), buf, nfTokenIdBuf.slice(4, 32)]));
342
- return stateKeyBuf.toString('hex').toUpperCase();
343
- }
344
-
345
- static generateHostAddrStateKey(address) {
346
- // 1 byte - Key Type.
347
- // 8 bytes - Zeros.
348
- let buf = Buffer.allocUnsafe(9);
349
- buf.writeUInt8(STATE_KEY_TYPES.HOST_ADDR);
350
- for (let i = 0; i < HOST_ADDR_KEY_ZERO_COUNT; i++) {
351
- buf.writeUInt8(0, i + 1);
352
- }
353
-
354
- const addrBuf = Buffer.from(codec.decodeAccountID(address), "hex");
355
- const stateKeyBuf = Buffer.concat([Buffer.from(EVERNODE_PREFIX, "utf-8"), buf, addrBuf]);
356
- return stateKeyBuf.toString('hex').toUpperCase();
357
- }
358
-
359
- static generateTransfereeAddrStateKey(address) {
360
- // 1 byte - Key Type.
361
- // 8 bytes - Zeros.
362
- let buf = Buffer.allocUnsafe(9);
363
- buf.writeUInt8(STATE_KEY_TYPES.TRANSFEREE_ADDR);
364
- for (let i = 0; i < TRANSFEREE_ADDR_KEY_ZERO_COUNT; i++) {
365
- buf.writeUInt8(0, i + 1);
366
- }
367
-
368
- const addrBuf = Buffer.from(codec.decodeAccountID(address), "hex");
369
- const stateKeyBuf = Buffer.concat([Buffer.from(EVERNODE_PREFIX, "utf-8"), buf, addrBuf]);
370
- return stateKeyBuf.toString('hex').toUpperCase();
371
- }
372
-
373
- static getHookStateIndex(hookAccount, stateKey, hookNamespace = EvernodeConstants.HOOK_NAMESPACE) {
374
- const typeBuf = Buffer.allocUnsafe(2);
375
- typeBuf.writeInt16BE(HOOK_STATE_LEDGER_TYPE_PREFIX);
376
-
377
- const accIdBuf = codec.decodeAccountID(hookAccount);
378
- const stateKeyBuf = Buffer.from(stateKey, 'hex');
379
- const namespaceBuf = Buffer.from(hookNamespace, 'hex');
380
-
381
- let hash = crypto.createHash('sha512');
382
-
383
- let data = hash.update(typeBuf);
384
- data = hash.update(accIdBuf);
385
- data = hash.update(stateKeyBuf);
386
- data = hash.update(namespaceBuf);
387
-
388
- const digest = data.digest('hex');
389
- // Get the first 32 bytes of hash.
390
- return digest.substring(0, 64).toUpperCase();
391
- }
392
- }
393
-
394
- module.exports = {
395
- StateHelpers
396
- }
@@ -1,62 +0,0 @@
1
- const { MemoFormats } = require('./evernode-common');
2
-
3
- class TransactionHelper {
4
-
5
- // Convert memos from our object type to xrpl lib object type.
6
- static formatMemos(memos) {
7
- return memos ? memos.filter(m => m.type).map(m => {
8
- const data = (m.format === MemoFormats.HEX) ? m.data :
9
- TransactionHelper.asciiToHex((typeof m.data === "object") ? JSON.stringify(m.data) : m.data)
10
- return {
11
- Memo: {
12
- MemoType: TransactionHelper.asciiToHex(m.type),
13
- MemoFormat: TransactionHelper.asciiToHex(m.format),
14
- MemoData: data
15
- }
16
- }
17
- }) : [];
18
- }
19
-
20
- // Convert memos from xrpl lib object type to our object type.
21
- static deserializeMemos(memos) {
22
- if (!memos)
23
- return [];
24
-
25
- return memos.filter(m => m.Memo).map(m => {
26
- const format = m.Memo.MemoFormat ? TransactionHelper.hexToASCII(m.Memo.MemoFormat) : null;
27
- const data = m.Memo.MemoData ?
28
- ((format === MemoFormats.HEX) ? m.Memo.MemoData : TransactionHelper.hexToASCII(m.Memo.MemoData)) : null;
29
- return {
30
- type: m.Memo.MemoType ? TransactionHelper.hexToASCII(m.Memo.MemoType) : null,
31
- format: format,
32
- data: data
33
- }
34
- })
35
- }
36
-
37
- static hexToASCII(hex) {
38
- if (!hex)
39
- return "";
40
-
41
- let str = "";
42
- for (let n = 0; n < hex.length; n += 2) {
43
- str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
44
- }
45
- return str;
46
- }
47
-
48
- static asciiToHex(str) {
49
- if (!str)
50
- return "";
51
-
52
- let hex = "";
53
- for (let n = 0; n < str.length; n++) {
54
- hex += str.charCodeAt(n).toString(16)
55
- }
56
- return hex;
57
- }
58
- }
59
-
60
- module.exports = {
61
- TransactionHelper
62
- }
@@ -1,50 +0,0 @@
1
- const { Buffer } = require('buffer');
2
- const { XflHelpers } = require('./xfl-helpers');
3
- const { EvernodeConstants, ErrorReasons } = require('./evernode-common');
4
-
5
- // Utility helper functions.
6
- class UtilHelpers {
7
-
8
- static readUInt(buf, base = 32, isBE = true) {
9
- buf = Buffer.from(buf);
10
- switch (base) {
11
- case (8):
12
- return buf.readUInt8();
13
- case (16):
14
- return isBE ? buf.readUInt16BE() : buf.readUInt16LE();
15
- case (32):
16
- return isBE ? buf.readUInt32BE() : buf.readUInt32LE();
17
- case (64):
18
- return isBE ? Number(buf.readBigUInt64BE()) : Number(buf.readBigUInt64LE());
19
- default:
20
- throw 'Invalid base value';
21
- }
22
- }
23
-
24
- static decodeLeaseNftUri(hexUri) {
25
- // Get the lease index from the nft URI.
26
- // <prefix><lease index (uint16)><half of tos hash (16 bytes)><lease amount (uint32)>
27
- const prefixLen = EvernodeConstants.LEASE_NFT_PREFIX_HEX.length / 2;
28
- const halfToSLen = 16;
29
- const uriBuf = Buffer.from(hexUri, 'hex');
30
- return {
31
- leaseIndex: uriBuf.readUint16BE(prefixLen),
32
- halfTos: uriBuf.slice(prefixLen + 2, halfToSLen),
33
- leaseAmount: parseFloat(XflHelpers.toString(uriBuf.readBigInt64BE(prefixLen + 2 + halfToSLen)))
34
- }
35
- }
36
-
37
- static getCurrentUnixTime(format = "sec") {
38
- const time = Date.now();
39
- switch (format) {
40
- case "sec":
41
- return Math.floor(time / 1000);
42
- default:
43
- return time;
44
- }
45
- }
46
- }
47
-
48
- module.exports = {
49
- UtilHelpers
50
- }
@@ -1,130 +0,0 @@
1
- const minMantissa = 1000000000000000n
2
- const maxMantissa = 9999999999999999n
3
- const minExponent = -96
4
- const maxExponent = 80
5
-
6
- // Helper class to handle XFL float numbers.
7
- class XflHelpers {
8
-
9
- static getExponent(xfl) {
10
- if (xfl < 0n)
11
- throw "Invalid XFL";
12
- if (xfl == 0n)
13
- return 0n;
14
- return ((xfl >> 54n) & 0xFFn) - 97n;
15
- }
16
-
17
- static getMantissa(xfl) {
18
- if (xfl < 0n)
19
- throw "Invalid XFL";
20
- if (xfl == 0n)
21
- return 0n;
22
- return xfl - ((xfl >> 54n) << 54n);
23
- }
24
-
25
- static isNegative(xfl) {
26
- if (xfl < 0n)
27
- throw "Invalid XFL";
28
- if (xfl == 0n)
29
- return false;
30
- return ((xfl >> 62n) & 1n) == 0n;
31
- }
32
-
33
- static toString(xfl) {
34
- if (xfl < 0n)
35
- throw "Invalid XFL";
36
- if (xfl == 0n)
37
- return '0';
38
-
39
- const mantissa = this.getMantissa(xfl);
40
- const exponent = this.getExponent(xfl);
41
- const mantissaStr = mantissa.toString();
42
- let finalResult = '';
43
- if (exponent > 0n) {
44
- finalResult = mantissaStr.padEnd(mantissaStr.length + Number(exponent), '0');
45
- } else {
46
- const newExponent = Number(exponent) + mantissaStr.length;
47
- const cleanedMantissa = mantissaStr.replace(/0+$/, '');
48
- if (newExponent == 0) {
49
- finalResult = '0.' + cleanedMantissa;
50
- } else if (newExponent < 0) {
51
- finalResult = '0.' + cleanedMantissa.padStart(newExponent * (-1) + cleanedMantissa.length, '0');
52
- } else {
53
- finalResult = mantissaStr.substr(0, newExponent) + '.' + mantissaStr.substr(newExponent).replace(/0+$/, '');
54
- }
55
- }
56
- return (this.isNegative(xfl) ? '-' : '') + finalResult.replace(/\.+$/, '');
57
- }
58
-
59
- static getXfl(floatStr) {
60
- let exponent;
61
- let mantissa;
62
- floatStr = parseFloat(floatStr).toString();
63
-
64
- if (floatStr === '0') {
65
- exponent = BigInt(0);
66
- mantissa = BigInt(0);
67
- }
68
- else if (floatStr.includes('.')) {
69
- const parts = floatStr.split('.');
70
- exponent = BigInt(-parts[1].length);
71
- mantissa = BigInt(parseInt(parts.join('')));
72
- }
73
- else if (floatStr.endsWith('0')) {
74
- const mantissaStr = floatStr.replace(/0+$/g, "");
75
- exponent = BigInt(floatStr.length - mantissaStr.length);
76
- mantissa = BigInt(parseInt(mantissaStr));
77
- }
78
- else {
79
- exponent = BigInt(0);
80
- mantissa = BigInt(parseInt(floatStr));
81
- }
82
-
83
- // Convert types as needed.
84
- if (typeof (exponent) != 'bigint')
85
- exponent = BigInt(exponent);
86
-
87
- if (typeof (mantissa) != 'bigint')
88
- mantissa = BigInt(mantissa);
89
-
90
- // Canonical zero.
91
- if (mantissa == 0n)
92
- return 0n;
93
-
94
- // Normalize.
95
- let is_negative = mantissa < 0;
96
- if (is_negative)
97
- mantissa *= -1n;
98
-
99
- while (mantissa > maxMantissa) {
100
- mantissa /= 10n;
101
- exponent++;
102
- }
103
- while (mantissa < minMantissa) {
104
- mantissa *= 10n;
105
- exponent--;
106
- }
107
-
108
- // Canonical zero on mantissa underflow.
109
- if (mantissa == 0)
110
- return 0n;
111
-
112
- // Under and overflows.
113
- if (exponent > maxExponent || exponent < minExponent)
114
- return -1; // Note this is an "invalid" XFL used to propagate errors.
115
-
116
- exponent += 97n;
117
-
118
- let xfl = (is_negative ? 0n : 1n);
119
- xfl <<= 8n;
120
- xfl |= BigInt(exponent);
121
- xfl <<= 54n;
122
- xfl |= BigInt(mantissa);
123
-
124
- return xfl;
125
- }
126
- }
127
-
128
- module.exports = {
129
- XflHelpers
130
- }