@injectivelabs/sdk-ts 1.19.26 → 1.19.27

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.
@@ -262,6 +262,377 @@ const getTxRawFromTxRawOrDirectSignResponse = (txRawOrDirectSignResponse) => {
262
262
  return txRawOrDirectSignResponse.signed === void 0 ? txRawOrDirectSignResponse : createTxRawFromSigResponse(txRawOrDirectSignResponse);
263
263
  };
264
264
 
265
+ //#endregion
266
+ //#region src/core/tx/types/tx.ts
267
+ const TxInclusionStrategy = {
268
+ Poll: "poll",
269
+ TendermintEvent: "tendermint-event",
270
+ TendermintEventAndPoll: "tendermint-event-and-poll"
271
+ };
272
+ const TxClientMode = {
273
+ gRpc: "grpc",
274
+ rest: "rest"
275
+ };
276
+
277
+ //#endregion
278
+ //#region src/core/tx/api/TxEventInclusion.ts
279
+ function normalizeTendermintWebSocketEndpoint(endpoint) {
280
+ let normalized = endpoint;
281
+ if (normalized.startsWith("http://")) normalized = `ws://${normalized.slice(7)}`;
282
+ else if (normalized.startsWith("https://")) normalized = `wss://${normalized.slice(8)}`;
283
+ return normalized.endsWith("/websocket") ? normalized : `${normalized.replace(/\/$/, "")}/websocket`;
284
+ }
285
+ async function subscribeToTendermintTxEvent({ txHash, timeout, endpoint, webSocketFactory }) {
286
+ const normalizedTxHash = normalizeTendermintTxHash(txHash);
287
+ const socket = createTendermintSocket(normalizeTendermintWebSocketEndpoint(endpoint), webSocketFactory);
288
+ const query = `tm.event='Tx' AND tx.hash='${normalizedTxHash}'`;
289
+ const requestId = `tx-event-${Date.now()}-${Math.random()}`;
290
+ return new Promise((resolve, reject) => {
291
+ let ready = false;
292
+ let waitSettled = false;
293
+ let closedIntentionally = false;
294
+ let timeoutId;
295
+ let waitResolve;
296
+ let waitReject;
297
+ const waitPromise = new Promise((resolveWait$1, rejectWait$1) => {
298
+ waitResolve = resolveWait$1;
299
+ waitReject = rejectWait$1;
300
+ });
301
+ const resolveSubscription = () => {
302
+ if (ready) return;
303
+ ready = true;
304
+ resolve({
305
+ close: cleanup,
306
+ wait: () => waitPromise
307
+ });
308
+ };
309
+ const cleanup = () => {
310
+ closedIntentionally = true;
311
+ clearTimeout(timeoutId);
312
+ socket.removeEventListener("open", onOpen);
313
+ socket.removeEventListener("message", onMessage);
314
+ socket.removeEventListener("error", onError);
315
+ socket.removeEventListener("close", onClose);
316
+ if (socket.readyState === 1 || socket.readyState === 0) socket.close();
317
+ };
318
+ const rejectWait = (error) => {
319
+ if (waitSettled) return;
320
+ waitSettled = true;
321
+ waitReject(error);
322
+ cleanup();
323
+ };
324
+ timeoutId = setTimeout(() => {
325
+ const error = /* @__PURE__ */ new Error(`Timed out waiting for Tendermint tx event after ${timeout}ms`);
326
+ if (ready) {
327
+ rejectWait(error);
328
+ return;
329
+ }
330
+ cleanup();
331
+ reject(error);
332
+ }, timeout);
333
+ const resolveWait = (response) => {
334
+ if (waitSettled) return;
335
+ waitSettled = true;
336
+ waitResolve(response);
337
+ cleanup();
338
+ };
339
+ const rejectForMessageError = (error) => {
340
+ if (ready) {
341
+ rejectWait(error);
342
+ return;
343
+ }
344
+ cleanup();
345
+ reject(error);
346
+ };
347
+ const onOpen = () => {
348
+ socket.send(JSON.stringify({
349
+ id: requestId,
350
+ jsonrpc: "2.0",
351
+ method: "subscribe",
352
+ params: { query }
353
+ }));
354
+ };
355
+ const onMessage = (event) => {
356
+ readMessageEventData(event).then((messageData) => {
357
+ const message = JSON.parse(messageData);
358
+ const eventResponse = parseTxEventResponse(message, normalizedTxHash);
359
+ if (eventResponse) {
360
+ resolveSubscription();
361
+ resolveWait(eventResponse);
362
+ return;
363
+ }
364
+ if (message.id !== requestId) return;
365
+ if (message.error) {
366
+ rejectForMessageError(/* @__PURE__ */ new Error(`Tendermint subscribe failed: ${JSON.stringify(message.error)}`));
367
+ return;
368
+ }
369
+ resolveSubscription();
370
+ }).catch((error) => {
371
+ rejectForMessageError(error instanceof Error ? error : /* @__PURE__ */ new Error(`Invalid Tendermint WebSocket JSON: ${String(error)}`));
372
+ });
373
+ };
374
+ const onError = () => {
375
+ const error = /* @__PURE__ */ new Error("Tendermint WebSocket error");
376
+ if (ready) {
377
+ rejectWait(error);
378
+ return;
379
+ }
380
+ cleanup();
381
+ reject(error);
382
+ };
383
+ const onClose = () => {
384
+ if (closedIntentionally) return;
385
+ const error = /* @__PURE__ */ new Error("Tendermint WebSocket closed");
386
+ if (ready) {
387
+ rejectWait(error);
388
+ return;
389
+ }
390
+ cleanup();
391
+ reject(error);
392
+ };
393
+ socket.addEventListener("open", onOpen);
394
+ socket.addEventListener("message", onMessage);
395
+ socket.addEventListener("error", onError);
396
+ socket.addEventListener("close", onClose);
397
+ });
398
+ }
399
+ function normalizeTendermintTxHash(txHash) {
400
+ if (!/^[0-9a-fA-F]{64}$/.test(txHash)) throw new Error("Invalid Tendermint tx hash");
401
+ return txHash.toUpperCase();
402
+ }
403
+ function createTendermintSocket(endpoint, webSocketFactory) {
404
+ if (webSocketFactory) return webSocketFactory(endpoint);
405
+ if (!globalThis.WebSocket) throw new Error("WebSocket is not available in this environment");
406
+ return new globalThis.WebSocket(endpoint);
407
+ }
408
+ async function readMessageEventData(event) {
409
+ const { data } = event;
410
+ if (typeof data === "string") return data;
411
+ if (typeof Blob !== "undefined" && data instanceof Blob) return data.text();
412
+ if (typeof ArrayBuffer !== "undefined" && data instanceof ArrayBuffer) return new TextDecoder().decode(data);
413
+ if (ArrayBuffer.isView(data)) return new TextDecoder().decode(data);
414
+ return String(data);
415
+ }
416
+ function parseTxEventResponse(message, txHash) {
417
+ var _message$params$resul, _message$params, _message$result, _data$value, _ref, _value$TxResult, _txResult$result;
418
+ const data = (_message$params$resul = message === null || message === void 0 || (_message$params = message.params) === null || _message$params === void 0 || (_message$params = _message$params.result) === null || _message$params === void 0 ? void 0 : _message$params.data) !== null && _message$params$resul !== void 0 ? _message$params$resul : message === null || message === void 0 || (_message$result = message.result) === null || _message$result === void 0 ? void 0 : _message$result.data;
419
+ const eventTxHashes = readTxEventHashes(data);
420
+ if (eventTxHashes.length > 0 && !eventTxHashes.some((eventTxHash) => eventTxHash.toUpperCase() === txHash.toUpperCase())) return;
421
+ const value = (_data$value = data === null || data === void 0 ? void 0 : data.value) !== null && _data$value !== void 0 ? _data$value : data;
422
+ const txResult = (_ref = (_value$TxResult = value === null || value === void 0 ? void 0 : value.TxResult) !== null && _value$TxResult !== void 0 ? _value$TxResult : value === null || value === void 0 ? void 0 : value.tx_result) !== null && _ref !== void 0 ? _ref : value;
423
+ const result = (_txResult$result = txResult === null || txResult === void 0 ? void 0 : txResult.result) !== null && _txResult$result !== void 0 ? _txResult$result : txResult === null || txResult === void 0 ? void 0 : txResult.Result;
424
+ if (!txResult || !result) return;
425
+ return {
426
+ txHash,
427
+ logs: [],
428
+ timestamp: "",
429
+ data: result.data || "",
430
+ info: result.info || "",
431
+ events: result.events || [],
432
+ code: Number(result.code || 0),
433
+ codespace: result.codespace || "",
434
+ rawLog: result.log || result.raw_log || "",
435
+ height: Number(txResult.height || (value === null || value === void 0 ? void 0 : value.height) || 0),
436
+ gasUsed: Number(result.gas_used || result.gasUsed || 0),
437
+ gasWanted: Number(result.gas_wanted || result.gasWanted || 0)
438
+ };
439
+ }
440
+ function readTxEventHashes(data) {
441
+ var _data$events$txHash, _data$events, _data$events2;
442
+ const txHashEvent = (_data$events$txHash = data === null || data === void 0 || (_data$events = data.events) === null || _data$events === void 0 ? void 0 : _data$events["tx.hash"]) !== null && _data$events$txHash !== void 0 ? _data$events$txHash : data === null || data === void 0 || (_data$events2 = data.events) === null || _data$events2 === void 0 ? void 0 : _data$events2.tx_hash;
443
+ if (Array.isArray(txHashEvent)) return txHashEvent.map(String);
444
+ if (txHashEvent) return [String(txHashEvent)];
445
+ return [];
446
+ }
447
+
448
+ //#endregion
449
+ //#region src/core/tx/api/TxInclusion.ts
450
+ function isTendermintEventStrategy(inclusionStrategy) {
451
+ return inclusionStrategy === TxInclusionStrategy.TendermintEvent || inclusionStrategy === TxInclusionStrategy.TendermintEventAndPoll;
452
+ }
453
+ async function prepareTxInclusionWaiter({ txHash, timeout, options, fetchTx, fetchTxPoll, createRequestException }) {
454
+ const inclusionStrategy = options === null || options === void 0 ? void 0 : options.inclusionStrategy;
455
+ if (!isTendermintEventStrategy(inclusionStrategy)) return createPollingInclusionWaiter({
456
+ txHash,
457
+ timeout,
458
+ fetchTxPoll
459
+ });
460
+ const eventOptions = options === null || options === void 0 ? void 0 : options.eventInclusion;
461
+ const rpcEndpoint = eventOptions === null || eventOptions === void 0 ? void 0 : eventOptions.rpcEndpoint;
462
+ const fallbackToPolling = (eventOptions === null || eventOptions === void 0 ? void 0 : eventOptions.fallbackToPolling) !== false;
463
+ if (!rpcEndpoint) {
464
+ var _eventOptions$onFallb;
465
+ const error = new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error("Tendermint RPC endpoint is required for event inclusion"));
466
+ if (!fallbackToPolling) throw createRequestException(error, "event-inclusion");
467
+ eventOptions === null || eventOptions === void 0 || (_eventOptions$onFallb = eventOptions.onFallback) === null || _eventOptions$onFallb === void 0 || _eventOptions$onFallb.call(eventOptions, error);
468
+ return createPollingInclusionWaiter({
469
+ txHash,
470
+ timeout,
471
+ fetchTxPoll
472
+ });
473
+ }
474
+ try {
475
+ const subscription = await subscribeToTendermintTxEvent({
476
+ txHash,
477
+ endpoint: rpcEndpoint,
478
+ timeout: (eventOptions === null || eventOptions === void 0 ? void 0 : eventOptions.timeout) || timeout,
479
+ webSocketFactory: eventOptions === null || eventOptions === void 0 ? void 0 : eventOptions.webSocketFactory
480
+ });
481
+ const hashMismatchPollAbortController = new AbortController();
482
+ const close = () => {
483
+ hashMismatchPollAbortController.abort();
484
+ subscription.close();
485
+ };
486
+ return {
487
+ txHash,
488
+ inclusionStrategy,
489
+ close,
490
+ wait: async (includedTxHash = txHash) => {
491
+ if (includedTxHash.toUpperCase() !== txHash.toUpperCase()) {
492
+ var _eventOptions$onFallb2;
493
+ subscription.close();
494
+ eventOptions === null || eventOptions === void 0 || (_eventOptions$onFallb2 = eventOptions.onFallback) === null || _eventOptions$onFallb2 === void 0 || _eventOptions$onFallb2.call(eventOptions, new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error(`Broadcast tx hash ${includedTxHash} did not match subscribed tx hash ${txHash}`)));
495
+ return fetchTxPoll({
496
+ txHash: includedTxHash,
497
+ timeout,
498
+ abortSignal: hashMismatchPollAbortController.signal
499
+ });
500
+ }
501
+ if (inclusionStrategy === TxInclusionStrategy.TendermintEventAndPoll) return waitForSubscribedTxInclusionAndPoll({
502
+ txHash,
503
+ timeout,
504
+ fetchTx,
505
+ options,
506
+ fetchTxPoll,
507
+ subscription
508
+ });
509
+ return waitForSubscribedTxInclusion({
510
+ txHash,
511
+ timeout,
512
+ options,
513
+ fetchTx,
514
+ subscription,
515
+ fetchTxPoll,
516
+ createRequestException
517
+ });
518
+ }
519
+ };
520
+ } catch (e) {
521
+ var _eventOptions$onFallb3;
522
+ if (e instanceof __injectivelabs_exceptions.TransactionException) throw e;
523
+ const error = e instanceof Error ? e : new Error(String(e));
524
+ if (!fallbackToPolling) throw createRequestException(error, "event-inclusion");
525
+ eventOptions === null || eventOptions === void 0 || (_eventOptions$onFallb3 = eventOptions.onFallback) === null || _eventOptions$onFallb3 === void 0 || _eventOptions$onFallb3.call(eventOptions, error);
526
+ return createPollingInclusionWaiter({
527
+ txHash,
528
+ timeout,
529
+ fetchTxPoll
530
+ });
531
+ }
532
+ }
533
+ function createPollingInclusionWaiter({ txHash, timeout, fetchTxPoll }) {
534
+ const pollAbortController = new AbortController();
535
+ return {
536
+ txHash,
537
+ inclusionStrategy: TxInclusionStrategy.Poll,
538
+ close: () => {
539
+ pollAbortController.abort();
540
+ },
541
+ wait: (includedTxHash = txHash) => fetchTxPoll({
542
+ txHash: includedTxHash,
543
+ timeout,
544
+ abortSignal: pollAbortController.signal
545
+ })
546
+ };
547
+ }
548
+ async function waitForSubscribedTxInclusion({ txHash, timeout, options, fetchTx, fetchTxPoll, subscription, createRequestException }) {
549
+ var _options$eventInclusi;
550
+ const fallbackToPolling = (options === null || options === void 0 || (_options$eventInclusi = options.eventInclusion) === null || _options$eventInclusi === void 0 ? void 0 : _options$eventInclusi.fallbackToPolling) !== false;
551
+ try {
552
+ return await waitForSubscribedTxEvent({
553
+ txHash,
554
+ subscription,
555
+ fetchTx
556
+ });
557
+ } catch (e) {
558
+ var _options$eventInclusi2, _options$eventInclusi3;
559
+ if (e instanceof __injectivelabs_exceptions.TransactionException) throw e;
560
+ const error = e instanceof __injectivelabs_exceptions.GeneralException ? e : new __injectivelabs_exceptions.GeneralException(new Error(String(e)));
561
+ if (!fallbackToPolling) throw createRequestException(error, "event-inclusion");
562
+ options === null || options === void 0 || (_options$eventInclusi2 = options.eventInclusion) === null || _options$eventInclusi2 === void 0 || (_options$eventInclusi3 = _options$eventInclusi2.onFallback) === null || _options$eventInclusi3 === void 0 || _options$eventInclusi3.call(_options$eventInclusi2, error);
563
+ return fetchTxPoll({
564
+ txHash,
565
+ timeout
566
+ });
567
+ }
568
+ }
569
+ async function waitForSubscribedTxInclusionAndPoll({ txHash, timeout, options, fetchTx, fetchTxPoll, subscription }) {
570
+ const pollAbortController = new AbortController();
571
+ return new Promise((resolve, reject) => {
572
+ let settled = false;
573
+ let finishedCount = 0;
574
+ let eventError;
575
+ let pollError;
576
+ const rejectIfBothFailed = () => {
577
+ if (finishedCount < 2 || settled) return;
578
+ reject(pollError || eventError || new __injectivelabs_exceptions.GeneralException(/* @__PURE__ */ new Error("Tx inclusion failed")));
579
+ };
580
+ const resolveOnce = (txResponse, source) => {
581
+ if (settled) return;
582
+ settled = true;
583
+ if (source === "poll") {
584
+ subscription.close();
585
+ resolve(txResponse);
586
+ return;
587
+ }
588
+ pollAbortController.abort();
589
+ resolve(txResponse);
590
+ };
591
+ const rejectTerminal = (error) => {
592
+ if (settled) return true;
593
+ if (error instanceof __injectivelabs_exceptions.TransactionException) {
594
+ settled = true;
595
+ subscription.close();
596
+ pollAbortController.abort();
597
+ reject(error);
598
+ return true;
599
+ }
600
+ return false;
601
+ };
602
+ waitForSubscribedTxEvent({
603
+ txHash,
604
+ subscription,
605
+ fetchTx
606
+ }).then((txResponse) => resolveOnce(txResponse, "event")).catch((error) => {
607
+ var _options$eventInclusi4, _options$eventInclusi5;
608
+ if (rejectTerminal(error)) return;
609
+ const fallbackError = error instanceof Error ? error : new Error(String(error));
610
+ eventError = fallbackError;
611
+ finishedCount += 1;
612
+ options === null || options === void 0 || (_options$eventInclusi4 = options.eventInclusion) === null || _options$eventInclusi4 === void 0 || (_options$eventInclusi5 = _options$eventInclusi4.onFallback) === null || _options$eventInclusi5 === void 0 || _options$eventInclusi5.call(_options$eventInclusi4, fallbackError);
613
+ rejectIfBothFailed();
614
+ });
615
+ fetchTxPoll({
616
+ txHash,
617
+ timeout,
618
+ abortSignal: pollAbortController.signal
619
+ }).then((txResponse) => resolveOnce(txResponse, "poll")).catch((error) => {
620
+ if (rejectTerminal(error)) return;
621
+ pollError = error instanceof Error ? error : new Error(String(error));
622
+ finishedCount += 1;
623
+ rejectIfBothFailed();
624
+ });
625
+ });
626
+ }
627
+ async function waitForSubscribedTxEvent({ txHash, fetchTx, subscription }) {
628
+ const eventTx = await subscription.wait();
629
+ if (eventTx.code !== 0) throw new __injectivelabs_exceptions.TransactionException(new Error(eventTx.rawLog), {
630
+ contextCode: eventTx.code,
631
+ contextModule: eventTx.codespace
632
+ });
633
+ return fetchTx(txHash);
634
+ }
635
+
265
636
  //#endregion
266
637
  //#region src/core/tx/api/TxGrpcApi.ts
267
638
  var TxGrpcApi = class extends require_BaseGrpcConsumer.BaseGrpcConsumer {
@@ -301,15 +672,19 @@ var TxGrpcApi = class extends require_BaseGrpcConsumer.BaseGrpcConsumer {
301
672
  });
302
673
  }
303
674
  }
304
- async fetchTxPoll(txHash, timeout = __injectivelabs_utils.DEFAULT_TX_BLOCK_INCLUSION_TIMEOUT_IN_MS) {
675
+ async fetchTxPoll({ txHash, timeout = __injectivelabs_utils.DEFAULT_TX_BLOCK_INCLUSION_TIMEOUT_IN_MS, abortSignal }) {
305
676
  const deadline = Date.now() + timeout;
306
677
  for (let start = Date.now(); start < deadline; start = Date.now()) {
678
+ this.throwIfTxPollingCancelled(abortSignal);
307
679
  try {
308
- const tx = await this.fetchTxDual(txHash, deadline);
680
+ const tx = await this.fetchTxDual(txHash, deadline, abortSignal);
681
+ this.throwIfTxPollingCancelled(abortSignal);
309
682
  if (tx) return tx;
310
683
  } catch (e) {
684
+ this.throwIfTxPollingCancelled(abortSignal);
311
685
  if (e instanceof __injectivelabs_exceptions.TransactionException) throw e;
312
686
  }
687
+ this.throwIfTxPollingCancelled(abortSignal);
313
688
  const gap = __injectivelabs_utils.DEFAULT_TX_POLL_INTERVAL_MS - (Date.now() - start);
314
689
  if (gap > 0) await (0, __injectivelabs_utils.sleep)(gap);
315
690
  }
@@ -318,20 +693,46 @@ var TxGrpcApi = class extends require_BaseGrpcConsumer.BaseGrpcConsumer {
318
693
  contextModule: "fetch-tx-poll"
319
694
  });
320
695
  }
321
- async safeFetchTx(txHash, delay) {
696
+ async waitForTxInclusion(txHash, timeout = __injectivelabs_utils.DEFAULT_TX_BLOCK_INCLUSION_TIMEOUT_IN_MS, options) {
697
+ const txResponse = await (await this.prepareTxInclusionWait(txHash, timeout, options)).wait();
698
+ if (!txResponse) throw new __injectivelabs_exceptions.GrpcUnaryRequestException(/* @__PURE__ */ new Error(`The transaction with ${txHash} is not found`), {
699
+ context: "TxGrpcApi",
700
+ contextModule: "wait-for-tx-inclusion"
701
+ });
702
+ return txResponse;
703
+ }
704
+ async prepareTxInclusionWait(txHash, timeout = __injectivelabs_utils.DEFAULT_TX_BLOCK_INCLUSION_TIMEOUT_IN_MS, options) {
705
+ return prepareTxInclusionWaiter({
706
+ txHash,
707
+ timeout,
708
+ options,
709
+ fetchTx: (includedTxHash) => this.fetchTx(includedTxHash),
710
+ fetchTxPoll: (args) => this.fetchTxPoll(args),
711
+ createRequestException: (error, contextModule) => new __injectivelabs_exceptions.GrpcUnaryRequestException(error, {
712
+ context: "TxGrpcApi",
713
+ contextModule
714
+ })
715
+ });
716
+ }
717
+ async safeFetchTx(txHash, delay, abortSignal) {
322
718
  if (delay) await (0, __injectivelabs_utils.sleep)(delay);
719
+ this.throwIfTxPollingCancelled(abortSignal);
323
720
  return this.fetchTx(txHash).catch((e) => {
324
721
  if (e instanceof __injectivelabs_exceptions.TransactionException) throw e;
325
722
  return null;
326
723
  });
327
724
  }
328
- fetchTxDual(txHash, deadline) {
725
+ fetchTxDual(txHash, deadline, abortSignal) {
329
726
  const STAGGER = 300;
330
727
  const timeout = Math.max(0, Math.min(__injectivelabs_utils.DEFAULT_TX_POLL_CALL_TIMEOUT_MS, deadline - Date.now()));
331
- const fetches = Promise.all([this.safeFetchTx(txHash), this.safeFetchTx(txHash, STAGGER)]).then(([a, b]) => a !== null && a !== void 0 ? a : b);
728
+ const fetches = Promise.all([this.safeFetchTx(txHash, void 0, abortSignal), this.safeFetchTx(txHash, STAGGER, abortSignal)]).then(([a, b]) => a !== null && a !== void 0 ? a : b);
332
729
  fetches.catch(() => {});
333
730
  return Promise.race([fetches, (0, __injectivelabs_utils.sleep)(timeout).then(() => null)]);
334
731
  }
732
+ throwIfTxPollingCancelled(abortSignal) {
733
+ if (!(abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted)) return;
734
+ throw new Error("Transaction inclusion polling was cancelled");
735
+ }
335
736
  async simulate(txRaw) {
336
737
  const txRawClone = __injectivelabs_core_proto_ts_v2_generated_cosmos_tx_v1beta1_tx_pb.TxRaw.create({ ...txRaw });
337
738
  const simulateRequest = __injectivelabs_core_proto_ts_v2_generated_cosmos_tx_v1beta1_service_pb.SimulateRequest.create();
@@ -361,12 +762,15 @@ var TxGrpcApi = class extends require_BaseGrpcConsumer.BaseGrpcConsumer {
361
762
  }
362
763
  }
363
764
  async broadcast(txRaw, options) {
364
- const mode = (options === null || options === void 0 ? void 0 : options.mode) || __injectivelabs_core_proto_ts_v2_generated_cosmos_tx_v1beta1_service_pb.BroadcastMode.SYNC;
365
765
  const timeout = (options === null || options === void 0 ? void 0 : options.timeout) || (0, __injectivelabs_utils.toBigNumber)((options === null || options === void 0 ? void 0 : options.txTimeout) || __injectivelabs_utils.DEFAULT_BLOCK_TIMEOUT_HEIGHT).times(__injectivelabs_utils.DEFAULT_BLOCK_TIME_IN_SECONDS * 1e3).toNumber();
366
- const broadcastTxRequest = __injectivelabs_core_proto_ts_v2_generated_cosmos_tx_v1beta1_service_pb.BroadcastTxRequest.create();
367
- broadcastTxRequest.txBytes = __injectivelabs_core_proto_ts_v2_generated_cosmos_tx_v1beta1_tx_pb.TxRaw.toBinary(txRaw);
368
- broadcastTxRequest.mode = mode;
766
+ const txHash = TxClient.hash(txRaw);
767
+ let inclusionWaiter;
369
768
  try {
769
+ inclusionWaiter = await this.prepareTxInclusionWait(txHash, timeout, options);
770
+ const mode = (options === null || options === void 0 ? void 0 : options.mode) || (inclusionWaiter.inclusionStrategy !== TxInclusionStrategy.Poll ? __injectivelabs_core_proto_ts_v2_generated_cosmos_tx_v1beta1_service_pb.BroadcastMode.ASYNC : __injectivelabs_core_proto_ts_v2_generated_cosmos_tx_v1beta1_service_pb.BroadcastMode.SYNC);
771
+ const broadcastTxRequest = __injectivelabs_core_proto_ts_v2_generated_cosmos_tx_v1beta1_service_pb.BroadcastTxRequest.create();
772
+ broadcastTxRequest.txBytes = __injectivelabs_core_proto_ts_v2_generated_cosmos_tx_v1beta1_tx_pb.TxRaw.toBinary(txRaw);
773
+ broadcastTxRequest.mode = mode;
370
774
  const txResponse = (await this.executeGrpcCall(broadcastTxRequest, this.client.broadcastTx.bind(this.client))).txResponse;
371
775
  if (!txResponse) throw new __injectivelabs_exceptions.GrpcUnaryRequestException(/* @__PURE__ */ new Error(`The transaction has failed to be broadcasted`), {
372
776
  context: "TxGrpcApi.broadcast",
@@ -377,8 +781,14 @@ var TxGrpcApi = class extends require_BaseGrpcConsumer.BaseGrpcConsumer {
377
781
  contextModule: txResponse.codespace
378
782
  });
379
783
  if (options === null || options === void 0 ? void 0 : options.onBroadcast) options.onBroadcast(txResponse.txhash);
380
- return await this.fetchTxPoll(txResponse.txhash, timeout);
784
+ const result = await inclusionWaiter.wait(txResponse.txhash);
785
+ if (!result) throw new __injectivelabs_exceptions.GrpcUnaryRequestException(/* @__PURE__ */ new Error(`The transaction with ${txResponse.txhash} is not found`), {
786
+ context: "TxGrpcApi.broadcast",
787
+ contextModule: "wait-for-tx-inclusion"
788
+ });
789
+ return result;
381
790
  } catch (e) {
791
+ inclusionWaiter === null || inclusionWaiter === void 0 || inclusionWaiter.close();
382
792
  if (e instanceof __injectivelabs_exceptions.TransactionException) throw e;
383
793
  if (e instanceof __injectivelabs_exceptions.GrpcUnaryRequestException) throw e;
384
794
  throw new __injectivelabs_exceptions.TransactionException(new Error(e));
@@ -465,16 +875,19 @@ var TxRestApi = class {
465
875
  });
466
876
  }
467
877
  }
468
- async fetchTxPoll(txHash, timeout = __injectivelabs_utils.DEFAULT_TX_BLOCK_INCLUSION_TIMEOUT_IN_MS) {
878
+ async fetchTxPoll({ txHash, timeout = __injectivelabs_utils.DEFAULT_TX_BLOCK_INCLUSION_TIMEOUT_IN_MS, abortSignal }) {
469
879
  const deadline = Date.now() + timeout;
470
880
  for (let start = Date.now(); start < deadline; start = Date.now()) {
881
+ this.throwIfTxPollingCancelled(abortSignal);
471
882
  const callTimeout = Math.max(0, Math.min(__injectivelabs_utils.DEFAULT_TX_POLL_CALL_TIMEOUT_MS, deadline - Date.now()));
472
883
  try {
473
884
  const txResponse = await Promise.race([this.fetchTx(txHash), (0, __injectivelabs_utils.sleep)(callTimeout).then(() => null)]);
474
885
  if (txResponse) return txResponse;
475
886
  } catch (e) {
887
+ this.throwIfTxPollingCancelled(abortSignal);
476
888
  if (e instanceof __injectivelabs_exceptions.TransactionException) throw e;
477
889
  }
890
+ this.throwIfTxPollingCancelled(abortSignal);
478
891
  const remaining = __injectivelabs_utils.DEFAULT_TX_POLL_INTERVAL_MS - (Date.now() - start);
479
892
  if (remaining > 0) await (0, __injectivelabs_utils.sleep)(remaining);
480
893
  }
@@ -483,6 +896,31 @@ var TxRestApi = class {
483
896
  contextModule: "TxRestApi.fetch-tx-poll"
484
897
  });
485
898
  }
899
+ throwIfTxPollingCancelled(abortSignal) {
900
+ if (!(abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted)) return;
901
+ throw new Error("Transaction inclusion polling was cancelled");
902
+ }
903
+ async waitForTxInclusion(txHash, timeout = __injectivelabs_utils.DEFAULT_TX_BLOCK_INCLUSION_TIMEOUT_IN_MS, options) {
904
+ const txResponse = await (await this.prepareTxInclusionWait(txHash, timeout, options)).wait();
905
+ if (!txResponse) throw new __injectivelabs_exceptions.HttpRequestException(/* @__PURE__ */ new Error(`The transaction with ${txHash} is not found`), {
906
+ context: "TxRestApi",
907
+ contextModule: "wait-for-tx-inclusion"
908
+ });
909
+ return txResponse;
910
+ }
911
+ async prepareTxInclusionWait(txHash, timeout = __injectivelabs_utils.DEFAULT_TX_BLOCK_INCLUSION_TIMEOUT_IN_MS, options) {
912
+ return prepareTxInclusionWaiter({
913
+ txHash,
914
+ timeout,
915
+ options,
916
+ fetchTx: (includedTxHash) => this.fetchTx(includedTxHash),
917
+ fetchTxPoll: (args) => this.fetchTxPoll(args),
918
+ createRequestException: (error, contextModule) => new __injectivelabs_exceptions.HttpRequestException(error, {
919
+ context: "TxRestApi",
920
+ contextModule
921
+ })
922
+ });
923
+ }
486
924
  async simulate(txRaw) {
487
925
  const txRawClone = __injectivelabs_core_proto_ts_v2_generated_cosmos_tx_v1beta1_tx_pb.TxRaw.create({ ...txRaw });
488
926
  if (txRawClone.signatures.length === 0) txRawClone.signatures = [new Uint8Array(0)];
@@ -505,8 +943,11 @@ var TxRestApi = class {
505
943
  }
506
944
  async broadcast(txRaw, options) {
507
945
  const timeout = (options === null || options === void 0 ? void 0 : options.timeout) || (0, __injectivelabs_utils.toBigNumber)((options === null || options === void 0 ? void 0 : options.txTimeout) || __injectivelabs_utils.DEFAULT_BLOCK_TIMEOUT_HEIGHT).times(__injectivelabs_utils.DEFAULT_BLOCK_TIME_IN_SECONDS * 1e3).toNumber();
946
+ const txHash = TxClient.hash(txRaw);
947
+ let inclusionWaiter;
508
948
  try {
509
- const { tx_response: txResponse } = await this.broadcastTx(txRaw, BroadcastMode.Sync);
949
+ inclusionWaiter = await this.prepareTxInclusionWait(txHash, timeout, options);
950
+ const { tx_response: txResponse } = await this.broadcastTx(txRaw, inclusionWaiter.inclusionStrategy !== TxInclusionStrategy.Poll ? BroadcastMode.Async : BroadcastMode.Sync);
510
951
  if (!txResponse) throw new __injectivelabs_exceptions.HttpRequestException(/* @__PURE__ */ new Error("The transaction has failed to be broadcasted"), {
511
952
  context: "TxRestApi.broadcast",
512
953
  contextModule: "broadcast"
@@ -516,8 +957,14 @@ var TxRestApi = class {
516
957
  contextModule: txResponse.codespace
517
958
  });
518
959
  if (options === null || options === void 0 ? void 0 : options.onBroadcast) options.onBroadcast(txResponse.txhash);
519
- return await this.fetchTxPoll(txResponse.txhash, timeout);
960
+ const result = await inclusionWaiter.wait(txResponse.txhash);
961
+ if (!result) throw new __injectivelabs_exceptions.HttpRequestException(/* @__PURE__ */ new Error(`The transaction with ${txResponse.txhash} is not found`), {
962
+ context: "TxRestApi.broadcast",
963
+ contextModule: "wait-for-tx-inclusion"
964
+ });
965
+ return result;
520
966
  } catch (e) {
967
+ inclusionWaiter === null || inclusionWaiter === void 0 || inclusionWaiter.close();
521
968
  if (e instanceof __injectivelabs_exceptions.HttpRequestException) {
522
969
  if (e.code !== http_status_codes.StatusCodes.OK) throw e;
523
970
  }
@@ -610,7 +1057,13 @@ var TxRestApi = class {
610
1057
  //#region src/core/tx/api/utils.ts
611
1058
  const waitTxBroadcasted = (txHash, options) => {
612
1059
  const timeout = (0, __injectivelabs_utils.toBigNumber)((options === null || options === void 0 ? void 0 : options.txTimeout) || __injectivelabs_utils.DEFAULT_BLOCK_TIMEOUT_HEIGHT).times(__injectivelabs_utils.DEFAULT_BLOCK_TIME_IN_SECONDS * 1e3).toNumber();
613
- return options.endpoints.grpc ? new TxGrpcApi(options.endpoints.grpc).fetchTxPoll(txHash, timeout) : new TxRestApi(options.endpoints.rest).fetchTxPoll(txHash, timeout);
1060
+ return options.endpoints.grpc ? new TxGrpcApi(options.endpoints.grpc).fetchTxPoll({
1061
+ txHash,
1062
+ timeout
1063
+ }) : new TxRestApi(options.endpoints.rest).fetchTxPoll({
1064
+ txHash,
1065
+ timeout
1066
+ });
614
1067
  };
615
1068
 
616
1069
  //#endregion
@@ -641,13 +1094,6 @@ const generateArbitrarySignDoc = (message, signer) => {
641
1094
  };
642
1095
  };
643
1096
 
644
- //#endregion
645
- //#region src/core/tx/types/tx.ts
646
- const TxClientMode = {
647
- gRpc: "grpc",
648
- rest: "rest"
649
- };
650
-
651
1097
  //#endregion
652
1098
  //#region src/core/tx/broadcaster/MsgBroadcasterWithPk.ts
653
1099
  /**
@@ -737,7 +1183,11 @@ var MsgBroadcasterWithPk = class {
737
1183
  chainId: evmChainId,
738
1184
  signature: `0x${require_utils.uint8ArrayToHex(signature)}`
739
1185
  });
740
- return await new TxGrpcApi(endpoints.grpc).fetchTxPoll(response.txHash);
1186
+ const timeoutInMs = (0, __injectivelabs_utils.toBigNumber)(txTimeout).times(__injectivelabs_utils.DEFAULT_BLOCK_TIME_IN_SECONDS).times(1e3).toNumber();
1187
+ return await new TxGrpcApi(endpoints.grpc).fetchTxPoll({
1188
+ txHash: response.txHash,
1189
+ timeout: timeoutInMs
1190
+ });
741
1191
  }
742
1192
  /**
743
1193
  * Broadcasting the transaction using the client
@@ -952,6 +1402,12 @@ Object.defineProperty(exports, 'TxGrpcApi', {
952
1402
  return TxGrpcApi;
953
1403
  }
954
1404
  });
1405
+ Object.defineProperty(exports, 'TxInclusionStrategy', {
1406
+ enumerable: true,
1407
+ get: function () {
1408
+ return TxInclusionStrategy;
1409
+ }
1410
+ });
955
1411
  Object.defineProperty(exports, 'TxRestApi', {
956
1412
  enumerable: true,
957
1413
  get: function () {
@@ -1024,6 +1480,18 @@ Object.defineProperty(exports, 'isTxNotFoundError', {
1024
1480
  return isTxNotFoundError;
1025
1481
  }
1026
1482
  });
1483
+ Object.defineProperty(exports, 'normalizeTendermintWebSocketEndpoint', {
1484
+ enumerable: true,
1485
+ get: function () {
1486
+ return normalizeTendermintWebSocketEndpoint;
1487
+ }
1488
+ });
1489
+ Object.defineProperty(exports, 'subscribeToTendermintTxEvent', {
1490
+ enumerable: true,
1491
+ get: function () {
1492
+ return subscribeToTendermintTxEvent;
1493
+ }
1494
+ });
1027
1495
  Object.defineProperty(exports, 'waitTxBroadcasted', {
1028
1496
  enumerable: true,
1029
1497
  get: function () {
@@ -1,6 +1,6 @@
1
1
  import "./tx_pb-BGCQilBY.cjs";
2
2
  import "./index-C15wCMY6.cjs";
3
- import { $d as cosmosSdkDecToBigNumber, $f as SignTypedDataVersionV4, Ad as hexToBuff, Af as spotPriceFromChainPriceToFixed, Bd as getChecksumAddress, Bf as getErrorMessage, Cd as base64ToUint8Array, Cf as formatPriceToAllowablePrice, Cp as protobufTimestampToUnixSeconds, Dd as fromBase64, Df as isNumber, Ed as concatUint8Arrays, Ef as getTensMultiplier, Fd as uint8ArrayToBase64, Ff as spotQuantityToChainQuantity, Fx as GrpcWebFetchTransport, Gd as getSubaccountId, Gf as isNode, Hd as getEthereumAddress, Hf as hexToNumber, Id as uint8ArrayToHex, If as spotQuantityToChainQuantityToFixed, Jd as getDerivativeMarketDecimals, Jf as objectToJson, Kd as isCw20ContractAddress, Kf as isReactNative, Ld as uint8ArrayToString, Lf as bigIntReplacer, Md as stringToUint8Array, Mf as spotPriceToChainPriceToFixed, Nd as toBase64, Nf as spotQuantityFromChainQuantity, Od as fromUtf8, Of as numberToCosmosSdkDecString, Pd as toUtf8, Pf as spotQuantityFromChainQuantityToFixed, Qd as amountToCosmosSdkDecAmount, Qf as sortObjectByKeysWithReduce, Rd as addHexPrefix, Rf as bigIntToNumber, Sd as DEFAULT_DERIVATION_PATH, Sf as formatPriceToAllowableDecimals, Sp as protobufTimestampToUnixMs, Td as binaryToBase64, Tf as getSignificantDecimalsFromNumber, Ud as getInjectiveAddress, Uf as isBrowser, Vd as getDefaultSubaccountId, Vf as grpcCoinToUiCoin, Wd as getInjectiveAddressFromSubaccountId, Wf as isJsonString, Xd as getSpotMarketDecimals, Xf as safeBigIntStringify, Yd as getDerivativeMarketTensMultiplier, Yf as protoObjectToJson, Zd as getSpotMarketTensMultiplier, Zf as sortObjectByKeys, _d as BECH32_ADDR_CONS_PREFIX, _f as derivativeQuantityToChainQuantityToFixed, _p as getGrpcWebTransport, af as denomAmountToGrpcChainDenomAmount, ap as hashToHex, bd as BECH32_PUBKEY_CONS_PREFIX, bf as formatNumberToAllowableDecimals, bp as makeTimeoutTimestampInNs, cd as recoverTypedSignaturePubKey, cf as derivativeMarginToChainMargin, cp as privateKeyHashToPublicKeyBase64, dd as grpcPagingToPaging, df as derivativePriceFromChainPriceToFixed, dp as publicKeyToAddress, ef as denomAmountFromChainDenomAmount, ep as TypedDataUtilsHashStruct, fd as grpcPagingToPagingV2, ff as derivativePriceToChainPrice, fp as ripemd160, gd as BECH32_ADDR_ACC_PREFIX, gf as derivativeQuantityToChainQuantity, gp as ofacList, hd as paginationUint8ArrayToString, hf as derivativeQuantityFromChainQuantityToFixed, hp as parseCoins, if as denomAmountToChainDenomAmountToFixed, ip as domainHash, jd as hexToUint8Array, jf as spotPriceToChainPrice, kd as hexToBase64, kf as spotPriceFromChainPrice, ld as fetchAllWithPagination, lf as derivativeMarginToChainMarginToFixed, lp as privateKeyToPublicKey, md as paginationRequestFromPagination, mf as derivativeQuantityFromChainQuantity, mp as sha256, nf as denomAmountFromGrpcChainDenomAmount, np as TypedMessageV4, of as derivativeMarginFromChainMargin, op as messageHash, pd as pageRequestToGrpcPageRequestV2, pf as derivativePriceToChainPriceToFixed, pp as sanitizeTypedData, qd as removeHexPrefix, qf as isServerSide, rf as denomAmountToChainDenomAmount, rp as decompressPubKey, sf as derivativeMarginFromChainMarginToFixed, sp as privateKeyHashToPublicKey, tf as denomAmountFromChainDenomAmountToFixed, tp as TypedDataUtilsSanitizeData, ud as grpcPaginationToPagination, uf as derivativePriceFromChainPrice, up as privateKeyToPublicKeyBase64, vd as BECH32_ADDR_VAL_PREFIX, vf as formatAmountToAllowableAmount, vp as getGasPriceBasedOnMessage, wd as base64ToUtf8, wf as getExactDecimalsFromNumber, xd as BECH32_PUBKEY_VAL_PREFIX, xf as formatNumberToAllowableTensMultiplier, xp as protobufTimestampToDate, yd as BECH32_PUBKEY_ACC_PREFIX, yf as formatAmountToAllowableDecimals, yp as makeTimeoutTimestamp, zd as getAddressFromInjectiveAddress, zf as bigIntToString } from "./index-Dd2CQPyj.cjs";
3
+ import { $d as cosmosSdkDecToBigNumber, $f as SignTypedDataVersionV4, Ad as hexToBuff, Af as spotPriceFromChainPriceToFixed, Bd as getChecksumAddress, Bf as getErrorMessage, Cd as base64ToUint8Array, Cf as formatPriceToAllowablePrice, Cp as protobufTimestampToUnixSeconds, Dd as fromBase64, Df as isNumber, Ed as concatUint8Arrays, Ef as getTensMultiplier, Fd as uint8ArrayToBase64, Ff as spotQuantityToChainQuantity, Gd as getSubaccountId, Gf as isNode, Hd as getEthereumAddress, Hf as hexToNumber, Id as uint8ArrayToHex, If as spotQuantityToChainQuantityToFixed, Jd as getDerivativeMarketDecimals, Jf as objectToJson, Kd as isCw20ContractAddress, Kf as isReactNative, Ld as uint8ArrayToString, Lf as bigIntReplacer, Md as stringToUint8Array, Mf as spotPriceToChainPriceToFixed, Nd as toBase64, Nf as spotQuantityFromChainQuantity, Od as fromUtf8, Of as numberToCosmosSdkDecString, Pd as toUtf8, Pf as spotQuantityFromChainQuantityToFixed, Qd as amountToCosmosSdkDecAmount, Qf as sortObjectByKeysWithReduce, Rd as addHexPrefix, Rf as bigIntToNumber, Sd as DEFAULT_DERIVATION_PATH, Sf as formatPriceToAllowableDecimals, Sp as protobufTimestampToUnixMs, Td as binaryToBase64, Tf as getSignificantDecimalsFromNumber, Ud as getInjectiveAddress, Uf as isBrowser, Ux as GrpcWebFetchTransport, Vd as getDefaultSubaccountId, Vf as grpcCoinToUiCoin, Wd as getInjectiveAddressFromSubaccountId, Wf as isJsonString, Xd as getSpotMarketDecimals, Xf as safeBigIntStringify, Yd as getDerivativeMarketTensMultiplier, Yf as protoObjectToJson, Zd as getSpotMarketTensMultiplier, Zf as sortObjectByKeys, _d as BECH32_ADDR_CONS_PREFIX, _f as derivativeQuantityToChainQuantityToFixed, _p as getGrpcWebTransport, af as denomAmountToGrpcChainDenomAmount, ap as hashToHex, bd as BECH32_PUBKEY_CONS_PREFIX, bf as formatNumberToAllowableDecimals, bp as makeTimeoutTimestampInNs, cd as recoverTypedSignaturePubKey, cf as derivativeMarginToChainMargin, cp as privateKeyHashToPublicKeyBase64, dd as grpcPagingToPaging, df as derivativePriceFromChainPriceToFixed, dp as publicKeyToAddress, ef as denomAmountFromChainDenomAmount, ep as TypedDataUtilsHashStruct, fd as grpcPagingToPagingV2, ff as derivativePriceToChainPrice, fp as ripemd160, gd as BECH32_ADDR_ACC_PREFIX, gf as derivativeQuantityToChainQuantity, gp as ofacList, hd as paginationUint8ArrayToString, hf as derivativeQuantityFromChainQuantityToFixed, hp as parseCoins, if as denomAmountToChainDenomAmountToFixed, ip as domainHash, jd as hexToUint8Array, jf as spotPriceToChainPrice, kd as hexToBase64, kf as spotPriceFromChainPrice, ld as fetchAllWithPagination, lf as derivativeMarginToChainMarginToFixed, lp as privateKeyToPublicKey, md as paginationRequestFromPagination, mf as derivativeQuantityFromChainQuantity, mp as sha256, nf as denomAmountFromGrpcChainDenomAmount, np as TypedMessageV4, of as derivativeMarginFromChainMargin, op as messageHash, pd as pageRequestToGrpcPageRequestV2, pf as derivativePriceToChainPriceToFixed, pp as sanitizeTypedData, qd as removeHexPrefix, qf as isServerSide, rf as denomAmountToChainDenomAmount, rp as decompressPubKey, sf as derivativeMarginFromChainMarginToFixed, sp as privateKeyHashToPublicKey, tf as denomAmountFromChainDenomAmountToFixed, tp as TypedDataUtilsSanitizeData, ud as grpcPaginationToPagination, uf as derivativePriceFromChainPrice, up as privateKeyToPublicKeyBase64, vd as BECH32_ADDR_VAL_PREFIX, vf as formatAmountToAllowableAmount, vp as getGasPriceBasedOnMessage, wd as base64ToUtf8, wf as getExactDecimalsFromNumber, xd as BECH32_PUBKEY_VAL_PREFIX, xf as formatNumberToAllowableTensMultiplier, xp as protobufTimestampToDate, yd as BECH32_PUBKEY_ACC_PREFIX, yf as formatAmountToAllowableDecimals, yp as makeTimeoutTimestamp, zd as getAddressFromInjectiveAddress, zf as bigIntToString } from "./index-DJm-qDcY.cjs";
4
4
  import "./BaseGrpcConsumer-CZTAcNtS.cjs";
5
5
  import "./index-C00Yswov.cjs";
6
6
  import "./index-Dvfd07fs.cjs";