evernode-js-client 0.4.45 → 0.4.48
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.
- package/index.js +81 -21
- 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
|
|
11806
|
-
|
|
11807
|
-
|
|
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,40 @@ 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
|
+
try {
|
|
12065
|
+
const addrStateKey = StateHelpers.generateHostAddrStateKey(hostAddress);
|
|
12066
|
+
const addrStateIndex = StateHelpers.getHookStateIndex(this.registryAddress, addrStateKey);
|
|
12067
|
+
const addrLedgerEntry = await this.xrplApi.getLedgerEntry(addrStateIndex);
|
|
12068
|
+
const addrStateData = addrLedgerEntry?.HookStateData;
|
|
12069
|
+
if (addrStateData) {
|
|
12070
|
+
const addrStateDecoded = StateHelpers.decodeHostAddressState(Buffer.from(addrStateKey, 'hex'), Buffer.from(addrStateData, 'hex'));
|
|
12071
|
+
const curMomentStartIdx = await this.getMomentStartIndex();
|
|
12072
|
+
addrStateDecoded.active = (addrStateDecoded.lastHeartbeatLedger > (this.config.hostHeartbeatFreq * this.config.momentSize) ?
|
|
12073
|
+
(addrStateDecoded.lastHeartbeatLedger >= (curMomentStartIdx - (this.config.hostHeartbeatFreq * this.config.momentSize))) :
|
|
12074
|
+
(addrStateDecoded.lastHeartbeatLedger > 0))
|
|
12075
|
+
|
|
12076
|
+
const nftIdStatekey = StateHelpers.generateTokenIdStateKey(addrStateDecoded.nfTokenId);
|
|
12077
|
+
const nftIdStateIndex = StateHelpers.getHookStateIndex(this.registryAddress, nftIdStatekey);
|
|
12078
|
+
const nftIdLedgerEntry = await this.xrplApi.getLedgerEntry(nftIdStateIndex);
|
|
12079
|
+
|
|
12080
|
+
const nftIdStateData = nftIdLedgerEntry?.HookStateData;
|
|
12081
|
+
if (nftIdStateData) {
|
|
12082
|
+
const nftIdStateDecoded = StateHelpers.decodeTokenIdState(Buffer.from(nftIdStateData, 'hex'));
|
|
12083
|
+
return {...addrStateDecoded, ...nftIdStateDecoded};
|
|
12084
|
+
}
|
|
12085
|
+
}
|
|
12086
|
+
}
|
|
12087
|
+
catch (e) {
|
|
12088
|
+
// If the exeption is entryNotFound from Rippled there's no entry for the host, So return null.
|
|
12089
|
+
if (e?.data?.error !== 'entryNotFound')
|
|
12090
|
+
throw e;
|
|
12091
|
+
}
|
|
12092
|
+
|
|
12093
|
+
return null;
|
|
12094
|
+
}
|
|
12095
|
+
|
|
12063
12096
|
// To fetch records from host collection in Firestore database. (Pagination is applied - default page size :20)
|
|
12064
12097
|
async getHosts(filters = null, pageSize = null, nextPageToken = null) {
|
|
12065
12098
|
const hosts = await this.#firestoreHandler.getHosts(filters, pageSize, nextPageToken);
|
|
@@ -12165,9 +12198,8 @@ class HostClient extends BaseEvernodeClient {
|
|
|
12165
12198
|
// Check whether we own an evernode host token.
|
|
12166
12199
|
const nft = await this.getRegistrationNft();
|
|
12167
12200
|
if (nft) {
|
|
12168
|
-
const host = await this.
|
|
12169
|
-
|
|
12170
|
-
return host[0];
|
|
12201
|
+
const host = await this.getHostInfo();
|
|
12202
|
+
return (host?.nfTokenId == nft.NFTokenID) ? host : null;
|
|
12171
12203
|
}
|
|
12172
12204
|
|
|
12173
12205
|
return null;
|
|
@@ -12266,10 +12298,10 @@ class HostClient extends BaseEvernodeClient {
|
|
|
12266
12298
|
// from the client-side in order to complete the registration.
|
|
12267
12299
|
const regNft = await this.getRegistrationNft();
|
|
12268
12300
|
if (!regNft) {
|
|
12269
|
-
const regInfo = await this.
|
|
12270
|
-
if (regInfo
|
|
12301
|
+
const regInfo = await this.getHostInfo(this.xrplAcc.address);
|
|
12302
|
+
if (regInfo) {
|
|
12271
12303
|
const registryAcc = new XrplAccount(this.registryAddress, null, { xrplApi: this.xrplApi });
|
|
12272
|
-
const sellOffer = (await registryAcc.getNftOffers()).find(o => o.NFTokenID == regInfo
|
|
12304
|
+
const sellOffer = (await registryAcc.getNftOffers()).find(o => o.NFTokenID == regInfo.nfTokenId);
|
|
12273
12305
|
if (sellOffer) {
|
|
12274
12306
|
await this.xrplAcc.buyNft(sellOffer.index);
|
|
12275
12307
|
console.log("Registration was successfully completed after acquiring the NFT.");
|
|
@@ -12516,7 +12548,7 @@ class RegistryClient extends BaseEvernodeClient {
|
|
|
12516
12548
|
while (currentPageToken) {
|
|
12517
12549
|
nextHosts = await this.getHosts(null, null, currentPageToken);
|
|
12518
12550
|
fullHostList = fullHostList.concat(nextHosts.nextPageToken ? nextHosts.data : nextHosts);
|
|
12519
|
-
currentPageToken = nextHosts.nextPageToken;
|
|
12551
|
+
currentPageToken = nextHosts.nextPageToken;
|
|
12520
12552
|
}
|
|
12521
12553
|
} else {
|
|
12522
12554
|
fullHostList = fullHostList.concat(hosts);
|
|
@@ -12604,10 +12636,10 @@ class TenantClient extends BaseEvernodeClient {
|
|
|
12604
12636
|
throw { reason: ErrorReasons.HOST_INVALID, error: "Host is not registered." };
|
|
12605
12637
|
|
|
12606
12638
|
// Check whether active.
|
|
12607
|
-
const
|
|
12608
|
-
if (!
|
|
12639
|
+
const hostInfo = await this.getHostInfo(host.address);
|
|
12640
|
+
if (!hostInfo)
|
|
12609
12641
|
throw { reason: ErrorReasons.HOST_INVALID, error: "Host is not registered." };
|
|
12610
|
-
else if (!
|
|
12642
|
+
else if (!hostInfo.active)
|
|
12611
12643
|
throw { reason: ErrorReasons.HOST_INACTIVE, error: "Host is not active." };
|
|
12612
12644
|
|
|
12613
12645
|
return host;
|
|
@@ -12620,7 +12652,7 @@ class TenantClient extends BaseEvernodeClient {
|
|
|
12620
12652
|
|
|
12621
12653
|
// Attempt to get first available offer, if offer is not specified in options.
|
|
12622
12654
|
if (!selectedOfferIndex) {
|
|
12623
|
-
const nftOffers = EvernodeHelpers.getLeaseOffers(hostAcc);
|
|
12655
|
+
const nftOffers = await EvernodeHelpers.getLeaseOffers(hostAcc);
|
|
12624
12656
|
selectedOfferIndex = nftOffers && nftOffers[0] && nftOffers[0].index;
|
|
12625
12657
|
|
|
12626
12658
|
if (!selectedOfferIndex)
|
|
@@ -12751,7 +12783,7 @@ module.exports = {
|
|
|
12751
12783
|
/***/ ((module) => {
|
|
12752
12784
|
|
|
12753
12785
|
const DefaultValues = {
|
|
12754
|
-
registryAddress: '
|
|
12786
|
+
registryAddress: 'raaFre81618XegCrzTzVotAmarBcqNSAvK',
|
|
12755
12787
|
rippledServer: 'wss://hooks-testnet-v2.xrpl-labs.com',
|
|
12756
12788
|
xrplApi: null,
|
|
12757
12789
|
stateIndexId: 'evernodeindex'
|
|
@@ -13142,7 +13174,8 @@ module.exports = {
|
|
|
13142
13174
|
const EvernodeConstants = {
|
|
13143
13175
|
EVR: 'EVR',
|
|
13144
13176
|
NFT_PREFIX_HEX: '657672686F7374', // evrhost
|
|
13145
|
-
LEASE_NFT_PREFIX_HEX: '6576726C65617365' // evrlease
|
|
13177
|
+
LEASE_NFT_PREFIX_HEX: '6576726C65617365', // evrlease
|
|
13178
|
+
HOOK_NAMESPACE: '01EAF09326B4911554384121FF56FA8FECC215FDDE2EC35D9E59F2C53EC665A0'
|
|
13146
13179
|
}
|
|
13147
13180
|
|
|
13148
13181
|
const MemoTypes = {
|
|
@@ -13587,10 +13620,11 @@ module.exports = {
|
|
|
13587
13620
|
|
|
13588
13621
|
const codec = __nccwpck_require__(597);
|
|
13589
13622
|
const { Buffer } = __nccwpck_require__(4300);
|
|
13590
|
-
const { HookStateKeys } = __nccwpck_require__(9849);
|
|
13623
|
+
const { HookStateKeys, EvernodeConstants } = __nccwpck_require__(9849);
|
|
13591
13624
|
const { XflHelpers } = __nccwpck_require__(3243);
|
|
13625
|
+
const crypto = __nccwpck_require__(6113);
|
|
13592
13626
|
|
|
13593
|
-
const NFTOKEN_PREFIX = '
|
|
13627
|
+
const NFTOKEN_PREFIX = '00000000';
|
|
13594
13628
|
|
|
13595
13629
|
const HOST_TOKEN_ID_OFFSET = 0;
|
|
13596
13630
|
const HOST_COUNTRY_CODE_OFFSET = 32;
|
|
@@ -13618,6 +13652,7 @@ const STATE_KEY_TYPES = {
|
|
|
13618
13652
|
|
|
13619
13653
|
const EVERNODE_PREFIX = 'EVR';
|
|
13620
13654
|
const HOST_ADDR_KEY_ZERO_COUNT = 8;
|
|
13655
|
+
const HOOK_STATE_LEDGER_TYPE_PREFIX = 118; // Decimal value of ASCII 'v'
|
|
13621
13656
|
|
|
13622
13657
|
class StateHelpers {
|
|
13623
13658
|
static StateTypes = {
|
|
@@ -13645,7 +13680,7 @@ class StateHelpers {
|
|
|
13645
13680
|
static decodeTokenIdState(stateDataBuf) {
|
|
13646
13681
|
return {
|
|
13647
13682
|
address: codec.encodeAccountID(stateDataBuf.slice(HOST_ADDRESS_OFFSET, HOST_CPU_MODEL_NAME_OFFSET)),
|
|
13648
|
-
cpuModelName: stateDataBuf.slice(HOST_CPU_MODEL_NAME_OFFSET, HOST_CPU_COUNT_OFFSET).toString(),
|
|
13683
|
+
cpuModelName: stateDataBuf.slice(HOST_CPU_MODEL_NAME_OFFSET, HOST_CPU_COUNT_OFFSET).toString().replace(/\x00+$/, ''), // Remove trailing \x00 characters.
|
|
13649
13684
|
cpuCount: stateDataBuf.readUInt16BE(HOST_CPU_COUNT_OFFSET),
|
|
13650
13685
|
cpuMHz: stateDataBuf.readUInt16BE(HOST_CPU_SPEED_OFFSET),
|
|
13651
13686
|
cpuMicrosec: stateDataBuf.readUInt32BE(HOST_CPU_MICROSEC_OFFSET),
|
|
@@ -13795,6 +13830,26 @@ class StateHelpers {
|
|
|
13795
13830
|
const stateKeyBuf = Buffer.concat([Buffer.from(EVERNODE_PREFIX, "utf-8"), buf, addrBuf]);
|
|
13796
13831
|
return stateKeyBuf.toString('hex').toUpperCase();
|
|
13797
13832
|
}
|
|
13833
|
+
|
|
13834
|
+
static getHookStateIndex(hookAccount, stateKey, hookNamespace = EvernodeConstants.HOOK_NAMESPACE) {
|
|
13835
|
+
const typeBuf = Buffer.allocUnsafe(2);
|
|
13836
|
+
typeBuf.writeInt16BE(HOOK_STATE_LEDGER_TYPE_PREFIX);
|
|
13837
|
+
|
|
13838
|
+
const accIdBuf = codec.decodeAccountID(hookAccount);
|
|
13839
|
+
const stateKeyBuf = Buffer.from(stateKey, 'hex');
|
|
13840
|
+
const namespaceBuf = Buffer.from(hookNamespace, 'hex');
|
|
13841
|
+
|
|
13842
|
+
let hash = crypto.createHash('sha512');
|
|
13843
|
+
|
|
13844
|
+
let data = hash.update(typeBuf);
|
|
13845
|
+
data = hash.update(accIdBuf);
|
|
13846
|
+
data = hash.update(stateKeyBuf);
|
|
13847
|
+
data = hash.update(namespaceBuf);
|
|
13848
|
+
|
|
13849
|
+
const digest = data.digest('hex');
|
|
13850
|
+
// Get the first 32 bytes of hash.
|
|
13851
|
+
return digest.substring(0, 64).toUpperCase();
|
|
13852
|
+
}
|
|
13798
13853
|
}
|
|
13799
13854
|
|
|
13800
13855
|
module.exports = {
|
|
@@ -14757,6 +14812,11 @@ class XrplApi {
|
|
|
14757
14812
|
return [];
|
|
14758
14813
|
}
|
|
14759
14814
|
|
|
14815
|
+
async getLedgerEntry(index, options) {
|
|
14816
|
+
const resp = (await this.#client.request({ command: 'ledger_entry', index: index, ledger_index: "validated", ...options }));
|
|
14817
|
+
return resp?.result?.node;
|
|
14818
|
+
}
|
|
14819
|
+
|
|
14760
14820
|
async submitAndVerify(tx, options) {
|
|
14761
14821
|
return await this.#client.submitAndWait(tx, options);
|
|
14762
14822
|
}
|