@rango-dev/queue-manager-rango-preset 0.5.1-next.1 → 0.5.1-next.11

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.
package/src/helpers.ts CHANGED
@@ -5,11 +5,16 @@ import {
5
5
  QueueType,
6
6
  } from '@rango-dev/queue-manager-core';
7
7
  import {
8
+ ArrayElement,
8
9
  BlockReason,
10
+ StepEventType,
9
11
  SwapActionTypes,
10
12
  SwapQueueContext,
11
13
  SwapQueueDef,
12
14
  SwapStorage,
15
+ StepExecutionEventStatus,
16
+ StepExecutionBlockedEventStatus,
17
+ Step,
13
18
  } from './types';
14
19
  import {
15
20
  getBlockChainNameFromId,
@@ -26,15 +31,10 @@ import {
26
31
  TransactionType,
27
32
  EvmBlockchainMeta,
28
33
  CreateTransactionResponse,
29
- isEvmTransaction,
30
- isCosmosTransaction,
31
- isSolanaTransaction,
32
- isTronTransaction,
33
- isStarknetTransaction,
34
- isTransferTransaction,
35
34
  } from 'rango-sdk';
36
35
 
37
36
  import {
37
+ DEFAULT_ERROR_CODE,
38
38
  ERROR_MESSAGE_WAIT_FOR_CHANGE_NETWORK,
39
39
  ERROR_MESSAGE_WAIT_FOR_WALLET,
40
40
  ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION,
@@ -42,7 +42,6 @@ import {
42
42
  import { Manager } from '@rango-dev/queue-manager-core';
43
43
  import { Status } from '@rango-dev/queue-manager-core';
44
44
  import {
45
- EventType,
46
45
  getCurrentBlockchainOf,
47
46
  getCurrentBlockchainOfOrNull,
48
47
  getScannerUrl,
@@ -65,6 +64,7 @@ import {
65
64
  } from './shared-errors';
66
65
  import { httpService } from './services';
67
66
  import { APIErrorCode, SignerErrorCode } from 'rango-types/lib';
67
+ import { notifier } from './services/eventEmitter';
68
68
 
69
69
  type WhenTaskBlocked = Parameters<NonNullable<SwapQueueDef['whenTaskBlocked']>>;
70
70
  type WhenTaskBlockedEvent = WhenTaskBlocked[0];
@@ -102,7 +102,7 @@ type TransactionData = {
102
102
  receiptReceived?: boolean; // e.g. is TransactionReceipt ready in case of EVM transactions
103
103
  };
104
104
  const swapTransactionToDataMap: { [id: string]: TransactionData } = {};
105
- export function useTransactionsData() {
105
+ export function inMemoryTransactionsData() {
106
106
  return {
107
107
  getTransactionDataByHash: (hash: string) =>
108
108
  swapTransactionToDataMap[hash] || {},
@@ -207,24 +207,36 @@ export const setCurrentStepTx = (
207
207
  currentStep.tronApprovalTransaction = null;
208
208
  currentStep.tronTransaction = null;
209
209
 
210
- if (isEvmTransaction(transaction)) {
211
- if (transaction.isApprovalTx)
212
- currentStep.evmApprovalTransaction = transaction;
213
- else currentStep.evmTransaction = transaction;
214
- } else if (isCosmosTransaction(transaction)) {
215
- currentStep.cosmosTransaction = transaction;
216
- } else if (isSolanaTransaction(transaction)) {
217
- currentStep.solanaTransaction = transaction;
218
- } else if (isTransferTransaction(transaction)) {
219
- currentStep.transferTransaction = transaction;
220
- } else if (isStarknetTransaction(transaction)) {
221
- if (transaction.isApprovalTx)
222
- currentStep.starknetApprovalTransaction = transaction;
223
- else currentStep.starknetTransaction = transaction;
224
- } else if (isTronTransaction(transaction)) {
225
- if (transaction.isApprovalTx)
226
- currentStep.tronApprovalTransaction = transaction;
227
- else currentStep.tronTransaction = transaction;
210
+ const txType = transaction.type;
211
+ switch (txType) {
212
+ case TransactionType.EVM:
213
+ if (transaction.isApprovalTx)
214
+ currentStep.evmApprovalTransaction = transaction;
215
+ else currentStep.evmTransaction = transaction;
216
+ break;
217
+ case TransactionType.TRON:
218
+ if (transaction.isApprovalTx)
219
+ currentStep.tronApprovalTransaction = transaction;
220
+ else currentStep.tronTransaction = transaction;
221
+ break;
222
+ case TransactionType.STARKNET:
223
+ if (transaction.isApprovalTx)
224
+ currentStep.starknetApprovalTransaction = transaction;
225
+ else currentStep.starknetTransaction = transaction;
226
+ break;
227
+ case TransactionType.COSMOS:
228
+ currentStep.cosmosTransaction = transaction;
229
+ break;
230
+ case TransactionType.SOLANA:
231
+ currentStep.solanaTransaction = transaction;
232
+ break;
233
+ case TransactionType.TRANSFER:
234
+ currentStep.transferTransaction = transaction;
235
+ break;
236
+ default:
237
+ ((x: never) => {
238
+ throw new Error(`${x} was unhandled!`);
239
+ })(txType);
228
240
  }
229
241
  return currentStep;
230
242
  };
@@ -293,9 +305,18 @@ export function updateSwapStatus({
293
305
  }): {
294
306
  swap: PendingSwap;
295
307
  step: PendingSwapStep | null;
308
+ failureType?: APIErrorCode;
296
309
  } {
297
310
  const swap = getStorage().swapDetails;
298
311
  const currentStep = getCurrentStep(swap);
312
+ const updatedResult: {
313
+ swap: PendingSwap;
314
+ step: PendingSwapStep | null;
315
+ failureType?: APIErrorCode;
316
+ } = {
317
+ swap,
318
+ step: currentStep,
319
+ };
299
320
  if (!!nextStepStatus && !!currentStep) currentStep.status = nextStepStatus;
300
321
 
301
322
  if (nextStatus) swap.status = nextStatus;
@@ -317,11 +338,14 @@ export function updateSwapStatus({
317
338
  const walletType = getRelatedWalletOrNull(swap, currentStep!)?.walletType;
318
339
  swap.extraMessageSeverity = MessageSeverity.error;
319
340
 
341
+ const failureType = mapAppErrorCodesToAPIErrorCode(errorCode);
342
+ updatedResult.failureType = failureType;
343
+
320
344
  httpService()
321
345
  .reportFailure({
322
346
  requestId: swap.requestId,
323
347
  step: currentStep?.id || 1,
324
- eventType: mapAppErrorCodesToAPIErrorCode(errorCode),
348
+ eventType: failureType,
325
349
  reason: errorReason || '',
326
350
  data: walletType ? { wallet: walletType } : undefined,
327
351
  })
@@ -342,10 +366,7 @@ export function updateSwapStatus({
342
366
  swapDetails: swap,
343
367
  });
344
368
 
345
- return {
346
- swap,
347
- step: currentStep,
348
- };
369
+ return updatedResult;
349
370
  }
350
371
 
351
372
  /**
@@ -356,8 +377,6 @@ export function updateSwapStatus({
356
377
  export function setStepTransactionIds(
357
378
  { getStorage, setStorage }: ExecuterActions<SwapStorage, SwapActionTypes>,
358
379
  txId: string | null,
359
- notifier: SwapQueueContext['notifier'],
360
- eventType?: EventType,
361
380
  explorerUrl?: { url?: string; description?: string }
362
381
  ): void {
363
382
  const swap = getStorage().swapDetails;
@@ -374,22 +393,34 @@ export function setStepTransactionIds(
374
393
  description: explorerUrl.description || null,
375
394
  },
376
395
  ];
377
- if (eventType === 'check_tx_status') {
378
- swap.extraMessage = 'Checking transaction status ...';
379
- swap.extraMessageDetail = '';
380
- swap.extraMessageSeverity = MessageSeverity.info;
381
- } else if (eventType === 'check_approve_tx_status') {
382
- swap.extraMessage = 'Checking approve transaction status ...';
383
- swap.extraMessageDetail = '';
384
- swap.extraMessageSeverity = MessageSeverity.info;
385
- }
396
+
397
+ const isApproval = isApprovalCurrentStepTx(currentStep);
398
+
399
+ if (isApproval) swap.extraMessage = 'Checking approve transaction status ...';
400
+ else swap.extraMessage = 'Checking transaction status ...';
401
+
402
+ swap.extraMessageDetail = '';
403
+ swap.extraMessageSeverity = MessageSeverity.info;
386
404
 
387
405
  setStorage({
388
406
  ...getStorage(),
389
407
  swapDetails: swap,
390
408
  });
391
- if (eventType)
392
- notifier({ eventType: eventType, swap: swap, step: currentStep });
409
+
410
+ notifier({
411
+ event: {
412
+ type: StepEventType.TX_EXECUTION,
413
+ status: StepExecutionEventStatus.TX_SENT,
414
+ },
415
+ swap: swap,
416
+ step: currentStep,
417
+ });
418
+
419
+ notifier({
420
+ event: { type: StepEventType.CHECK_STATUS },
421
+ swap: swap,
422
+ step: currentStep,
423
+ });
393
424
  }
394
425
 
395
426
  /**
@@ -480,10 +511,7 @@ export function markRunningSwapAsSwitchingNetwork({
480
511
  export function markRunningSwapAsDependsOnOtherQueues({
481
512
  getStorage,
482
513
  setStorage,
483
- notifier,
484
- }: Pick<ExecuterActions, 'getStorage' | 'setStorage'> & {
485
- notifier: SwapQueueContext['notifier'];
486
- }):
514
+ }: Pick<ExecuterActions, 'getStorage' | 'setStorage'>):
487
515
  | {
488
516
  swap: PendingSwap;
489
517
  step: PendingSwapStep;
@@ -498,7 +526,10 @@ export function markRunningSwapAsDependsOnOtherQueues({
498
526
  currentStep.networkStatus = PendingSwapNetworkStatus.WaitingForQueue;
499
527
 
500
528
  notifier({
501
- eventType: 'waiting_for_queue',
529
+ event: {
530
+ type: StepEventType.TX_EXECUTION_BLOCKED,
531
+ status: StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE,
532
+ },
502
533
  swap,
503
534
  step: currentStep,
504
535
  });
@@ -737,11 +768,23 @@ export function onBlockForConnectWallet(
737
768
  if (!ok) {
738
769
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
739
770
  const currentStep = getCurrentStep(swap)!;
740
- context.notifier({
741
- eventType:
742
- reason === 'account_miss_match'
743
- ? 'waiting_for_change_wallet_account'
744
- : 'waiting_for_connecting_wallet',
771
+ const { type: walletType, address } = getRequiredWallet(swap);
772
+ notifier({
773
+ event: {
774
+ type: StepEventType.TX_EXECUTION_BLOCKED,
775
+ ...(reason === 'account_miss_match'
776
+ ? {
777
+ status:
778
+ StepExecutionBlockedEventStatus.WAITING_FOR_CHANGE_WALLET_ACCOUNT,
779
+ requiredAccount: address ?? undefined,
780
+ }
781
+ : {
782
+ status:
783
+ StepExecutionBlockedEventStatus.WAITING_FOR_WALLET_CONNECT,
784
+ requiredWallet: walletType ?? undefined,
785
+ requiredAccount: address ?? undefined,
786
+ }),
787
+ },
745
788
  swap: swap,
746
789
  step: currentStep,
747
790
  });
@@ -784,9 +827,22 @@ export function onBlockForChangeNetwork(
784
827
  setStorage: queue.setStorage.bind(queue),
785
828
  });
786
829
 
830
+ const requiredNetwork = getCurrentBlockchainOfOrNull(swap, currentStep);
831
+
832
+ const requiredWallet = getRequiredWallet(swap).type;
833
+
834
+ const currentNetwork = requiredWallet
835
+ ? context.state(requiredWallet).network
836
+ : undefined;
837
+
787
838
  if (result) {
788
- context.notifier({
789
- eventType: 'waiting_for_network_change',
839
+ notifier({
840
+ event: {
841
+ type: StepEventType.TX_EXECUTION_BLOCKED,
842
+ status: StepExecutionBlockedEventStatus.WAITING_FOR_NETWORK_CHANGE,
843
+ requiredNetwork: requiredNetwork ?? undefined,
844
+ currentNetwork: currentNetwork ?? undefined,
845
+ },
790
846
  swap: result.swap,
791
847
  step: result.step,
792
848
  });
@@ -845,7 +901,6 @@ export function onDependsOnOtherQueues(
845
901
  markRunningSwapAsDependsOnOtherQueues({
846
902
  getStorage: queue.getStorage.bind(queue),
847
903
  setStorage: queue.setStorage.bind(queue),
848
- notifier: context.notifier,
849
904
  });
850
905
  return;
851
906
  }
@@ -876,7 +931,6 @@ export function onDependsOnOtherQueues(
876
931
  // TODO: Use key generator
877
932
  retryOn(
878
933
  `${type}-${network}:${address}`,
879
- context.notifier,
880
934
  manager,
881
935
  context.canSwitchNetworkTo
882
936
  );
@@ -907,9 +961,9 @@ export function isRequiredWalletConnected(
907
961
  export function singTransaction(
908
962
  actions: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>
909
963
  ): void {
910
- const { setTransactionDataByHash } = useTransactionsData();
964
+ const { setTransactionDataByHash } = inMemoryTransactionsData();
911
965
  const { getStorage, setStorage, failed, next, schedule, context } = actions;
912
- const { meta, getSigners, notifier, isMobileWallet } = context;
966
+ const { meta, getSigners, isMobileWallet } = context;
913
967
  const swap = getStorage().swapDetails;
914
968
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
915
969
  const currentStep = getCurrentStep(swap)!;
@@ -930,20 +984,40 @@ export function singTransaction(
930
984
  const tx = getCurrentStepTx(currentStep);
931
985
  const txType = tx?.type;
932
986
  const isApproval = isApprovalCurrentStepTx(currentStep);
933
- const isSmartContractCall = [
934
- TransactionType.EVM,
935
- TransactionType.STARKNET,
936
- TransactionType.TRON,
937
- ].includes(txType!);
987
+
988
+ if (!tx || !txType) {
989
+ const extraMessage = 'Unexpected Error: tx is null!';
990
+ const updateResult = updateSwapStatus({
991
+ getStorage,
992
+ setStorage,
993
+ nextStatus: 'failed',
994
+ nextStepStatus: 'failed',
995
+ message: extraMessage,
996
+ details: undefined,
997
+ errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
998
+ });
999
+ notifier({
1000
+ event: {
1001
+ type: StepEventType.FAILED,
1002
+ reason: extraMessage,
1003
+ reasonCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
1004
+ },
1005
+ ...updateResult,
1006
+ });
1007
+ failed();
1008
+ return onFinish();
1009
+ }
1010
+
1011
+ const chainId = meta.blockchains?.[tx.blockChain]?.chainId;
938
1012
 
939
1013
  const hasAlreadyProceededToSign =
940
1014
  typeof swap.hasAlreadyProceededToSign === 'boolean';
941
1015
 
942
1016
  let nextStatus: SwapStatus | undefined,
943
1017
  nextStepStatus: StepStatus,
944
- eventType: EventType,
945
1018
  message: string,
946
- details: string;
1019
+ details: string,
1020
+ eventType: StepEventType;
947
1021
 
948
1022
  if (isApproval) {
949
1023
  message = `Waiting for approval of ${currentStep?.fromSymbol} coin ${
@@ -953,21 +1027,19 @@ export function singTransaction(
953
1027
  'Waiting for approve transaction to be mined and confirmed successfully';
954
1028
  nextStepStatus = 'waitingForApproval';
955
1029
  nextStatus = undefined;
956
- eventType = 'confirm_approve_contract';
1030
+ eventType = StepEventType.TX_EXECUTION;
957
1031
  } else if (hasAlreadyProceededToSign) {
958
1032
  message = 'Transaction is expired. Please try again.';
959
1033
  nextStepStatus = 'failed';
960
1034
  nextStatus = 'failed';
961
1035
  details = '';
962
- eventType = 'transaction_expired';
1036
+ eventType = StepEventType.FAILED;
963
1037
  } else {
964
1038
  message = 'Executing transaction ...';
965
1039
  nextStepStatus = 'running';
966
1040
  nextStatus = 'running';
967
1041
  details = `${mobileWallet ? 'Check your mobile phone!' : ''}`;
968
- eventType = isSmartContractCall
969
- ? 'calling_smart_contract'
970
- : 'confirm_transfer';
1042
+ eventType = StepEventType.TX_EXECUTION;
971
1043
  }
972
1044
 
973
1045
  const updateResult = updateSwapStatus({
@@ -982,18 +1054,29 @@ export function singTransaction(
982
1054
  : hasAlreadyProceededToSign,
983
1055
  errorCode: hasAlreadyProceededToSign ? 'TX_EXPIRED' : undefined,
984
1056
  });
985
- notifier({
986
- eventType,
987
- ...updateResult,
988
- });
1057
+
1058
+ if (eventType === StepEventType.FAILED) {
1059
+ notifier({
1060
+ event: {
1061
+ type: eventType,
1062
+ reason: message,
1063
+ reasonCode: updateResult.failureType ?? DEFAULT_ERROR_CODE,
1064
+ },
1065
+ ...updateResult,
1066
+ });
1067
+ } else
1068
+ notifier({
1069
+ event: { type: eventType, status: StepExecutionEventStatus.SEND_TX },
1070
+ ...updateResult,
1071
+ });
989
1072
 
990
1073
  if (hasAlreadyProceededToSign) {
991
1074
  failed();
992
1075
  onFinish();
993
1076
  return;
994
1077
  }
995
- const signer = walletSigners.getSigner(txType!);
996
- signer.signAndSendTx(tx!, walletAddress, null).then(
1078
+ const signer = walletSigners.getSigner(txType);
1079
+ signer.signAndSendTx(tx, walletAddress, chainId).then(
997
1080
  ({ hash, response }) => {
998
1081
  const explorerUrl = getScannerUrl(
999
1082
  hash,
@@ -1003,8 +1086,6 @@ export function singTransaction(
1003
1086
  setStepTransactionIds(
1004
1087
  actions,
1005
1088
  hash,
1006
- notifier,
1007
- isApproval ? 'check_approve_tx_status' : 'check_tx_status',
1008
1089
  explorerUrl
1009
1090
  ? { url: explorerUrl, description: isApproval ? 'Approve' : 'Swap' }
1010
1091
  : undefined
@@ -1022,13 +1103,7 @@ export function singTransaction(
1022
1103
  prettifyErrorMessage(error);
1023
1104
 
1024
1105
  // if it is an rpc error with details, send the log to sentry
1025
- if (
1026
- error &&
1027
- error?.root &&
1028
- error?.root?.message &&
1029
- error?.root?.code &&
1030
- error?.root?.reason
1031
- )
1106
+ if (error?.root?.message && error?.root?.code && error?.root?.reason)
1032
1107
  logRPCError(error.root, swap, currentStep, sourceWallet?.walletType);
1033
1108
 
1034
1109
  const updateResult = updateSwapStatus({
@@ -1040,14 +1115,13 @@ export function singTransaction(
1040
1115
  details: extraMessageDetail,
1041
1116
  errorCode: extraMessageErrorCode,
1042
1117
  });
1043
- const eventType =
1044
- extraMessageErrorCode === 'REJECTED_BY_USER'
1045
- ? 'contract_rejected'
1046
- : isSmartContractCall
1047
- ? 'smart_contract_call_failed'
1048
- : 'transfer_failed';
1118
+
1049
1119
  notifier({
1050
- eventType,
1120
+ event: {
1121
+ type: StepEventType.FAILED,
1122
+ reason: extraMessage,
1123
+ reasonCode: updateResult.failureType ?? DEFAULT_ERROR_CODE,
1124
+ },
1051
1125
  ...updateResult,
1052
1126
  });
1053
1127
  failed();
@@ -1060,7 +1134,6 @@ export function checkWaitingForConnectWalletChange(params: {
1060
1134
  wallet_network: string;
1061
1135
  manager?: Manager;
1062
1136
  evmChains: EvmBlockchainMeta[];
1063
- notifier: SwapQueueContext['notifier'];
1064
1137
  }): void {
1065
1138
  const { wallet_network, evmChains, manager } = params;
1066
1139
  const [wallet, network] = splitWalletNetwork(wallet_network);
@@ -1089,10 +1162,12 @@ export function checkWaitingForConnectWalletChange(params: {
1089
1162
  }
1090
1163
  );
1091
1164
 
1165
+ const requiredNetwork = getCurrentBlockchainOfOrNull(swap, currentStep);
1166
+
1092
1167
  if (
1093
1168
  currentStepRequiredWallet === wallet &&
1094
1169
  hasWaitingForConnect &&
1095
- getCurrentBlockchainOfOrNull(swap, currentStep) != network
1170
+ requiredNetwork != network
1096
1171
  ) {
1097
1172
  const queueInstance = q.list;
1098
1173
  const { type } = getRequiredWallet(swap);
@@ -1112,8 +1187,14 @@ export function checkWaitingForConnectWalletChange(params: {
1112
1187
  });
1113
1188
 
1114
1189
  if (result) {
1115
- params?.notifier({
1116
- eventType: 'waiting_for_network_change',
1190
+ notifier({
1191
+ event: {
1192
+ type: StepEventType.TX_EXECUTION_BLOCKED,
1193
+ status:
1194
+ StepExecutionBlockedEventStatus.WAITING_FOR_NETWORK_CHANGE,
1195
+ currentNetwork: network,
1196
+ requiredNetwork: requiredNetwork ?? undefined,
1197
+ },
1117
1198
  swap: result.swap,
1118
1199
  step: result.step,
1119
1200
  });
@@ -1186,21 +1267,26 @@ export function getRunningSwaps(manager: Manager): PendingSwap[] {
1186
1267
  * @param notifier
1187
1268
  * @returns
1188
1269
  */
1189
- export function resetRunningSwapNotifsOnPageLoad(
1190
- runningSwaps: PendingSwap[],
1191
- notifier: SwapQueueContext['notifier']
1192
- ) {
1270
+ export function resetRunningSwapNotifsOnPageLoad(runningSwaps: PendingSwap[]) {
1193
1271
  runningSwaps.forEach((swap) => {
1194
1272
  const currentStep = getCurrentStep(swap);
1195
- let eventType: EventType | undefined;
1273
+ const eventType = StepEventType.TX_EXECUTION_BLOCKED;
1274
+ let eventSubtype:
1275
+ | StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE
1276
+ | StepExecutionBlockedEventStatus.WAITING_FOR_WALLET_CONNECT
1277
+ | undefined;
1196
1278
  if (currentStep?.networkStatus === PendingSwapNetworkStatus.WaitingForQueue)
1197
- eventType = 'waiting_for_queue';
1279
+ eventSubtype = StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE;
1198
1280
  else if (swap?.status === 'running') {
1199
- eventType = 'waiting_for_connecting_wallet';
1281
+ eventSubtype = StepExecutionBlockedEventStatus.WAITING_FOR_WALLET_CONNECT;
1200
1282
  }
1201
1283
  if (!!eventType && !!notifier) {
1202
1284
  notifier({
1203
- eventType,
1285
+ event: {
1286
+ type: eventType,
1287
+ status:
1288
+ eventSubtype ?? StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE,
1289
+ },
1204
1290
  swap: swap,
1205
1291
  step: currentStep,
1206
1292
  });
@@ -1221,7 +1307,6 @@ export function resetRunningSwapNotifsOnPageLoad(
1221
1307
  */
1222
1308
  export function retryOn(
1223
1309
  wallet_network: string,
1224
- notifier: SwapQueueContext['notifier'],
1225
1310
  manager?: Manager,
1226
1311
  canSwitchNetworkTo?: (type: WalletType, network: Network) => boolean,
1227
1312
  options = { fallbackToOnlyWallet: true }
@@ -1270,7 +1355,6 @@ export function retryOn(
1270
1355
  markRunningSwapAsDependsOnOtherQueues({
1271
1356
  getStorage: currentQueue.getStorage.bind(currentQueue),
1272
1357
  setStorage: currentQueue.setStorage.bind(currentQueue),
1273
- notifier: notifier,
1274
1358
  });
1275
1359
  }
1276
1360
  }
@@ -1326,8 +1410,49 @@ export function cancelSwap(
1326
1410
  nextStepStatus: 'failed',
1327
1411
  errorCode: 'USER_CANCEL',
1328
1412
  });
1413
+
1414
+ notifier({
1415
+ event: {
1416
+ type: StepEventType.FAILED,
1417
+ reasonCode: 'USER_CANCEL',
1418
+ reason: updateResult.swap.extraMessage ?? undefined,
1419
+ },
1420
+
1421
+ swap: updateResult.swap,
1422
+ step: updateResult.step,
1423
+ });
1424
+
1329
1425
  reset();
1330
1426
  if (manager) manager?.retry();
1331
1427
 
1332
1428
  return updateResult;
1333
1429
  }
1430
+
1431
+ export function getLastSuccessfulStep<T extends { status: StepStatus }[]>(
1432
+ steps: T
1433
+ ): ArrayElement<T> | undefined {
1434
+ return steps
1435
+ .slice()
1436
+ .reverse()
1437
+ .find((step) => step.status === 'success') as ArrayElement<T> | undefined;
1438
+ }
1439
+
1440
+ export function getFailedStep<T extends { status: StepStatus }[]>(
1441
+ steps: T
1442
+ ): ArrayElement<T> | undefined {
1443
+ return steps
1444
+ .slice()
1445
+ .reverse()
1446
+ .find((step) => step.status === 'failed') as ArrayElement<T> | undefined;
1447
+ }
1448
+
1449
+ export function isApprovalTX(step: Step): boolean {
1450
+ const { transaction } = step;
1451
+ const approvalTx =
1452
+ (transaction?.type === TransactionType.EVM && transaction.isApprovalTx) ||
1453
+ (transaction?.type === TransactionType.STARKNET &&
1454
+ transaction.isApprovalTx) ||
1455
+ (transaction?.type === TransactionType.TRON && transaction.isApprovalTx);
1456
+
1457
+ return approvalTx;
1458
+ }
package/src/hooks.ts CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  } from './helpers';
8
8
  import { migrated, migration } from './migration';
9
9
  import { UseQueueManagerParams } from './types';
10
+ import { eventEmitter } from './services/eventEmitter';
10
11
 
11
12
  let isCalled = 0;
12
13
 
@@ -54,14 +55,8 @@ function useQueueManager(params: UseQueueManagerParams): void {
54
55
  evmChains: params.evmChains,
55
56
  wallet_network: params.lastConnectedWallet,
56
57
  manager,
57
- notifier: params.notifier,
58
58
  });
59
- retryOn(
60
- params.lastConnectedWallet,
61
- params.notifier,
62
- manager,
63
- params.canSwitchNetworkTo
64
- );
59
+ retryOn(params.lastConnectedWallet, manager, params.canSwitchNetworkTo);
65
60
  }
66
61
  }, [params.lastConnectedWallet]);
67
62
 
@@ -78,4 +73,8 @@ function useQueueManager(params: UseQueueManagerParams): void {
78
73
  }, [params.disconnectedWallet]);
79
74
  }
80
75
 
81
- export { useQueueManager, useMigration };
76
+ function useEvents() {
77
+ return eventEmitter;
78
+ }
79
+
80
+ export { useQueueManager, useMigration, useEvents };
package/src/index.ts CHANGED
@@ -3,13 +3,39 @@ import { SwapQueueDef } from './types';
3
3
  import { swapQueueDef } from './queueDef';
4
4
 
5
5
  export { PrettyError, prettifyErrorMessage } from './shared-errors';
6
- export type { SwapQueueContext, SwapStorage } from './types';
6
+ export type {
7
+ SwapQueueContext,
8
+ SwapStorage,
9
+ RouteExecutionEvents,
10
+ Route,
11
+ Step,
12
+ RouteEvent,
13
+ StepEvent,
14
+ EventSeverity,
15
+ RouteStartedEvent,
16
+ RouteSucceededEvent,
17
+ RouteFailedEvent,
18
+ StepStartedEvent,
19
+ StepSucceededEvent,
20
+ StepFailedEvent,
21
+ StepTxExecutionUpdatedEvent,
22
+ StepTxExecutionBlockedEvent,
23
+ StepCheckStatusEvent,
24
+ StepApprovalTxSucceededEvent,
25
+ StepOutputRevealedEvent,
26
+ } from './types';
27
+ export {
28
+ MainEvents,
29
+ StepEventType,
30
+ RouteEventType,
31
+ StepExecutionEventStatus,
32
+ StepExecutionBlockedEventStatus,
33
+ } from './types';
7
34
  export type {
8
35
  PendingSwapWithQueueID,
9
36
  PendingSwapStep,
10
37
  PendingSwap,
11
38
  EventType,
12
- SwapProgressNotification,
13
39
  } from './shared';
14
40
  export {
15
41
  getCurrentBlockchainOfOrNull,
@@ -29,8 +55,9 @@ export {
29
55
  getRunningSwaps,
30
56
  splitWalletNetwork,
31
57
  resetRunningSwapNotifsOnPageLoad,
58
+ isApprovalTX,
32
59
  } from './helpers';
33
- export { useMigration, useQueueManager } from './hooks';
60
+ export { useMigration, useQueueManager, useEvents } from './hooks';
34
61
 
35
62
  export function makeQueueDefinition(configs: Configs): SwapQueueDef {
36
63
  initConfig(configs);