evernode-js-client 0.6.28 → 0.6.30

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 +102 -32
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -52510,6 +52510,40 @@ class BaseEvernodeClient {
52510
52510
  return (hosts.nextPageToken ? { ...hosts, data: res } : res);
52511
52511
  }
52512
52512
 
52513
+ /**
52514
+ * Get the hosts registered in Evernode.
52515
+ * @returns The list of hosts.
52516
+ */
52517
+ async getAllHostsFromLedger() {
52518
+ const states = await this.getHookStates();
52519
+ let hosts = {};
52520
+
52521
+ for (const state of states) {
52522
+ const stateKey = Buffer.from(state.key, 'hex');
52523
+ if (state.data) {
52524
+ const stateData = Buffer.from(state.data, 'hex');
52525
+ const decoded = StateHelpers.decodeStateData(stateKey, stateData);
52526
+ if (decoded.type == StateHelpers.StateTypes.HOST_ADDR || decoded.type == StateHelpers.StateTypes.TOKEN_ID) {
52527
+ hosts[decoded.address] = { ...(hosts[decoded.address] ?? {}), ...decoded };
52528
+ }
52529
+ }
52530
+ }
52531
+
52532
+ const hostList = Object.values(hosts);
52533
+
52534
+ const curMomentStartIdx = await this.getMomentStartIndex();
52535
+ await Promise.all((hostList).map(async host => {
52536
+ const hostAcc = new XrplAccount(host.address, null, { xrplApi: this.xrplApi });
52537
+ host.domain = await hostAcc.getDomain();
52538
+ host.active = (host.lastHeartbeatIndex > (this.config.hostHeartbeatFreq * this.config.momentSize) ?
52539
+ (host.lastHeartbeatIndex >= (curMomentStartIdx - (this.config.hostHeartbeatFreq * this.config.momentSize))) :
52540
+ (host.lastHeartbeatIndex > 0));
52541
+ return host;
52542
+ }));
52543
+
52544
+ return hostList;
52545
+ }
52546
+
52513
52547
  /**
52514
52548
  * Get the candidates proposed in Evernode. The result's are paginated. Default page size is 20. _Note: Specifying both filter and pagination does not supported._
52515
52549
  * @param {object} filters [Optional] Filter criteria to filter the candidates. The filter key can be a either property of the candidate.
@@ -53251,6 +53285,16 @@ class RegistryClient extends BaseEvernodeClient {
53251
53285
  // Filter only active hosts.
53252
53286
  return fullHostList.filter(h => h.active);
53253
53287
  }
53288
+
53289
+ /**
53290
+ * Gets all the active hosts registered in ledger.
53291
+ * @returns The list of active hosts.
53292
+ */
53293
+ async getActiveHostsFromLedger() {
53294
+ const hosts = await this.getAllHostsFromLedger();
53295
+ // Filter only active hosts.
53296
+ return hosts.filter(h => h.active);
53297
+ }
53254
53298
  }
53255
53299
 
53256
53300
  module.exports = {
@@ -53310,12 +53354,22 @@ const VOTE_VALIDATION_ERR = "VOTE_VALIDATION_ERR";
53310
53354
 
53311
53355
  const IPV6_FAMILY = 6;
53312
53356
 
53357
+ const MAX_HOST_LEDGER_OFFSET = 30;
53358
+
53313
53359
  class HostClient extends BaseEvernodeClient {
53314
53360
 
53315
53361
  constructor(xrpAddress, xrpSecret, options = {}) {
53316
53362
  super(xrpAddress, xrpSecret, Object.values(HostEvents), true, options);
53317
53363
  }
53318
53364
 
53365
+ /**
53366
+ * Get max ledger sequence for host client.
53367
+ * @returns Max ledger sequence number.
53368
+ */
53369
+ #getMaxLedgerSequence() {
53370
+ return (this.xrplApi.ledgerIndex + MAX_HOST_LEDGER_OFFSET);
53371
+ }
53372
+
53319
53373
  /**
53320
53374
  * Get registration URI token info.
53321
53375
  * @returns The registration URI token object.
@@ -53377,10 +53431,10 @@ class HostClient extends BaseEvernodeClient {
53377
53431
  { ...accountSetFields, Domain: domain } : accountSetFields;
53378
53432
 
53379
53433
  if (Object.keys(accountSetFields).length !== 0)
53380
- await this.xrplAcc.setAccountFields(accountSetFields);
53434
+ await this.xrplAcc.setAccountFields(accountSetFields, { maxLedgerIndex: this.#getMaxLedgerSequence() });
53381
53435
 
53382
53436
  if (trustLines.length === 0)
53383
- await this.xrplAcc.setTrustLine(EvernodeConstants.EVR, this.config.evrIssuerAddress, "99999999999999");
53437
+ await this.xrplAcc.setTrustLine(EvernodeConstants.EVR, this.config.evrIssuerAddress, "99999999999999", null, null, { maxLedgerIndex: this.#getMaxLedgerSequence() });
53384
53438
  }
53385
53439
 
53386
53440
  /**
@@ -53442,15 +53496,15 @@ class HostClient extends BaseEvernodeClient {
53442
53496
  const uri = uriBuf.toString('base64');
53443
53497
 
53444
53498
  try {
53445
- await this.xrplAcc.mintURIToken(uri, null, { isBurnable: true, isHexUri: false });
53499
+ await this.xrplAcc.mintURIToken(uri, null, { isBurnable: true, isHexUri: false }, { maxLedgerIndex: this.#getMaxLedgerSequence() });
53446
53500
  } catch (e) {
53447
53501
  // Re-minting the URIToken after burning that sold URIToken.
53448
53502
  if (e.code === "tecDUPLICATE") {
53449
53503
  const uriTokenId = this.xrplAcc.generateIssuedURITokenId(uri);
53450
53504
  console.log(`Burning URIToken related to a previously sold lease.`);
53451
- await this.xrplAcc.burnURIToken(uriTokenId);
53505
+ await this.xrplAcc.burnURIToken(uriTokenId, { maxLedgerIndex: this.#getMaxLedgerSequence() });
53452
53506
  console.log("Re-mint the URIToken for the new lease offer.")
53453
- await this.xrplAcc.mintURIToken(uri, null, { isBurnable: true, isHexUri: false });
53507
+ await this.xrplAcc.mintURIToken(uri, null, { isBurnable: true, isHexUri: false }, { maxLedgerIndex: this.#getMaxLedgerSequence() });
53454
53508
  }
53455
53509
  }
53456
53510
 
@@ -53461,7 +53515,7 @@ class HostClient extends BaseEvernodeClient {
53461
53515
  await this.xrplAcc.sellURIToken(uriToken.index,
53462
53516
  leaseAmount.toString(),
53463
53517
  EvernodeConstants.EVR,
53464
- this.config.evrIssuerAddress);
53518
+ this.config.evrIssuerAddress, null, null, { maxLedgerIndex: this.#getMaxLedgerSequence() });
53465
53519
  }
53466
53520
 
53467
53521
  /**
@@ -53469,7 +53523,7 @@ class HostClient extends BaseEvernodeClient {
53469
53523
  * @param {string} uriTokenId Hex URI token id of the lease.
53470
53524
  */
53471
53525
  async expireLease(uriTokenId) {
53472
- await this.xrplAcc.burnURIToken(uriTokenId);
53526
+ await this.xrplAcc.burnURIToken(uriTokenId, { maxLedgerIndex: this.#getMaxLedgerSequence() });
53473
53527
  }
53474
53528
 
53475
53529
  /**
@@ -53523,7 +53577,7 @@ class HostClient extends BaseEvernodeClient {
53523
53577
  if (existingLeaseURITokens) {
53524
53578
  console.log("Burning unsold URITokens related to the previous leases.");
53525
53579
  for (const uriToken of existingLeaseURITokens) {
53526
- await this.xrplAcc.burnURIToken(uriToken.index);
53580
+ await this.xrplAcc.burnURIToken(uriToken.index, { maxLedgerIndex: this.#getMaxLedgerSequence() });
53527
53581
  }
53528
53582
  }
53529
53583
 
@@ -53538,7 +53592,7 @@ class HostClient extends BaseEvernodeClient {
53538
53592
  const sellOffer = (await registryAcc.getURITokens()).find(o => o.index == regInfo.uriTokenId && o.Amount);
53539
53593
  console.log('sell offer')
53540
53594
  if (sellOffer) {
53541
- await this.xrplAcc.buyURIToken(sellOffer);
53595
+ await this.xrplAcc.buyURIToken(sellOffer, null, { maxLedgerIndex: this.#getMaxLedgerSequence() });
53542
53596
  console.log("Registration was successfully completed after acquiring the NFT.");
53543
53597
  return await this.isRegistered();
53544
53598
  }
@@ -53588,6 +53642,7 @@ class HostClient extends BaseEvernodeClient {
53588
53642
  { name: HookParamKeys.PARAM_EVENT_TYPE_KEY, value: EventTypes.HOST_REG },
53589
53643
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: paramBuf.toString('hex').toUpperCase() }
53590
53644
  ],
53645
+ maxLedgerIndex: this.#getMaxLedgerSequence(),
53591
53646
  ...options.transactionOptions
53592
53647
  });
53593
53648
 
@@ -53626,7 +53681,7 @@ class HostClient extends BaseEvernodeClient {
53626
53681
  resolve();
53627
53682
  });
53628
53683
 
53629
- await this.xrplAcc.buyURIToken(sellOffer);
53684
+ await this.xrplAcc.buyURIToken(sellOffer, null, { maxLedgerIndex: this.#getMaxLedgerSequence() });
53630
53685
  return await this.isRegistered();
53631
53686
  }
53632
53687
 
@@ -53659,6 +53714,7 @@ class HostClient extends BaseEvernodeClient {
53659
53714
  { name: HookParamKeys.PARAM_EVENT_TYPE_KEY, value: EventTypes.HOST_DEREG },
53660
53715
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: paramBuf.toString('hex').toUpperCase() }
53661
53716
  ],
53717
+ maxLedgerIndex: this.#getMaxLedgerSequence(),
53662
53718
  ...options.transactionOptions
53663
53719
  });
53664
53720
 
@@ -53720,6 +53776,7 @@ class HostClient extends BaseEvernodeClient {
53720
53776
  { name: HookParamKeys.PARAM_EVENT_TYPE_KEY, value: EventTypes.HOST_UPDATE_INFO },
53721
53777
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: paramBuf.toString('hex') }
53722
53778
  ],
53779
+ maxLedgerIndex: this.#getMaxLedgerSequence(),
53723
53780
  ...options.transactionOptions
53724
53781
  });
53725
53782
  }
@@ -53751,6 +53808,7 @@ class HostClient extends BaseEvernodeClient {
53751
53808
  { name: HookParamKeys.PARAM_EVENT_TYPE_KEY, value: EventTypes.HEARTBEAT },
53752
53809
  ...(data ? [{ name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: data }] : [])
53753
53810
  ],
53811
+ maxLedgerIndex: this.#getMaxLedgerSequence(),
53754
53812
  ...options.transactionOptions
53755
53813
  });
53756
53814
  return res;
@@ -53817,6 +53875,7 @@ class HostClient extends BaseEvernodeClient {
53817
53875
  { name: HookParamKeys.PARAM_EVENT_TYPE_KEY, value: EventTypes.ACQUIRE_SUCCESS },
53818
53876
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: txHash }
53819
53877
  ],
53878
+ maxLedgerIndex: this.#getMaxLedgerSequence(),
53820
53879
  ...options.transactionOptions
53821
53880
  });
53822
53881
  }
@@ -53844,6 +53903,7 @@ class HostClient extends BaseEvernodeClient {
53844
53903
  { name: HookParamKeys.PARAM_EVENT_TYPE_KEY, value: EventTypes.ACQUIRE_ERROR },
53845
53904
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: txHash }
53846
53905
  ],
53906
+ maxLedgerIndex: this.#getMaxLedgerSequence(),
53847
53907
  ...options.transactionOptions
53848
53908
  });
53849
53909
  }
@@ -53872,6 +53932,7 @@ class HostClient extends BaseEvernodeClient {
53872
53932
  { name: HookParamKeys.PARAM_EVENT_TYPE_KEY, value: EventTypes.EXTEND_SUCCESS },
53873
53933
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: txHash }
53874
53934
  ],
53935
+ maxLedgerIndex: this.#getMaxLedgerSequence(),
53875
53936
  ...options.transactionOptions
53876
53937
  });
53877
53938
  }
@@ -53900,6 +53961,7 @@ class HostClient extends BaseEvernodeClient {
53900
53961
  { name: HookParamKeys.PARAM_EVENT_TYPE_KEY, value: EventTypes.EXTEND_ERROR },
53901
53962
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: txHash }
53902
53963
  ],
53964
+ maxLedgerIndex: this.#getMaxLedgerSequence(),
53903
53965
  ...options.transactionOptions
53904
53966
  });
53905
53967
  }
@@ -53925,6 +53987,7 @@ class HostClient extends BaseEvernodeClient {
53925
53987
  { name: HookParamKeys.PARAM_EVENT_TYPE_KEY, value: EventTypes.REFUND },
53926
53988
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: txHash }
53927
53989
  ],
53990
+ maxLedgerIndex: this.#getMaxLedgerSequence(),
53928
53991
  ...options.transactionOptions
53929
53992
  });
53930
53993
  }
@@ -53946,6 +54009,7 @@ class HostClient extends BaseEvernodeClient {
53946
54009
  hookParams: [
53947
54010
  { name: HookParamKeys.PARAM_EVENT_TYPE_KEY, value: EventTypes.HOST_REBATE }
53948
54011
  ],
54012
+ maxLedgerIndex: this.#getMaxLedgerSequence(),
53949
54013
  ...options.transactionOptions
53950
54014
  });
53951
54015
  }
@@ -53983,6 +54047,7 @@ class HostClient extends BaseEvernodeClient {
53983
54047
  { name: HookParamKeys.PARAM_EVENT_TYPE_KEY, value: EventTypes.HOST_TRANSFER },
53984
54048
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: paramData.toString('hex') }
53985
54049
  ],
54050
+ maxLedgerIndex: this.#getMaxLedgerSequence(),
53986
54051
  ...options.transactionOptions
53987
54052
  });
53988
54053
 
@@ -54029,6 +54094,7 @@ class HostClient extends BaseEvernodeClient {
54029
54094
  if (!(await this.isRegistered()))
54030
54095
  throw 'Host should be registered to propose candidates.';
54031
54096
 
54097
+ options.transactionOptions = { maxLedgerIndex: this.#getMaxLedgerSequence(), ...(options.transactionOptions || {}) }
54032
54098
  return await super._propose(hashes, shortName, options);
54033
54099
  }
54034
54100
 
@@ -54042,6 +54108,7 @@ class HostClient extends BaseEvernodeClient {
54042
54108
  if (!(await this.isRegistered()))
54043
54109
  throw 'Host should be registered to withdraw candidates.';
54044
54110
 
54111
+ options.transactionOptions = { maxLedgerIndex: this.#getMaxLedgerSequence(), ...(options.transactionOptions || {}) }
54045
54112
  return await super._withdraw(candidateId, options);
54046
54113
  }
54047
54114
 
@@ -54055,6 +54122,7 @@ class HostClient extends BaseEvernodeClient {
54055
54122
  if (!(await this.isRegistered()))
54056
54123
  throw 'Host should be registered to report dud hosts.';
54057
54124
 
54125
+ options.transactionOptions = { maxLedgerIndex: this.#getMaxLedgerSequence(), ...(options.transactionOptions || {}) }
54058
54126
  return await this._reportDudHost(hostAddress, options);
54059
54127
  }
54060
54128
  }
@@ -55663,6 +55731,7 @@ const HOST_LAST_VOTE_TIMESTAMP_OFFSET = 116;
55663
55731
  const HOST_SUPPORT_VOTE_FLAG_OFFSET = 124;
55664
55732
  const HOST_REPUTATION_OFFSET = 125;
55665
55733
  const HOST_FLAGS_OFFSET = 126;
55734
+ const HOST_TRANSFER_TIMESTAMP_OFFSET = 127;
55666
55735
 
55667
55736
  const HOST_ADDRESS_OFFSET = 0;
55668
55737
  const HOST_CPU_MODEL_NAME_OFFSET = 20;
@@ -55774,6 +55843,9 @@ class StateHelpers {
55774
55843
  const flags = stateDataBuf.readUInt8(HOST_FLAGS_OFFSET);
55775
55844
  data.reputedOnHeartbeat = !!(flags & HOST_FLAGS.REPUTED_ON_HEARTBEAT);
55776
55845
  }
55846
+ if (stateDataBuf.length > HOST_TRANSFER_TIMESTAMP_OFFSET) {
55847
+ data.transferTimestamp = Number(stateDataBuf.readBigUInt64LE(HOST_TRANSFER_TIMESTAMP_OFFSET));
55848
+ }
55777
55849
  return data;
55778
55850
  }
55779
55851
 
@@ -57473,6 +57545,8 @@ class XrplApi {
57473
57545
  });
57474
57546
 
57475
57547
  client.on('disconnected', async (code) => {
57548
+ this.#events.emit(XrplApiEvents.DISCONNECTED, code);
57549
+
57476
57550
  this.#isPrimaryServerConnected = false;
57477
57551
  this.#isFallbackServerConnected = false;
57478
57552
 
@@ -57895,30 +57969,25 @@ class XrplApi {
57895
57969
  * @returns prepared response of the transaction result.
57896
57970
  */
57897
57971
  async #prepareResponse(tx, submissionResult) {
57898
- const resultCode = submissionResult?.result?.engine_result;
57899
- if (resultCode === "tesSUCCESS" || resultCode === "tefPAST_SEQ" || resultCode === "tefALREADY") {
57900
- const result = await this.#waitForFinalTransactionOutcome(submissionResult.result.tx_json.hash, tx.LastLedgerSequence, submissionResult);
57901
- const txResult = {
57902
- id: result?.hash,
57903
- code: result?.meta?.TransactionResult,
57904
- details: result
57905
- };
57972
+ const result = await this.#waitForFinalTransactionOutcome(submissionResult.result.tx_json.hash, tx.LastLedgerSequence, submissionResult);
57973
+ const txResult = {
57974
+ id: result?.hash,
57975
+ code: result?.meta?.TransactionResult,
57976
+ details: result
57977
+ };
57906
57978
 
57907
- console.log("Transaction result: " + txResult.code);
57908
- const hookExecRes = txResult.details?.meta?.HookExecutions?.map(o => {
57909
- return {
57910
- result: o.HookExecution?.HookResult,
57911
- returnCode: parseInt(o.HookExecution?.HookReturnCode, 16),
57912
- message: TransactionHelper.hexToASCII(o.HookExecution?.HookReturnString).replace(/\x00+$/, '')
57913
- }
57914
- });
57915
- if (txResult.code === "tesSUCCESS")
57916
- return { ...txResult, ...(hookExecRes ? { hookExecutionResult: hookExecRes } : {}) };
57917
- else
57918
- throw { ...txResult, ...(hookExecRes ? { hookExecutionResult: hookExecRes } : {}) };
57919
- }
57979
+ console.log("Transaction result: " + txResult.code);
57980
+ const hookExecRes = txResult.details?.meta?.HookExecutions?.map(o => {
57981
+ return {
57982
+ result: o.HookExecution?.HookResult,
57983
+ returnCode: parseInt(o.HookExecution?.HookReturnCode, 16),
57984
+ message: TransactionHelper.hexToASCII(o.HookExecution?.HookReturnString).replace(/\x00+$/, '')
57985
+ }
57986
+ });
57987
+ if (txResult.code === "tesSUCCESS")
57988
+ return { ...txResult, ...(hookExecRes ? { hookExecutionResult: hookExecRes } : {}) };
57920
57989
  else
57921
- throw resultCode ? `Transaction failed with error ${resultCode}` : 'Transaction failed';
57990
+ throw { ...txResult, ...(hookExecRes ? { hookExecutionResult: hookExecRes } : {}) };
57922
57991
 
57923
57992
  }
57924
57993
 
@@ -57988,6 +58057,7 @@ module.exports = {
57988
58057
 
57989
58058
  const XrplApiEvents = {
57990
58059
  LEDGER: 'ledger',
58060
+ DISCONNECTED: 'disconnected',
57991
58061
  PAYMENT: 'payment',
57992
58062
  NFT_OFFER_CREATE: 'nftokencreateoffer',
57993
58063
  NFT_OFFER_ACCEPT: 'nftokenacceptoffer',
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  ],
7
7
  "homepage": "https://github.com/HotPocketDev/evernode-js-client",
8
8
  "license": "SEE LICENSE IN https://raw.githubusercontent.com/EvernodeXRPL/evernode-resources/main/license/evernode-license.pdf",
9
- "version": "0.6.28",
9
+ "version": "0.6.30",
10
10
  "dependencies": {
11
11
  "elliptic": "6.5.4",
12
12
  "libsodium-wrappers": "0.7.10",