evernode-js-client 0.5.2 → 0.5.4

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.
Files changed (2) hide show
  1. package/index.js +123 -47
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -11846,29 +11846,29 @@ class BaseEvernodeClient {
11846
11846
  }
11847
11847
 
11848
11848
  /**
11849
- * Get the moment from the given XRP ledger index. (1 Moment - 1190 XRP ledgers).
11850
- * @param {number} ledgerIndex [Optional] Ledger index to get the moment value.
11851
- * @returns The moment of the given XPR ledger index as 'number'. Returns current moment if XRP ledger index is not given.
11852
- */
11853
- async getMoment(ledgerIndex = null) {
11854
- const lv = ledgerIndex || this.xrplApi.ledgerIndex;
11855
- const m = Math.floor((lv - this.config.momentBaseIdx) / this.config.momentSize);
11856
-
11857
- await Promise.resolve(); // Awaiter placeholder for future async requirements.
11849
+ * Get the moment from the given index (timestamp).
11850
+ * @param {number} index [Optional] Index (timestamp) to get the moment value.
11851
+ * @returns The moment of the given index (timestamp) as 'number'. Returns current moment if index (timestamp) is not given.
11852
+ */
11853
+ async getMoment(index = null) {
11854
+ const i = index || UtilHelpers.getCurrentUnixTime();
11855
+ const m = this.config.momentBaseInfo.baseTransitionMoment + Math.floor((i - this.config.momentBaseInfo.baseIdx) / this.config.momentSize);
11856
+ await Promise.resolve();
11858
11857
  return m;
11859
11858
  }
11860
11859
 
11861
11860
  /**
11862
- * Get start XRP ledger index of the moment (of the given XRPL index).
11863
- * @param {number} ledgerIndex [Optional] Ledger index to get the moment value.
11864
- * @returns The XRP ledger index of the moment (of the given XRPL index) as a 'number'. Returns the current moment's start XRP ledger index if ledger index parameter is not given.
11861
+ * Get start index (timestamp) of the moment.
11862
+ * @param {number} index [Optional] Index (timestamp) to get the moment value.
11863
+ * @returns The index (timestamp) of the moment as a 'number'. Returns the current moment's start index (timestamp) if ledger index parameter is not given.
11865
11864
  */
11866
- async getMomentStartIndex(ledgerIndex = null) {
11867
- const lv = ledgerIndex || this.xrplApi.ledgerIndex;
11868
- const m = Math.floor((lv - this.config.momentBaseIdx) / this.config.momentSize);
11865
+ async getMomentStartIndex(index = null) {
11866
+ const i = index || UtilHelpers.getCurrentUnixTime();
11867
+
11868
+ const m = Math.floor((i - this.config.momentBaseInfo.baseIdx) / this.config.momentSize);
11869
11869
 
11870
11870
  await Promise.resolve(); // Awaiter placeholder for future async requirements.
11871
- return this.config.momentBaseIdx + (m * this.config.momentSize);
11871
+ return this.config.momentBaseInfo.baseIdx + (m * this.config.momentSize);
11872
11872
  }
11873
11873
 
11874
11874
  /**
@@ -11883,19 +11883,23 @@ class BaseEvernodeClient {
11883
11883
  hostRegFee: HookStateKeys.HOST_REG_FEE,
11884
11884
  momentSize: HookStateKeys.MOMENT_SIZE,
11885
11885
  hostHeartbeatFreq: HookStateKeys.HOST_HEARTBEAT_FREQ,
11886
- momentBaseIdx: HookStateKeys.MOMENT_BASE_IDX,
11886
+ momentBaseInfo: HookStateKeys.MOMENT_BASE_INFO,
11887
11887
  purchaserTargetPrice: HookStateKeys.PURCHASER_TARGET_PRICE,
11888
11888
  leaseAcquireWindow: HookStateKeys.LEASE_ACQUIRE_WINDOW,
11889
11889
  rewardInfo: HookStateKeys.REWARD_INFO,
11890
- rewardConfiguaration: HookStateKeys.REWARD_CONFIGURATION,
11891
- hostCount: HookStateKeys.HOST_COUNT
11890
+ rewardConfiguration: HookStateKeys.REWARD_CONFIGURATION,
11891
+ hostCount: HookStateKeys.HOST_COUNT,
11892
+ momentTransitInfo: HookStateKeys.MOMENT_TRANSIT_INFO
11892
11893
  }
11893
11894
  let config = {};
11894
11895
  for (const [key, value] of Object.entries(configStateKeys)) {
11895
11896
  const stateKey = Buffer.from(value, 'hex');
11896
- const stateData = Buffer.from(UtilHelpers.getStateData(states, value), 'hex');
11897
- const decoded = StateHelpers.decodeStateData(stateKey, stateData);
11898
- config[key] = decoded.value;
11897
+ const stateDataBin = StateHelpers.getStateData(states, value);
11898
+ if (stateDataBin) {
11899
+ const stateData = Buffer.from(StateHelpers.getStateData(states, value), 'hex');
11900
+ const decoded = StateHelpers.decodeStateData(stateKey, stateData);
11901
+ config[key] = decoded.value;
11902
+ }
11899
11903
  }
11900
11904
  return config;
11901
11905
  }
@@ -12141,6 +12145,17 @@ class BaseEvernodeClient {
12141
12145
  }
12142
12146
  }
12143
12147
  }
12148
+ else if (tx.Memos.length >= 1 &&
12149
+ tx.Memos[0].type === MemoTypes.HOST_REBATE) {
12150
+
12151
+ return {
12152
+ name: EvernodeEvents.HostRebate,
12153
+ data: {
12154
+ transaction: tx,
12155
+ host: tx.Account
12156
+ }
12157
+ }
12158
+ }
12144
12159
 
12145
12160
  return null;
12146
12161
  }
@@ -12159,9 +12174,9 @@ class BaseEvernodeClient {
12159
12174
  if (addrStateData) {
12160
12175
  const addrStateDecoded = StateHelpers.decodeHostAddressState(Buffer.from(addrStateKey, 'hex'), Buffer.from(addrStateData, 'hex'));
12161
12176
  const curMomentStartIdx = await this.getMomentStartIndex();
12162
- addrStateDecoded.active = (addrStateDecoded.lastHeartbeatLedger > (this.config.hostHeartbeatFreq * this.config.momentSize) ?
12163
- (addrStateDecoded.lastHeartbeatLedger >= (curMomentStartIdx - (this.config.hostHeartbeatFreq * this.config.momentSize))) :
12164
- (addrStateDecoded.lastHeartbeatLedger > 0))
12177
+ addrStateDecoded.active = (addrStateDecoded.lastHeartbeatIndex > (this.config.hostHeartbeatFreq * this.config.momentSize) ?
12178
+ (addrStateDecoded.lastHeartbeatIndex >= (curMomentStartIdx - (this.config.hostHeartbeatFreq * this.config.momentSize))) :
12179
+ (addrStateDecoded.lastHeartbeatIndex > 0))
12165
12180
 
12166
12181
  const nftIdStatekey = StateHelpers.generateTokenIdStateKey(addrStateDecoded.nfTokenId);
12167
12182
  const nftIdStateIndex = StateHelpers.getHookStateIndex(this.registryAddress, nftIdStatekey);
@@ -12195,9 +12210,9 @@ class BaseEvernodeClient {
12195
12210
  const curMomentStartIdx = await this.getMomentStartIndex();
12196
12211
  // Populate the host active status.
12197
12212
  (hosts.nextPageToken ? hosts.data : hosts).forEach(h => {
12198
- h.active = (h.lastHeartbeatLedger > (this.config.hostHeartbeatFreq * this.config.momentSize) ?
12199
- (h.lastHeartbeatLedger >= (curMomentStartIdx - (this.config.hostHeartbeatFreq * this.config.momentSize))) :
12200
- (h.lastHeartbeatLedger > 0))
12213
+ h.active = (h.lastHeartbeatIndex > (this.config.hostHeartbeatFreq * this.config.momentSize) ?
12214
+ (h.lastHeartbeatIndex >= (curMomentStartIdx - (this.config.hostHeartbeatFreq * this.config.momentSize))) :
12215
+ (h.lastHeartbeatIndex > 0))
12201
12216
  });
12202
12217
  return hosts;
12203
12218
  }
@@ -12622,6 +12637,15 @@ class HostClient extends BaseEvernodeClient {
12622
12637
  options.transactionOptions);
12623
12638
  }
12624
12639
 
12640
+ async requestRebate(options = {}) {
12641
+ return this.xrplAcc.makePayment(this.registryAddress,
12642
+ XrplConstants.MIN_XRP_AMOUNT,
12643
+ XrplConstants.XRP,
12644
+ null,
12645
+ [{ type: MemoTypes.HOST_REBATE, format: "", data: "" }],
12646
+ options.transactionOptions);
12647
+ }
12648
+
12625
12649
  getLeaseNFTokenIdPrefix() {
12626
12650
  let buf = Buffer.allocUnsafe(24);
12627
12651
  buf.writeUInt16BE(1);
@@ -12652,7 +12676,8 @@ const RegistryEvents = {
12652
12676
  RegistryInitialized: EvernodeEvents.RegistryInitialized,
12653
12677
  Heartbeat: EvernodeEvents.Heartbeat,
12654
12678
  HostPostDeregistered: EvernodeEvents.HostPostDeregistered,
12655
- DeadHostPrune: EvernodeEvents.DeadHostPrune
12679
+ DeadHostPrune: EvernodeEvents.DeadHostPrune,
12680
+ HostRebate: EvernodeEvents.HostRebate
12656
12681
  }
12657
12682
 
12658
12683
  class RegistryClient extends BaseEvernodeClient {
@@ -13394,7 +13419,8 @@ const MemoTypes = {
13394
13419
  REGISTRY_INIT: 'evnInitialize',
13395
13420
  REFUND: 'evnRefund',
13396
13421
  REFUND_REF: 'evnRefundRef',
13397
- DEAD_HOST_PRUNE: 'evnDeadHostPrune'
13422
+ DEAD_HOST_PRUNE: 'evnDeadHostPrune',
13423
+ HOST_REBATE: 'evnHostRebate'
13398
13424
  }
13399
13425
 
13400
13426
  const MemoFormats = {
@@ -13434,10 +13460,11 @@ const HookStateKeys = {
13434
13460
  LEASE_ACQUIRE_WINDOW: "4556520100000000000000000000000000000000000000000000000000000008",
13435
13461
  REWARD_CONFIGURATION: "4556520100000000000000000000000000000000000000000000000000000009",
13436
13462
  MAX_TOLERABLE_DOWNTIME: "455652010000000000000000000000000000000000000000000000000000000A",
13463
+ MOMENT_TRANSIT_INFO: "455652010000000000000000000000000000000000000000000000000000000B",
13437
13464
 
13438
13465
  // Singleton
13439
13466
  HOST_COUNT: "4556523200000000000000000000000000000000000000000000000000000000",
13440
- MOMENT_BASE_IDX: "4556523300000000000000000000000000000000000000000000000000000000",
13467
+ MOMENT_BASE_INFO: "4556523300000000000000000000000000000000000000000000000000000000",
13441
13468
  HOST_REG_FEE: "4556523400000000000000000000000000000000000000000000000000000000",
13442
13469
  MAX_REG: "4556523500000000000000000000000000000000000000000000000000000000",
13443
13470
  REWARD_INFO: "4556523600000000000000000000000000000000000000000000000000000000",
@@ -13461,7 +13488,8 @@ const EvernodeEvents = {
13461
13488
  HostRegUpdated: "HostRegUpdated",
13462
13489
  HostReRegistered: "HostReRegistered",
13463
13490
  RegistryInitialized: "RegistryInitialized",
13464
- DeadHostPrune: "DeadHostPrune"
13491
+ DeadHostPrune: "DeadHostPrune",
13492
+ HostRebate: "HostRebate"
13465
13493
  }
13466
13494
 
13467
13495
  module.exports = {
@@ -13876,6 +13904,14 @@ const FIRST_EPOCH_REWARD_QUOTA_OFFSET = 1;
13876
13904
  const EPOCH_REWARD_AMOUNT_OFFSET = 5;
13877
13905
  const REWARD_START_MOMENT_OFFSET = 9;
13878
13906
 
13907
+ const TRANSIT_IDX_OFFSET = 0;
13908
+ const TRANSIT_MOMENT_SIZE_OFFSET = 8;
13909
+ const TRANSIT_MOMENT_TYPE_OFFSET = 10;
13910
+
13911
+ const MOMENT_BASE_POINT_OFFSET = 0;
13912
+ const MOMENT_AT_TRANSITION_OFFSET = 8;
13913
+ const MOMENT_TYPE_OFFSET = 12;
13914
+
13879
13915
  const HOST_TOKEN_ID_OFFSET = 0;
13880
13916
  const HOST_COUNTRY_CODE_OFFSET = 32;
13881
13917
  const HOST_RESERVED_OFFSET = 34;
@@ -13886,6 +13922,7 @@ const HOST_TOT_INS_COUNT_OFFSET = 84;
13886
13922
  const HOST_ACT_INS_COUNT_OFFSET = 88;
13887
13923
  const HOST_HEARTBEAT_LEDGER_IDX_OFFSET = 92;
13888
13924
  const HOST_VERSION_OFFSET = 100;
13925
+ const HOST_REG_TIMESTAMP_OFFSET = 103;
13889
13926
 
13890
13927
  const HOST_ADDRESS_OFFSET = 0;
13891
13928
  const HOST_CPU_MODEL_NAME_OFFSET = 20;
@@ -13900,6 +13937,11 @@ const STATE_KEY_TYPES = {
13900
13937
  HOST_ADDR: 3
13901
13938
  }
13902
13939
 
13940
+ const MOMENT_TYPES = {
13941
+ LEDGER: 0,
13942
+ TIMESTAMP: 1
13943
+ }
13944
+
13903
13945
  const EVERNODE_PREFIX = 'EVR';
13904
13946
  const HOST_ADDR_KEY_ZERO_COUNT = 8;
13905
13947
  const HOOK_STATE_LEDGER_TYPE_PREFIX = 118; // Decimal value of ASCII 'v'
@@ -13912,8 +13954,20 @@ class StateHelpers {
13912
13954
  CONFIGURATION: 'configuration'
13913
13955
  }
13914
13956
 
13957
+ static timeLines = {
13958
+ SEC: "SEC"
13959
+ }
13960
+
13961
+ static getStateData(states, key) {
13962
+ const state = states.find(s => key === s.key);
13963
+ if (!state)
13964
+ return null;
13965
+
13966
+ return state.data;
13967
+ }
13968
+
13915
13969
  static decodeHostAddressState(stateKeyBuf, stateDataBuf) {
13916
- return {
13970
+ let data = {
13917
13971
  address: codec.encodeAccountID(stateKeyBuf.slice(12)),
13918
13972
  nfTokenId: stateDataBuf.slice(HOST_TOKEN_ID_OFFSET, HOST_COUNTRY_CODE_OFFSET).toString('hex').toUpperCase(),
13919
13973
  countryCode: stateDataBuf.slice(HOST_COUNTRY_CODE_OFFSET, HOST_RESERVED_OFFSET).toString(),
@@ -13922,9 +13976,12 @@ class StateHelpers {
13922
13976
  registrationFee: Number(stateDataBuf.readBigUInt64BE(HOST_REG_FEE_OFFSET)),
13923
13977
  maxInstances: stateDataBuf.readUInt32BE(HOST_TOT_INS_COUNT_OFFSET),
13924
13978
  activeInstances: stateDataBuf.readUInt32BE(HOST_ACT_INS_COUNT_OFFSET),
13925
- lastHeartbeatLedger: Number(stateDataBuf.readBigUInt64BE(HOST_HEARTBEAT_LEDGER_IDX_OFFSET)),
13926
- version: `${stateDataBuf.readUInt8(HOST_VERSION_OFFSET)}.${stateDataBuf.readUInt8(HOST_VERSION_OFFSET + 1)}.${stateDataBuf.readUInt8(HOST_VERSION_OFFSET + 2)}`
13979
+ lastHeartbeatIndex: Number(stateDataBuf.readBigUInt64BE(HOST_HEARTBEAT_LEDGER_IDX_OFFSET)),
13980
+ version: `${stateDataBuf.readUInt8(HOST_VERSION_OFFSET)}.${stateDataBuf.readUInt8(HOST_VERSION_OFFSET + 1)}.${stateDataBuf.readUInt8(HOST_VERSION_OFFSET + 2)}`,
13927
13981
  }
13982
+ if (stateDataBuf.length > HOST_REG_TIMESTAMP_OFFSET)
13983
+ data.registrationTimestamp = Number(stateDataBuf.readBigUInt64BE(HOST_REG_TIMESTAMP_OFFSET));
13984
+ return data;
13928
13985
  }
13929
13986
 
13930
13987
  static decodeTokenIdState(stateDataBuf) {
@@ -13967,11 +14024,15 @@ class StateHelpers {
13967
14024
  value: stateData.readUInt32BE()
13968
14025
  }
13969
14026
  }
13970
- else if (Buffer.from(HookStateKeys.MOMENT_BASE_IDX, 'hex').compare(stateKey) === 0) {
14027
+ else if (Buffer.from(HookStateKeys.MOMENT_BASE_INFO, 'hex').compare(stateKey) === 0) {
13971
14028
  return {
13972
14029
  type: this.StateTypes.SIGLETON,
13973
14030
  key: hexKey,
13974
- value: Number(stateData.readBigInt64BE())
14031
+ value: {
14032
+ baseIdx: Number(stateData.readBigUInt64BE(MOMENT_BASE_POINT_OFFSET)),
14033
+ baseTransitionMoment: stateData.length > MOMENT_AT_TRANSITION_OFFSET ? stateData.readUInt32BE(MOMENT_AT_TRANSITION_OFFSET) : 0,
14034
+ momentType: (stateData.length <= MOMENT_TYPE_OFFSET || stateData.readUInt8(MOMENT_TYPE_OFFSET) === MOMENT_TYPES.LEDGER) ? 'ledger' : 'timestamp'
14035
+ }
13975
14036
  }
13976
14037
  }
13977
14038
  else if (Buffer.from(HookStateKeys.HOST_REG_FEE, 'hex').compare(stateKey) === 0 || Buffer.from(HookStateKeys.MAX_REG, 'hex').compare(stateKey) === 0) {
@@ -14045,6 +14106,18 @@ class StateHelpers {
14045
14106
  value: stateData.readUInt16BE()
14046
14107
  }
14047
14108
  }
14109
+ else if (Buffer.from(HookStateKeys.MOMENT_TRANSIT_INFO, 'hex').compare(stateKey) === 0) {
14110
+ Buffer.alloc(1).readUInt8()
14111
+ return {
14112
+ type: this.StateTypes.CONFIGURATION,
14113
+ key: hexKey,
14114
+ value: {
14115
+ transitionIndex: Number(stateData.readBigInt64BE(TRANSIT_IDX_OFFSET)),
14116
+ momentSize: stateData.readUInt16BE(TRANSIT_MOMENT_SIZE_OFFSET),
14117
+ momentType: stateData.readUInt8(TRANSIT_MOMENT_TYPE_OFFSET) === MOMENT_TYPES.LEDGER ? 'ledger' : 'timestamp'
14118
+ }
14119
+ }
14120
+ }
14048
14121
  else
14049
14122
  throw { type: 'Validation Error', message: 'Invalid state key.' };
14050
14123
  }
@@ -14064,7 +14137,7 @@ class StateHelpers {
14064
14137
  };
14065
14138
  }
14066
14139
  else if (Buffer.from(HookStateKeys.HOST_COUNT, 'hex').compare(stateKey) === 0 ||
14067
- Buffer.from(HookStateKeys.MOMENT_BASE_IDX, 'hex').compare(stateKey) === 0 ||
14140
+ Buffer.from(HookStateKeys.MOMENT_BASE_INFO, 'hex').compare(stateKey) === 0 ||
14068
14141
  Buffer.from(HookStateKeys.HOST_REG_FEE, 'hex').compare(stateKey) === 0 ||
14069
14142
  Buffer.from(HookStateKeys.MAX_REG, 'hex').compare(stateKey) === 0 ||
14070
14143
  Buffer.from(HookStateKeys.REWARD_INFO, 'hex').compare(stateKey) === 0) {
@@ -14082,7 +14155,8 @@ class StateHelpers {
14082
14155
  Buffer.from(HookStateKeys.FIXED_REG_FEE, 'hex').compare(stateKey) === 0 ||
14083
14156
  Buffer.from(HookStateKeys.LEASE_ACQUIRE_WINDOW, 'hex').compare(stateKey) === 0 ||
14084
14157
  Buffer.from(HookStateKeys.REWARD_CONFIGURATION, 'hex').compare(stateKey) === 0 ||
14085
- Buffer.from(HookStateKeys.MAX_TOLERABLE_DOWNTIME, 'hex').compare(stateKey) === 0) {
14158
+ Buffer.from(HookStateKeys.MAX_TOLERABLE_DOWNTIME, 'hex').compare(stateKey) === 0 ||
14159
+ Buffer.from(HookStateKeys.MOMENT_TRANSIT_INFO, 'hex').compare(stateKey) === 0) {
14086
14160
  return {
14087
14161
  key: hexKey,
14088
14162
  type: this.STATE_TYPES.CONFIGURATION
@@ -14221,14 +14295,6 @@ const { EvernodeConstants, ErrorReasons } = __nccwpck_require__(9849);
14221
14295
  // Utility helper functions.
14222
14296
  class UtilHelpers {
14223
14297
 
14224
- static getStateData(states, key) {
14225
- const state = states.find(s => key === s.key);
14226
- if (!state)
14227
- throw { code: ErrorReasons.NO_STATE_KEY, error: `State key '${key}' not found.` };
14228
-
14229
- return state.data;
14230
- }
14231
-
14232
14298
  static readUInt(buf, base = 32, isBE = true) {
14233
14299
  buf = Buffer.from(buf);
14234
14300
  switch (base) {
@@ -14257,6 +14323,16 @@ class UtilHelpers {
14257
14323
  leaseAmount: parseFloat(XflHelpers.toString(uriBuf.readBigInt64BE(prefixLen + 2 + halfToSLen)))
14258
14324
  }
14259
14325
  }
14326
+
14327
+ static getCurrentUnixTime(format = "sec") {
14328
+ const time = Date.now();
14329
+ switch (format) {
14330
+ case "sec":
14331
+ return Math.floor(time / 1000);
14332
+ default:
14333
+ return time;
14334
+ }
14335
+ }
14260
14336
  }
14261
14337
 
14262
14338
  module.exports = {
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  ],
7
7
  "homepage": "https://github.com/HotPocketDev/evernode-js-client",
8
8
  "license": "MIT",
9
- "version": "0.5.2",
9
+ "version": "0.5.4",
10
10
  "dependencies": {
11
11
  "elliptic": "6.5.4",
12
12
  "ripple-address-codec": "4.2.0",