evernode-js-client 0.5.13 → 0.5.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- }