evernode-js-client 0.6.21 → 0.6.23

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 +132 -90
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -51840,6 +51840,7 @@ const { FirestoreHandler } = __nccwpck_require__(9718);
51840
51840
  const { StateHelpers } = __nccwpck_require__(3860);
51841
51841
  const { EvernodeHelpers } = __nccwpck_require__(2523);
51842
51842
  const { HookHelpers } = __nccwpck_require__(4675);
51843
+ const xrpl = __nccwpck_require__(4666);
51843
51844
 
51844
51845
  const CANDIDATE_PROPOSE_HASHES_PARAM_OFFSET = 0;
51845
51846
  const CANDIDATE_PROPOSE_KEYLETS_PARAM_OFFSET = 96;
@@ -52219,7 +52220,7 @@ class BaseEvernodeClient {
52219
52220
  extendRefId: tx.hash,
52220
52221
  tenant: tx.Account,
52221
52222
  currency: tx.Amount.currency,
52222
- payment: parseFloat(tx.Amount.value),
52223
+ payment: (tx.Flags & xrpl.PaymentFlags.tfPartialPayment) ? parseFloat(tx.DeliveredAmount.value) : parseFloat(tx.Amount.value),
52223
52224
  uriTokenId: uriTokenId
52224
52225
  }
52225
52226
  }
@@ -54219,6 +54220,10 @@ class TenantClient extends BaseEvernodeClient {
54219
54220
  for (let t of txList) {
54220
54221
  t.tx.Memos = TransactionHelper.deserializeMemos(t.tx?.Memos);
54221
54222
  t.tx.HookParameters = TransactionHelper.deserializeHookParams(t.tx?.HookParameters);
54223
+
54224
+ if (t.meta?.delivered_amount)
54225
+ t.tx.DeliveredAmount = t.meta.delivered_amount;
54226
+
54222
54227
  const res = await this.extractEvernodeEvent(t.tx);
54223
54228
  if ((res?.name === EvernodeEvents.AcquireSuccess || res?.name === EvernodeEvents.AcquireError) && res?.data?.acquireRefId === tx.id) {
54224
54229
  clearTimeout(failTimeout);
@@ -54330,6 +54335,10 @@ class TenantClient extends BaseEvernodeClient {
54330
54335
  for (let t of txList) {
54331
54336
  t.tx.Memos = TransactionHelper.deserializeMemos(t.tx.Memos);
54332
54337
  t.tx.HookParameters = TransactionHelper.deserializeHookParams(t.tx?.HookParameters);
54338
+
54339
+ if (t.meta?.delivered_amount)
54340
+ t.tx.DeliveredAmount = t.meta.delivered_amount;
54341
+
54333
54342
  const res = await this.extractEvernodeEvent(t.tx);
54334
54343
  if ((res?.name === TenantEvents.ExtendSuccess || res?.name === TenantEvents.ExtendError) && res?.data?.extendRefId === tx.id) {
54335
54344
  clearTimeout(failTimeout);
@@ -54413,6 +54422,7 @@ const DefinitionsUrl = 'https://raw.githubusercontent.com/EvernodeXRPL/evernode-
54413
54422
 
54414
54423
  const DefaultValues = {
54415
54424
  xrplApi: null,
54425
+ useCentralizedRegistry: false,
54416
54426
  }
54417
54427
 
54418
54428
  const HookTypes = {
@@ -55322,6 +55332,11 @@ class FirestoreHandler {
55322
55332
  * @returns Result set.
55323
55333
  */
55324
55334
  async sendRequest(httpMethod, url, params = null, data = null, options = null) {
55335
+ if (!Defaults.values.useCentralizedRegistry) {
55336
+ console.warn("Please change the useCentralizedRegistry flag to true in Defaults if you want to use this function!")
55337
+ throw new Error("Centralized function is in use!!")
55338
+ }
55339
+
55325
55340
  const urlObj = new URL(url);
55326
55341
  // Populate uri params to the URL object.
55327
55342
  if (params) {
@@ -57287,6 +57302,9 @@ class XrplAccount {
57287
57302
  NetworkID: Defaults.values.networkID
57288
57303
  }
57289
57304
 
57305
+ if (options?.Flags)
57306
+ txOptions.Flags = options.Flags;
57307
+
57290
57308
  Object.assign(tx, txOptions);
57291
57309
  const txnBlob = this.xrplApi.xrplHelper.encode(tx);
57292
57310
  const fees = options.fee || await this.xrplApi.getTransactionFee(txnBlob);
@@ -57365,12 +57383,11 @@ class XrplApi {
57365
57383
  #client;
57366
57384
  #events = new EventEmitter();
57367
57385
  #addressSubscriptions = [];
57368
- #initialConnectCalled = false;
57369
57386
  #isPermanentlyDisconnected = false;
57370
- #isClientLocked = false;
57387
+ #isConnectionAcquired = false;
57388
+ #isClientAcquired = false;
57371
57389
  #isPrimaryServerConnected = false;
57372
57390
  #isFallbackServerConnected = false;
57373
- #isAttemptingConnection = false;
57374
57391
  #xrplClientOptions;
57375
57392
  #autoReconnect;
57376
57393
 
@@ -57386,47 +57403,77 @@ class XrplApi {
57386
57403
  throw 'Either primaryServer or fallbackServers required.';
57387
57404
 
57388
57405
  this.#xrplClientOptions = options.xrplClientOptions;
57389
- const initServer = this.#primaryServer || this.#fallbackServers[0];
57390
- const client = new xrpl.Client(initServer, this.#xrplClientOptions);
57391
- this.#initXrplClient(client);
57392
57406
  this.#autoReconnect = options.autoReconnect ?? true;
57393
57407
  }
57394
57408
 
57395
- async #setClient(client, removeCurrentClient = false) {
57396
- while (this.#isClientLocked) {
57409
+ async #acquireClient() {
57410
+ while (this.#isClientAcquired || this.#isConnectionAcquired) {
57397
57411
  await new Promise((resolve) => setTimeout(resolve, 100));
57398
57412
  }
57399
- if (removeCurrentClient) {
57400
- this.#isClientLocked = true;
57401
- this.#client.removeAllListeners(); // Remove existing event listeners to avoid them getting called from the old client object.
57402
- await this.#client.disconnect();
57403
- this.#isClientLocked = false;
57404
- }
57405
- this.#client = client;
57413
+ this.#isClientAcquired = true;
57406
57414
  }
57407
57415
 
57408
- async #initXrplClient(client) {
57409
- if (this.#client) { // If the client already exists, clean it up.
57410
- await this.#setClient(null, true);
57416
+ #releaseClient() {
57417
+ this.#isClientAcquired = false;
57418
+ }
57419
+
57420
+ async #acquireConnection() {
57421
+ while (this.#isClientAcquired) {
57422
+ await new Promise((resolve) => setTimeout(resolve, 100));
57411
57423
  }
57424
+ this.#isConnectionAcquired = true;
57425
+ }
57412
57426
 
57427
+ #releaseConnection() {
57428
+ this.#isConnectionAcquired = false;
57429
+ }
57430
+
57431
+ async #setXrplClient(client) {
57432
+ await this.#acquireClient();
57413
57433
  try {
57414
- await this.#setClient(client);
57434
+ if (this.#client) // Clear all listeners if there's an already created client.
57435
+ await this.#client.removeAllListeners();
57436
+
57437
+ this.#client = client;
57438
+ this.#releaseClient();
57415
57439
  }
57416
57440
  catch (e) {
57441
+ this.#releaseClient();
57417
57442
  console.log("Error occurred in Client initiation:", e)
57418
57443
  }
57444
+ }
57419
57445
 
57420
- this.#client.on('error', (errorCode, errorMessage) => {
57446
+ async #handleClientConnect(client) {
57447
+ await this.#initEventListeners(client);
57448
+
57449
+ if (!client.isConnected())
57450
+ await client.connect();
57451
+ }
57452
+
57453
+ async #initEventListeners(client) {
57454
+ // First remove all the listeners.
57455
+ try {
57456
+ await client.removeAllListeners();
57457
+ }
57458
+ catch { }
57459
+
57460
+ client.on('error', (errorCode, errorMessage) => {
57421
57461
  console.log(errorCode + ': ' + errorMessage);
57422
57462
  });
57423
57463
 
57424
- this.#client.on('disconnected', (code) => {
57464
+ client.on('connected', async () => {
57465
+ await this.#setXrplClient(client)
57466
+ });
57467
+
57468
+ client.on('disconnected', async (code) => {
57469
+ this.#isPrimaryServerConnected = false;
57470
+ this.#isFallbackServerConnected = false;
57471
+
57425
57472
  if (this.#autoReconnect && !this.#isPermanentlyDisconnected) {
57426
- console.log(`Connection failure for ${this.#client.url} (code:${code})`);
57473
+ console.log(`Connection failure for ${client.url} (code:${code})`);
57427
57474
  console.log("Re-initializing xrpl client.");
57428
57475
  try {
57429
- this.#initXrplClient(this.#client).then(() => this.#connectXrplClient(true));
57476
+ await this.#connectXrplClient(true);
57430
57477
  }
57431
57478
  catch (e) {
57432
57479
  console.log("Error occurred while re-initializing", e)
@@ -57434,12 +57481,12 @@ class XrplApi {
57434
57481
  }
57435
57482
  });
57436
57483
 
57437
- this.#client.on('ledgerClosed', (ledger) => {
57484
+ client.on('ledgerClosed', (ledger) => {
57438
57485
  this.ledgerIndex = ledger.ledger_index;
57439
57486
  this.#events.emit(XrplApiEvents.LEDGER, ledger);
57440
57487
  });
57441
57488
 
57442
- this.#client.on("transaction", async (data) => {
57489
+ client.on("transaction", async (data) => {
57443
57490
  if (data.validated) {
57444
57491
  // NFTokenAcceptOffer transactions does not contain a Destination. So we check whether the accepted offer is created by which subscribed account
57445
57492
  if (data.transaction.TransactionType === 'URITokenBuy') {
@@ -57467,7 +57514,12 @@ class XrplApi {
57467
57514
  LedgerHash: data.ledger_hash,
57468
57515
  LedgerIndex: data.ledger_index,
57469
57516
  ...data.transaction
57470
- }; // Create an object copy. Otherwise xrpl client will mutate the transaction object,
57517
+ };
57518
+
57519
+ if (data.meta?.delivered_amount)
57520
+ tx.DeliveredAmount = data.meta.delivered_amount;
57521
+
57522
+ // Create an object copy. Otherwise xrpl client will mutate the transaction object,
57471
57523
  const eventName = tx.TransactionType.toLowerCase();
57472
57524
  // Emit the event only for successful transactions, Otherwise emit error.
57473
57525
  if (data.engine_result === "tesSUCCESS") {
@@ -57480,7 +57532,6 @@ class XrplApi {
57480
57532
  }
57481
57533
  }
57482
57534
  }
57483
-
57484
57535
  });
57485
57536
  }
57486
57537
 
@@ -57496,30 +57547,22 @@ class XrplApi {
57496
57547
  if (this.#isPrimaryServerConnected || this.#isPermanentlyDisconnected) {
57497
57548
  break serverIterator;
57498
57549
  }
57499
- console.log(`Fallback server ${server} reconnection attempt ${++attempt}`);
57550
+ ++attempt;
57500
57551
  try {
57501
- while (this.#isAttemptingConnection) {
57502
- await new Promise((resolve) => setTimeout(resolve, 100));
57503
- }
57504
- this.#isAttemptingConnection = true;
57505
57552
  const client = new xrpl.Client(server, this.#xrplClientOptions);
57506
57553
  if (!this.#isPrimaryServerConnected) {
57507
57554
  await this.#handleClientConnect(client);
57508
- await this.#initXrplClient(client);
57509
57555
  this.#isFallbackServerConnected = true;
57510
- console.log(`Successfully connected to the fallback server ${server}`)
57511
57556
  }
57512
- this.#isAttemptingConnection = false;
57513
57557
  break serverIterator;
57514
57558
  }
57515
57559
  catch (e) {
57516
57560
  console.log(`Error occurred while connecting to fallback server ${server}`, e)
57517
- this.#isAttemptingConnection = false;
57518
57561
  if (!this.#isPermanentlyDisconnected) {
57519
57562
  if (!maxRounds || round < maxRounds)
57520
57563
  console.log(`Fallback server ${server} connection attempt ${attempt} failed. Retrying in ${2 * round}s...`);
57521
57564
  else
57522
- console.log(`Fallback server ${server} connection attempt failed.`);
57565
+ throw `Fallback server ${server} connection max attempts failed.`;
57523
57566
  await new Promise(resolve => setTimeout(resolve, 2 * round * 1000));
57524
57567
  }
57525
57568
  }
@@ -57529,30 +57572,25 @@ class XrplApi {
57529
57572
  }
57530
57573
  }
57531
57574
 
57532
- async #attemptPrimaryServerReconnect() {
57575
+ async #attemptPrimaryServerReconnect(maxAttempts = null) {
57533
57576
  let attempt = 0;
57534
57577
  while (!this.#isPermanentlyDisconnected && !this.#isPrimaryServerConnected) { // Keep attempting until consumer calls disconnect() manually.
57535
- console.log(`Primary server reconnection attempt ${++attempt}`);
57578
+ ++attempt;
57536
57579
  try {
57537
57580
  const client = new xrpl.Client(this.#primaryServer, this.#xrplClientOptions);
57538
- while (this.#isAttemptingConnection) {
57539
- await new Promise((resolve) => setTimeout(resolve, 100));
57540
- }
57541
- this.#isAttemptingConnection = true;
57542
57581
  await this.#handleClientConnect(client);
57543
- await this.#initXrplClient(client);
57544
57582
  this.#isFallbackServerConnected = false;
57545
57583
  this.#isPrimaryServerConnected = true;
57546
- console.log("Successfully connected to the primary server");
57547
- this.#isAttemptingConnection = false;
57548
57584
  break;
57549
57585
  }
57550
57586
  catch (e) {
57551
57587
  console.log("Error occurred while re-connecting to the primary server", e)
57552
- this.#isAttemptingConnection = false;
57553
57588
  if (!this.#isPermanentlyDisconnected) {
57554
57589
  const delaySec = 2 * attempt; // Retry with backoff delay.
57555
- console.log(`Attempt ${attempt} failed. Retrying in ${delaySec}s...`);
57590
+ if (!maxAttempts || attempt < maxAttempts)
57591
+ console.log(`Primary server ${this.#primaryServer} attempt ${attempt} failed. Retrying in ${delaySec}s...`);
57592
+ else
57593
+ throw `Primary server ${this.#primaryServer} connection max attempts failed.`;
57556
57594
  await new Promise(resolve => setTimeout(resolve, delaySec * 1000));
57557
57595
  }
57558
57596
  }
@@ -57566,26 +57604,22 @@ class XrplApi {
57566
57604
  } else {
57567
57605
  this.#attemptFallbackServerReconnect();
57568
57606
  }
57569
- await this.#waitForReconnection();
57570
57607
  }
57571
57608
  else {
57572
- // Single attempt and throw error. Used for initial connect() call.
57573
- try {
57574
- await this.#handleClientConnect();
57575
- this.#isPrimaryServerConnected = true;
57576
- } catch {
57577
- await this.#attemptFallbackServerReconnect(1, 1);
57578
- if (this.#isFallbackServerConnected)
57579
- await this.#attemptPrimaryServerReconnect();
57609
+ if (this.#primaryServer) {
57610
+ Promise.all([this.#attemptFallbackServerReconnect(1, 1), this.#attemptPrimaryServerReconnect(1)]);
57611
+ } else {
57612
+ this.#attemptFallbackServerReconnect(1, 1);
57580
57613
  }
57581
57614
  }
57582
57615
 
57616
+ await this.#waitForConnection();
57617
+
57583
57618
  // After connection established, check again whether maintainConnections has become false.
57584
57619
  // This is in case the consumer has called disconnect() while connection is being established.
57585
57620
  if (!this.#isPermanentlyDisconnected) {
57586
- this.#isClientLocked = true;
57587
- this.ledgerIndex = await this.#client.getLedgerIndex();
57588
- this.#isClientLocked = false;
57621
+ this.ledgerIndex = await this.#getLedgerIndex();
57622
+
57589
57623
  this.#subscribeToStream('ledger');
57590
57624
 
57591
57625
  // Re-subscribe to existing account address subscriptions (in case this is a reconnect)
@@ -57621,20 +57655,16 @@ class XrplApi {
57621
57655
  }
57622
57656
 
57623
57657
  async #handleClientRequest(request = {}) {
57624
- while (this.#isAttemptingConnection) {
57625
- await new Promise((resolve) => setTimeout(resolve, 100));
57658
+ await this.#acquireConnection();
57659
+ try {
57660
+ const response = await this.#client.request(request);
57661
+ this.#releaseConnection();
57662
+ return response;
57663
+ }
57664
+ catch (e) {
57665
+ this.#releaseConnection();
57666
+ throw e;
57626
57667
  }
57627
- this.#isClientLocked = true;
57628
- const response = await this.#client.request(request);
57629
-
57630
- this.#isClientLocked = false;
57631
- return response;
57632
- }
57633
-
57634
- async #handleClientConnect(client = this.#client) {
57635
- this.#isClientLocked = true;
57636
- await client.connect();
57637
- this.#isClientLocked = false;
57638
57668
  }
57639
57669
 
57640
57670
  on(event, handler) {
@@ -57649,7 +57679,7 @@ class XrplApi {
57649
57679
  this.#events.off(event, handler);
57650
57680
  }
57651
57681
 
57652
- async #waitForReconnection() {
57682
+ async #waitForConnection() {
57653
57683
  while (!(this.#isPrimaryServerConnected || this.#isFallbackServerConnected)) {
57654
57684
  await new Promise(resolve => setTimeout(resolve, 100));
57655
57685
  }
@@ -57657,10 +57687,6 @@ class XrplApi {
57657
57687
  }
57658
57688
 
57659
57689
  async connect() {
57660
- if (this.#initialConnectCalled) {
57661
- return
57662
- }
57663
- this.#initialConnectCalled = true;
57664
57690
  this.#isPermanentlyDisconnected = false;
57665
57691
  await this.#connectXrplClient();
57666
57692
  const definitions = await this.#handleClientRequest({ command: 'server_definitions' })
@@ -57668,15 +57694,33 @@ class XrplApi {
57668
57694
  }
57669
57695
 
57670
57696
  async disconnect() {
57671
- this.#initialConnectCalled = false;
57672
- this.#isPermanentlyDisconnected = true;
57697
+ await this.#acquireClient();
57673
57698
 
57674
- if (this.#client.isConnected()) {
57675
- this.#isClientLocked = true;
57676
- await this.#client.disconnect().catch(console.error);
57677
- this.#isClientLocked = false;
57678
- this.#isPrimaryServerConnected = false;
57679
- this.#isFallbackServerConnected = false;
57699
+ try {
57700
+ this.#isPermanentlyDisconnected = true;
57701
+
57702
+ if (this.#client.isConnected()) {
57703
+ await this.#client.disconnect().catch(console.error);
57704
+ }
57705
+ this.#releaseClient();
57706
+ }
57707
+ catch (e) {
57708
+ this.#releaseClient();
57709
+ throw e;
57710
+ }
57711
+ }
57712
+
57713
+ async #getLedgerIndex() {
57714
+ await this.#acquireConnection();
57715
+
57716
+ try {
57717
+ const index = await this.#client.getLedgerIndex();
57718
+ this.#releaseConnection();
57719
+ return index;
57720
+ }
57721
+ catch (e) {
57722
+ this.#releaseConnection();
57723
+ throw e;
57680
57724
  }
57681
57725
  }
57682
57726
 
@@ -57806,9 +57850,7 @@ class XrplApi {
57806
57850
 
57807
57851
  await new Promise(r => setTimeout(r, LEDGER_CLOSE_TIME));
57808
57852
 
57809
- this.#isClientLocked = true;
57810
- const latestLedger = await this.#client.getLedgerIndex();
57811
- this.#isClientLocked = false;
57853
+ const latestLedger = await this.#getLedgerIndex();
57812
57854
 
57813
57855
  if (lastLedger < latestLedger) {
57814
57856
  throw `The latest ledger sequence ${latestLedger} is greater than the transaction's LastLedgerSequence (${lastLedger}).\n` +
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.6.21",
9
+ "version": "0.6.23",
10
10
  "dependencies": {
11
11
  "elliptic": "6.5.4",
12
12
  "libsodium-wrappers": "0.7.10",