evernode-js-client 0.4.45 → 0.4.46

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