evernode-js-client 0.5.8 → 0.5.10
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 +281 -49
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -11732,6 +11732,7 @@ const { EventEmitter } = __nccwpck_require__(6170);
|
|
|
11732
11732
|
const { UtilHelpers } = __nccwpck_require__(6687);
|
|
11733
11733
|
const { FirestoreHandler } = __nccwpck_require__(9718);
|
|
11734
11734
|
const { StateHelpers } = __nccwpck_require__(3860);
|
|
11735
|
+
const { EvernodeHelpers } = __nccwpck_require__(2523);
|
|
11735
11736
|
|
|
11736
11737
|
class BaseEvernodeClient {
|
|
11737
11738
|
|
|
@@ -11905,7 +11906,8 @@ class BaseEvernodeClient {
|
|
|
11905
11906
|
rewardInfo: HookStateKeys.REWARD_INFO,
|
|
11906
11907
|
rewardConfiguration: HookStateKeys.REWARD_CONFIGURATION,
|
|
11907
11908
|
hostCount: HookStateKeys.HOST_COUNT,
|
|
11908
|
-
momentTransitInfo: HookStateKeys.MOMENT_TRANSIT_INFO
|
|
11909
|
+
momentTransitInfo: HookStateKeys.MOMENT_TRANSIT_INFO,
|
|
11910
|
+
registryMaxTrxEmitFee: HookStateKeys.MAX_TRX_EMISSION_FEE
|
|
11909
11911
|
}
|
|
11910
11912
|
let config = {};
|
|
11911
11913
|
for (const [key, value] of Object.entries(configStateKeys)) {
|
|
@@ -12036,17 +12038,13 @@ class BaseEvernodeClient {
|
|
|
12036
12038
|
}
|
|
12037
12039
|
}
|
|
12038
12040
|
else if (tx.Memos.length >= 1 &&
|
|
12039
|
-
tx.Memos[0].type === MemoTypes.HOST_REG && tx.Memos[0].format === MemoFormats.
|
|
12041
|
+
tx.Memos[0].type === MemoTypes.HOST_REG && tx.Memos[0].format === MemoFormats.HEX && tx.Memos[0].data) {
|
|
12040
12042
|
|
|
12041
|
-
const parts = tx.Memos[0].data.split(';');
|
|
12042
12043
|
return {
|
|
12043
12044
|
name: EvernodeEvents.HostRegistered,
|
|
12044
12045
|
data: {
|
|
12045
12046
|
transaction: tx,
|
|
12046
|
-
host: tx.Account
|
|
12047
|
-
token: parts[0],
|
|
12048
|
-
instanceSize: parts[1],
|
|
12049
|
-
location: parts[2]
|
|
12047
|
+
host: tx.Account
|
|
12050
12048
|
}
|
|
12051
12049
|
}
|
|
12052
12050
|
}
|
|
@@ -12134,17 +12132,13 @@ class BaseEvernodeClient {
|
|
|
12134
12132
|
}
|
|
12135
12133
|
}
|
|
12136
12134
|
else if (tx.Memos.length >= 1 &&
|
|
12137
|
-
tx.Memos[0].type === MemoTypes.HOST_UPDATE_INFO && tx.Memos[0].format === MemoFormats.
|
|
12138
|
-
|
|
12139
|
-
const specs = tx.Memos[0].data.split(';');
|
|
12135
|
+
tx.Memos[0].type === MemoTypes.HOST_UPDATE_INFO && tx.Memos[0].format === MemoFormats.HEX && tx.Memos[0].data) {
|
|
12140
12136
|
|
|
12141
12137
|
return {
|
|
12142
12138
|
name: EvernodeEvents.HostRegUpdated,
|
|
12143
12139
|
data: {
|
|
12144
12140
|
transaction: tx,
|
|
12145
|
-
host: tx.Account
|
|
12146
|
-
version: specs[specs.length - 1],
|
|
12147
|
-
specs: specs,
|
|
12141
|
+
host: tx.Account
|
|
12148
12142
|
}
|
|
12149
12143
|
}
|
|
12150
12144
|
}
|
|
@@ -12237,13 +12231,16 @@ class BaseEvernodeClient {
|
|
|
12237
12231
|
async getHosts(filters = null, pageSize = null, nextPageToken = null) {
|
|
12238
12232
|
const hosts = await this.#firestoreHandler.getHosts(filters, pageSize, nextPageToken);
|
|
12239
12233
|
const curMomentStartIdx = await this.getMomentStartIndex();
|
|
12240
|
-
|
|
12241
|
-
(hosts.nextPageToken ? hosts.data : hosts).
|
|
12242
|
-
|
|
12243
|
-
|
|
12244
|
-
|
|
12245
|
-
|
|
12246
|
-
|
|
12234
|
+
|
|
12235
|
+
return await Promise.all((hosts.nextPageToken ? hosts.data : hosts).map(async host => {
|
|
12236
|
+
const hostAcc = new XrplAccount(host.address);
|
|
12237
|
+
host.domain = await hostAcc.getDomain();
|
|
12238
|
+
|
|
12239
|
+
host.active = (host.lastHeartbeatIndex > (this.config.hostHeartbeatFreq * this.config.momentSize) ?
|
|
12240
|
+
(host.lastHeartbeatIndex >= (curMomentStartIdx - (this.config.hostHeartbeatFreq * this.config.momentSize))) :
|
|
12241
|
+
(host.lastHeartbeatIndex > 0));
|
|
12242
|
+
return host;
|
|
12243
|
+
}));
|
|
12247
12244
|
}
|
|
12248
12245
|
|
|
12249
12246
|
/**
|
|
@@ -12303,11 +12300,28 @@ class BaseEvernodeClient {
|
|
|
12303
12300
|
let memoData = Buffer.allocUnsafe(20);
|
|
12304
12301
|
codec.decodeAccountID(hostAddress).copy(memoData);
|
|
12305
12302
|
|
|
12306
|
-
|
|
12307
|
-
|
|
12308
|
-
|
|
12309
|
-
|
|
12310
|
-
|
|
12303
|
+
// To obtain registration NFT Page Keylet and index.
|
|
12304
|
+
const hostAcc = new XrplAccount(hostAddress, null, { xrplApi: this.xrplApi });
|
|
12305
|
+
const regNFT = (await hostAcc.getNfts()).find(n => n.URI.startsWith(EvernodeConstants.NFT_PREFIX_HEX) && n.Issuer === this.registryAddress);
|
|
12306
|
+
if (regNFT) {
|
|
12307
|
+
// Check whether the token was actually issued from Evernode registry contract.
|
|
12308
|
+
const issuerHex = regNFT.NFTokenID.substr(8, 40);
|
|
12309
|
+
const issuerAddr = codec.encodeAccountID(Buffer.from(issuerHex, 'hex'));
|
|
12310
|
+
if (issuerAddr == this.registryAddress) {
|
|
12311
|
+
const nftPageDataBuf = await EvernodeHelpers.getNFTPageAndLocation(regNFT.NFTokenID, hostAcc, this.xrplApi);
|
|
12312
|
+
|
|
12313
|
+
await this.xrplAcc.makePayment(this.registryAddress,
|
|
12314
|
+
XrplConstants.MIN_XRP_AMOUNT,
|
|
12315
|
+
XrplConstants.XRP,
|
|
12316
|
+
null,
|
|
12317
|
+
[
|
|
12318
|
+
{ type: MemoTypes.DEAD_HOST_PRUNE, format: MemoFormats.HEX, data: memoData.toString('hex') },
|
|
12319
|
+
{ type: MemoTypes.HOST_REGISTRY_REF, format: MemoFormats.HEX, data: nftPageDataBuf.toString('hex') }
|
|
12320
|
+
]);
|
|
12321
|
+
} else
|
|
12322
|
+
throw "Invalid Registration NFT."
|
|
12323
|
+
} else
|
|
12324
|
+
throw "No Registration NFT was found for the Host account."
|
|
12311
12325
|
|
|
12312
12326
|
}
|
|
12313
12327
|
}
|
|
@@ -12340,6 +12354,29 @@ const HostEvents = {
|
|
|
12340
12354
|
ExtendLease: EvernodeEvents.ExtendLease
|
|
12341
12355
|
}
|
|
12342
12356
|
|
|
12357
|
+
const HOST_COUNTRY_CODE_MEMO_OFFSET = 0;
|
|
12358
|
+
const HOST_CPU_MICROSEC_MEMO_OFFSET = 2;
|
|
12359
|
+
const HOST_RAM_MB_MEMO_OFFSET = 6;
|
|
12360
|
+
const HOST_DISK_MB_MEMO_OFFSET = 10;
|
|
12361
|
+
const HOST_TOT_INS_COUNT_MEMO_OFFSET = 14;
|
|
12362
|
+
const HOST_CPU_MODEL_NAME_MEMO_OFFSET = 18;
|
|
12363
|
+
const HOST_CPU_COUNT_MEMO_OFFSET = 58;
|
|
12364
|
+
const HOST_CPU_SPEED_MEMO_OFFSET = 60;
|
|
12365
|
+
const HOST_DESCRIPTION_MEMO_OFFSET = 62;
|
|
12366
|
+
const HOST_EMAIL_ADDRESS_MEMO_OFFSET = 88;
|
|
12367
|
+
const HOST_REG_MEMO_SIZE = 128;
|
|
12368
|
+
|
|
12369
|
+
const HOST_UPDATE_TOKEN_ID_MEMO_OFFSET = 0;
|
|
12370
|
+
const HOST_UPDATE_COUNTRY_CODE_MEMO_OFFSET = 32;
|
|
12371
|
+
const HOST_UPDATE_CPU_MICROSEC_MEMO_OFFSET = 34;
|
|
12372
|
+
const HOST_UPDATE_RAM_MB_MEMO_OFFSET = 38;
|
|
12373
|
+
const HOST_UPDATE_DISK_MB_MEMO_OFFSET = 42;
|
|
12374
|
+
const HOST_UPDATE_TOT_INS_COUNT_MEMO_OFFSET = 46;
|
|
12375
|
+
const HOST_UPDATE_ACT_INS_COUNT_MEMO_OFFSET = 50;
|
|
12376
|
+
const HOST_UPDATE_DESCRIPTION_MEMO_OFFSET = 54;
|
|
12377
|
+
const HOST_UPDATE_VERSION_MEMO_OFFSET = 80;
|
|
12378
|
+
const HOST_UPDATE_MEMO_SIZE = 83;
|
|
12379
|
+
|
|
12343
12380
|
class HostClient extends BaseEvernodeClient {
|
|
12344
12381
|
|
|
12345
12382
|
constructor(xrpAddress, xrpSecret, options = {}) {
|
|
@@ -12459,8 +12496,8 @@ class HostClient extends BaseEvernodeClient {
|
|
|
12459
12496
|
throw "description should consist of 0-26 ascii characters except ';'";
|
|
12460
12497
|
|
|
12461
12498
|
else if (!emailAddress || !(/[a-z0-9]+@[a-z]+.[a-z]{2,3}/.test(emailAddress)) || (emailAddress.length > 40))
|
|
12462
|
-
throw "Email address should be valid and can not have more than 40 characters.";
|
|
12463
|
-
|
|
12499
|
+
throw "Email address should be valid and can not have more than 40 characters.";
|
|
12500
|
+
|
|
12464
12501
|
if (await this.isRegistered())
|
|
12465
12502
|
throw "Host already registered.";
|
|
12466
12503
|
|
|
@@ -12500,12 +12537,24 @@ class HostClient extends BaseEvernodeClient {
|
|
|
12500
12537
|
console.log("No initiated transfers were found.");
|
|
12501
12538
|
}
|
|
12502
12539
|
|
|
12503
|
-
|
|
12540
|
+
// <country_code(2)><cpu_microsec(4)><ram_mb(4)><disk_mb(4)><no_of_total_instances(4)><cpu_model(40)><cpu_count(2)><cpu_speed(2)><description(26)><email_address(40)>
|
|
12541
|
+
const memoBuf = Buffer.alloc(HOST_REG_MEMO_SIZE, 0);
|
|
12542
|
+
Buffer.from(countryCode.substr(0, 2), "utf-8").copy(memoBuf, HOST_COUNTRY_CODE_MEMO_OFFSET);
|
|
12543
|
+
memoBuf.writeUInt32BE(cpuMicroSec, HOST_CPU_MICROSEC_MEMO_OFFSET);
|
|
12544
|
+
memoBuf.writeUInt32BE(ramMb, HOST_RAM_MB_MEMO_OFFSET);
|
|
12545
|
+
memoBuf.writeUInt32BE(diskMb, HOST_DISK_MB_MEMO_OFFSET);
|
|
12546
|
+
memoBuf.writeUInt32BE(totalInstanceCount, HOST_TOT_INS_COUNT_MEMO_OFFSET);
|
|
12547
|
+
Buffer.from(cpuModel.substr(0, 40), "utf-8").copy(memoBuf, HOST_CPU_MODEL_NAME_MEMO_OFFSET);
|
|
12548
|
+
memoBuf.writeUInt16BE(cpuCount, HOST_CPU_COUNT_MEMO_OFFSET);
|
|
12549
|
+
memoBuf.writeUInt16BE(cpuSpeed, HOST_CPU_SPEED_MEMO_OFFSET);
|
|
12550
|
+
Buffer.from(description.substr(0, 26), "utf-8").copy(memoBuf, HOST_DESCRIPTION_MEMO_OFFSET);
|
|
12551
|
+
Buffer.from(emailAddress.substr(0, 40), "utf-8").copy(memoBuf, HOST_EMAIL_ADDRESS_MEMO_OFFSET);
|
|
12552
|
+
|
|
12504
12553
|
const tx = await this.xrplAcc.makePayment(this.registryAddress,
|
|
12505
12554
|
(transferredNFTokenId) ? EvernodeConstants.NOW_IN_EVRS : this.config.hostRegFee.toString(),
|
|
12506
12555
|
EvernodeConstants.EVR,
|
|
12507
12556
|
this.config.evrIssuerAddress,
|
|
12508
|
-
[{ type: MemoTypes.HOST_REG, format: MemoFormats.
|
|
12557
|
+
[{ type: MemoTypes.HOST_REG, format: MemoFormats.HEX, data: memoBuf.toString('hex') }],
|
|
12509
12558
|
options.transactionOptions);
|
|
12510
12559
|
|
|
12511
12560
|
console.log('Waiting for the sell offer')
|
|
@@ -12550,11 +12599,18 @@ class HostClient extends BaseEvernodeClient {
|
|
|
12550
12599
|
throw "Host not registered."
|
|
12551
12600
|
|
|
12552
12601
|
const regNFT = await this.getRegistrationNft();
|
|
12602
|
+
|
|
12603
|
+
// To obtain registration NFT Page Keylet and index.
|
|
12604
|
+
const nftPageDataBuf = await EvernodeHelpers.getNFTPageAndLocation(regNFT.NFTokenID, this.xrplAcc, this.xrplApi);
|
|
12605
|
+
|
|
12553
12606
|
await this.xrplAcc.makePayment(this.registryAddress,
|
|
12554
12607
|
XrplConstants.MIN_XRP_AMOUNT,
|
|
12555
12608
|
XrplConstants.XRP,
|
|
12556
12609
|
null,
|
|
12557
|
-
[
|
|
12610
|
+
[
|
|
12611
|
+
{ type: MemoTypes.HOST_DEREG, format: MemoFormats.HEX, data: regNFT.NFTokenID },
|
|
12612
|
+
{ type: MemoTypes.HOST_REGISTRY_REF, format: MemoFormats.HEX, data: nftPageDataBuf.toString('hex') }
|
|
12613
|
+
],
|
|
12558
12614
|
options.transactionOptions);
|
|
12559
12615
|
|
|
12560
12616
|
console.log('Waiting for the buy offer')
|
|
@@ -12593,21 +12649,62 @@ class HostClient extends BaseEvernodeClient {
|
|
|
12593
12649
|
}
|
|
12594
12650
|
|
|
12595
12651
|
async updateRegInfo(activeInstanceCount = null, version = null, totalInstanceCount = null, tokenID = null, countryCode = null, cpuMicroSec = null, ramMb = null, diskMb = null, description = null, options = {}) {
|
|
12596
|
-
|
|
12652
|
+
// <token_id(32)><country_code(2)><cpu_microsec(4)><ram_mb(4)><disk_mb(4)><total_instance_count(4)><active_instances(4)><description(26)><version(3)>
|
|
12653
|
+
const memoBuf = Buffer.alloc(HOST_UPDATE_MEMO_SIZE, 0);
|
|
12654
|
+
if (tokenID)
|
|
12655
|
+
Buffer.from(tokenID.substr(0, 32), "hex").copy(memoBuf, HOST_UPDATE_TOKEN_ID_MEMO_OFFSET);
|
|
12656
|
+
if (countryCode)
|
|
12657
|
+
Buffer.from(countryCode.substr(0, 2), "utf-8").copy(memoBuf, HOST_UPDATE_COUNTRY_CODE_MEMO_OFFSET);
|
|
12658
|
+
if (cpuMicroSec)
|
|
12659
|
+
memoBuf.writeUInt32BE(cpuMicroSec, HOST_UPDATE_CPU_MICROSEC_MEMO_OFFSET);
|
|
12660
|
+
if (ramMb)
|
|
12661
|
+
memoBuf.writeUInt32BE(ramMb, HOST_UPDATE_RAM_MB_MEMO_OFFSET);
|
|
12662
|
+
if (diskMb)
|
|
12663
|
+
memoBuf.writeUInt32BE(diskMb, HOST_UPDATE_DISK_MB_MEMO_OFFSET);
|
|
12664
|
+
if (totalInstanceCount)
|
|
12665
|
+
memoBuf.writeUInt32BE(totalInstanceCount, HOST_UPDATE_TOT_INS_COUNT_MEMO_OFFSET);
|
|
12666
|
+
if (activeInstanceCount)
|
|
12667
|
+
memoBuf.writeUInt32BE(activeInstanceCount, HOST_UPDATE_ACT_INS_COUNT_MEMO_OFFSET);
|
|
12668
|
+
if (description)
|
|
12669
|
+
Buffer.from(description.substr(0, 26), "utf-8").copy(memoBuf, HOST_UPDATE_DESCRIPTION_MEMO_OFFSET);
|
|
12670
|
+
if (version) {
|
|
12671
|
+
const components = version.split('.').map(v => parseInt(v));
|
|
12672
|
+
if (components.length != 3)
|
|
12673
|
+
throw 'Invalid version format.';
|
|
12674
|
+
memoBuf.writeUInt8(components[0], HOST_UPDATE_VERSION_MEMO_OFFSET);
|
|
12675
|
+
memoBuf.writeUInt8(components[1], HOST_UPDATE_VERSION_MEMO_OFFSET + 1);
|
|
12676
|
+
memoBuf.writeUInt8(components[2], HOST_UPDATE_VERSION_MEMO_OFFSET + 2);
|
|
12677
|
+
}
|
|
12678
|
+
|
|
12679
|
+
// To obtain registration NFT Page Keylet and index.
|
|
12680
|
+
if (!tokenID)
|
|
12681
|
+
tokenID = (await this.getRegistrationNft()).NFTokenID;
|
|
12682
|
+
const nftPageDataBuf = await EvernodeHelpers.getNFTPageAndLocation(tokenID, this.xrplAcc, this.xrplApi);
|
|
12683
|
+
|
|
12597
12684
|
return await this.xrplAcc.makePayment(this.registryAddress,
|
|
12598
12685
|
XrplConstants.MIN_XRP_AMOUNT,
|
|
12599
12686
|
XrplConstants.XRP,
|
|
12600
12687
|
null,
|
|
12601
|
-
[
|
|
12688
|
+
[
|
|
12689
|
+
{ type: MemoTypes.HOST_UPDATE_INFO, format: MemoFormats.HEX, data: memoBuf.toString('hex') },
|
|
12690
|
+
{ type: MemoTypes.HOST_REGISTRY_REF, format: MemoFormats.HEX, data: nftPageDataBuf.toString('hex') }
|
|
12691
|
+
],
|
|
12602
12692
|
options.transactionOptions);
|
|
12603
12693
|
}
|
|
12604
12694
|
|
|
12605
12695
|
async heartbeat(options = {}) {
|
|
12696
|
+
// To obtain registration NFT Page Keylet and index.
|
|
12697
|
+
const regNFT = await this.getRegistrationNft();
|
|
12698
|
+
const nftPageDataBuf = await EvernodeHelpers.getNFTPageAndLocation(regNFT.NFTokenID, this.xrplAcc, this.xrplApi);
|
|
12699
|
+
|
|
12606
12700
|
return this.xrplAcc.makePayment(this.registryAddress,
|
|
12607
12701
|
XrplConstants.MIN_XRP_AMOUNT,
|
|
12608
12702
|
XrplConstants.XRP,
|
|
12609
12703
|
null,
|
|
12610
|
-
[
|
|
12704
|
+
[
|
|
12705
|
+
{ type: MemoTypes.HEARTBEAT, format: "", data: "" },
|
|
12706
|
+
{ type: MemoTypes.HOST_REGISTRY_REF, format: MemoFormats.HEX, data: nftPageDataBuf.toString('hex') }
|
|
12707
|
+
],
|
|
12611
12708
|
options.transactionOptions);
|
|
12612
12709
|
}
|
|
12613
12710
|
|
|
@@ -12691,11 +12788,19 @@ class HostClient extends BaseEvernodeClient {
|
|
|
12691
12788
|
}
|
|
12692
12789
|
|
|
12693
12790
|
async requestRebate(options = {}) {
|
|
12791
|
+
|
|
12792
|
+
// To obtain registration NFT Page Keylet and index.
|
|
12793
|
+
const regNFT = await this.getRegistrationNft();
|
|
12794
|
+
const nftPageDataBuf = await EvernodeHelpers.getNFTPageAndLocation(regNFT.NFTokenID, this.xrplAcc, this.xrplApi);
|
|
12795
|
+
|
|
12694
12796
|
return this.xrplAcc.makePayment(this.registryAddress,
|
|
12695
12797
|
XrplConstants.MIN_XRP_AMOUNT,
|
|
12696
12798
|
XrplConstants.XRP,
|
|
12697
12799
|
null,
|
|
12698
|
-
[
|
|
12800
|
+
[
|
|
12801
|
+
{ type: MemoTypes.HOST_REBATE, format: "", data: "" },
|
|
12802
|
+
{ type: MemoTypes.HOST_REGISTRY_REF, format: MemoFormats.HEX, data: nftPageDataBuf.toString('hex') }
|
|
12803
|
+
],
|
|
12699
12804
|
options.transactionOptions);
|
|
12700
12805
|
}
|
|
12701
12806
|
|
|
@@ -12726,16 +12831,21 @@ class HostClient extends BaseEvernodeClient {
|
|
|
12726
12831
|
}
|
|
12727
12832
|
}
|
|
12728
12833
|
|
|
12729
|
-
const regNFT = (await this.xrplAcc.getNfts()).find(n => n.URI.startsWith(EvernodeConstants.NFT_PREFIX_HEX) && n.Issuer === this.registryAddress);
|
|
12730
|
-
|
|
12731
12834
|
let memoData = Buffer.allocUnsafe(20);
|
|
12732
12835
|
codec.decodeAccountID(transfereeAddress).copy(memoData);
|
|
12733
12836
|
|
|
12837
|
+
// To obtain registration NFT Page Keylet and index.
|
|
12838
|
+
const regNFT = await this.getRegistrationNft();
|
|
12839
|
+
const nftPageDataBuf = await EvernodeHelpers.getNFTPageAndLocation(regNFT.NFTokenID, this.xrplAcc, this.xrplApi);
|
|
12840
|
+
|
|
12734
12841
|
await this.xrplAcc.makePayment(this.registryAddress,
|
|
12735
12842
|
XrplConstants.MIN_XRP_AMOUNT,
|
|
12736
12843
|
XrplConstants.XRP,
|
|
12737
12844
|
null,
|
|
12738
|
-
[
|
|
12845
|
+
[
|
|
12846
|
+
{ type: MemoTypes.HOST_TRANSFER, format: MemoFormats.HEX, data: memoData.toString('hex') },
|
|
12847
|
+
{ type: MemoTypes.HOST_REGISTRY_REF, format: MemoFormats.HEX, data: nftPageDataBuf.toString('hex') }
|
|
12848
|
+
],
|
|
12739
12849
|
options.transactionOptions);
|
|
12740
12850
|
|
|
12741
12851
|
let offer = null;
|
|
@@ -12767,6 +12877,19 @@ class HostClient extends BaseEvernodeClient {
|
|
|
12767
12877
|
|
|
12768
12878
|
await this.xrplAcc.sellNft(offer.index);
|
|
12769
12879
|
}
|
|
12880
|
+
|
|
12881
|
+
async hasPendingTransfer() {
|
|
12882
|
+
|
|
12883
|
+
// Check the availability of TRANSFEREE state for this host address.
|
|
12884
|
+
const stateTransfereeAddrKey = StateHelpers.generateTransfereeAddrStateKey(this.xrplAcc.address);
|
|
12885
|
+
const stateTransfereeAddrIndex = StateHelpers.getHookStateIndex(this.registryAddress, stateTransfereeAddrKey);
|
|
12886
|
+
const res = await this.xrplApi.getLedgerEntry(stateTransfereeAddrIndex);
|
|
12887
|
+
|
|
12888
|
+
if (res && res?.HookStateData)
|
|
12889
|
+
return true;
|
|
12890
|
+
|
|
12891
|
+
return false;
|
|
12892
|
+
}
|
|
12770
12893
|
}
|
|
12771
12894
|
|
|
12772
12895
|
module.exports = {
|
|
@@ -13593,7 +13716,8 @@ const MemoTypes = {
|
|
|
13593
13716
|
REFUND: 'evnRefund',
|
|
13594
13717
|
REFUND_REF: 'evnRefundRef',
|
|
13595
13718
|
DEAD_HOST_PRUNE: 'evnDeadHostPrune',
|
|
13596
|
-
HOST_REBATE: 'evnHostRebate'
|
|
13719
|
+
HOST_REBATE: 'evnHostRebate',
|
|
13720
|
+
HOST_REGISTRY_REF: 'evnHostRegistryRef'
|
|
13597
13721
|
}
|
|
13598
13722
|
|
|
13599
13723
|
const MemoFormats = {
|
|
@@ -13634,6 +13758,8 @@ const HookStateKeys = {
|
|
|
13634
13758
|
REWARD_CONFIGURATION: "4556520100000000000000000000000000000000000000000000000000000009",
|
|
13635
13759
|
MAX_TOLERABLE_DOWNTIME: "455652010000000000000000000000000000000000000000000000000000000A",
|
|
13636
13760
|
MOMENT_TRANSIT_INFO: "455652010000000000000000000000000000000000000000000000000000000B",
|
|
13761
|
+
MAX_TRX_EMISSION_FEE: "455652010000000000000000000000000000000000000000000000000000000C",
|
|
13762
|
+
|
|
13637
13763
|
|
|
13638
13764
|
// Singleton
|
|
13639
13765
|
HOST_COUNT: "4556523200000000000000000000000000000000000000000000000000000000",
|
|
@@ -13683,6 +13809,7 @@ module.exports = {
|
|
|
13683
13809
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
|
13684
13810
|
|
|
13685
13811
|
const { EvernodeConstants } = __nccwpck_require__(9849);
|
|
13812
|
+
const NFT_PAGE_LEDGER_ENTRY_TYPE_HEX = '0050';
|
|
13686
13813
|
|
|
13687
13814
|
class EvernodeHelpers {
|
|
13688
13815
|
static async getLeaseOffers(xrplAcc) {
|
|
@@ -13691,6 +13818,36 @@ class EvernodeHelpers {
|
|
|
13691
13818
|
const nftOffers = (await xrplAcc.getNftOffers())?.filter(offer => (offer.Flags == 1 && hostTokenIDs.includes(offer.NFTokenID))); // Filter only sell offers
|
|
13692
13819
|
return nftOffers;
|
|
13693
13820
|
}
|
|
13821
|
+
|
|
13822
|
+
static async getNFTPageAndLocation(nfTokenId, xrplAcc, xrplApi, buffer = true) {
|
|
13823
|
+
|
|
13824
|
+
const nftPageApprxKeylet = xrplAcc.generateKeylet('nftPage', { nfTokenId: nfTokenId });
|
|
13825
|
+
const nftPageMaxKeylet = xrplAcc.generateKeylet('nftPageMax');
|
|
13826
|
+
// Index is the last 32 bytes of the Keylet (Last 64 HEX characters).
|
|
13827
|
+
let page = await xrplApi.getLedgerEntry(nftPageMaxKeylet.substring(4, 68));
|
|
13828
|
+
while (page?.PreviousPageMin) {
|
|
13829
|
+
// Compare the low 96 bits. (Last 24 HEX characters).
|
|
13830
|
+
if (Number('0x' + page.index.substring(40, 64)) >= Number('0x' + nftPageApprxKeylet.substring(40, 64))) {
|
|
13831
|
+
// Check the existence of the NFToken
|
|
13832
|
+
let token = page.NFTokens.find(n => n.NFToken.NFTokenID == nfTokenId);
|
|
13833
|
+
if (!token) {
|
|
13834
|
+
page = await xrplApi.getLedgerEntry(page.PreviousPageMin);
|
|
13835
|
+
}
|
|
13836
|
+
else
|
|
13837
|
+
break;
|
|
13838
|
+
}
|
|
13839
|
+
}
|
|
13840
|
+
|
|
13841
|
+
const nftPageInfo = page.NFTokens.map((n, loc) => { return { NFTPage: NFT_PAGE_LEDGER_ENTRY_TYPE_HEX + page.index, NFTokenID: n.NFToken.NFTokenID, location: loc } }).find(n => n.NFTokenID == nfTokenId);
|
|
13842
|
+
if (buffer) {
|
|
13843
|
+
let locBuf = Buffer.allocUnsafe(2);
|
|
13844
|
+
locBuf.writeUInt16BE(nftPageInfo.location);
|
|
13845
|
+
// <NFT_PAGE_KEYLET(34 bytes)><LOCATION(2 bytes)>
|
|
13846
|
+
return Buffer.concat([Buffer.from(nftPageInfo.NFTPage, "hex"), locBuf]);
|
|
13847
|
+
}
|
|
13848
|
+
|
|
13849
|
+
return nftPageInfo;
|
|
13850
|
+
}
|
|
13694
13851
|
}
|
|
13695
13852
|
|
|
13696
13853
|
module.exports = {
|
|
@@ -14107,7 +14264,7 @@ const HOST_CPU_SPEED_OFFSET = 62;
|
|
|
14107
14264
|
const HOST_CPU_MICROSEC_OFFSET = 64;
|
|
14108
14265
|
const HOST_RAM_MB_OFFSET = 68;
|
|
14109
14266
|
const HOST_DISK_MB_OFFSET = 72;
|
|
14110
|
-
const
|
|
14267
|
+
const HOST_EMAIL_ADDRESS_OFFSET = 76;
|
|
14111
14268
|
|
|
14112
14269
|
const PREV_HOST_ADDRESS_OFFSET = 0;
|
|
14113
14270
|
const TRANSFER_LEDGER_IDX_OFFSET = 20;
|
|
@@ -14134,6 +14291,7 @@ const HOST_ADDR_KEY_ZERO_COUNT = 8;
|
|
|
14134
14291
|
const TRANSFEREE_ADDR_KEY_ZERO_COUNT = 8;
|
|
14135
14292
|
const HOOK_STATE_LEDGER_TYPE_PREFIX = 118; // Decimal value of ASCII 'v'
|
|
14136
14293
|
const PENDING_TRANSFER = 1;
|
|
14294
|
+
const HOST_EMAIL_ADDRESS_LEN = 40;
|
|
14137
14295
|
|
|
14138
14296
|
class StateHelpers {
|
|
14139
14297
|
static StateTypes = {
|
|
@@ -14184,7 +14342,9 @@ class StateHelpers {
|
|
|
14184
14342
|
cpuMicrosec: stateDataBuf.readUInt32BE(HOST_CPU_MICROSEC_OFFSET),
|
|
14185
14343
|
ramMb: stateDataBuf.readUInt32BE(HOST_RAM_MB_OFFSET),
|
|
14186
14344
|
diskMb: stateDataBuf.readUInt32BE(HOST_DISK_MB_OFFSET),
|
|
14187
|
-
email: (stateDataBuf.length >
|
|
14345
|
+
email: (stateDataBuf.length > HOST_EMAIL_ADDRESS_OFFSET ?
|
|
14346
|
+
stateDataBuf.slice(HOST_EMAIL_ADDRESS_OFFSET, HOST_EMAIL_ADDRESS_OFFSET + HOST_EMAIL_ADDRESS_LEN).toString().toString().replace(/\0/g, '') :
|
|
14347
|
+
"")
|
|
14188
14348
|
}
|
|
14189
14349
|
}
|
|
14190
14350
|
|
|
@@ -14329,6 +14489,13 @@ class StateHelpers {
|
|
|
14329
14489
|
}
|
|
14330
14490
|
}
|
|
14331
14491
|
}
|
|
14492
|
+
else if (Buffer.from(HookStateKeys.MAX_TRX_EMISSION_FEE, 'hex').compare(stateKey) === 0) {
|
|
14493
|
+
return {
|
|
14494
|
+
type: this.StateTypes.CONFIGURATION,
|
|
14495
|
+
key: hexKey,
|
|
14496
|
+
value: Number(stateData.readBigUInt64BE())
|
|
14497
|
+
}
|
|
14498
|
+
}
|
|
14332
14499
|
else
|
|
14333
14500
|
throw { type: 'Validation Error', message: 'Invalid state key.' };
|
|
14334
14501
|
}
|
|
@@ -14347,6 +14514,12 @@ class StateHelpers {
|
|
|
14347
14514
|
type: this.StateTypes.TOKEN_ID
|
|
14348
14515
|
};
|
|
14349
14516
|
}
|
|
14517
|
+
else if (Buffer.from(HookStateKeys.PREFIX_TRANSFEREE_ADDR, 'hex').compare(stateKey, 0, 4) === 0) {
|
|
14518
|
+
return {
|
|
14519
|
+
key: hexKey,
|
|
14520
|
+
type: this.StateTypes.TRANSFEREE_ADDR
|
|
14521
|
+
};
|
|
14522
|
+
}
|
|
14350
14523
|
else if (Buffer.from(HookStateKeys.HOST_COUNT, 'hex').compare(stateKey) === 0 ||
|
|
14351
14524
|
Buffer.from(HookStateKeys.MOMENT_BASE_INFO, 'hex').compare(stateKey) === 0 ||
|
|
14352
14525
|
Buffer.from(HookStateKeys.HOST_REG_FEE, 'hex').compare(stateKey) === 0 ||
|
|
@@ -14367,7 +14540,8 @@ class StateHelpers {
|
|
|
14367
14540
|
Buffer.from(HookStateKeys.LEASE_ACQUIRE_WINDOW, 'hex').compare(stateKey) === 0 ||
|
|
14368
14541
|
Buffer.from(HookStateKeys.REWARD_CONFIGURATION, 'hex').compare(stateKey) === 0 ||
|
|
14369
14542
|
Buffer.from(HookStateKeys.MAX_TOLERABLE_DOWNTIME, 'hex').compare(stateKey) === 0 ||
|
|
14370
|
-
Buffer.from(HookStateKeys.MOMENT_TRANSIT_INFO, 'hex').compare(stateKey) === 0
|
|
14543
|
+
Buffer.from(HookStateKeys.MOMENT_TRANSIT_INFO, 'hex').compare(stateKey) === 0 ||
|
|
14544
|
+
Buffer.from(HookStateKeys.MAX_TRX_EMISSION_FEE, 'hex').compare(stateKey) === 0) {
|
|
14371
14545
|
return {
|
|
14372
14546
|
key: hexKey,
|
|
14373
14547
|
type: this.STATE_TYPES.CONFIGURATION
|
|
@@ -14721,18 +14895,27 @@ class XrplAccount {
|
|
|
14721
14895
|
#subscribed = false;
|
|
14722
14896
|
#txStreamHandler;
|
|
14723
14897
|
|
|
14724
|
-
constructor(address, secret = null, options = {}) {
|
|
14898
|
+
constructor(address = null, secret = null, options = {}) {
|
|
14899
|
+
if (!address && !secret)
|
|
14900
|
+
throw "Both address and secret cannot be empty";
|
|
14901
|
+
|
|
14902
|
+
this.address = address;
|
|
14903
|
+
this.secret = secret;
|
|
14725
14904
|
this.xrplApi = options.xrplApi || DefaultValues.xrplApi;
|
|
14726
14905
|
|
|
14727
14906
|
if (!this.xrplApi)
|
|
14728
14907
|
throw "XrplAccount: xrplApi not specified.";
|
|
14729
14908
|
|
|
14730
|
-
this.address
|
|
14731
|
-
|
|
14732
|
-
this.secret = secret;
|
|
14733
|
-
if (this.secret) {
|
|
14909
|
+
if (!this.address && this.secret) {
|
|
14734
14910
|
this.wallet = xrpl.Wallet.fromSeed(this.secret);
|
|
14735
|
-
this.address= this.wallet.classicAddress;
|
|
14911
|
+
this.address = this.wallet.classicAddress;
|
|
14912
|
+
} else if (this.secret) {
|
|
14913
|
+
const keypair = kp.deriveKeypair(this.secret);
|
|
14914
|
+
const derivedPubKeyAddress = kp.deriveAddress(keypair.publicKey);
|
|
14915
|
+
if (this.address == derivedPubKeyAddress)
|
|
14916
|
+
this.wallet = xrpl.Wallet.fromSeed(this.secret);
|
|
14917
|
+
else
|
|
14918
|
+
this.wallet = xrpl.Wallet.fromSeed(this.secret, { masterAddress: this.address });
|
|
14736
14919
|
}
|
|
14737
14920
|
|
|
14738
14921
|
this.#txStreamHandler = (eventName, tx, error) => {
|
|
@@ -14759,6 +14942,10 @@ class XrplAccount {
|
|
|
14759
14942
|
return kp.deriveKeypair(this.secret);
|
|
14760
14943
|
}
|
|
14761
14944
|
|
|
14945
|
+
async exists() {
|
|
14946
|
+
return await this.xrplApi.isAccountExists(this.address);
|
|
14947
|
+
}
|
|
14948
|
+
|
|
14762
14949
|
async getInfo() {
|
|
14763
14950
|
return await this.xrplApi.getAccountInfo(this.address);
|
|
14764
14951
|
}
|
|
@@ -14832,6 +15019,10 @@ class XrplAccount {
|
|
|
14832
15019
|
return await this.xrplApi.getAccountTrx(this.address, { ledger_index_min: minLedgerIndex, ledger_index_max: maxLedgerIndex, forward: isForward });
|
|
14833
15020
|
}
|
|
14834
15021
|
|
|
15022
|
+
async hasValidKeyPair() {
|
|
15023
|
+
return await this.xrplApi.isValidKeyForAddress(this.wallet.publicKey, this.address);
|
|
15024
|
+
}
|
|
15025
|
+
|
|
14835
15026
|
setAccountFields(fields, options = {}) {
|
|
14836
15027
|
/**
|
|
14837
15028
|
* Example for fields
|
|
@@ -15055,6 +15246,29 @@ class XrplAccount {
|
|
|
15055
15246
|
return this.#submitAndVerifyTransaction(owner ? { ...tx, Owner: owner } : tx, options);
|
|
15056
15247
|
}
|
|
15057
15248
|
|
|
15249
|
+
generateKeylet(type, data = {}) {
|
|
15250
|
+
switch (type) {
|
|
15251
|
+
case 'nftPage': {
|
|
15252
|
+
const accIdHex = (codec.decodeAccountID(this.address)).toString('hex').toUpperCase();
|
|
15253
|
+
const tokenPortion = data?.nfTokenId.substr(40, 64);
|
|
15254
|
+
return '0050' + accIdHex + tokenPortion;
|
|
15255
|
+
}
|
|
15256
|
+
|
|
15257
|
+
case 'nftPageMax': {
|
|
15258
|
+
const accIdHex = (codec.decodeAccountID(this.address)).toString('hex').toUpperCase();
|
|
15259
|
+
return '0050' + accIdHex + 'F'.repeat(24);
|
|
15260
|
+
}
|
|
15261
|
+
|
|
15262
|
+
case 'nftPageMin': {
|
|
15263
|
+
const accIdHex = (codec.decodeAccountID(this.address)).toString('hex').toUpperCase();
|
|
15264
|
+
return '0050' + accIdHex + '0'.repeat(24);
|
|
15265
|
+
}
|
|
15266
|
+
|
|
15267
|
+
default:
|
|
15268
|
+
return null;
|
|
15269
|
+
}
|
|
15270
|
+
}
|
|
15271
|
+
|
|
15058
15272
|
async subscribe() {
|
|
15059
15273
|
// Subscribe only once. Otherwise event handlers will be duplicated.
|
|
15060
15274
|
if (this.#subscribed)
|
|
@@ -15390,6 +15604,17 @@ class XrplApi {
|
|
|
15390
15604
|
return derivedPubKeyAddress === address || (regularKey && derivedPubKeyAddress === regularKey);
|
|
15391
15605
|
}
|
|
15392
15606
|
|
|
15607
|
+
async isAccountExists(address) {
|
|
15608
|
+
try {
|
|
15609
|
+
await this.#client.request({ command: 'account_info', account: address });
|
|
15610
|
+
return true;
|
|
15611
|
+
}
|
|
15612
|
+
catch (e) {
|
|
15613
|
+
if (e.data.error === 'actNotFound') return false;
|
|
15614
|
+
else throw e;
|
|
15615
|
+
}
|
|
15616
|
+
}
|
|
15617
|
+
|
|
15393
15618
|
async getAccountInfo(address) {
|
|
15394
15619
|
const resp = (await this.#client.request({ command: 'account_info', account: address }));
|
|
15395
15620
|
return resp?.result?.account_data;
|
|
@@ -15434,8 +15659,15 @@ class XrplApi {
|
|
|
15434
15659
|
}
|
|
15435
15660
|
|
|
15436
15661
|
async getLedgerEntry(index, options) {
|
|
15437
|
-
|
|
15438
|
-
|
|
15662
|
+
try {
|
|
15663
|
+
const resp = (await this.#client.request({ command: 'ledger_entry', index: index, ledger_index: "validated", ...options }));
|
|
15664
|
+
return resp?.result?.node;
|
|
15665
|
+
|
|
15666
|
+
} catch (e) {
|
|
15667
|
+
if (e?.data?.error === 'entryNotFound')
|
|
15668
|
+
return null;
|
|
15669
|
+
throw e;
|
|
15670
|
+
}
|
|
15439
15671
|
}
|
|
15440
15672
|
|
|
15441
15673
|
async submitAndVerify(tx, options) {
|