evernode-js-client 0.6.28 → 0.6.30

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 +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",