evernode-js-client 0.6.35 → 0.6.37

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 +188 -107
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -52488,7 +52488,7 @@ class BaseEvernodeClient {
52488
52488
  * Get the hosts registered in Evernode.
52489
52489
  * @returns The list of hosts.
52490
52490
  */
52491
- async getAllHostsFromLedger() {
52491
+ async getAllHostsFromLedger(skipGetDomain = false) {
52492
52492
  const states = await this.getHookStates();
52493
52493
  let hosts = {};
52494
52494
 
@@ -52508,7 +52508,9 @@ class BaseEvernodeClient {
52508
52508
  const curMomentStartIdx = await this.getMomentStartIndex();
52509
52509
  await Promise.all((hostList).map(async host => {
52510
52510
  const hostAcc = new XrplAccount(host.address, null, { xrplApi: this.xrplApi });
52511
- host.domain = await hostAcc.getDomain();
52511
+ if (!skipGetDomain) {
52512
+ host.domain = await hostAcc.getDomain();
52513
+ }
52512
52514
  host.active = (host.lastHeartbeatIndex > (this.config.hostHeartbeatFreq * this.config.momentSize) ?
52513
52515
  (host.lastHeartbeatIndex >= (curMomentStartIdx - (this.config.hostHeartbeatFreq * this.config.momentSize))) :
52514
52516
  (host.lastHeartbeatIndex > 0));
@@ -53315,10 +53317,11 @@ class HostClient extends BaseEvernodeClient {
53315
53317
  let attempt = 0;
53316
53318
  let feeUplift = 0;
53317
53319
  const maxAttempts = (options?.maxRetryAttempts || 1);
53320
+ let submissionRef = options.submissionRef || {};
53318
53321
  while (attempt <= maxAttempts) {
53319
53322
  attempt++;
53320
53323
  try {
53321
- return await callback(feeUplift);
53324
+ return await callback(feeUplift, submissionRef);
53322
53325
  }
53323
53326
  catch (e) {
53324
53327
  if (attempt == maxAttempts || e.code === "tecDUPLICATE" || e.code === "tefPAST_SEQ" || e.code === "tefALREADY")
@@ -53329,6 +53332,16 @@ class HostClient extends BaseEvernodeClient {
53329
53332
  console.error(e);
53330
53333
  console.error(`Submission attempt ${attempt} failed. Retrying...`);
53331
53334
  await new Promise(resolve => setTimeout(resolve, TX_RETRY_INTERVAL));
53335
+
53336
+ // Check again wether the transaction is validated before retry.
53337
+ const txHash = submissionRef?.submissionResult?.result?.tx_json?.hash;
53338
+ if (txHash) {
53339
+ const txResponse = await this.xrplApi.getTransactionValidatedResults(txHash);
53340
+ if (txResponse && txResponse.code === "tesSUCCESS") {
53341
+ console.log('Transaction is validated and success, Retry skipped!')
53342
+ return txResponse;
53343
+ }
53344
+ }
53332
53345
  }
53333
53346
  }
53334
53347
  }
@@ -53353,15 +53366,15 @@ class HostClient extends BaseEvernodeClient {
53353
53366
  { ...accountSetFields, Domain: domain } : accountSetFields;
53354
53367
 
53355
53368
  if (Object.keys(accountSetFields).length !== 0) {
53356
- await this.#submitWithRetry(async (feeUplift) => {
53357
- await this.xrplAcc.setAccountFields(accountSetFields, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift });
53358
- }, options.retryOptions);
53369
+ await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53370
+ await this.xrplAcc.setAccountFields(accountSetFields, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift, submissionRef: submissionRef });
53371
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53359
53372
  }
53360
53373
 
53361
53374
  if (trustLines.length === 0) {
53362
- await this.#submitWithRetry(async (feeUplift) => {
53363
- await this.xrplAcc.setTrustLine(EvernodeConstants.EVR, this.config.evrIssuerAddress, "99999999999999", null, null, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift });
53364
- }, options.retryOptions);
53375
+ await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53376
+ await this.xrplAcc.setTrustLine(EvernodeConstants.EVR, this.config.evrIssuerAddress, "99999999999999", null, null, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift, submissionRef: submissionRef });
53377
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53365
53378
  }
53366
53379
  }
53367
53380
 
@@ -53424,9 +53437,9 @@ class HostClient extends BaseEvernodeClient {
53424
53437
  const uri = uriBuf.toString('base64');
53425
53438
 
53426
53439
  try {
53427
- await this.#submitWithRetry(async (feeUplift) => {
53428
- await this.xrplAcc.mintURIToken(uri, null, { isBurnable: true, isHexUri: false }, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift });
53429
- }, options.retryOptions);
53440
+ await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53441
+ await this.xrplAcc.mintURIToken(uri, null, { isBurnable: true, isHexUri: false }, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift, submissionRef: submissionRef });
53442
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53430
53443
  } catch (e) {
53431
53444
  // Re-minting the URIToken after burning that sold URIToken.
53432
53445
  if (e.code === "tecDUPLICATE") {
@@ -53442,12 +53455,12 @@ class HostClient extends BaseEvernodeClient {
53442
53455
  if (!uriToken)
53443
53456
  throw "Offer lease NFT creation error.";
53444
53457
 
53445
- await this.#submitWithRetry(async (feeUplift) => {
53458
+ await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53446
53459
  await this.xrplAcc.sellURIToken(uriToken.index,
53447
53460
  leaseAmount.toString(),
53448
53461
  EvernodeConstants.EVR,
53449
- this.config.evrIssuerAddress, null, null, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift });
53450
- }, options.retryOptions);
53462
+ this.config.evrIssuerAddress, null, null, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift, submissionRef: submissionRef });
53463
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53451
53464
  }
53452
53465
 
53453
53466
  /**
@@ -53509,9 +53522,9 @@ class HostClient extends BaseEvernodeClient {
53509
53522
  const uri = uriBuf.toString('base64');
53510
53523
 
53511
53524
  try {
53512
- await this.#submitWithRetry(async (feeUplift) => {
53513
- await this.xrplAcc.mintURIToken(uri, null, { isBurnable: true, isHexUri: false }, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift });
53514
- }, options.retryOptions);
53525
+ await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53526
+ await this.xrplAcc.mintURIToken(uri, null, { isBurnable: true, isHexUri: false }, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift, submissionRef: submissionRef });
53527
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53515
53528
  } catch (e) {
53516
53529
  // Re-minting the URIToken after burning that sold URIToken.
53517
53530
  if (e.code === "tecDUPLICATE") {
@@ -53530,11 +53543,11 @@ class HostClient extends BaseEvernodeClient {
53530
53543
  * @param {number} leaseAmount Amount (EVRs) of the lease offer.
53531
53544
  */
53532
53545
  async offerMintedLease(uriTokenId, leaseAmount, options = {}) {
53533
- await this.#submitWithRetry(async (feeUplift) => {
53546
+ await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53534
53547
  await this.xrplAcc.sellURIToken(uriTokenId, leaseAmount.toString(),
53535
53548
  EvernodeConstants.EVR,
53536
- this.config.evrIssuerAddress, null, null, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift });
53537
- }, options.retryOptions);
53549
+ this.config.evrIssuerAddress, null, null, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift, submissionRef: submissionRef });
53550
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53538
53551
  }
53539
53552
 
53540
53553
  /**
@@ -53542,9 +53555,9 @@ class HostClient extends BaseEvernodeClient {
53542
53555
  * @param {string} uriTokenId Hex URI token id of the lease.
53543
53556
  */
53544
53557
  async expireLease(uriTokenId, options = {}) {
53545
- await this.#submitWithRetry(async (feeUplift) => {
53546
- await this.xrplAcc.burnURIToken(uriTokenId, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift });
53547
- }, options.retryOptions);
53558
+ await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53559
+ await this.xrplAcc.burnURIToken(uriTokenId, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift, submissionRef: submissionRef });
53560
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53548
53561
  }
53549
53562
 
53550
53563
  /**
@@ -53564,9 +53577,9 @@ class HostClient extends BaseEvernodeClient {
53564
53577
  const sellOffer = (await registryAcc.getURITokens()).find(o => o.index == regInfo.uriTokenId && o.Amount);
53565
53578
  console.log('Pending sell offer found.')
53566
53579
  if (sellOffer) {
53567
- await this.#submitWithRetry(async (feeUplift) => {
53568
- await this.xrplAcc.buyURIToken(sellOffer, null, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift });
53569
- }, options.retryOptions);
53580
+ await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53581
+ await this.xrplAcc.buyURIToken(sellOffer, null, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift, submissionRef: submissionRef });
53582
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53570
53583
  console.log("Registration was successfully completed after acquiring the NFT.");
53571
53584
  return await this.isRegistered();
53572
53585
  }
@@ -53627,9 +53640,9 @@ class HostClient extends BaseEvernodeClient {
53627
53640
  if (existingLeaseURITokens) {
53628
53641
  console.log("Burning unsold URITokens related to the previous leases.");
53629
53642
  for (const uriToken of existingLeaseURITokens) {
53630
- await this.#submitWithRetry(async (feeUplift) => {
53631
- await this.xrplAcc.burnURIToken(uriToken.index, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift });
53632
- }, options.retryOptions);
53643
+ await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53644
+ await this.xrplAcc.burnURIToken(uriToken.index, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift, submissionRef: submissionRef });
53645
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53633
53646
  }
53634
53647
  }
53635
53648
 
@@ -53669,7 +53682,7 @@ class HostClient extends BaseEvernodeClient {
53669
53682
  Buffer.from(description.substr(0, 26), "utf-8").copy(paramBuf, HOST_DESCRIPTION_PARAM_OFFSET);
53670
53683
  Buffer.from(emailAddress.substr(0, 40), "utf-8").copy(paramBuf, HOST_EMAIL_ADDRESS_PARAM_OFFSET);
53671
53684
 
53672
- const tx = await this.#submitWithRetry(async (feeUplift) => {
53685
+ const tx = await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53673
53686
  return await this.xrplAcc.makePayment(this.config.registryAddress,
53674
53687
  (transferredNFTokenId) ? EvernodeConstants.NOW_IN_EVRS : this.config.hostRegFee.toString(),
53675
53688
  EvernodeConstants.EVR,
@@ -53681,10 +53694,10 @@ class HostClient extends BaseEvernodeClient {
53681
53694
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: paramBuf.toString('hex').toUpperCase() }
53682
53695
  ],
53683
53696
  maxLedgerIndex: this.#getMaxLedgerSequence(),
53684
- feeUplift: feeUplift,
53697
+ feeUplift: feeUplift, submissionRef: submissionRef,
53685
53698
  ...options.transactionOptions
53686
53699
  });
53687
- }, options.retryOptions);
53700
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53688
53701
 
53689
53702
  console.log('Waiting for the sell offer', tx.id)
53690
53703
  const registryAcc = new XrplAccount(this.config.registryAddress, null, { xrplApi: this.xrplApi });
@@ -53722,9 +53735,9 @@ class HostClient extends BaseEvernodeClient {
53722
53735
  resolve();
53723
53736
  });
53724
53737
 
53725
- await this.#submitWithRetry(async (feeUplift) => {
53726
- await this.xrplAcc.buyURIToken(sellOffer, null, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift });
53727
- }, options.retryOptions);
53738
+ await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53739
+ await this.xrplAcc.buyURIToken(sellOffer, null, { maxLedgerIndex: this.#getMaxLedgerSequence(), feeUplift: feeUplift, submissionRef: submissionRef });
53740
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53728
53741
  return await this.isRegistered();
53729
53742
  }
53730
53743
 
@@ -53747,7 +53760,7 @@ class HostClient extends BaseEvernodeClient {
53747
53760
  paramBuf.writeUInt8(1, 32);
53748
53761
  }
53749
53762
 
53750
- await this.#submitWithRetry(async (feeUplift) => {
53763
+ await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53751
53764
  await this.xrplAcc.makePayment(this.config.registryAddress,
53752
53765
  XrplConstants.MIN_DROPS,
53753
53766
  null,
@@ -53759,10 +53772,10 @@ class HostClient extends BaseEvernodeClient {
53759
53772
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: paramBuf.toString('hex').toUpperCase() }
53760
53773
  ],
53761
53774
  maxLedgerIndex: this.#getMaxLedgerSequence(),
53762
- feeUplift: feeUplift,
53775
+ feeUplift: feeUplift, submissionRef: submissionRef,
53763
53776
  ...options.transactionOptions
53764
53777
  });
53765
- }, options.retryOptions);
53778
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53766
53779
 
53767
53780
  return await this.isRegistered();
53768
53781
  }
@@ -53812,7 +53825,7 @@ class HostClient extends BaseEvernodeClient {
53812
53825
  paramBuf.writeUInt8(components[2], HOST_UPDATE_VERSION_PARAM_OFFSET + 2);
53813
53826
  }
53814
53827
 
53815
- return await this.#submitWithRetry(async (feeUplift) => {
53828
+ return await this.#submitWithRetry(async (feeUplift, submissionRef) => {
53816
53829
  return await this.xrplAcc.makePayment(this.config.registryAddress,
53817
53830
  XrplConstants.MIN_DROPS,
53818
53831
  null,
@@ -53824,10 +53837,10 @@ class HostClient extends BaseEvernodeClient {
53824
53837
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: paramBuf.toString('hex') }
53825
53838
  ],
53826
53839
  maxLedgerIndex: this.#getMaxLedgerSequence(),
53827
- feeUplift: feeUplift,
53840
+ feeUplift: feeUplift, submissionRef: submissionRef,
53828
53841
  ...options.transactionOptions
53829
53842
  });
53830
- }, options.retryOptions);
53843
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
53831
53844
 
53832
53845
  }
53833
53846
 
@@ -53838,6 +53851,12 @@ class HostClient extends BaseEvernodeClient {
53838
53851
  * @returns Transaction result.
53839
53852
  */
53840
53853
  async heartbeat(voteInfo = {}, options = {}) {
53854
+ let unofferedLeases = await this.getUnofferedLeases();
53855
+ if (unofferedLeases.length > 0) {
53856
+ console.log("Unoffered leases detected. Heartbeat was not sent.");
53857
+ return;
53858
+ }
53859
+
53841
53860
  let data;
53842
53861
  // Prepare voteInfo
53843
53862
  if (Object.keys(voteInfo).length > 1) {
@@ -53859,7 +53878,8 @@ class HostClient extends BaseEvernodeClient {
53859
53878
  ...(data ? [{ name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: data }] : [])
53860
53879
  ],
53861
53880
  maxLedgerIndex: this.#getMaxLedgerSequence(),
53862
- ...options.transactionOptions
53881
+ ...options.transactionOptions,
53882
+ submissionRef: options.submissionRef
53863
53883
  });
53864
53884
  return res;
53865
53885
  }
@@ -53926,7 +53946,8 @@ class HostClient extends BaseEvernodeClient {
53926
53946
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: txHash }
53927
53947
  ],
53928
53948
  maxLedgerIndex: this.#getMaxLedgerSequence(),
53929
- ...options.transactionOptions
53949
+ ...options.transactionOptions,
53950
+ submissionRef: options.submissionRef
53930
53951
  });
53931
53952
  }
53932
53953
 
@@ -53954,7 +53975,8 @@ class HostClient extends BaseEvernodeClient {
53954
53975
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: txHash }
53955
53976
  ],
53956
53977
  maxLedgerIndex: this.#getMaxLedgerSequence(),
53957
- ...options.transactionOptions
53978
+ ...options.transactionOptions,
53979
+ submissionRef: options.submissionRef
53958
53980
  });
53959
53981
  }
53960
53982
 
@@ -53983,7 +54005,8 @@ class HostClient extends BaseEvernodeClient {
53983
54005
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: txHash }
53984
54006
  ],
53985
54007
  maxLedgerIndex: this.#getMaxLedgerSequence(),
53986
- ...options.transactionOptions
54008
+ ...options.transactionOptions,
54009
+ submissionRef: options.submissionRef
53987
54010
  });
53988
54011
  }
53989
54012
 
@@ -54012,7 +54035,8 @@ class HostClient extends BaseEvernodeClient {
54012
54035
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: txHash }
54013
54036
  ],
54014
54037
  maxLedgerIndex: this.#getMaxLedgerSequence(),
54015
- ...options.transactionOptions
54038
+ ...options.transactionOptions,
54039
+ submissionRef: options.submissionRef
54016
54040
  });
54017
54041
  }
54018
54042
 
@@ -54038,7 +54062,8 @@ class HostClient extends BaseEvernodeClient {
54038
54062
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: txHash }
54039
54063
  ],
54040
54064
  maxLedgerIndex: this.#getMaxLedgerSequence(),
54041
- ...options.transactionOptions
54065
+ ...options.transactionOptions,
54066
+ submissionRef: options.submissionRef
54042
54067
  });
54043
54068
  }
54044
54069
 
@@ -54060,7 +54085,8 @@ class HostClient extends BaseEvernodeClient {
54060
54085
  { name: HookParamKeys.PARAM_EVENT_TYPE_KEY, value: EventTypes.HOST_REBATE }
54061
54086
  ],
54062
54087
  maxLedgerIndex: this.#getMaxLedgerSequence(),
54063
- ...options.transactionOptions
54088
+ ...options.transactionOptions,
54089
+ submissionRef: options.submissionRef
54064
54090
  });
54065
54091
  }
54066
54092
 
@@ -54086,7 +54112,7 @@ class HostClient extends BaseEvernodeClient {
54086
54112
 
54087
54113
  const regUriToken = await this.getRegistrationUriToken();
54088
54114
 
54089
- await this.#submitWithRetry(async (feeUplift) => {
54115
+ await this.#submitWithRetry(async (feeUplift, submissionRef) => {
54090
54116
  await this.xrplAcc.sellURIToken(regUriToken.index,
54091
54117
  XrplConstants.MIN_DROPS,
54092
54118
  null,
@@ -54099,10 +54125,10 @@ class HostClient extends BaseEvernodeClient {
54099
54125
  { name: HookParamKeys.PARAM_EVENT_DATA1_KEY, value: paramData.toString('hex') }
54100
54126
  ],
54101
54127
  maxLedgerIndex: this.#getMaxLedgerSequence(),
54102
- feeUplift: feeUplift,
54128
+ feeUplift: feeUplift, submissionRef: submissionRef,
54103
54129
  ...options.transactionOptions
54104
54130
  });
54105
- }, options.retryOptions);
54131
+ }, { ...(options.retryOptions ? options.retryOptions : {}), submissionRef: options.submissionRef });
54106
54132
 
54107
54133
  let token = null;
54108
54134
  let attempts = 0;
@@ -56512,7 +56538,7 @@ class XrplAccount {
56512
56538
 
56513
56539
  async setAccountFields(fields, options = {}) {
56514
56540
  const preparedTxn = await this.prepareSetAccountFields(fields, options);
56515
- return await this.signAndSubmit(preparedTxn);
56541
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56516
56542
  }
56517
56543
 
56518
56544
  async prepareSetAccountFields(fields, options = {}) {
@@ -56559,7 +56585,7 @@ class XrplAccount {
56559
56585
  async setSignerList(signerList = [], options = {}) {
56560
56586
 
56561
56587
  const preparedTxn = await this.prepareSetSignerList(signerList, options);
56562
- return await this.signAndSubmit(preparedTxn);
56588
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56563
56589
  }
56564
56590
 
56565
56591
  /**
@@ -56605,7 +56631,7 @@ class XrplAccount {
56605
56631
 
56606
56632
  async makePayment(toAddr, amount, currency = null, issuer = null, memos = null, options = {}) {
56607
56633
  const preparedTxn = await this.prepareMakePayment(toAddr, amount, currency, issuer, memos, options);
56608
- return await this.signAndSubmit(preparedTxn);
56634
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56609
56635
  }
56610
56636
 
56611
56637
  async prepareMakePayment(toAddr, amount, currency = null, issuer = null, memos = null, options = {}) {
@@ -56624,7 +56650,7 @@ class XrplAccount {
56624
56650
 
56625
56651
  async setTrustLine(currency, issuer, limit, allowRippling = false, memos = null, options = {}) {
56626
56652
  const preparedTxn = await this.prepareSetTrustLine(currency, issuer, limit, allowRippling, memos, options);
56627
- return await this.signAndSubmit(preparedTxn);
56653
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56628
56654
  }
56629
56655
 
56630
56656
  async prepareSetTrustLine(currency, issuer, limit, allowRippling = false, memos = null, options = {}) {
@@ -56652,7 +56678,7 @@ class XrplAccount {
56652
56678
 
56653
56679
  async setRegularKey(regularKey, memos = null, options = {}) {
56654
56680
  const preparedTxn = await this.prepareSetRegularKey(regularKey, memos, options);
56655
- return await this.signAndSubmit(preparedTxn);
56681
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56656
56682
  }
56657
56683
 
56658
56684
  async prepareSetRegularKey(regularKey, memos = null, options = {}) {
@@ -56668,7 +56694,7 @@ class XrplAccount {
56668
56694
 
56669
56695
  async cashCheck(check, options = {}) {
56670
56696
  const preparedTxn = await this.prepareCashCheck(check, options);
56671
- return await this.signAndSubmit(preparedTxn);
56697
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56672
56698
  }
56673
56699
 
56674
56700
  async prepareCashCheck(check, options = {}) {
@@ -56695,7 +56721,7 @@ class XrplAccount {
56695
56721
 
56696
56722
  async offerSell(sellAmount, sellCurrency, sellIssuer, forAmount, forCurrency, forIssuer = null, expiration = 4294967295, memos = null, options = {}) {
56697
56723
  const preparedTxn = await this.prepareOfferSell(sellAmount, sellCurrency, sellIssuer, forAmount, forCurrency, forIssuer, expiration, memos, options);
56698
- return await this.signAndSubmit(preparedTxn);
56724
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56699
56725
  }
56700
56726
 
56701
56727
  async prepareOfferSell(sellAmount, sellCurrency, sellIssuer, forAmount, forCurrency, forIssuer = null, expiration = 4294967295, memos = null, options = {}) {
@@ -56716,7 +56742,7 @@ class XrplAccount {
56716
56742
 
56717
56743
  async offerBuy(buyAmount, buyCurrency, buyIssuer, forAmount, forCurrency, forIssuer = null, expiration = 4294967295, memos = null, options = {}) {
56718
56744
  const preparedTxn = await this.prepareOfferBuy(buyAmount, buyCurrency, buyIssuer, forAmount, forCurrency, forIssuer, expiration, memos, options);
56719
- return await this.signAndSubmit(preparedTxn);
56745
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56720
56746
  }
56721
56747
 
56722
56748
  async prepareOfferBuy(buyAmount, buyCurrency, buyIssuer, forAmount, forCurrency, forIssuer = null, expiration = 4294967295, memos = null, options = {}) {
@@ -56737,7 +56763,7 @@ class XrplAccount {
56737
56763
 
56738
56764
  async cancelOffer(offerSequence, memos = null, options = {}) {
56739
56765
  const preparedTxn = await this.prepareCancelOffer(offerSequence, memos, options);
56740
- return await this.signAndSubmit(preparedTxn);
56766
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56741
56767
  }
56742
56768
 
56743
56769
  async prepareCancelOffer(offerSequence, memos = null, options = {}) {
@@ -56752,7 +56778,7 @@ class XrplAccount {
56752
56778
 
56753
56779
  async mintNft(uri, taxon, transferFee, flags = {}, memos = null, options = {}) {
56754
56780
  const preparedTxn = await this.prepareMintNft(uri, taxon, transferFee, flags, memos, options);
56755
- return await this.signAndSubmit(preparedTxn);
56781
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56756
56782
  }
56757
56783
 
56758
56784
  async prepareMintNft(uri, taxon, transferFee, flags = {}, memos = null, options = {}) {
@@ -56770,7 +56796,7 @@ class XrplAccount {
56770
56796
 
56771
56797
  async offerSellNft(nfTokenId, amount, currency, issuer = null, destination = null, expiration = 4294967295, memos = null, options = {}) {
56772
56798
  const preparedTxn = await this.prepareOfferSellNft(nfTokenId, amount, currency, issuer, destination, expiration, memos, options);
56773
- return await this.signAndSubmit(preparedTxn);
56799
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56774
56800
  }
56775
56801
 
56776
56802
  async prepareOfferSellNft(nfTokenId, amount, currency, issuer = null, destination = null, expiration = 4294967295, memos = null, options = {}) {
@@ -56792,7 +56818,7 @@ class XrplAccount {
56792
56818
 
56793
56819
  async offerBuyNft(nfTokenId, owner, amount, currency, issuer = null, expiration = 4294967295, memos = null, options = {}) {
56794
56820
  const preparedTxn = await this.prepareOfferSellNft(nfTokenId, owner, amount, currency, issuer, expiration, memos, options);
56795
- return await this.signAndSubmit(preparedTxn);
56821
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56796
56822
  }
56797
56823
 
56798
56824
  async prepareOfferBuyNft(nfTokenId, owner, amount, currency, issuer = null, expiration = 4294967295, memos = null, options = {}) {
@@ -56815,7 +56841,7 @@ class XrplAccount {
56815
56841
 
56816
56842
  async sellNft(offerId, memos = null, options = {}) {
56817
56843
  const preparedTxn = await this.prepareSellNft(offerId, memos, options);
56818
- return await this.signAndSubmit(preparedTxn);
56844
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56819
56845
  }
56820
56846
 
56821
56847
  async prepareSellNft(offerId, memos = null, options = {}) {
@@ -56831,7 +56857,7 @@ class XrplAccount {
56831
56857
 
56832
56858
  async buyNft(offerId, memos = null, options = {}) {
56833
56859
  const preparedTxn = await this.prepareBuyNft(offerId, memos, options);
56834
- return await this.signAndSubmit(preparedTxn);
56860
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56835
56861
  }
56836
56862
 
56837
56863
  async prepareBuyNft(offerId, memos = null, options = {}) {
@@ -56847,7 +56873,7 @@ class XrplAccount {
56847
56873
 
56848
56874
  async burnNft(nfTokenId, owner = null, memos = null, options = {}) {
56849
56875
  const preparedTxn = await this.prepareBurnNft(nfTokenId, owner, memos, options);
56850
- return await this.signAndSubmit(preparedTxn);
56876
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56851
56877
  }
56852
56878
 
56853
56879
  async prepareBurnNft(nfTokenId, owner = null, memos = null, options = {}) {
@@ -56963,7 +56989,7 @@ class XrplAccount {
56963
56989
 
56964
56990
  async mintURIToken(uri, digest = null, flags = {}, options = {}) {
56965
56991
  const preparedTxn = await this.prepareMintURIToken(uri, digest, flags, options);
56966
- return await this.signAndSubmit(preparedTxn);
56992
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56967
56993
  }
56968
56994
 
56969
56995
  async prepareMintURIToken(uri, digest = null, flags = {}, options = {}) {
@@ -56983,7 +57009,7 @@ class XrplAccount {
56983
57009
 
56984
57010
  async burnURIToken(uriTokenID, options = {}) {
56985
57011
  const preparedTxn = await this.prepareBurnURIToken(uriTokenID, options);
56986
- return await this.signAndSubmit(preparedTxn);
57012
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
56987
57013
  }
56988
57014
 
56989
57015
  async prepareBurnURIToken(uriTokenID, options = {}) {
@@ -56997,7 +57023,7 @@ class XrplAccount {
56997
57023
 
56998
57024
  async sellURIToken(uriTokenID, amount, currency, issuer = null, toAddr = null, memos = null, options = {}) {
56999
57025
  const preparedTxn = await this.prepareSellURIToken(uriTokenID, amount, currency, issuer, toAddr, memos, options);
57000
- return await this.signAndSubmit(preparedTxn);
57026
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
57001
57027
  }
57002
57028
 
57003
57029
  async prepareSellURIToken(uriTokenID, amount, currency, issuer = null, toAddr = null, memos = null, options = {}) {
@@ -57023,7 +57049,7 @@ class XrplAccount {
57023
57049
 
57024
57050
  async buyURIToken(uriToken, memos = null, options = {}) {
57025
57051
  const preparedTxn = await this.prepareBuyURIToken(uriToken, memos, options);
57026
- return await this.signAndSubmit(preparedTxn);
57052
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
57027
57053
  }
57028
57054
 
57029
57055
  async prepareBuyURIToken(uriToken, memos = null, options = {}) {
@@ -57045,7 +57071,7 @@ class XrplAccount {
57045
57071
 
57046
57072
  async clearURITokenOffer(uriTokenID, options = {}) {
57047
57073
  const preparedTxn = await this.prepareClearURITokenOffer(uriTokenID, options);
57048
- return await this.signAndSubmit(preparedTxn);
57074
+ return await this.signAndSubmit(preparedTxn, options.submissionRef);
57049
57075
  }
57050
57076
 
57051
57077
  async prepareClearURITokenOffer(uriTokenID, options = {}) {
@@ -57127,11 +57153,12 @@ class XrplAccount {
57127
57153
  /**
57128
57154
  * Sign and submit prepared transaction.
57129
57155
  * @param {object} preparedTransaction Prepared transaction.
57156
+ * @param {object} submissionRef [Optional] Reference object to take submission references.
57130
57157
  * @returns result of the submitted transaction.
57131
57158
  */
57132
- async signAndSubmit(preparedTransaction) {
57159
+ async signAndSubmit(preparedTransaction, submissionRef = {}) {
57133
57160
  const signedTxn = this.sign(preparedTransaction, false);
57134
- return await this.xrplApi.submitAndWait(preparedTransaction, signedTxn.tx_blob);
57161
+ return await this.xrplApi.submitAndWait(preparedTransaction, signedTxn.tx_blob, submissionRef);
57135
57162
  }
57136
57163
 
57137
57164
  /**
@@ -57218,7 +57245,7 @@ class XrplApi {
57218
57245
  }
57219
57246
 
57220
57247
  async #acquireClient() {
57221
- while (this.#isClientAcquired || this.#isConnectionAcquired) {
57248
+ while (!(this.#isPrimaryServerConnected || this.#isFallbackServerConnected) && this.#isClientAcquired) {
57222
57249
  await new Promise((resolve) => setTimeout(resolve, 100));
57223
57250
  }
57224
57251
  this.#isClientAcquired = true;
@@ -57229,7 +57256,7 @@ class XrplApi {
57229
57256
  }
57230
57257
 
57231
57258
  async #acquireConnection() {
57232
- while (this.#isClientAcquired) {
57259
+ while (this.#isConnectionAcquired) {
57233
57260
  await new Promise((resolve) => setTimeout(resolve, 100));
57234
57261
  }
57235
57262
  this.#isConnectionAcquired = true;
@@ -57240,16 +57267,15 @@ class XrplApi {
57240
57267
  }
57241
57268
 
57242
57269
  async #setXrplClient(client) {
57243
- await this.#acquireClient();
57244
57270
  try {
57245
- if (this.#client) // Clear all listeners if there's an already created client.
57271
+ if (this.#client) { // Clear all listeners if there's an already created client.
57246
57272
  await this.#client.removeAllListeners();
57273
+ await this.#client.disconnect();
57274
+ }
57247
57275
 
57248
57276
  this.#client = client;
57249
- this.#releaseClient();
57250
57277
  }
57251
57278
  catch (e) {
57252
- this.#releaseClient();
57253
57279
  console.log("Error occurred in Client initiation:", e)
57254
57280
  }
57255
57281
  }
@@ -57349,9 +57375,14 @@ class XrplApi {
57349
57375
  }
57350
57376
 
57351
57377
  async #attemptFallbackServerReconnect(maxRounds, attemptsPerServer = 3) {
57378
+ if (!this.#fallbackServers || this.#fallbackServers?.length == 0)
57379
+ return;
57380
+
57381
+ await this.#acquireClient();
57382
+
57352
57383
  const fallbackServers = this.#fallbackServers;
57353
57384
  let round = 0;
57354
- while (fallbackServers?.length > 0 && !this.#isPermanentlyDisconnected && !this.#isPrimaryServerConnected && !this.#isFallbackServerConnected && (!maxRounds || round < maxRounds)) { // Keep attempting until consumer calls disconnect() manually or if the primary server is disconnected.
57385
+ while (!this.#isPermanentlyDisconnected && !this.#isPrimaryServerConnected && !this.#isFallbackServerConnected && (!maxRounds || round < maxRounds)) { // Keep attempting until consumer calls disconnect() manually or if the primary server is disconnected.
57355
57386
  ++round;
57356
57387
  serverIterator:
57357
57388
  for (let serverIndex in fallbackServers) {
@@ -57361,8 +57392,8 @@ class XrplApi {
57361
57392
  break serverIterator;
57362
57393
  }
57363
57394
  ++attempt;
57395
+ const client = new xrpl.Client(server, this.#xrplClientOptions);
57364
57396
  try {
57365
- const client = new xrpl.Client(server, this.#xrplClientOptions);
57366
57397
  if (!this.#isPrimaryServerConnected) {
57367
57398
  await this.#handleClientConnect(client);
57368
57399
  this.#isFallbackServerConnected = true;
@@ -57370,67 +57401,90 @@ class XrplApi {
57370
57401
  break serverIterator;
57371
57402
  }
57372
57403
  catch (e) {
57373
- console.log(`Error occurred while connecting to fallback server ${server}`, e)
57404
+ this.#releaseClient();
57405
+ console.log(`Error occurred while connecting to fallback server ${server}`);
57406
+ await new Promise(resolve => setTimeout(resolve, 1000));
57407
+ if (client.isConnected()) {
57408
+ console.log('Connection closure already handled');
57409
+ await client.disconnect();
57410
+ }
57411
+
57374
57412
  if (!this.#isPermanentlyDisconnected) {
57375
57413
  if (!maxRounds || round < maxRounds)
57376
57414
  console.log(`Fallback server ${server} connection attempt ${attempt} failed. Retrying in ${2 * round}s...`);
57377
57415
  else
57378
- throw `Fallback server ${server} connection max attempts failed.`;
57416
+ return { error: `Fallback server ${server} connection max attempts failed.`, exception: e };
57379
57417
  await new Promise(resolve => setTimeout(resolve, 2 * round * 1000));
57380
57418
  }
57381
57419
  }
57382
57420
  }
57383
57421
  }
57384
-
57385
57422
  }
57423
+
57424
+ return {};
57386
57425
  }
57387
57426
 
57388
57427
  async #attemptPrimaryServerReconnect(maxAttempts = null) {
57428
+ await this.#acquireClient();
57429
+
57389
57430
  let attempt = 0;
57390
- while (!this.#isPermanentlyDisconnected && !this.#isPrimaryServerConnected) { // Keep attempting until consumer calls disconnect() manually.
57431
+ while (!this.#isPermanentlyDisconnected && !this.#isPrimaryServerConnected && !this.#isFallbackServerConnected) { // Keep attempting until consumer calls disconnect() manually.
57391
57432
  ++attempt;
57433
+ const client = new xrpl.Client(this.#primaryServer, this.#xrplClientOptions);
57392
57434
  try {
57393
- const client = new xrpl.Client(this.#primaryServer, this.#xrplClientOptions);
57394
57435
  await this.#handleClientConnect(client);
57395
- this.#isFallbackServerConnected = false;
57396
57436
  this.#isPrimaryServerConnected = true;
57397
57437
  break;
57398
57438
  }
57399
57439
  catch (e) {
57400
- console.log("Error occurred while re-connecting to the primary server", e)
57440
+ this.#releaseClient();
57441
+ console.log("Error occurred while re-connecting to the primary server")
57442
+ await new Promise(resolve => setTimeout(resolve, 1000));
57443
+ if (client.isConnected()) {
57444
+ console.log('Connection closure already handled');
57445
+ await client.disconnect();
57446
+ }
57447
+
57401
57448
  if (!this.#isPermanentlyDisconnected) {
57402
57449
  const delaySec = 2 * attempt; // Retry with backoff delay.
57403
57450
  if (!maxAttempts || attempt < maxAttempts)
57404
57451
  console.log(`Primary server ${this.#primaryServer} attempt ${attempt} failed. Retrying in ${delaySec}s...`);
57405
57452
  else
57406
- throw `Primary server ${this.#primaryServer} connection max attempts failed.`;
57453
+ return { error: `Primary server ${this.#primaryServer} connection max attempts failed.`, exception: e };
57407
57454
  await new Promise(resolve => setTimeout(resolve, delaySec * 1000));
57408
57455
  }
57409
57456
  }
57410
57457
  }
57458
+
57459
+ return {};
57411
57460
  }
57412
57461
 
57413
57462
  async #connectXrplClient(reconnect = false) {
57463
+ let res = [];
57414
57464
  if (reconnect) {
57415
57465
  if (this.#primaryServer) {
57416
- Promise.all([this.#attemptFallbackServerReconnect(), this.#attemptPrimaryServerReconnect()]);
57466
+ res = await Promise.all([this.#attemptPrimaryServerReconnect(), this.#attemptFallbackServerReconnect()]);
57417
57467
  } else {
57418
- this.#attemptFallbackServerReconnect();
57468
+ res = [await this.#attemptFallbackServerReconnect()];
57419
57469
  }
57420
57470
  }
57421
57471
  else {
57422
57472
  if (this.#primaryServer) {
57423
- Promise.all([this.#attemptFallbackServerReconnect(1, 1), this.#attemptPrimaryServerReconnect(1)]);
57473
+ res = await Promise.all([this.#attemptPrimaryServerReconnect(1), this.#attemptFallbackServerReconnect(1, 1)]);
57424
57474
  } else {
57425
- this.#attemptFallbackServerReconnect(1, 1);
57475
+ res = [await this.#attemptFallbackServerReconnect(1, 1)];
57426
57476
  }
57427
57477
  }
57428
57478
 
57429
- await this.#waitForConnection();
57479
+ if (res.filter(r => r && !r.error).length == 0)
57480
+ throw res.filter(r => r && r.error).map(r => r.error);
57430
57481
 
57431
57482
  // After connection established, check again whether maintainConnections has become false.
57432
57483
  // This is in case the consumer has called disconnect() while connection is being established.
57433
57484
  if (!this.#isPermanentlyDisconnected) {
57485
+ await this.#waitForConnection();
57486
+ this.#releaseClient();
57487
+
57434
57488
  this.ledgerIndex = await this.#getLedgerIndex();
57435
57489
 
57436
57490
  this.#subscribeToStream('ledger');
@@ -57440,6 +57494,7 @@ class XrplApi {
57440
57494
  await this.#handleClientRequest({ command: 'subscribe', accounts: this.#addressSubscriptions.map(s => s.address) });
57441
57495
  }
57442
57496
  else {
57497
+ this.#releaseClient();
57443
57498
  await this.disconnect();
57444
57499
  }
57445
57500
  }
@@ -57501,24 +57556,27 @@ class XrplApi {
57501
57556
 
57502
57557
  async connect() {
57503
57558
  this.#isPermanentlyDisconnected = false;
57504
- await this.#connectXrplClient();
57559
+
57560
+ if (!this.#client || !this.#client.isConnected()) {
57561
+ await this.#connectXrplClient();
57562
+ }
57505
57563
  const definitions = await this.#handleClientRequest({ command: 'server_definitions' })
57506
57564
  this.xrplHelper = new XrplHelpers(definitions.result);
57507
57565
  }
57508
57566
 
57509
57567
  async disconnect() {
57510
- await this.#acquireClient();
57568
+ await this.#acquireConnection();
57511
57569
 
57512
57570
  try {
57513
57571
  this.#isPermanentlyDisconnected = true;
57514
57572
 
57515
- if (this.#client.isConnected()) {
57573
+ if (this.#client && this.#client.isConnected()) {
57516
57574
  await this.#client.disconnect().catch(console.error);
57517
57575
  }
57518
- this.#releaseClient();
57576
+ this.#releaseConnection();
57519
57577
  }
57520
57578
  catch (e) {
57521
- this.#releaseClient();
57579
+ this.#releaseConnection();
57522
57580
  throw e;
57523
57581
  }
57524
57582
  }
@@ -57655,6 +57713,28 @@ class XrplApi {
57655
57713
  await this.#handleClientRequest({ command: 'subscribe', streams: [streamName] });
57656
57714
  }
57657
57715
 
57716
+ /**
57717
+ * Get the transaction results if validated.
57718
+ * @param {string} txHash Hash of the transaction to check.
57719
+ * @returns Validated results of the transaction.
57720
+ */
57721
+ async getTransactionValidatedResults(txHash) {
57722
+ const txResponse = await this.getTxnInfo(txHash)
57723
+ .catch((e) => {
57724
+ return null;
57725
+ });
57726
+
57727
+ if (txResponse?.validated) {
57728
+ return {
57729
+ id: txResponse?.hash,
57730
+ code: txResponse?.meta?.TransactionResult,
57731
+ details: txResponse
57732
+ };
57733
+ }
57734
+
57735
+ return null;
57736
+ }
57737
+
57658
57738
  /**
57659
57739
  * Watching to acquire the transaction submission. (Waits until txn. is applied to the ledger.)
57660
57740
  * @param {string} txHash Transaction Hash
@@ -57723,18 +57803,18 @@ class XrplApi {
57723
57803
  return { ...txResult, ...(hookExecRes ? { hookExecutionResult: hookExecRes } : {}) };
57724
57804
  else
57725
57805
  throw { ...txResult, ...(hookExecRes ? { hookExecutionResult: hookExecRes } : {}) };
57726
-
57727
57806
  }
57728
57807
 
57729
57808
  /**
57730
57809
  * Submit a multi-signature transaction and wait for validation.
57731
57810
  * @param {object} tx Multi-signed transaction object.
57811
+ * @param {object} submissionRef [Optional] Reference object to take submission references.
57732
57812
  * @returns response object of the validated transaction.
57733
57813
  */
57734
- async submitMultisignedAndWait(tx) {
57814
+ async submitMultisignedAndWait(tx, submissionRef = {}) {
57735
57815
  tx.SigningPubKey = "";
57736
- const submissionResult = await this.#handleClientRequest({ command: 'submit_multisigned', tx_json: tx });
57737
- return await this.#prepareResponse(tx, submissionResult);
57816
+ submissionRef.submissionResult = await this.#handleClientRequest({ command: 'submit_multisigned', tx_json: tx });
57817
+ return await this.#prepareResponse(tx, submissionRef.submissionResult);
57738
57818
  }
57739
57819
 
57740
57820
  /**
@@ -57750,11 +57830,12 @@ class XrplApi {
57750
57830
  /**
57751
57831
  * Submit a single-signature transaction.
57752
57832
  * @param {string} tx_blob Signed transaction object.
57833
+ * @param {object} submissionRef [Optional] Reference object to take submission references.
57753
57834
  * @returns response object of the validated transaction.
57754
57835
  */
57755
- async submitAndWait(tx, tx_blob) {
57756
- const submissionResult = await this.#handleClientRequest({ command: 'submit', tx_blob: tx_blob });
57757
- return await this.#prepareResponse(tx, submissionResult);
57836
+ async submitAndWait(tx, tx_blob, submissionRef = {}) {
57837
+ submissionRef.submissionResult = await this.#handleClientRequest({ command: 'submit', tx_blob: tx_blob });
57838
+ return await this.#prepareResponse(tx, submissionRef.submissionResult);
57758
57839
  }
57759
57840
 
57760
57841
  /**
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  ],
7
7
  "homepage": "https://github.com/HotPocketDev/evernode-js-client",
8
8
  "license": "SEE LICENSE IN https://raw.githubusercontent.com/EvernodeXRPL/evernode-resources/main/license/evernode-license.pdf",
9
- "version": "0.6.35",
9
+ "version": "0.6.37",
10
10
  "dependencies": {
11
11
  "elliptic": "6.5.4",
12
12
  "libsodium-wrappers": "0.7.10",