evernode-js-client 0.4.45 → 0.4.48
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|