evernode-js-client 0.5.2 → 0.5.4

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