evernode-js-client 0.4.45 → 0.4.46

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 +63 -19
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -11716,6 +11716,7 @@ const { EventEmitter } = __nccwpck_require__(6170);
11716
11716
  const { UtilHelpers } = __nccwpck_require__(6687);
11717
11717
  const { FirestoreHandler } = __nccwpck_require__(9718);
11718
11718
  const { XflHelpers } = __nccwpck_require__(3243);
11719
+ const { StateHelpers } = __nccwpck_require__(3860);
11719
11720
 
11720
11721
  class BaseEvernodeClient {
11721
11722
 
@@ -11802,13 +11803,11 @@ class BaseEvernodeClient {
11802
11803
 
11803
11804
  async getHookStates() {
11804
11805
  const regAcc = new XrplAccount(this.registryAddress, null, { xrplApi: this.xrplApi });
11805
- const hookNamespaces = (await regAcc.getInfo())?.HookNamespaces;
11806
- if (hookNamespaces) {
11807
- const configs = await regAcc.getNamespaceEntries(hookNamespaces[0]);
11806
+ const configs = await regAcc.getNamespaceEntries(EvernodeConstants.HOOK_NAMESPACE);
11807
+
11808
+ if (configs)
11808
11809
  return configs.filter(c => c.LedgerEntryType === 'HookState').map(c => { return { key: c.HookStateKey, data: c.HookStateData } });
11809
- }
11810
11810
  return [];
11811
-
11812
11811
  }
11813
11812
 
11814
11813
  async getMoment(ledgerIndex = null) {
@@ -12060,6 +12059,24 @@ class BaseEvernodeClient {
12060
12059
  return null;
12061
12060
  }
12062
12061
 
12062
+ // To get Host details from Hook States.
12063
+ async getHostInfo(hostAddress = this.xrplAcc.address) {
12064
+ const hostAddrStatekey = StateHelpers.generateHostAddrStateKey(hostAddress);
12065
+ const stateLedgerIndex = StateHelpers.getHookStateIndex(this.registryAddress, hostAddrStatekey);
12066
+ const ledgerEntry = await this.xrplApi.getLedgerEntry(stateLedgerIndex);
12067
+ const curMomentStartIdx = await this.getMomentStartIndex();
12068
+ if (ledgerEntry?.HookStateData) {
12069
+ const hostAddrStateData = ledgerEntry.HookStateData;
12070
+ const hostInfo = StateHelpers.decodeHostAddressState(Buffer.from(hostAddrStatekey, 'hex'), Buffer.from(hostAddrStateData, 'hex'));
12071
+ hostInfo.active = (hostInfo.lastHeartbeatLedger > (this.config.hostHeartbeatFreq * this.config.momentSize) ?
12072
+ (hostInfo.lastHeartbeatLedger >= (curMomentStartIdx - (this.config.hostHeartbeatFreq * this.config.momentSize))) :
12073
+ (hostInfo.lastHeartbeatLedger > 0))
12074
+ return hostInfo;
12075
+ }
12076
+
12077
+ return null;
12078
+ }
12079
+
12063
12080
  // To fetch records from host collection in Firestore database. (Pagination is applied - default page size :20)
12064
12081
  async getHosts(filters = null, pageSize = null, nextPageToken = null) {
12065
12082
  const hosts = await this.#firestoreHandler.getHosts(filters, pageSize, nextPageToken);
@@ -12165,9 +12182,8 @@ class HostClient extends BaseEvernodeClient {
12165
12182
  // Check whether we own an evernode host token.
12166
12183
  const nft = await this.getRegistrationNft();
12167
12184
  if (nft) {
12168
- const host = await this.getHosts({ nfTokenId: nft.NFTokenID });
12169
- if (host && host.length == 1)
12170
- return host[0];
12185
+ const host = await this.getHostInfo();
12186
+ return (host?.nfTokenId == nft.NFTokenID) ? host : null;
12171
12187
  }
12172
12188
 
12173
12189
  return null;
@@ -12266,10 +12282,10 @@ class HostClient extends BaseEvernodeClient {
12266
12282
  // from the client-side in order to complete the registration.
12267
12283
  const regNft = await this.getRegistrationNft();
12268
12284
  if (!regNft) {
12269
- const regInfo = await this.getHosts({ address: this.xrplAcc.address });
12270
- if (regInfo.length !== 0) {
12285
+ const regInfo = await this.getHostInfo(this.xrplAcc.address);
12286
+ if (regInfo) {
12271
12287
  const registryAcc = new XrplAccount(this.registryAddress, null, { xrplApi: this.xrplApi });
12272
- const sellOffer = (await registryAcc.getNftOffers()).find(o => o.NFTokenID == regInfo[0].nfTokenId);
12288
+ const sellOffer = (await registryAcc.getNftOffers()).find(o => o.NFTokenID == regInfo.nfTokenId);
12273
12289
  if (sellOffer) {
12274
12290
  await this.xrplAcc.buyNft(sellOffer.index);
12275
12291
  console.log("Registration was successfully completed after acquiring the NFT.");
@@ -12516,7 +12532,7 @@ class RegistryClient extends BaseEvernodeClient {
12516
12532
  while (currentPageToken) {
12517
12533
  nextHosts = await this.getHosts(null, null, currentPageToken);
12518
12534
  fullHostList = fullHostList.concat(nextHosts.nextPageToken ? nextHosts.data : nextHosts);
12519
- currentPageToken = nextHosts.nextPageToken;
12535
+ currentPageToken = nextHosts.nextPageToken;
12520
12536
  }
12521
12537
  } else {
12522
12538
  fullHostList = fullHostList.concat(hosts);
@@ -12604,10 +12620,10 @@ class TenantClient extends BaseEvernodeClient {
12604
12620
  throw { reason: ErrorReasons.HOST_INVALID, error: "Host is not registered." };
12605
12621
 
12606
12622
  // Check whether active.
12607
- const hosts = await this.getHosts({ address: host.address });
12608
- if (!hosts || !hosts.length)
12623
+ const hostInfo = await this.getHostInfo(host.address);
12624
+ if (hostInfo)
12609
12625
  throw { reason: ErrorReasons.HOST_INVALID, error: "Host is not registered." };
12610
- else if (!hosts[0].active)
12626
+ else if (hostInfo.active)
12611
12627
  throw { reason: ErrorReasons.HOST_INACTIVE, error: "Host is not active." };
12612
12628
 
12613
12629
  return host;
@@ -12620,7 +12636,7 @@ class TenantClient extends BaseEvernodeClient {
12620
12636
 
12621
12637
  // Attempt to get first available offer, if offer is not specified in options.
12622
12638
  if (!selectedOfferIndex) {
12623
- const nftOffers = EvernodeHelpers.getLeaseOffers(hostAcc);
12639
+ const nftOffers = await EvernodeHelpers.getLeaseOffers(hostAcc);
12624
12640
  selectedOfferIndex = nftOffers && nftOffers[0] && nftOffers[0].index;
12625
12641
 
12626
12642
  if (!selectedOfferIndex)
@@ -12751,7 +12767,7 @@ module.exports = {
12751
12767
  /***/ ((module) => {
12752
12768
 
12753
12769
  const DefaultValues = {
12754
- registryAddress: 'rDPqJv7zu6DfeXexAYseABNM2hT2j2rpHv',
12770
+ registryAddress: 'raaFre81618XegCrzTzVotAmarBcqNSAvK',
12755
12771
  rippledServer: 'wss://hooks-testnet-v2.xrpl-labs.com',
12756
12772
  xrplApi: null,
12757
12773
  stateIndexId: 'evernodeindex'
@@ -13142,7 +13158,8 @@ module.exports = {
13142
13158
  const EvernodeConstants = {
13143
13159
  EVR: 'EVR',
13144
13160
  NFT_PREFIX_HEX: '657672686F7374', // evrhost
13145
- LEASE_NFT_PREFIX_HEX: '6576726C65617365' // evrlease
13161
+ LEASE_NFT_PREFIX_HEX: '6576726C65617365', // evrlease
13162
+ HOOK_NAMESPACE: '01EAF09326B4911554384121FF56FA8FECC215FDDE2EC35D9E59F2C53EC665A0'
13146
13163
  }
13147
13164
 
13148
13165
  const MemoTypes = {
@@ -13587,8 +13604,9 @@ module.exports = {
13587
13604
 
13588
13605
  const codec = __nccwpck_require__(597);
13589
13606
  const { Buffer } = __nccwpck_require__(4300);
13590
- const { HookStateKeys } = __nccwpck_require__(9849);
13607
+ const { HookStateKeys, EvernodeConstants } = __nccwpck_require__(9849);
13591
13608
  const { XflHelpers } = __nccwpck_require__(3243);
13609
+ const crypto = __nccwpck_require__(6113);
13592
13610
 
13593
13611
  const NFTOKEN_PREFIX = '00080000';
13594
13612
 
@@ -13618,6 +13636,7 @@ const STATE_KEY_TYPES = {
13618
13636
 
13619
13637
  const EVERNODE_PREFIX = 'EVR';
13620
13638
  const HOST_ADDR_KEY_ZERO_COUNT = 8;
13639
+ const HOOK_STATE_LEDGER_TYPE_PREFIX = 118; // Decimal value of ASCII 'v'
13621
13640
 
13622
13641
  class StateHelpers {
13623
13642
  static StateTypes = {
@@ -13795,6 +13814,26 @@ class StateHelpers {
13795
13814
  const stateKeyBuf = Buffer.concat([Buffer.from(EVERNODE_PREFIX, "utf-8"), buf, addrBuf]);
13796
13815
  return stateKeyBuf.toString('hex').toUpperCase();
13797
13816
  }
13817
+
13818
+ static getHookStateIndex(hookAccount, stateKey, hookNamespace = EvernodeConstants.HOOK_NAMESPACE) {
13819
+ const typeBuf = Buffer.allocUnsafe(2);
13820
+ typeBuf.writeInt16BE(HOOK_STATE_LEDGER_TYPE_PREFIX);
13821
+
13822
+ const accIdBuf = codec.decodeAccountID(hookAccount);
13823
+ const stateKeyBuf = Buffer.from(stateKey, 'hex');
13824
+ const namespaceBuf = Buffer.from(hookNamespace, 'hex');
13825
+
13826
+ let hash = crypto.createHash('sha512');
13827
+
13828
+ let data = hash.update(typeBuf);
13829
+ data = hash.update(accIdBuf);
13830
+ data = hash.update(stateKeyBuf);
13831
+ data = hash.update(namespaceBuf);
13832
+
13833
+ const digest = data.digest('hex');
13834
+ // Get the first 32 bytes of hash.
13835
+ return digest.substring(0, 64).toUpperCase();
13836
+ }
13798
13837
  }
13799
13838
 
13800
13839
  module.exports = {
@@ -14757,6 +14796,11 @@ class XrplApi {
14757
14796
  return [];
14758
14797
  }
14759
14798
 
14799
+ async getLedgerEntry(index, options) {
14800
+ const resp = (await this.#client.request({ command: 'ledger_entry', index: index, ledger_index: "validated", ...options }));
14801
+ return resp?.result?.node;
14802
+ }
14803
+
14760
14804
  async submitAndVerify(tx, options) {
14761
14805
  return await this.#client.submitAndWait(tx, options);
14762
14806
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evernode-js-client",
3
- "version": "0.4.45",
3
+ "version": "0.4.46",
4
4
  "dependencies": {
5
5
  "elliptic": "6.5.4",
6
6
  "ripple-address-codec": "4.2.0",