evernode-js-client 0.6.49 → 0.6.51

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 +207 -94
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -59620,6 +59620,9 @@ class BaseEvernodeClient {
59620
59620
  if (!options.xrplApi && !Defaults.values.xrplApi)
59621
59621
  this.#ownsXrplApi = true;
59622
59622
 
59623
+ if (options.config)
59624
+ this.config = options.config;
59625
+
59623
59626
  this.xrplAcc = new XrplAccount(xrpAddress, xrpSecret, { xrplApi: this.xrplApi });
59624
59627
  this.accKeyPair = xrpSecret && this.xrplAcc.deriveKeypair();
59625
59628
  this.messagePrivateKey = options.messagePrivateKey || (this.accKeyPair ? this.accKeyPair.privateKey : null);
@@ -59665,7 +59668,7 @@ class BaseEvernodeClient {
59665
59668
  * Connects the client to xrpl server and do the config loading and subscriptions. 'subscribe' is called inside this.
59666
59669
  * @returns boolean value, 'true' if success.
59667
59670
  */
59668
- async connect() {
59671
+ async connect(options = {}) {
59669
59672
  if (this.connected)
59670
59673
  return true;
59671
59674
 
@@ -59675,7 +59678,9 @@ class BaseEvernodeClient {
59675
59678
  // identify a network reset from XRPL.
59676
59679
  await this.xrplAcc.getInfo();
59677
59680
 
59678
- this.config = await this.#getEvernodeConfig();
59681
+ if (!this.config && !options.skipConfigs)
59682
+ this.config = await this.#getEvernodeConfig();
59683
+
59679
59684
  this.connected = true;
59680
59685
 
59681
59686
  if (this.#autoSubscribe)
@@ -59764,7 +59769,6 @@ class BaseEvernodeClient {
59764
59769
  * @returns An object with all the configuration and their values.
59765
59770
  */
59766
59771
  async #getEvernodeConfig() {
59767
- let states = await this.getHookStates();
59768
59772
  const configStateKeys = {
59769
59773
  registryAddress: HookStateKeys.REGISTRY_ADDR,
59770
59774
  heartbeatAddress: HookStateKeys.HEARTBEAT_ADDR,
@@ -59788,12 +59792,12 @@ class BaseEvernodeClient {
59788
59792
  }
59789
59793
  let config = {};
59790
59794
  for (const [key, value] of Object.entries(configStateKeys)) {
59791
- const stateKey = Buffer.from(value, 'hex');
59792
- const stateDataBin = StateHelpers.getStateData(states, value);
59793
- if (stateDataBin) {
59794
- const stateData = Buffer.from(StateHelpers.getStateData(states, value), 'hex');
59795
- const decoded = StateHelpers.decodeStateData(stateKey, stateData);
59796
- config[key] = decoded.value;
59795
+ const index = StateHelpers.getHookStateIndex(this.governorAddress, value);
59796
+ const ledgerEntry = await this.xrplApi.getLedgerEntry(index);
59797
+ const stateData = ledgerEntry?.HookStateData;
59798
+ if (stateData) {
59799
+ const stateDecoded = StateHelpers.decodeStateData(Buffer.from(value, 'hex'), Buffer.from(stateData, 'hex'));
59800
+ config[key] = stateDecoded.value;
59797
59801
  }
59798
59802
  }
59799
59803
  return config;
@@ -60485,13 +60489,63 @@ class BaseEvernodeClient {
60485
60489
  return null;
60486
60490
  }
60487
60491
 
60492
+ async getReputationAddressByOrderId(hostReputationOrderedId, moment = null) {
60493
+ try {
60494
+ const repMoment = moment ?? await this.getMoment();
60495
+ const orderedIdStateKey = StateHelpers.generateHostReputationOrderedIdStateKey(hostReputationOrderedId, repMoment);
60496
+ const orderedIdStateIndex = StateHelpers.getHookStateIndex(this.xrplAcc.address, orderedIdStateKey);
60497
+ const orderedIdLedgerEntry = await this.xrplApi.getLedgerEntry(orderedIdStateIndex);
60498
+ const orderedIdStateData = orderedIdLedgerEntry?.HookStateData;
60499
+
60500
+ if (orderedIdStateData) {
60501
+ const orderedIdStateDecoded = StateHelpers.decodeHostReputationOrderedIdState(Buffer.from(orderedIdStateKey, 'hex'), Buffer.from(orderedIdStateData, 'hex'));
60502
+ return orderedIdStateDecoded;
60503
+ }
60504
+ }
60505
+ catch (e) {
60506
+ // If the exception is entryNotFound from Rippled there's no entry for the host, So return null.
60507
+ if (e?.data?.error !== 'entryNotFound')
60508
+ throw e;
60509
+ }
60510
+
60511
+ return null;
60512
+ }
60513
+
60488
60514
  /**
60489
60515
  * Get reputation info of given host.
60490
60516
  * @param {string} hostReputationAddress Host's reputation address.
60491
60517
  * @param {number} moment (optional) Moment to get reputation info for.
60492
60518
  * @returns Reputation info object.
60493
60519
  */
60494
- async _getReputationInfoByAddress(hostReputationAddress, moment = null) {
60520
+ async getReputationOrderByAddress(hostReputationAddress, moment = null) {
60521
+ try {
60522
+ const repMoment = moment ?? await this.getMoment();
60523
+ const orderedAddrStateKey = StateHelpers.generateHostReputationOrderAddressStateKey(hostReputationAddress, repMoment);
60524
+ const orderedAddrStateIndex = StateHelpers.getHookStateIndex(this.config.reputationAddress, orderedAddrStateKey);
60525
+ const orderedAddrLedgerEntry = await this.xrplApi.getLedgerEntry(orderedAddrStateIndex);
60526
+ const orderedAddrStateData = orderedAddrLedgerEntry?.HookStateData;
60527
+
60528
+ if (orderedAddrStateData) {
60529
+ const orderedAddrStateDecoded = StateHelpers.decodeHostReputationOrderAddressState(Buffer.from(orderedAddrStateKey, 'hex'), Buffer.from(orderedAddrStateData, 'hex'));
60530
+ return orderedAddrStateDecoded;
60531
+ }
60532
+ }
60533
+ catch (e) {
60534
+ // If the exception is entryNotFound from Rippled there's no entry for the host, So return null.
60535
+ if (e?.data?.error !== 'entryNotFound')
60536
+ throw e;
60537
+ }
60538
+
60539
+ return null;
60540
+ }
60541
+
60542
+ /**
60543
+ * Get reputation info of given host.
60544
+ * @param {string} hostReputationAddress Host's reputation address.
60545
+ * @param {number} moment (optional) Moment to get reputation info for.
60546
+ * @returns Reputation info object.
60547
+ */
60548
+ async getReputationInfoByAddress(hostReputationAddress, moment = null) {
60495
60549
  try {
60496
60550
  const addrStateKey = StateHelpers.generateHostReputationAddrStateKey(hostReputationAddress);
60497
60551
  const addrStateIndex = StateHelpers.getHookStateIndex(this.config.reputationAddress, addrStateKey);
@@ -60505,15 +60559,6 @@ class BaseEvernodeClient {
60505
60559
  }
60506
60560
 
60507
60561
  const repMoment = moment ?? await this.getMoment();
60508
- const orderedAddrStateKey = StateHelpers.generateHostReputationOrderAddressStateKey(hostReputationAddress, repMoment);
60509
- const orderedAddrStateIndex = StateHelpers.getHookStateIndex(this.config.reputationAddress, orderedAddrStateKey);
60510
- const orderedAddrLedgerEntry = await this.xrplApi.getLedgerEntry(orderedAddrStateIndex);
60511
- const orderedAddrStateData = orderedAddrLedgerEntry?.HookStateData;
60512
-
60513
- if (orderedAddrStateData) {
60514
- const orderedAddrStateDecoded = StateHelpers.decodeHostReputationOrderAddressState(Buffer.from(orderedAddrStateKey, 'hex'), Buffer.from(orderedAddrStateData, 'hex'));
60515
- data = { ...data, ...orderedAddrStateDecoded };
60516
- }
60517
60562
 
60518
60563
  const hostRepAcc = new XrplAccount(hostReputationAddress, null, { xrplApi: this.xrplApi });
60519
60564
  const [wl, rep] = await Promise.all([
@@ -60922,26 +60967,39 @@ class HookClientFactory {
60922
60967
  * @param {string} hookType Type of the Required Hook. (Supported Hook types 'GOVERNOR', 'REGISTRY' and 'HEARTBEAT')
60923
60968
  * @returns Instance of requested HookClient type.
60924
60969
  */
60925
- static async create(hookType) {
60970
+ static async create(hookType, options = {}) {
60971
+ let governorClient;
60972
+ if (hookType !== HookTypes.governor && !options.config) {
60973
+ governorClient = new GovernorClient(options);
60974
+ try {
60975
+ await governorClient.connect();
60976
+ options.config = governorClient.config;
60977
+ } catch (error) {
60978
+ throw (error)
60979
+ } finally {
60980
+ await governorClient.disconnect();
60981
+ }
60982
+ }
60983
+
60926
60984
  let hookClient;
60927
60985
  switch (hookType) {
60928
60986
  case HookTypes.governor: {
60929
- hookClient = new GovernorClient();
60987
+ hookClient = new GovernorClient(options);
60930
60988
  break;
60931
60989
  }
60932
60990
  case HookTypes.registry: {
60933
- const registryAddress = await HookClientFactory.#getAccountAddress(hookType);
60934
- hookClient = new RegistryClient({ registryAddress: registryAddress });
60991
+ const registryAddress = await HookClientFactory.#getAccountAddress(hookType, options.config);
60992
+ hookClient = new RegistryClient({ ...options, registryAddress: registryAddress });
60935
60993
  break;
60936
60994
  }
60937
60995
  case HookTypes.heartbeat: {
60938
- const heartbeatAddress = await HookClientFactory.#getAccountAddress(hookType);
60939
- hookClient = new HeartbeatClient({ heartbeatAddress: heartbeatAddress });
60996
+ const heartbeatAddress = await HookClientFactory.#getAccountAddress(hookType, options.config);
60997
+ hookClient = new HeartbeatClient({ ...options, heartbeatAddress: heartbeatAddress });
60940
60998
  break;
60941
60999
  }
60942
61000
  case HookTypes.reputation: {
60943
- const reputationAddress = await HookClientFactory.#getAccountAddress(hookType);
60944
- hookClient = new ReputationClient({ reputationAddress: reputationAddress });
61001
+ const reputationAddress = await HookClientFactory.#getAccountAddress(hookType, options.config);
61002
+ hookClient = new ReputationClient({ ...options, reputationAddress: reputationAddress });
60945
61003
  break;
60946
61004
  }
60947
61005
  default: {
@@ -60953,25 +61011,13 @@ class HookClientFactory {
60953
61011
  return hookClient;
60954
61012
  }
60955
61013
 
60956
- static async #getAccountAddress(hookType) {
60957
- const governorHook = await HookClientFactory.create(HookTypes.governor);
60958
-
60959
- let configs;
60960
- try {
60961
- await governorHook.connect();
60962
- configs = governorHook.config;
60963
- } catch (error) {
60964
- throw (error)
60965
- } finally {
60966
- await governorHook.disconnect();
60967
- }
60968
-
61014
+ static async #getAccountAddress(hookType, config) {
60969
61015
  if (hookType == HookTypes.registry)
60970
- return configs.registryAddress;
61016
+ return config.registryAddress;
60971
61017
  else if (hookType == HookTypes.heartbeat)
60972
- return configs.heartbeatAddress;
61018
+ return config.heartbeatAddress;
60973
61019
  else if (hookType == HookTypes.reputation)
60974
- return configs.reputationAddress;
61020
+ return config.reputationAddress;
60975
61021
  }
60976
61022
  }
60977
61023
 
@@ -61024,8 +61070,11 @@ module.exports = {
61024
61070
  /***/ 7541:
61025
61071
  /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
61026
61072
 
61073
+ const codec = __nccwpck_require__(597);
61027
61074
  const { StateHelpers } = __nccwpck_require__(3860);
61075
+ const { XrplAccount } = __nccwpck_require__(9329);
61028
61076
  const { BaseEvernodeClient } = __nccwpck_require__(6263);
61077
+ const { ReputationConstants } = __nccwpck_require__(9849);
61029
61078
 
61030
61079
  const ReputationEvents = {}
61031
61080
 
@@ -61035,6 +61084,53 @@ class ReputationClient extends BaseEvernodeClient {
61035
61084
  super(options.reputationAddress, null, Object.values(ReputationEvents), false, options);
61036
61085
  }
61037
61086
 
61087
+ async getReputationContractInfoByOrderedId(hostReputationOrderedId, moment = null) {
61088
+ try {
61089
+ const repMoment = moment ?? await this.getMoment();
61090
+ const addressInfo = await this.getReputationAddressByOrderId(hostReputationOrderedId, repMoment);
61091
+ if (addressInfo?.address) {
61092
+ let data = addressInfo;
61093
+
61094
+ const hostRepAcc = new XrplAccount(addressInfo?.address, null, { xrplApi: this.xrplApi });
61095
+ const [wl, rep] = await Promise.all([
61096
+ hostRepAcc.getWalletLocator(),
61097
+ hostRepAcc.getDomain()]);
61098
+
61099
+ if (wl && rep && rep.length > 0) {
61100
+ const hostReputationAccId = wl.slice(0, 40);
61101
+ const hostAddress = codec.encodeAccountID(Buffer.from(hostReputationAccId, 'hex'));
61102
+ const hostAcc = new XrplAccount(hostAddress, null, { xrplApi: this.xrplApi });
61103
+
61104
+ const repBuf = Buffer.from(rep, 'hex');
61105
+ const publicKey = repBuf.slice(0, ReputationConstants.REP_INFO_PEER_PORT_OFFSET).toString('hex').toLocaleLowerCase();
61106
+ const peerPort = repBuf.readUInt16LE(ReputationConstants.REP_INFO_PEER_PORT_OFFSET);
61107
+ const instanceMoment = (repBuf.length > ReputationConstants.REP_INFO_MOMENT_OFFSET) ? Number(repBuf.readBigUInt64LE(ReputationConstants.REP_INFO_MOMENT_OFFSET)) : null;
61108
+ const domain = await hostAcc.getDomain();
61109
+
61110
+ if (instanceMoment === repMoment) {
61111
+ data = {
61112
+ ...data,
61113
+ contract: {
61114
+ domain: domain,
61115
+ pubkey: publicKey,
61116
+ peerPort: peerPort
61117
+ }
61118
+ }
61119
+ }
61120
+ }
61121
+ return data;
61122
+ }
61123
+
61124
+ }
61125
+ catch (e) {
61126
+ // If the exception is entryNotFound from Rippled there's no entry for the host, So return null.
61127
+ if (e?.data?.error !== 'entryNotFound')
61128
+ throw e;
61129
+ }
61130
+
61131
+ return null;
61132
+ }
61133
+
61038
61134
  /**
61039
61135
  * Get reputation info of given host reputation orderId.
61040
61136
  * @param {number} hostReputationOrderedId Reputation order id of the host.
@@ -61044,14 +61140,11 @@ class ReputationClient extends BaseEvernodeClient {
61044
61140
  async getReputationInfoByOrderedId(hostReputationOrderedId, moment = null) {
61045
61141
  try {
61046
61142
  const repMoment = moment ?? await this.getMoment();
61047
- const orderedIdStateKey = StateHelpers.generateHostReputationOrderedIdStateKey(hostReputationOrderedId, repMoment);
61048
- const orderedIdStateIndex = StateHelpers.getHookStateIndex(this.xrplAcc.address, orderedIdStateKey);
61049
- const orderedIdLedgerEntry = await this.xrplApi.getLedgerEntry(orderedIdStateIndex);
61050
- const orderedIdStateData = orderedIdLedgerEntry?.HookStateData;
61143
+ const addressInfo = this.getReputationAddressByOrderId(hostReputationOrderedId, repMoment);
61051
61144
 
61052
- if (orderedIdStateData) {
61053
- const orderedIdStateDecoded = StateHelpers.decodeHostReputationOrderedIdState(Buffer.from(orderedIdStateKey, 'hex'), Buffer.from(orderedIdStateData, 'hex'));
61054
- return await this._getReputationInfoByAddress(orderedIdStateDecoded.address, moment);
61145
+ if (addressInfo?.address) {
61146
+ const info = await this.getReputationInfoByAddress(addressInfo?.address, repMoment);
61147
+ return info ? { ...addressInfo, ...info } : addressInfo;
61055
61148
  }
61056
61149
  }
61057
61150
  catch (e) {
@@ -61162,7 +61255,7 @@ class HostClient extends BaseEvernodeClient {
61162
61255
  }
61163
61256
 
61164
61257
  async connect(options = {}) {
61165
- const res = await super.connect();
61258
+ const res = await super.connect(options);
61166
61259
  await this.setReputationAcc(options.reputationAddress, options.reputationSecret);
61167
61260
  return res;
61168
61261
  }
@@ -61398,7 +61491,22 @@ class HostClient extends BaseEvernodeClient {
61398
61491
  if (!this.reputationAcc)
61399
61492
  return null;
61400
61493
 
61401
- return await this._getReputationInfoByAddress(this.reputationAcc.address, moment);
61494
+ try {
61495
+ const repMoment = moment ?? await this.getMoment();
61496
+ const orderInfo = await this.getReputationOrderByAddress(this.reputationAcc.address, repMoment);
61497
+
61498
+ if (orderInfo?.orderedId) {
61499
+ const info = await this.getReputationInfoByAddress(this.reputationAcc.address, repMoment);
61500
+ return info ? { ...orderInfo, ...info } : orderInfo;
61501
+ }
61502
+ }
61503
+ catch (e) {
61504
+ // If the exception is entryNotFound from Rippled there's no entry for the host, So return null.
61505
+ if (e?.data?.error !== 'entryNotFound')
61506
+ throw e;
61507
+ }
61508
+
61509
+ return null;
61402
61510
  }
61403
61511
 
61404
61512
  /**
@@ -61407,7 +61515,10 @@ class HostClient extends BaseEvernodeClient {
61407
61515
  * @returns Unified reputation score array.
61408
61516
  */
61409
61517
  async prepareHostReputationScores(collectedScores = {}) {
61410
- const myReputationInfo = await this.getReputationInfo();
61518
+ const myReputationInfo = await this.getReputationOrderByAddress(this.reputationAcc.address);
61519
+ if (!myReputationInfo?.orderedId)
61520
+ throw 'You are not registered for reputation for this moment.';
61521
+
61411
61522
  const myOrderId = myReputationInfo.orderedId;
61412
61523
 
61413
61524
  // Deciding universe.
@@ -61418,7 +61529,7 @@ class HostClient extends BaseEvernodeClient {
61418
61529
  let data = {};
61419
61530
  await Promise.all(Array.from({ length: 64 }, (_, i) => i + universeStartIndex).map(async (i) => {
61420
61531
  try {
61421
- const hostReputationInfo = await reputationClient.getReputationInfoByOrderedId(i);
61532
+ const hostReputationInfo = await reputationClient.getReputationContractInfoByOrderedId(i);
61422
61533
  if (!hostReputationInfo)
61423
61534
  throw 'No reputation info for this order id';
61424
61535
  data[i.toString()] = {
@@ -65484,7 +65595,6 @@ const { TransactionHelper } = __nccwpck_require__(7071);
65484
65595
  const { XrplApiEvents } = __nccwpck_require__(3307);
65485
65596
  const { XrplAccount } = __nccwpck_require__(9329);
65486
65597
  const { XrplHelpers } = __nccwpck_require__(3189);
65487
- const { UtilHelpers } = __nccwpck_require__(6687);
65488
65598
 
65489
65599
  const MAX_PAGE_LIMIT = 400;
65490
65600
  const API_REQ_TYPE = {
@@ -65535,7 +65645,7 @@ class XrplApi {
65535
65645
  }
65536
65646
 
65537
65647
  async #acquireClient() {
65538
- while (!(this.#isPrimaryServerConnected || this.#isFallbackServerConnected) && this.#isClientAcquired || this.#isConnectionAcquired) {
65648
+ while (!(this.#isPrimaryServerConnected || this.#isFallbackServerConnected) && this.#isClientAcquired) {
65539
65649
  await new Promise((resolve) => setTimeout(resolve, 100));
65540
65650
  }
65541
65651
  this.#isClientAcquired = true;
@@ -65546,7 +65656,7 @@ class XrplApi {
65546
65656
  }
65547
65657
 
65548
65658
  async #acquireConnection() {
65549
- while (this.#isClientAcquired) {
65659
+ while (this.#isConnectionAcquired) {
65550
65660
  await new Promise((resolve) => setTimeout(resolve, 100));
65551
65661
  }
65552
65662
  this.#isConnectionAcquired = true;
@@ -65581,8 +65691,6 @@ class XrplApi {
65581
65691
 
65582
65692
  if (!FUNCTIONING_SERVER_STATES.includes(serverState))
65583
65693
  throw "Client might have functioning issues."
65584
-
65585
- await this.#setXrplClient(client);
65586
65694
  }
65587
65695
 
65588
65696
  async #initEventListeners(client) {
@@ -65597,6 +65705,10 @@ class XrplApi {
65597
65705
  console.log(errorCode + ': ' + errorMessage);
65598
65706
  });
65599
65707
 
65708
+ client.on('connected', async () => {
65709
+ await this.#setXrplClient(client)
65710
+ });
65711
+
65600
65712
  client.on('disconnected', async (code) => {
65601
65713
  this.#events.emit(XrplApiEvents.DISCONNECTED, code);
65602
65714
 
@@ -65698,50 +65810,51 @@ class XrplApi {
65698
65810
  });
65699
65811
  }
65700
65812
 
65701
- async #attemptFallbackServerReconnect(maxAttempts = null) {
65813
+ async #attemptFallbackServerReconnect(maxRounds, attemptsPerServer = 3) {
65702
65814
  if (!this.#fallbackServers || this.#fallbackServers?.length == 0)
65703
65815
  return;
65704
65816
 
65705
65817
  await this.#acquireClient();
65706
65818
 
65707
- let errors = {};
65708
- let attempt = 0;
65709
- retryIterator:
65710
- while (!this.#isPermanentlyDisconnected && !this.#isPrimaryServerConnected && !this.#isFallbackServerConnected) { // Keep attempting until consumer calls disconnect() manually or if the primary server is disconnected.
65711
- ++attempt;
65712
- for (const server of this.#fallbackServers) {
65713
- const client = new xrpl.Client(server, this.#xrplClientOptions);
65714
- try {
65715
- if (!this.#isPrimaryServerConnected) {
65716
- await this.#handleClientConnect(client);
65717
- this.#isFallbackServerConnected = true;
65819
+ const fallbackServers = this.#fallbackServers;
65820
+ let round = 0;
65821
+ while (!this.#isPermanentlyDisconnected && !this.#isPrimaryServerConnected && !this.#isFallbackServerConnected && (!maxRounds || round < maxRounds)) { // Keep attempting until consumer calls disconnect() manually or if the primary server is disconnected.
65822
+ ++round;
65823
+ serverIterator:
65824
+ for (let serverIndex in fallbackServers) {
65825
+ const server = fallbackServers[serverIndex];
65826
+ for (let attempt = 0; attempt < attemptsPerServer;) {
65827
+ if (this.#isPrimaryServerConnected || this.#isPermanentlyDisconnected) {
65828
+ break serverIterator;
65718
65829
  }
65719
- break retryIterator;
65720
- }
65721
- catch (e) {
65722
- this.#releaseClient();
65723
- console.log(`Error occurred while connecting to fallback server ${server}`);
65724
- await new Promise(resolve => setTimeout(resolve, 1000));
65725
- if (client.isConnected()) {
65726
- console.log('Connection closure already handled');
65727
- await client.disconnect();
65830
+ ++attempt;
65831
+ const client = new xrpl.Client(server, this.#xrplClientOptions);
65832
+ try {
65833
+ if (!this.#isPrimaryServerConnected) {
65834
+ await this.#handleClientConnect(client);
65835
+ this.#isFallbackServerConnected = true;
65836
+ }
65837
+ break serverIterator;
65728
65838
  }
65729
-
65730
- if (!this.#isPermanentlyDisconnected) {
65731
- const delaySec = 2 * attempt; // Retry with backoff delay.
65732
- if (!maxAttempts || attempt < maxAttempts)
65733
- console.log(`Fallback server ${server} connection attempt ${attempt} failed. Retrying in ${delaySec}s...`);
65734
- else {
65735
- errors[server] = { error: `Fallback server ${server} connection max attempts failed.`, exception: e };
65839
+ catch (e) {
65840
+ this.#releaseClient();
65841
+ console.log(`Error occurred while connecting to fallback server ${server}`);
65842
+ await new Promise(resolve => setTimeout(resolve, 1000));
65843
+ if (client.isConnected()) {
65844
+ console.log('Connection closure already handled');
65845
+ await client.disconnect();
65736
65846
  }
65737
65847
 
65738
- await new Promise(resolve => setTimeout(resolve, delaySec * 1000));
65848
+ if (!this.#isPermanentlyDisconnected) {
65849
+ if (!maxRounds || round < maxRounds)
65850
+ console.log(`Fallback server ${server} connection attempt ${attempt} failed. Retrying in ${2 * round}s...`);
65851
+ else
65852
+ return { error: `Fallback server ${server} connection max attempts failed.`, exception: e };
65853
+ await new Promise(resolve => setTimeout(resolve, 2 * round * 1000));
65854
+ }
65739
65855
  }
65740
65856
  }
65741
65857
  }
65742
-
65743
- if (maxAttempts && attempt >= maxAttempts)
65744
- return { error: Object.values(errors) };
65745
65858
  }
65746
65859
 
65747
65860
  return {};
@@ -65793,9 +65906,9 @@ class XrplApi {
65793
65906
  }
65794
65907
  else {
65795
65908
  if (this.#primaryServer) {
65796
- res = await Promise.all([this.#attemptPrimaryServerReconnect(1), this.#attemptFallbackServerReconnect(1)]);
65909
+ res = await Promise.all([this.#attemptPrimaryServerReconnect(1), this.#attemptFallbackServerReconnect(1, 1)]);
65797
65910
  } else {
65798
- res = [await this.#attemptFallbackServerReconnect(1)];
65911
+ res = [await this.#attemptFallbackServerReconnect(1, 1)];
65799
65912
  }
65800
65913
  }
65801
65914
 
@@ -65925,7 +66038,7 @@ class XrplApi {
65925
66038
  const info = await this.getAccountInfo(address);
65926
66039
  const accountFlags = xrpl.parseAccountRootFlags(info.Flags);
65927
66040
  const regularKey = info.RegularKey;
65928
- const derivedPubKeyAddress = UtilHelpers.deriveAddress(publicKey);
66041
+ const derivedPubKeyAddress = kp.deriveAddress(publicKey);
65929
66042
 
65930
66043
  // If the master key is disabled the derived pubkey address should be the regular key.
65931
66044
  // Otherwise it could be account address or the regular key
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.49",
9
+ "version": "0.6.51",
10
10
  "dependencies": {
11
11
  "elliptic": "6.5.4",
12
12
  "libsodium-wrappers": "0.7.10",