evernode-js-client 0.6.21 → 0.6.23

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 +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",