evernode-js-client 0.5.4 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
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",