evernode-js-client 0.5.4 → 0.5.6

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.
Files changed (2) hide show
  1. package/index.js +80 -3
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -12653,6 +12653,67 @@ class HostClient extends BaseEvernodeClient {
12653
12653
  codec.decodeAccountID(this.xrplAcc.address).copy(buf, 4);
12654
12654
  return buf.toString('hex');
12655
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
+ }
12656
12717
  }
12657
12718
 
12658
12719
  module.exports = {
@@ -12677,6 +12738,7 @@ const RegistryEvents = {
12677
12738
  Heartbeat: EvernodeEvents.Heartbeat,
12678
12739
  HostPostDeregistered: EvernodeEvents.HostPostDeregistered,
12679
12740
  DeadHostPrune: EvernodeEvents.DeadHostPrune,
12741
+ HostTransfer: EvernodeEvents.HostTransfer,
12680
12742
  HostRebate: EvernodeEvents.HostRebate
12681
12743
  }
12682
12744
 
@@ -13412,6 +13474,7 @@ const MemoTypes = {
13412
13474
  HOST_UPDATE_INFO: 'evnHostUpdateReg',
13413
13475
  HEARTBEAT: 'evnHeartbeat',
13414
13476
  HOST_POST_DEREG: 'evnHostPostDereg',
13477
+ HOST_TRANSFER: 'evnTransfer',
13415
13478
  EXTEND_LEASE: 'evnExtendLease',
13416
13479
  EXTEND_SUCCESS: 'evnExtendSuccess',
13417
13480
  EXTEND_ERROR: 'evnExtendError',
@@ -13472,12 +13535,14 @@ const HookStateKeys = {
13472
13535
  // Prefixes
13473
13536
  PREFIX_HOST_TOKENID: "45565202",
13474
13537
  PREFIX_HOST_ADDR: "45565203",
13538
+ PREFIX_TRANSFEREE_ADDR: "45565204",
13475
13539
  }
13476
13540
 
13477
13541
  const EvernodeEvents = {
13478
13542
  HostRegistered: "HostRegistered",
13479
13543
  HostDeregistered: "HostDeregistered",
13480
13544
  HostPostDeregistered: "HostPostDeregistered",
13545
+ HostTransfer: "HostTransfer",
13481
13546
  AcquireLease: "AcquireLease",
13482
13547
  AcquireSuccess: "AcquireSuccess",
13483
13548
  AcquireError: "AcquireError",
@@ -13923,6 +13988,7 @@ const HOST_ACT_INS_COUNT_OFFSET = 88;
13923
13988
  const HOST_HEARTBEAT_LEDGER_IDX_OFFSET = 92;
13924
13989
  const HOST_VERSION_OFFSET = 100;
13925
13990
  const HOST_REG_TIMESTAMP_OFFSET = 103;
13991
+ const HOST_TRANSFER_FLAG_OFFSET = 111;
13926
13992
 
13927
13993
  const HOST_ADDRESS_OFFSET = 0;
13928
13994
  const HOST_CPU_MODEL_NAME_OFFSET = 20;
@@ -13945,13 +14011,15 @@ const MOMENT_TYPES = {
13945
14011
  const EVERNODE_PREFIX = 'EVR';
13946
14012
  const HOST_ADDR_KEY_ZERO_COUNT = 8;
13947
14013
  const HOOK_STATE_LEDGER_TYPE_PREFIX = 118; // Decimal value of ASCII 'v'
14014
+ const PENDING_TRANSFER = 1;
13948
14015
 
13949
14016
  class StateHelpers {
13950
14017
  static StateTypes = {
13951
14018
  TOKEN_ID: 'tokenId',
13952
14019
  HOST_ADDR: 'hostAddr',
13953
14020
  SIGLETON: 'singleton',
13954
- CONFIGURATION: 'configuration'
14021
+ CONFIGURATION: 'configuration',
14022
+ TRANSFEREE_ADDR: 'transfereeAddr'
13955
14023
  }
13956
14024
 
13957
14025
  static timeLines = {
@@ -13978,6 +14046,7 @@ class StateHelpers {
13978
14046
  activeInstances: stateDataBuf.readUInt32BE(HOST_ACT_INS_COUNT_OFFSET),
13979
14047
  lastHeartbeatIndex: Number(stateDataBuf.readBigUInt64BE(HOST_HEARTBEAT_LEDGER_IDX_OFFSET)),
13980
14048
  version: `${stateDataBuf.readUInt8(HOST_VERSION_OFFSET)}.${stateDataBuf.readUInt8(HOST_VERSION_OFFSET + 1)}.${stateDataBuf.readUInt8(HOST_VERSION_OFFSET + 2)}`,
14049
+ hasPendingTransfer: (stateDataBuf.length > HOST_TRANSFER_FLAG_OFFSET && (stateDataBuf.readUInt8(HOST_TRANSFER_FLAG_OFFSET) === PENDING_TRANSFER)) ? true : false
13981
14050
  }
13982
14051
  if (stateDataBuf.length > HOST_REG_TIMESTAMP_OFFSET)
13983
14052
  data.registrationTimestamp = Number(stateDataBuf.readBigUInt64BE(HOST_REG_TIMESTAMP_OFFSET));
@@ -14017,6 +14086,12 @@ class StateHelpers {
14017
14086
  ...this.decodeTokenIdState(stateData)
14018
14087
  }
14019
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
+ }
14020
14095
  else if (Buffer.from(HookStateKeys.HOST_COUNT, 'hex').compare(stateKey) === 0) {
14021
14096
  return {
14022
14097
  type: this.StateTypes.SIGLETON,
@@ -14505,8 +14580,10 @@ class XrplAccount {
14505
14580
  this.address = address;
14506
14581
 
14507
14582
  this.secret = secret;
14508
- if (this.secret)
14583
+ if (this.secret) {
14509
14584
  this.wallet = xrpl.Wallet.fromSeed(this.secret);
14585
+ this.address= this.wallet.classicAddress;
14586
+ }
14510
14587
 
14511
14588
  this.#txStreamHandler = (eventName, tx, error) => {
14512
14589
  this.#events.emit(eventName, tx, error);
@@ -14602,7 +14679,7 @@ class XrplAccount {
14602
14679
  }
14603
14680
 
14604
14681
  async getAccountTrx(minLedgerIndex = -1, maxLedgerIndex = -1, isForward = true) {
14605
- 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 });
14606
14683
  }
14607
14684
 
14608
14685
  setAccountFields(fields, options = {}) {
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  ],
7
7
  "homepage": "https://github.com/HotPocketDev/evernode-js-client",
8
8
  "license": "MIT",
9
- "version": "0.5.4",
9
+ "version": "0.5.6",
10
10
  "dependencies": {
11
11
  "elliptic": "6.5.4",
12
12
  "ripple-address-codec": "4.2.0",