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

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,29 @@ 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
+ swap.extraMessage = 'Transaction sent ...';
397
+ swap.extraMessageDetail = '';
398
+ swap.extraMessageSeverity = MessageSeverity.info;
386
399
 
387
400
  setStorage({
388
401
  ...getStorage(),
389
402
  swapDetails: swap,
390
403
  });
391
- if (eventType)
392
- notifier({ eventType: eventType, swap: swap, step: currentStep });
404
+
405
+ notifier({
406
+ event: {
407
+ type: StepEventType.TX_EXECUTION,
408
+ status: StepExecutionEventStatus.TX_SENT,
409
+ },
410
+ swap: swap,
411
+ step: currentStep,
412
+ });
413
+
414
+ notifier({
415
+ event: { type: StepEventType.CHECK_STATUS },
416
+ swap: swap,
417
+ step: currentStep,
418
+ });
393
419
  }
394
420
 
395
421
  /**
@@ -480,10 +506,7 @@ export function markRunningSwapAsSwitchingNetwork({
480
506
  export function markRunningSwapAsDependsOnOtherQueues({
481
507
  getStorage,
482
508
  setStorage,
483
- notifier,
484
- }: Pick<ExecuterActions, 'getStorage' | 'setStorage'> & {
485
- notifier: SwapQueueContext['notifier'];
486
- }):
509
+ }: Pick<ExecuterActions, 'getStorage' | 'setStorage'>):
487
510
  | {
488
511
  swap: PendingSwap;
489
512
  step: PendingSwapStep;
@@ -498,7 +521,10 @@ export function markRunningSwapAsDependsOnOtherQueues({
498
521
  currentStep.networkStatus = PendingSwapNetworkStatus.WaitingForQueue;
499
522
 
500
523
  notifier({
501
- eventType: 'waiting_for_queue',
524
+ event: {
525
+ type: StepEventType.TX_EXECUTION_BLOCKED,
526
+ status: StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE,
527
+ },
502
528
  swap,
503
529
  step: currentStep,
504
530
  });
@@ -737,11 +763,23 @@ export function onBlockForConnectWallet(
737
763
  if (!ok) {
738
764
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
739
765
  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',
766
+ const { type: walletType, address } = getRequiredWallet(swap);
767
+ notifier({
768
+ event: {
769
+ type: StepEventType.TX_EXECUTION_BLOCKED,
770
+ ...(reason === 'account_miss_match'
771
+ ? {
772
+ status:
773
+ StepExecutionBlockedEventStatus.WAITING_FOR_CHANGE_WALLET_ACCOUNT,
774
+ requiredAccount: address ?? undefined,
775
+ }
776
+ : {
777
+ status:
778
+ StepExecutionBlockedEventStatus.WAITING_FOR_WALLET_CONNECT,
779
+ requiredWallet: walletType ?? undefined,
780
+ requiredAccount: address ?? undefined,
781
+ }),
782
+ },
745
783
  swap: swap,
746
784
  step: currentStep,
747
785
  });
@@ -784,9 +822,22 @@ export function onBlockForChangeNetwork(
784
822
  setStorage: queue.setStorage.bind(queue),
785
823
  });
786
824
 
825
+ const requiredNetwork = getCurrentBlockchainOfOrNull(swap, currentStep);
826
+
827
+ const requiredWallet = getRequiredWallet(swap).type;
828
+
829
+ const currentNetwork = requiredWallet
830
+ ? context.state(requiredWallet).network
831
+ : undefined;
832
+
787
833
  if (result) {
788
- context.notifier({
789
- eventType: 'waiting_for_network_change',
834
+ notifier({
835
+ event: {
836
+ type: StepEventType.TX_EXECUTION_BLOCKED,
837
+ status: StepExecutionBlockedEventStatus.WAITING_FOR_NETWORK_CHANGE,
838
+ requiredNetwork: requiredNetwork ?? undefined,
839
+ currentNetwork: currentNetwork ?? undefined,
840
+ },
790
841
  swap: result.swap,
791
842
  step: result.step,
792
843
  });
@@ -845,7 +896,6 @@ export function onDependsOnOtherQueues(
845
896
  markRunningSwapAsDependsOnOtherQueues({
846
897
  getStorage: queue.getStorage.bind(queue),
847
898
  setStorage: queue.setStorage.bind(queue),
848
- notifier: context.notifier,
849
899
  });
850
900
  return;
851
901
  }
@@ -876,7 +926,6 @@ export function onDependsOnOtherQueues(
876
926
  // TODO: Use key generator
877
927
  retryOn(
878
928
  `${type}-${network}:${address}`,
879
- context.notifier,
880
929
  manager,
881
930
  context.canSwitchNetworkTo
882
931
  );
@@ -907,9 +956,9 @@ export function isRequiredWalletConnected(
907
956
  export function singTransaction(
908
957
  actions: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>
909
958
  ): void {
910
- const { setTransactionDataByHash } = useTransactionsData();
959
+ const { setTransactionDataByHash } = inMemoryTransactionsData();
911
960
  const { getStorage, setStorage, failed, next, schedule, context } = actions;
912
- const { meta, getSigners, notifier, isMobileWallet } = context;
961
+ const { meta, getSigners, isMobileWallet } = context;
913
962
  const swap = getStorage().swapDetails;
914
963
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
915
964
  const currentStep = getCurrentStep(swap)!;
@@ -930,20 +979,40 @@ export function singTransaction(
930
979
  const tx = getCurrentStepTx(currentStep);
931
980
  const txType = tx?.type;
932
981
  const isApproval = isApprovalCurrentStepTx(currentStep);
933
- const isSmartContractCall = [
934
- TransactionType.EVM,
935
- TransactionType.STARKNET,
936
- TransactionType.TRON,
937
- ].includes(txType!);
982
+
983
+ if (!tx || !txType) {
984
+ const extraMessage = 'Unexpected Error: tx is null!';
985
+ const updateResult = updateSwapStatus({
986
+ getStorage,
987
+ setStorage,
988
+ nextStatus: 'failed',
989
+ nextStepStatus: 'failed',
990
+ message: extraMessage,
991
+ details: undefined,
992
+ errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
993
+ });
994
+ notifier({
995
+ event: {
996
+ type: StepEventType.FAILED,
997
+ reason: extraMessage,
998
+ reasonCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
999
+ },
1000
+ ...updateResult,
1001
+ });
1002
+ failed();
1003
+ return onFinish();
1004
+ }
1005
+
1006
+ const chainId = meta.blockchains?.[tx.blockChain]?.chainId;
938
1007
 
939
1008
  const hasAlreadyProceededToSign =
940
1009
  typeof swap.hasAlreadyProceededToSign === 'boolean';
941
1010
 
942
1011
  let nextStatus: SwapStatus | undefined,
943
1012
  nextStepStatus: StepStatus,
944
- eventType: EventType,
945
1013
  message: string,
946
- details: string;
1014
+ details: string,
1015
+ eventType: StepEventType;
947
1016
 
948
1017
  if (isApproval) {
949
1018
  message = `Waiting for approval of ${currentStep?.fromSymbol} coin ${
@@ -953,21 +1022,19 @@ export function singTransaction(
953
1022
  'Waiting for approve transaction to be mined and confirmed successfully';
954
1023
  nextStepStatus = 'waitingForApproval';
955
1024
  nextStatus = undefined;
956
- eventType = 'confirm_approve_contract';
1025
+ eventType = StepEventType.TX_EXECUTION;
957
1026
  } else if (hasAlreadyProceededToSign) {
958
1027
  message = 'Transaction is expired. Please try again.';
959
1028
  nextStepStatus = 'failed';
960
1029
  nextStatus = 'failed';
961
1030
  details = '';
962
- eventType = 'transaction_expired';
1031
+ eventType = StepEventType.FAILED;
963
1032
  } else {
964
1033
  message = 'Executing transaction ...';
965
1034
  nextStepStatus = 'running';
966
1035
  nextStatus = 'running';
967
1036
  details = `${mobileWallet ? 'Check your mobile phone!' : ''}`;
968
- eventType = isSmartContractCall
969
- ? 'calling_smart_contract'
970
- : 'confirm_transfer';
1037
+ eventType = StepEventType.TX_EXECUTION;
971
1038
  }
972
1039
 
973
1040
  const updateResult = updateSwapStatus({
@@ -982,18 +1049,29 @@ export function singTransaction(
982
1049
  : hasAlreadyProceededToSign,
983
1050
  errorCode: hasAlreadyProceededToSign ? 'TX_EXPIRED' : undefined,
984
1051
  });
985
- notifier({
986
- eventType,
987
- ...updateResult,
988
- });
1052
+
1053
+ if (eventType === StepEventType.FAILED) {
1054
+ notifier({
1055
+ event: {
1056
+ type: eventType,
1057
+ reason: message,
1058
+ reasonCode: updateResult.failureType ?? DEFAULT_ERROR_CODE,
1059
+ },
1060
+ ...updateResult,
1061
+ });
1062
+ } else
1063
+ notifier({
1064
+ event: { type: eventType, status: StepExecutionEventStatus.SEND_TX },
1065
+ ...updateResult,
1066
+ });
989
1067
 
990
1068
  if (hasAlreadyProceededToSign) {
991
1069
  failed();
992
1070
  onFinish();
993
1071
  return;
994
1072
  }
995
- const signer = walletSigners.getSigner(txType!);
996
- signer.signAndSendTx(tx!, walletAddress, null).then(
1073
+ const signer = walletSigners.getSigner(txType);
1074
+ signer.signAndSendTx(tx, walletAddress, chainId).then(
997
1075
  ({ hash, response }) => {
998
1076
  const explorerUrl = getScannerUrl(
999
1077
  hash,
@@ -1003,8 +1081,6 @@ export function singTransaction(
1003
1081
  setStepTransactionIds(
1004
1082
  actions,
1005
1083
  hash,
1006
- notifier,
1007
- isApproval ? 'check_approve_tx_status' : 'check_tx_status',
1008
1084
  explorerUrl
1009
1085
  ? { url: explorerUrl, description: isApproval ? 'Approve' : 'Swap' }
1010
1086
  : undefined
@@ -1022,13 +1098,7 @@ export function singTransaction(
1022
1098
  prettifyErrorMessage(error);
1023
1099
 
1024
1100
  // 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
- )
1101
+ if (error?.root?.message && error?.root?.code && error?.root?.reason)
1032
1102
  logRPCError(error.root, swap, currentStep, sourceWallet?.walletType);
1033
1103
 
1034
1104
  const updateResult = updateSwapStatus({
@@ -1040,14 +1110,13 @@ export function singTransaction(
1040
1110
  details: extraMessageDetail,
1041
1111
  errorCode: extraMessageErrorCode,
1042
1112
  });
1043
- const eventType =
1044
- extraMessageErrorCode === 'REJECTED_BY_USER'
1045
- ? 'contract_rejected'
1046
- : isSmartContractCall
1047
- ? 'smart_contract_call_failed'
1048
- : 'transfer_failed';
1113
+
1049
1114
  notifier({
1050
- eventType,
1115
+ event: {
1116
+ type: StepEventType.FAILED,
1117
+ reason: extraMessage,
1118
+ reasonCode: updateResult.failureType ?? DEFAULT_ERROR_CODE,
1119
+ },
1051
1120
  ...updateResult,
1052
1121
  });
1053
1122
  failed();
@@ -1060,7 +1129,6 @@ export function checkWaitingForConnectWalletChange(params: {
1060
1129
  wallet_network: string;
1061
1130
  manager?: Manager;
1062
1131
  evmChains: EvmBlockchainMeta[];
1063
- notifier: SwapQueueContext['notifier'];
1064
1132
  }): void {
1065
1133
  const { wallet_network, evmChains, manager } = params;
1066
1134
  const [wallet, network] = splitWalletNetwork(wallet_network);
@@ -1089,10 +1157,12 @@ export function checkWaitingForConnectWalletChange(params: {
1089
1157
  }
1090
1158
  );
1091
1159
 
1160
+ const requiredNetwork = getCurrentBlockchainOfOrNull(swap, currentStep);
1161
+
1092
1162
  if (
1093
1163
  currentStepRequiredWallet === wallet &&
1094
1164
  hasWaitingForConnect &&
1095
- getCurrentBlockchainOfOrNull(swap, currentStep) != network
1165
+ requiredNetwork != network
1096
1166
  ) {
1097
1167
  const queueInstance = q.list;
1098
1168
  const { type } = getRequiredWallet(swap);
@@ -1112,8 +1182,14 @@ export function checkWaitingForConnectWalletChange(params: {
1112
1182
  });
1113
1183
 
1114
1184
  if (result) {
1115
- params?.notifier({
1116
- eventType: 'waiting_for_network_change',
1185
+ notifier({
1186
+ event: {
1187
+ type: StepEventType.TX_EXECUTION_BLOCKED,
1188
+ status:
1189
+ StepExecutionBlockedEventStatus.WAITING_FOR_NETWORK_CHANGE,
1190
+ currentNetwork: network,
1191
+ requiredNetwork: requiredNetwork ?? undefined,
1192
+ },
1117
1193
  swap: result.swap,
1118
1194
  step: result.step,
1119
1195
  });
@@ -1186,21 +1262,26 @@ export function getRunningSwaps(manager: Manager): PendingSwap[] {
1186
1262
  * @param notifier
1187
1263
  * @returns
1188
1264
  */
1189
- export function resetRunningSwapNotifsOnPageLoad(
1190
- runningSwaps: PendingSwap[],
1191
- notifier: SwapQueueContext['notifier']
1192
- ) {
1265
+ export function resetRunningSwapNotifsOnPageLoad(runningSwaps: PendingSwap[]) {
1193
1266
  runningSwaps.forEach((swap) => {
1194
1267
  const currentStep = getCurrentStep(swap);
1195
- let eventType: EventType | undefined;
1268
+ const eventType = StepEventType.TX_EXECUTION_BLOCKED;
1269
+ let eventSubtype:
1270
+ | StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE
1271
+ | StepExecutionBlockedEventStatus.WAITING_FOR_WALLET_CONNECT
1272
+ | undefined;
1196
1273
  if (currentStep?.networkStatus === PendingSwapNetworkStatus.WaitingForQueue)
1197
- eventType = 'waiting_for_queue';
1274
+ eventSubtype = StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE;
1198
1275
  else if (swap?.status === 'running') {
1199
- eventType = 'waiting_for_connecting_wallet';
1276
+ eventSubtype = StepExecutionBlockedEventStatus.WAITING_FOR_WALLET_CONNECT;
1200
1277
  }
1201
1278
  if (!!eventType && !!notifier) {
1202
1279
  notifier({
1203
- eventType,
1280
+ event: {
1281
+ type: eventType,
1282
+ status:
1283
+ eventSubtype ?? StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE,
1284
+ },
1204
1285
  swap: swap,
1205
1286
  step: currentStep,
1206
1287
  });
@@ -1221,7 +1302,6 @@ export function resetRunningSwapNotifsOnPageLoad(
1221
1302
  */
1222
1303
  export function retryOn(
1223
1304
  wallet_network: string,
1224
- notifier: SwapQueueContext['notifier'],
1225
1305
  manager?: Manager,
1226
1306
  canSwitchNetworkTo?: (type: WalletType, network: Network) => boolean,
1227
1307
  options = { fallbackToOnlyWallet: true }
@@ -1270,7 +1350,6 @@ export function retryOn(
1270
1350
  markRunningSwapAsDependsOnOtherQueues({
1271
1351
  getStorage: currentQueue.getStorage.bind(currentQueue),
1272
1352
  setStorage: currentQueue.setStorage.bind(currentQueue),
1273
- notifier: notifier,
1274
1353
  });
1275
1354
  }
1276
1355
  }
@@ -1326,8 +1405,49 @@ export function cancelSwap(
1326
1405
  nextStepStatus: 'failed',
1327
1406
  errorCode: 'USER_CANCEL',
1328
1407
  });
1408
+
1409
+ notifier({
1410
+ event: {
1411
+ type: StepEventType.FAILED,
1412
+ reasonCode: 'USER_CANCEL',
1413
+ reason: updateResult.swap.extraMessage ?? undefined,
1414
+ },
1415
+
1416
+ swap: updateResult.swap,
1417
+ step: updateResult.step,
1418
+ });
1419
+
1329
1420
  reset();
1330
1421
  if (manager) manager?.retry();
1331
1422
 
1332
1423
  return updateResult;
1333
1424
  }
1425
+
1426
+ export function getLastSuccessfulStep<T extends { status: StepStatus }[]>(
1427
+ steps: T
1428
+ ): ArrayElement<T> | undefined {
1429
+ return steps
1430
+ .slice()
1431
+ .reverse()
1432
+ .find((step) => step.status === 'success') as ArrayElement<T> | undefined;
1433
+ }
1434
+
1435
+ export function getFailedStep<T extends { status: StepStatus }[]>(
1436
+ steps: T
1437
+ ): ArrayElement<T> | undefined {
1438
+ return steps
1439
+ .slice()
1440
+ .reverse()
1441
+ .find((step) => step.status === 'failed') as ArrayElement<T> | undefined;
1442
+ }
1443
+
1444
+ export function isApprovalTX(step: Step): boolean {
1445
+ const { transaction } = step;
1446
+ const approvalTx =
1447
+ (transaction?.type === TransactionType.EVM && transaction.isApprovalTx) ||
1448
+ (transaction?.type === TransactionType.STARKNET &&
1449
+ transaction.isApprovalTx) ||
1450
+ (transaction?.type === TransactionType.TRON && transaction.isApprovalTx);
1451
+
1452
+ return approvalTx;
1453
+ }
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,28 @@ 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
+ } from './types';
16
+ export {
17
+ MainEvents,
18
+ StepEventType,
19
+ RouteEventType,
20
+ StepExecutionEventStatus,
21
+ StepExecutionBlockedEventStatus,
22
+ } from './types';
7
23
  export type {
8
24
  PendingSwapWithQueueID,
9
25
  PendingSwapStep,
10
26
  PendingSwap,
11
27
  EventType,
12
- SwapProgressNotification,
13
28
  } from './shared';
14
29
  export {
15
30
  getCurrentBlockchainOfOrNull,
@@ -29,8 +44,9 @@ export {
29
44
  getRunningSwaps,
30
45
  splitWalletNetwork,
31
46
  resetRunningSwapNotifsOnPageLoad,
47
+ isApprovalTX,
32
48
  } from './helpers';
33
- export { useMigration, useQueueManager } from './hooks';
49
+ export { useMigration, useQueueManager, useEvents } from './hooks';
34
50
 
35
51
  export function makeQueueDefinition(configs: Configs): SwapQueueDef {
36
52
  initConfig(configs);