evernode-js-client 0.5.3 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- package/index.js +106 -6
- package/package.json +1 -1
package/index.js
CHANGED
@@ -12145,6 +12145,17 @@ class BaseEvernodeClient {
|
|
12145
12145
|
}
|
12146
12146
|
}
|
12147
12147
|
}
|
12148
|
+
else if (tx.Memos.length >= 1 &&
|
12149
|
+
tx.Memos[0].type === MemoTypes.HOST_REBATE) {
|
12150
|
+
|
12151
|
+
return {
|
12152
|
+
name: EvernodeEvents.HostRebate,
|
12153
|
+
data: {
|
12154
|
+
transaction: tx,
|
12155
|
+
host: tx.Account
|
12156
|
+
}
|
12157
|
+
}
|
12158
|
+
}
|
12148
12159
|
|
12149
12160
|
return null;
|
12150
12161
|
}
|
@@ -12626,6 +12637,15 @@ class HostClient extends BaseEvernodeClient {
|
|
12626
12637
|
options.transactionOptions);
|
12627
12638
|
}
|
12628
12639
|
|
12640
|
+
async requestRebate(options = {}) {
|
12641
|
+
return this.xrplAcc.makePayment(this.registryAddress,
|
12642
|
+
XrplConstants.MIN_XRP_AMOUNT,
|
12643
|
+
XrplConstants.XRP,
|
12644
|
+
null,
|
12645
|
+
[{ type: MemoTypes.HOST_REBATE, format: "", data: "" }],
|
12646
|
+
options.transactionOptions);
|
12647
|
+
}
|
12648
|
+
|
12629
12649
|
getLeaseNFTokenIdPrefix() {
|
12630
12650
|
let buf = Buffer.allocUnsafe(24);
|
12631
12651
|
buf.writeUInt16BE(1);
|
@@ -12633,6 +12653,67 @@ class HostClient extends BaseEvernodeClient {
|
|
12633
12653
|
codec.decodeAccountID(this.xrplAcc.address).copy(buf, 4);
|
12634
12654
|
return buf.toString('hex');
|
12635
12655
|
}
|
12656
|
+
|
12657
|
+
async transfer(transfereeAddress = this.xrplAcc.address, options = {}) {
|
12658
|
+
if (!(await this.isRegistered()))
|
12659
|
+
throw "Host is not registered.";
|
12660
|
+
|
12661
|
+
const transfereeAcc = new XrplAccount(transfereeAddress, null, { xrplApi: this.xrplApi });
|
12662
|
+
|
12663
|
+
if (this.xrplAcc.address !== transfereeAddress) {
|
12664
|
+
// Find the new transferee also owns an Evernode Host Registration NFT.
|
12665
|
+
const nft = (await transfereeAcc.getNfts()).find(n => n.URI.startsWith(EvernodeConstants.NFT_PREFIX_HEX) && n.Issuer === this.registryAddress);
|
12666
|
+
if (nft) {
|
12667
|
+
// Check whether the token was actually issued from Evernode registry contract.
|
12668
|
+
const issuerHex = nft.NFTokenID.substr(8, 40);
|
12669
|
+
const issuerAddr = codec.encodeAccountID(Buffer.from(issuerHex, 'hex'));
|
12670
|
+
if (issuerAddr == this.registryAddress) {
|
12671
|
+
throw "The transferee is already registered in Evernode.";
|
12672
|
+
}
|
12673
|
+
}
|
12674
|
+
}
|
12675
|
+
|
12676
|
+
const regNFT = (await this.xrplAcc.getNfts()).find(n => n.URI.startsWith(EvernodeConstants.NFT_PREFIX_HEX) && n.Issuer === this.registryAddress);
|
12677
|
+
|
12678
|
+
let memoData = Buffer.allocUnsafe(20);
|
12679
|
+
codec.decodeAccountID(transfereeAddress).copy(memoData);
|
12680
|
+
|
12681
|
+
await this.xrplAcc.makePayment(this.registryAddress,
|
12682
|
+
XrplConstants.MIN_XRP_AMOUNT,
|
12683
|
+
XrplConstants.XRP,
|
12684
|
+
null,
|
12685
|
+
[{ type: MemoTypes.HOST_TRANSFER, format: MemoFormats.HEX, data: memoData.toString('hex') }],
|
12686
|
+
options.transactionOptions);
|
12687
|
+
|
12688
|
+
let offer = null;
|
12689
|
+
let attempts = 0;
|
12690
|
+
let offerLedgerIndex = 0;
|
12691
|
+
const regAcc = new XrplAccount(this.registryAddress, null, { xrplApi: this.xrplApi });
|
12692
|
+
|
12693
|
+
while (attempts < OFFER_WAIT_TIMEOUT) {
|
12694
|
+
offer = (await regAcc.getNftOffers()).find(o => (o.NFTokenID == regNFT.NFTokenID) && (o.Flags === 0));
|
12695
|
+
offerLedgerIndex = this.xrplApi.ledgerIndex;
|
12696
|
+
if (offer)
|
12697
|
+
break;
|
12698
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
12699
|
+
attempts++;
|
12700
|
+
}
|
12701
|
+
if (!offer)
|
12702
|
+
throw 'No buy offer found within timeout.';
|
12703
|
+
|
12704
|
+
console.log('Accepting the buy offer..');
|
12705
|
+
|
12706
|
+
// Wait until the next ledger after the offer is created.
|
12707
|
+
// Otherwise if the offer accepted in the same legder which it's been created,
|
12708
|
+
// We cannot fetch the offer from registry contract event handler since it's getting deleted immediately.
|
12709
|
+
await new Promise(async resolve => {
|
12710
|
+
while (this.xrplApi.ledgerIndex <= offerLedgerIndex)
|
12711
|
+
await new Promise(resolve2 => setTimeout(resolve2, 1000));
|
12712
|
+
resolve();
|
12713
|
+
});
|
12714
|
+
|
12715
|
+
await this.xrplAcc.sellNft(offer.index);
|
12716
|
+
}
|
12636
12717
|
}
|
12637
12718
|
|
12638
12719
|
module.exports = {
|
@@ -12656,7 +12737,9 @@ const RegistryEvents = {
|
|
12656
12737
|
RegistryInitialized: EvernodeEvents.RegistryInitialized,
|
12657
12738
|
Heartbeat: EvernodeEvents.Heartbeat,
|
12658
12739
|
HostPostDeregistered: EvernodeEvents.HostPostDeregistered,
|
12659
|
-
DeadHostPrune: EvernodeEvents.DeadHostPrune
|
12740
|
+
DeadHostPrune: EvernodeEvents.DeadHostPrune,
|
12741
|
+
HostTransfer: EvernodeEvents.HostTransfer,
|
12742
|
+
HostRebate: EvernodeEvents.HostRebate
|
12660
12743
|
}
|
12661
12744
|
|
12662
12745
|
class RegistryClient extends BaseEvernodeClient {
|
@@ -13391,6 +13474,7 @@ const MemoTypes = {
|
|
13391
13474
|
HOST_UPDATE_INFO: 'evnHostUpdateReg',
|
13392
13475
|
HEARTBEAT: 'evnHeartbeat',
|
13393
13476
|
HOST_POST_DEREG: 'evnHostPostDereg',
|
13477
|
+
HOST_TRANSFER: 'evnTransfer',
|
13394
13478
|
EXTEND_LEASE: 'evnExtendLease',
|
13395
13479
|
EXTEND_SUCCESS: 'evnExtendSuccess',
|
13396
13480
|
EXTEND_ERROR: 'evnExtendError',
|
@@ -13398,7 +13482,8 @@ const MemoTypes = {
|
|
13398
13482
|
REGISTRY_INIT: 'evnInitialize',
|
13399
13483
|
REFUND: 'evnRefund',
|
13400
13484
|
REFUND_REF: 'evnRefundRef',
|
13401
|
-
DEAD_HOST_PRUNE: 'evnDeadHostPrune'
|
13485
|
+
DEAD_HOST_PRUNE: 'evnDeadHostPrune',
|
13486
|
+
HOST_REBATE: 'evnHostRebate'
|
13402
13487
|
}
|
13403
13488
|
|
13404
13489
|
const MemoFormats = {
|
@@ -13450,12 +13535,14 @@ const HookStateKeys = {
|
|
13450
13535
|
// Prefixes
|
13451
13536
|
PREFIX_HOST_TOKENID: "45565202",
|
13452
13537
|
PREFIX_HOST_ADDR: "45565203",
|
13538
|
+
PREFIX_TRANSFEREE_ADDR: "45565204",
|
13453
13539
|
}
|
13454
13540
|
|
13455
13541
|
const EvernodeEvents = {
|
13456
13542
|
HostRegistered: "HostRegistered",
|
13457
13543
|
HostDeregistered: "HostDeregistered",
|
13458
13544
|
HostPostDeregistered: "HostPostDeregistered",
|
13545
|
+
HostTransfer: "HostTransfer",
|
13459
13546
|
AcquireLease: "AcquireLease",
|
13460
13547
|
AcquireSuccess: "AcquireSuccess",
|
13461
13548
|
AcquireError: "AcquireError",
|
@@ -13466,7 +13553,8 @@ const EvernodeEvents = {
|
|
13466
13553
|
HostRegUpdated: "HostRegUpdated",
|
13467
13554
|
HostReRegistered: "HostReRegistered",
|
13468
13555
|
RegistryInitialized: "RegistryInitialized",
|
13469
|
-
DeadHostPrune: "DeadHostPrune"
|
13556
|
+
DeadHostPrune: "DeadHostPrune",
|
13557
|
+
HostRebate: "HostRebate"
|
13470
13558
|
}
|
13471
13559
|
|
13472
13560
|
module.exports = {
|
@@ -13900,6 +13988,7 @@ const HOST_ACT_INS_COUNT_OFFSET = 88;
|
|
13900
13988
|
const HOST_HEARTBEAT_LEDGER_IDX_OFFSET = 92;
|
13901
13989
|
const HOST_VERSION_OFFSET = 100;
|
13902
13990
|
const HOST_REG_TIMESTAMP_OFFSET = 103;
|
13991
|
+
const HOST_TRANSFER_FLAG_OFFSET = 111;
|
13903
13992
|
|
13904
13993
|
const HOST_ADDRESS_OFFSET = 0;
|
13905
13994
|
const HOST_CPU_MODEL_NAME_OFFSET = 20;
|
@@ -13922,13 +14011,15 @@ const MOMENT_TYPES = {
|
|
13922
14011
|
const EVERNODE_PREFIX = 'EVR';
|
13923
14012
|
const HOST_ADDR_KEY_ZERO_COUNT = 8;
|
13924
14013
|
const HOOK_STATE_LEDGER_TYPE_PREFIX = 118; // Decimal value of ASCII 'v'
|
14014
|
+
const PENDING_TRANSFER = 1;
|
13925
14015
|
|
13926
14016
|
class StateHelpers {
|
13927
14017
|
static StateTypes = {
|
13928
14018
|
TOKEN_ID: 'tokenId',
|
13929
14019
|
HOST_ADDR: 'hostAddr',
|
13930
14020
|
SIGLETON: 'singleton',
|
13931
|
-
CONFIGURATION: 'configuration'
|
14021
|
+
CONFIGURATION: 'configuration',
|
14022
|
+
TRANSFEREE_ADDR: 'transfereeAddr'
|
13932
14023
|
}
|
13933
14024
|
|
13934
14025
|
static timeLines = {
|
@@ -13955,6 +14046,7 @@ class StateHelpers {
|
|
13955
14046
|
activeInstances: stateDataBuf.readUInt32BE(HOST_ACT_INS_COUNT_OFFSET),
|
13956
14047
|
lastHeartbeatIndex: Number(stateDataBuf.readBigUInt64BE(HOST_HEARTBEAT_LEDGER_IDX_OFFSET)),
|
13957
14048
|
version: `${stateDataBuf.readUInt8(HOST_VERSION_OFFSET)}.${stateDataBuf.readUInt8(HOST_VERSION_OFFSET + 1)}.${stateDataBuf.readUInt8(HOST_VERSION_OFFSET + 2)}`,
|
14049
|
+
hasPendingTransfer: (stateDataBuf.readUInt8(HOST_TRANSFER_FLAG_OFFSET) === PENDING_TRANSFER) ? true : false
|
13958
14050
|
}
|
13959
14051
|
if (stateDataBuf.length > HOST_REG_TIMESTAMP_OFFSET)
|
13960
14052
|
data.registrationTimestamp = Number(stateDataBuf.readBigUInt64BE(HOST_REG_TIMESTAMP_OFFSET));
|
@@ -13994,6 +14086,12 @@ class StateHelpers {
|
|
13994
14086
|
...this.decodeTokenIdState(stateData)
|
13995
14087
|
}
|
13996
14088
|
}
|
14089
|
+
else if (Buffer.from(HookStateKeys.PREFIX_TRANSFEREE_ADDR, 'hex').compare(stateKey, 0, 4) === 0) {
|
14090
|
+
return {
|
14091
|
+
type: this.StateTypes.TRANSFEREE_ADDR,
|
14092
|
+
key: hexKey
|
14093
|
+
}
|
14094
|
+
}
|
13997
14095
|
else if (Buffer.from(HookStateKeys.HOST_COUNT, 'hex').compare(stateKey) === 0) {
|
13998
14096
|
return {
|
13999
14097
|
type: this.StateTypes.SIGLETON,
|
@@ -14482,8 +14580,10 @@ class XrplAccount {
|
|
14482
14580
|
this.address = address;
|
14483
14581
|
|
14484
14582
|
this.secret = secret;
|
14485
|
-
if (this.secret)
|
14583
|
+
if (this.secret) {
|
14486
14584
|
this.wallet = xrpl.Wallet.fromSeed(this.secret);
|
14585
|
+
this.address= this.wallet.classicAddress;
|
14586
|
+
}
|
14487
14587
|
|
14488
14588
|
this.#txStreamHandler = (eventName, tx, error) => {
|
14489
14589
|
this.#events.emit(eventName, tx, error);
|
@@ -14579,7 +14679,7 @@ class XrplAccount {
|
|
14579
14679
|
}
|
14580
14680
|
|
14581
14681
|
async getAccountTrx(minLedgerIndex = -1, maxLedgerIndex = -1, isForward = true) {
|
14582
|
-
return await this.xrplApi.getAccountTrx(this.address, { ledger_index_min: minLedgerIndex, ledger_index_max: maxLedgerIndex, forward: isForward});
|
14682
|
+
return await this.xrplApi.getAccountTrx(this.address, { ledger_index_min: minLedgerIndex, ledger_index_max: maxLedgerIndex, forward: isForward });
|
14583
14683
|
}
|
14584
14684
|
|
14585
14685
|
setAccountFields(fields, options = {}) {
|