@rango-dev/queue-manager-rango-preset 0.1.10-next.96 → 0.1.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
@@ -1,4 +1,9 @@
1
- import { ExecuterActions, QueueType } from '@rango-dev/queue-manager-core';
1
+ import {
2
+ ExecuterActions,
3
+ QueueInfo,
4
+ QueueName,
5
+ QueueType,
6
+ } from '@rango-dev/queue-manager-core';
2
7
  import {
3
8
  BlockReason,
4
9
  SwapActionTypes,
@@ -47,20 +52,21 @@ import {
47
52
  PendingSwap,
48
53
  PendingSwapNetworkStatus,
49
54
  PendingSwapStep,
50
- prettifyErrorMessage,
51
55
  StepStatus,
52
56
  SwapStatus,
53
57
  Wallet,
54
- WalletTypeAndAddress,
55
58
  SwapProgressNotification,
59
+ getRelatedWallet,
60
+ getCurrentAddressOf,
56
61
  } from './shared';
57
62
  import { logRPCError } from './shared-sentry';
58
63
  import {
59
64
  PrettyError,
60
65
  mapAppErrorCodesToAPIErrorCode,
61
- APIErrorCode,
66
+ prettifyErrorMessage,
62
67
  } from './shared-errors';
63
68
  import { httpService } from './services';
69
+ import { APIErrorCode, SignerErrorCode } from 'rango-types/lib';
64
70
 
65
71
  type WhenTaskBlocked = Parameters<NonNullable<SwapQueueDef['whenTaskBlocked']>>;
66
72
  type WhenTaskBlockedEvent = WhenTaskBlocked[0];
@@ -88,13 +94,26 @@ function claimQueue() {
88
94
  }
89
95
 
90
96
  /**
91
- *
97
+ * Sample inputs are:
98
+ * - "metamask-ETH"
99
+ * - "metamask-BSC-BSC:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
100
+ * - "token-pocket-BSC-BSC:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
92
101
  * Returns "wallet and network" separately, even if the wallet is dashed inside.
93
102
  *
94
103
  */
95
104
 
96
- function splitWalletNetwork(input: string): string[] {
97
- return input?.split(/-(?=[^-]*$)/);
105
+ export function splitWalletNetwork(input: string): string[] {
106
+ const removedAddressInput = input?.split(':')[0] || '';
107
+ const splittedInput = removedAddressInput.split('-');
108
+ const network = splittedInput[splittedInput.length - 1];
109
+ const walletNetwork = splittedInput.slice(0, -1);
110
+
111
+ if (walletNetwork[walletNetwork.length - 1] === network) {
112
+ walletNetwork.pop();
113
+ }
114
+ const wallet = walletNetwork.join('-');
115
+
116
+ return [wallet, network];
98
117
  }
99
118
 
100
119
  /**
@@ -139,7 +158,7 @@ export function updateSwapStatus({
139
158
  nextStepStatus?: StepStatus;
140
159
  message?: string;
141
160
  details?: string | null | undefined;
142
- errorCode?: string | null;
161
+ errorCode?: APIErrorCode | SignerErrorCode | null;
143
162
  hasAlreadyProceededToSign?: boolean;
144
163
  }): {
145
164
  swap: PendingSwap;
@@ -154,9 +173,10 @@ export function updateSwapStatus({
154
173
  if (!!nextStatus && ['failed', 'success'].includes(nextStatus))
155
174
  swap.finishTime = new Date().getTime().toString();
156
175
 
157
- if (!!message) swap.extraMessage = message;
158
-
159
- if (!!details) swap.extraMessageDetail = details;
176
+ if (!!message || !!details) {
177
+ swap.extraMessage = message || '';
178
+ swap.extraMessageDetail = details || '';
179
+ }
160
180
 
161
181
  if (!!nextStepStatus && ['failed'].includes(nextStepStatus)) {
162
182
  //if user cancel the swap, we should pass relevant reason to the server.
@@ -170,9 +190,7 @@ export function updateSwapStatus({
170
190
  .reportFailure({
171
191
  requestId: swap.requestId,
172
192
  step: currentStep?.id || 1,
173
- eventType: mapAppErrorCodesToAPIErrorCode(
174
- hasAlreadyProceededToSign ? APIErrorCode.TX_FAIL : errorCode
175
- ),
193
+ eventType: mapAppErrorCodesToAPIErrorCode(errorCode),
176
194
  reason: errorReason || '',
177
195
  data: walletType ? { wallet: walletType } : undefined,
178
196
  })
@@ -202,19 +220,40 @@ export function updateSwapStatus({
202
220
  export function setStepTransactionIds(
203
221
  { getStorage, setStorage }: ExecuterActions<SwapStorage, SwapActionTypes>,
204
222
  txId: string | null,
205
- eventType: EventType,
206
- notifier: SwapQueueContext['notifier']
223
+ notifier: SwapQueueContext['notifier'],
224
+ eventType?: EventType,
225
+ approveUrl?: string
207
226
  ): void {
208
227
  const swap = getStorage().swapDetails;
209
228
  swap.hasAlreadyProceededToSign = null;
210
229
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
211
230
  const currentStep = getCurrentStep(swap)!;
212
- currentStep.executedTransactionId = txId || currentStep.executedTransactionId;
231
+ currentStep.executedTransactionId = txId;
232
+ currentStep.executedTransactionTime = new Date().getTime().toString();
233
+ if (!!approveUrl)
234
+ currentStep.explorerUrl = [
235
+ ...(currentStep.explorerUrl || []),
236
+ {
237
+ url: approveUrl,
238
+ description: `approve`,
239
+ },
240
+ ];
241
+ if (eventType === 'check_tx_status') {
242
+ swap.extraMessage = 'Checking transaction status ...';
243
+ swap.extraMessageDetail = '';
244
+ swap.extraMessageSeverity = MessageSeverity.info;
245
+ } else if (eventType === 'check_approve_tx_status') {
246
+ swap.extraMessage = 'Checking approve transaction status ...';
247
+ swap.extraMessageDetail = '';
248
+ swap.extraMessageSeverity = MessageSeverity.info;
249
+ }
250
+
213
251
  setStorage({
214
252
  ...getStorage(),
215
253
  swapDetails: swap,
216
254
  });
217
- notifier({ eventType: eventType, swap: swap, step: currentStep });
255
+ if (!!eventType)
256
+ notifier({ eventType: eventType, swap: swap, step: currentStep });
218
257
  }
219
258
 
220
259
  export function getSwapNotitfication(
@@ -320,7 +359,10 @@ export function markRunningSwapAsSwitchingNetwork({
320
359
  export function markRunningSwapAsDependsOnOtherQueues({
321
360
  getStorage,
322
361
  setStorage,
323
- }: Pick<ExecuterActions, 'getStorage' | 'setStorage'>):
362
+ notifier,
363
+ }: Pick<ExecuterActions, 'getStorage' | 'setStorage'> & {
364
+ notifier: SwapQueueContext['notifier'];
365
+ }):
324
366
  | {
325
367
  swap: PendingSwap;
326
368
  step: PendingSwapStep;
@@ -334,6 +376,12 @@ export function markRunningSwapAsDependsOnOtherQueues({
334
376
  swap.networkStatusExtraMessageDetail = '';
335
377
  currentStep.networkStatus = PendingSwapNetworkStatus.WaitingForQueue;
336
378
 
379
+ notifier({
380
+ eventType: 'waiting_for_queue',
381
+ swap,
382
+ step: currentStep,
383
+ });
384
+
337
385
  setStorage({
338
386
  ...getStorage(),
339
387
  swapDetails: swap,
@@ -462,7 +510,6 @@ export async function isNetworkMatchedForTransaction(
462
510
  providers: Providers
463
511
  ): Promise<boolean> {
464
512
  if (isWalletNull(wallet)) {
465
- console.warn('wallet object is null');
466
513
  return false;
467
514
  }
468
515
  const fromBlockChain = getCurrentBlockchainOfOrNull(swap, step);
@@ -529,51 +576,6 @@ export async function isNetworkMatchedForTransaction(
529
576
  return true;
530
577
  }
531
578
 
532
- /**
533
- * Returns the wallet address, based on the current step of `PendingSwap`.
534
- */
535
- export const getCurrentAddressOf = (
536
- swap: PendingSwap,
537
- step: PendingSwapStep
538
- ): string => {
539
- const result =
540
- swap.wallets[step.evmTransaction?.blockChain || ''] ||
541
- swap.wallets[step.evmApprovalTransaction?.blockChain || ''] ||
542
- swap.wallets[step.tronTransaction?.blockChain || ''] ||
543
- swap.wallets[step.tronApprovalTransaction?.blockChain || ''] ||
544
- swap.wallets[step.starknetTransaction?.blockChain || ''] ||
545
- swap.wallets[step.starknetApprovalTransaction?.blockChain || ''] ||
546
- swap.wallets[step.cosmosTransaction?.blockChain || ''] ||
547
- swap.wallets[step.solanaTransaction?.blockChain || ''] ||
548
- (step.transferTransaction?.fromWalletAddress
549
- ? { address: step.transferTransaction?.fromWalletAddress }
550
- : null) ||
551
- null;
552
- if (result == null) throw PrettyError.WalletMissing();
553
- return result.address;
554
- };
555
-
556
- // Todo: Is it same with `getRequiredWallet`?
557
- export function getRelatedWallet(
558
- swap: PendingSwap,
559
- currentStep: PendingSwapStep
560
- ): WalletTypeAndAddress {
561
- const walletAddress = getCurrentAddressOf(swap, currentStep);
562
- const walletKV =
563
- Object.keys(swap.wallets)
564
- .map((k) => ({ k, v: swap.wallets[k] }))
565
- .find(({ v }) => v.address === walletAddress) || null;
566
- const blockchain = walletKV?.k || null;
567
- const wallet = walletKV?.v || null;
568
-
569
- const walletType = wallet?.walletType;
570
- if (walletType === WalletType.UNKNOWN || wallet === null)
571
- throw PrettyError.AssertionFailed(
572
- `Wallet for source ${blockchain} not passed: walletType: ${walletType}`
573
- );
574
- return wallet;
575
- }
576
-
577
579
  export const isTxAlreadyCreated = (
578
580
  swap: PendingSwap,
579
581
  step: PendingSwapStep
@@ -633,7 +635,7 @@ export function updateNetworkStatus(
633
635
 
634
636
  /**
635
637
  * Event handler for blocked tasks.
636
- * If a transcation execution is manually blocked (like for parallel or waiting for walle),
638
+ * If a transcation execution is manually blocked (like for parallel or waiting for wallet),
637
639
  * This function will be called by queue manager using `queue definition`.
638
640
  *
639
641
  * It checks if the required wallet is connected, unblock the queue to be run.
@@ -645,11 +647,16 @@ export function onBlockForConnectWallet(
645
647
  const { context, queue } = meta;
646
648
  const swap = queue.getStorage().swapDetails as SwapStorage['swapDetails'];
647
649
 
648
- if (!isRequiredWalletConnected(swap, context.state)) {
650
+ const { ok, reason } = isRequiredWalletConnected(swap, context.state);
651
+
652
+ if (!ok) {
649
653
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
650
654
  const currentStep = getCurrentStep(swap)!;
651
655
  context.notifier({
652
- eventType: 'waiting_for_connecting_wallet',
656
+ eventType:
657
+ reason === 'account_miss_match'
658
+ ? 'waiting_for_change_wallet_account'
659
+ : 'waiting_for_connecting_wallet',
653
660
  swap: swap,
654
661
  step: currentStep,
655
662
  });
@@ -714,7 +721,7 @@ export function onBlockForChangeNetwork(
714
721
 
715
722
  /**
716
723
  * Event handler for blocked tasks. (Parallel mode)
717
- * If a transcation execution is manually blocked (like for parallel or waiting for walle),
724
+ * If a transcation execution flow is manually blocked (like for parallel or waiting for walle),
718
725
  * This function will be called by queue manager using `queue definition`.
719
726
  *
720
727
  * It checks the blocked tasks, if there is no active `claimed` queue, try to give it to the best candidate.
@@ -723,7 +730,7 @@ export function onDependsOnOtherQueues(
723
730
  _event: WhenTaskBlockedEvent,
724
731
  meta: WhenTaskBlockedMeta
725
732
  ): void {
726
- const { getBlockedTasks, forceExecute, queue, manager } = meta;
733
+ const { getBlockedTasks, forceExecute, queue, manager, context } = meta;
727
734
  const { setClaimer, claimedBy, reset } = claimQueue();
728
735
 
729
736
  // We only needs those blocked tasks that have DEPENDS_ON_OTHER_QUEUES reason.
@@ -738,12 +745,15 @@ export function onDependsOnOtherQueues(
738
745
  const claimerId = claimedBy();
739
746
  const isClaimedByAnyQueue = !!claimerId;
740
747
 
748
+ if (claimerId === queue.id) return;
749
+
741
750
  // Check if any queue `claimed` before, if yes, we don't should do anything.
742
751
  if (isClaimedByAnyQueue) {
743
752
  // We need to keep the latest swap messages
744
753
  markRunningSwapAsDependsOnOtherQueues({
745
754
  getStorage: queue.getStorage.bind(queue),
746
755
  setStorage: queue.setStorage.bind(queue),
756
+ notifier: context.notifier,
747
757
  });
748
758
  return;
749
759
  }
@@ -772,7 +782,7 @@ export function onDependsOnOtherQueues(
772
782
  resetClaimedBy: () => {
773
783
  reset();
774
784
  // TODO: Use key generator
775
- retryOn(`${type}-${network}-${address}`, manager);
785
+ retryOn(`${type}-${network}:${address}`, context.notifier, manager);
776
786
  },
777
787
  });
778
788
  }
@@ -780,19 +790,21 @@ export function onDependsOnOtherQueues(
780
790
  export function isRequiredWalletConnected(
781
791
  swap: PendingSwap,
782
792
  getState: (type: WalletType) => WalletState
783
- ): boolean {
793
+ ): { ok: boolean; reason: 'not_connected' | 'account_miss_match' } {
784
794
  const { type, address } = getRequiredWallet(swap);
785
795
  if (!type || !address) {
786
- return false;
796
+ return { ok: false, reason: 'not_connected' };
787
797
  }
788
798
  const walletState = getState(type);
789
- const { accounts } = walletState;
799
+ const { accounts, connected } = walletState;
790
800
  const connectedAccounts = accounts || [];
801
+ if (!connected) return { ok: false, reason: 'not_connected' };
791
802
 
792
- return connectedAccounts.some((account) => {
803
+ const matched = connectedAccounts.some((account) => {
793
804
  const { address: accountAddress } = readAccountAddress(account);
794
805
  return address === accountAddress;
795
806
  });
807
+ return { ok: matched, reason: 'account_miss_match' };
796
808
  }
797
809
 
798
810
  export function singTransaction(
@@ -819,6 +831,7 @@ export function singTransaction(
819
831
  const walletSigners = getSigners(sourceWallet.walletType);
820
832
 
821
833
  const onFinish = () => {
834
+ // TODO resetClaimedBy is undefined here
822
835
  if (actions.context.resetClaimedBy) {
823
836
  actions.context.resetClaimedBy();
824
837
  }
@@ -847,7 +860,7 @@ export function singTransaction(
847
860
  'Waiting for approve transaction to be mined and confirmed successfully',
848
861
  });
849
862
  notifier({
850
- eventType: 'confirm_contract',
863
+ eventType: 'confirm_approve_contract',
851
864
  ...updateResult,
852
865
  });
853
866
 
@@ -857,25 +870,18 @@ export function singTransaction(
857
870
  .signAndSendTx(evmApprovalTransaction, walletAddress, null)
858
871
  .then(
859
872
  (hash) => {
860
- console.debug('transaction of approval minted successfully', hash);
861
873
  const approveUrl = getEvmApproveUrl(
862
874
  hash,
863
875
  getCurrentBlockchainOf(swap, currentStep),
864
876
  meta.evmBasedChains
865
877
  );
866
- currentStep.explorerUrl = [
867
- ...(currentStep.explorerUrl || []),
868
- {
869
- url: approveUrl,
870
- description: `approve`,
871
- },
872
- ];
873
-
874
- // `currentStep` has been mutated, let's update storage.
875
- setStorage({
876
- ...getStorage(),
877
- swapDetails: swap,
878
- });
878
+ setStepTransactionIds(
879
+ actions,
880
+ hash,
881
+ notifier,
882
+ 'check_approve_tx_status',
883
+ approveUrl
884
+ );
879
885
  schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS);
880
886
  next();
881
887
  onFinish();
@@ -883,7 +889,7 @@ export function singTransaction(
883
889
 
884
890
  (error) => {
885
891
  if (swap.status === 'failed') return;
886
- console.debug('error in approving', error);
892
+
887
893
  const { extraMessage, extraMessageDetail, extraMessageErrorCode } =
888
894
  prettifyErrorMessage(error);
889
895
  if (
@@ -936,7 +942,7 @@ export function singTransaction(
936
942
  'Waiting for approve transaction to be mined and confirmed successfully',
937
943
  });
938
944
  notifier({
939
- eventType: 'confirm_contract',
945
+ eventType: 'confirm_approve_contract',
940
946
  ...updateResult,
941
947
  });
942
948
 
@@ -946,21 +952,14 @@ export function singTransaction(
946
952
  .signAndSendTx(tronApprovalTransaction, walletAddress, null)
947
953
  .then(
948
954
  (hash) => {
949
- console.debug('transaction of approval minted successfully', hash);
950
955
  const approveUrl = getTronApproveUrl(hash);
951
- currentStep.explorerUrl = [
952
- ...(currentStep.explorerUrl || []),
953
- {
954
- url: approveUrl,
955
- description: `approve`,
956
- },
957
- ];
958
-
959
- // `currentStep` has been mutated, let's update storage.
960
- setStorage({
961
- ...getStorage(),
962
- swapDetails: swap,
963
- });
956
+ setStepTransactionIds(
957
+ actions,
958
+ hash,
959
+ notifier,
960
+ 'check_approve_tx_status',
961
+ approveUrl
962
+ );
964
963
  schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS);
965
964
  next();
966
965
  onFinish();
@@ -968,7 +967,7 @@ export function singTransaction(
968
967
 
969
968
  (error) => {
970
969
  if (swap.status === 'failed') return;
971
- console.debug('error in approving', error);
970
+
972
971
  const { extraMessage, extraMessageDetail, extraMessageErrorCode } =
973
972
  prettifyErrorMessage(error);
974
973
  if (
@@ -1021,7 +1020,7 @@ export function singTransaction(
1021
1020
  'Waiting for approve transaction to be mined and confirmed successfully',
1022
1021
  });
1023
1022
  notifier({
1024
- eventType: 'confirm_contract',
1023
+ eventType: 'confirm_approve_contract',
1025
1024
  ...updateResult,
1026
1025
  });
1027
1026
 
@@ -1031,21 +1030,14 @@ export function singTransaction(
1031
1030
  .signAndSendTx(starknetApprovalTransaction, walletAddress, null)
1032
1031
  .then(
1033
1032
  (hash) => {
1034
- console.debug('transaction of approval minted successfully', hash);
1035
1033
  const approveUrl = getStarknetApproveUrl(hash);
1036
- currentStep.explorerUrl = [
1037
- ...(currentStep.explorerUrl || []),
1038
- {
1039
- url: approveUrl,
1040
- description: `approve`,
1041
- },
1042
- ];
1043
-
1044
- // `currentStep` has been mutated, let's update storage.
1045
- setStorage({
1046
- ...getStorage(),
1047
- swapDetails: swap,
1048
- });
1034
+ setStepTransactionIds(
1035
+ actions,
1036
+ hash,
1037
+ notifier,
1038
+ 'check_approve_tx_status',
1039
+ approveUrl
1040
+ );
1049
1041
  schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS);
1050
1042
  next();
1051
1043
  onFinish();
@@ -1053,7 +1045,7 @@ export function singTransaction(
1053
1045
 
1054
1046
  (error) => {
1055
1047
  if (swap.status === 'failed') return;
1056
- console.debug('error in approving', error);
1048
+
1057
1049
  const { extraMessage, extraMessageDetail, extraMessageErrorCode } =
1058
1050
  prettifyErrorMessage(error);
1059
1051
  if (
@@ -1094,6 +1086,11 @@ export function singTransaction(
1094
1086
 
1095
1087
  const hasAlreadyProceededToSign =
1096
1088
  typeof swap.hasAlreadyProceededToSign === 'boolean';
1089
+ const nextStepStatusBasedOnHasAlreadyProceededToSign =
1090
+ hasAlreadyProceededToSign ? 'failed' : 'running';
1091
+ const errorCodeBasedOnHasAlreadyProceededToSign = hasAlreadyProceededToSign
1092
+ ? 'TX_EXPIRED'
1093
+ : null;
1097
1094
  const executeMessage = hasAlreadyProceededToSign
1098
1095
  ? 'Transaction is expired. Please try again'
1099
1096
  : 'executing transaction';
@@ -1107,11 +1104,12 @@ export function singTransaction(
1107
1104
  const updateResult = updateSwapStatus({
1108
1105
  getStorage,
1109
1106
  setStorage,
1110
- nextStepStatus: hasAlreadyProceededToSign ? 'failed' : 'running',
1111
- nextStatus: hasAlreadyProceededToSign ? 'failed' : 'running',
1107
+ nextStepStatus: nextStepStatusBasedOnHasAlreadyProceededToSign,
1108
+ nextStatus: nextStepStatusBasedOnHasAlreadyProceededToSign,
1112
1109
  message: executeMessage,
1113
1110
  details: executeDetails,
1114
1111
  hasAlreadyProceededToSign,
1112
+ errorCode: errorCodeBasedOnHasAlreadyProceededToSign,
1115
1113
  });
1116
1114
 
1117
1115
  const notification = getSwapNotitfication('confirm_transfer', updateResult);
@@ -1126,12 +1124,7 @@ export function singTransaction(
1126
1124
  .signAndSendTx(transferTransaction, walletAddress, null)
1127
1125
  .then(
1128
1126
  (txId) => {
1129
- setStepTransactionIds(
1130
- actions,
1131
- txId,
1132
- 'transfer_confirmed',
1133
- notifier
1134
- );
1127
+ setStepTransactionIds(actions, txId, notifier, 'check_tx_status');
1135
1128
  schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS);
1136
1129
  next();
1137
1130
  onFinish();
@@ -1162,11 +1155,12 @@ export function singTransaction(
1162
1155
  const updateResult = updateSwapStatus({
1163
1156
  getStorage,
1164
1157
  setStorage,
1165
- nextStepStatus: hasAlreadyProceededToSign ? 'failed' : 'running',
1166
- nextStatus: hasAlreadyProceededToSign ? 'failed' : 'running',
1158
+ nextStepStatus: nextStepStatusBasedOnHasAlreadyProceededToSign,
1159
+ nextStatus: nextStepStatusBasedOnHasAlreadyProceededToSign,
1167
1160
  message: executeMessage,
1168
1161
  details: executeDetails,
1169
1162
  hasAlreadyProceededToSign,
1163
+ errorCode: errorCodeBasedOnHasAlreadyProceededToSign,
1170
1164
  });
1171
1165
  const notification = getSwapNotitfication(
1172
1166
  'calling_smart_contract',
@@ -1183,12 +1177,7 @@ export function singTransaction(
1183
1177
  .signAndSendTx(evmTransaction, walletAddress, null)
1184
1178
  .then(
1185
1179
  (id) => {
1186
- setStepTransactionIds(
1187
- actions,
1188
- id,
1189
- 'smart_contract_called',
1190
- notifier
1191
- );
1180
+ setStepTransactionIds(actions, id, notifier, 'check_tx_status');
1192
1181
  schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS);
1193
1182
  next();
1194
1183
  onFinish();
@@ -1234,11 +1223,12 @@ export function singTransaction(
1234
1223
  const updateResult = updateSwapStatus({
1235
1224
  getStorage,
1236
1225
  setStorage,
1237
- nextStepStatus: hasAlreadyProceededToSign ? 'failed' : 'running',
1238
- nextStatus: hasAlreadyProceededToSign ? 'failed' : 'running',
1226
+ nextStepStatus: nextStepStatusBasedOnHasAlreadyProceededToSign,
1227
+ nextStatus: nextStepStatusBasedOnHasAlreadyProceededToSign,
1239
1228
  message: executeMessage,
1240
1229
  details: executeDetails,
1241
1230
  hasAlreadyProceededToSign,
1231
+ errorCode: errorCodeBasedOnHasAlreadyProceededToSign,
1242
1232
  });
1243
1233
  const notification = getSwapNotitfication(
1244
1234
  'calling_smart_contract',
@@ -1288,12 +1278,7 @@ export function singTransaction(
1288
1278
  .then(
1289
1279
  // todo
1290
1280
  (id: string | null) => {
1291
- setStepTransactionIds(
1292
- actions,
1293
- id,
1294
- 'smart_contract_called',
1295
- notifier
1296
- );
1281
+ setStepTransactionIds(actions, id, notifier, 'check_tx_status');
1297
1282
  schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS);
1298
1283
  next();
1299
1284
  onFinish();
@@ -1324,11 +1309,12 @@ export function singTransaction(
1324
1309
  const updateResult = updateSwapStatus({
1325
1310
  getStorage,
1326
1311
  setStorage,
1327
- nextStepStatus: hasAlreadyProceededToSign ? 'failed' : 'running',
1328
- nextStatus: hasAlreadyProceededToSign ? 'failed' : 'running',
1312
+ nextStepStatus: nextStepStatusBasedOnHasAlreadyProceededToSign,
1313
+ nextStatus: nextStepStatusBasedOnHasAlreadyProceededToSign,
1329
1314
  message: executeMessage,
1330
1315
  details: executeDetails,
1331
1316
  hasAlreadyProceededToSign,
1317
+ errorCode: errorCodeBasedOnHasAlreadyProceededToSign,
1332
1318
  });
1333
1319
  const notification = getSwapNotitfication(
1334
1320
  'calling_smart_contract',
@@ -1346,12 +1332,7 @@ export function singTransaction(
1346
1332
  .signAndSendTx(tx, walletAddress, null)
1347
1333
  .then(
1348
1334
  (txId) => {
1349
- setStepTransactionIds(
1350
- actions,
1351
- txId,
1352
- 'smart_contract_called',
1353
- notifier
1354
- );
1335
+ setStepTransactionIds(actions, txId, notifier, 'check_tx_status');
1355
1336
  schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS);
1356
1337
  next();
1357
1338
  onFinish();
@@ -1382,11 +1363,12 @@ export function singTransaction(
1382
1363
  const updateResult = updateSwapStatus({
1383
1364
  getStorage,
1384
1365
  setStorage,
1385
- nextStepStatus: hasAlreadyProceededToSign ? 'failed' : 'running',
1386
- nextStatus: hasAlreadyProceededToSign ? 'failed' : 'running',
1366
+ nextStepStatus: nextStepStatusBasedOnHasAlreadyProceededToSign,
1367
+ nextStatus: nextStepStatusBasedOnHasAlreadyProceededToSign,
1387
1368
  message: executeMessage,
1388
1369
  details: executeDetails,
1389
1370
  hasAlreadyProceededToSign,
1371
+ errorCode: errorCodeBasedOnHasAlreadyProceededToSign,
1390
1372
  });
1391
1373
  const notification = getSwapNotitfication(
1392
1374
  'calling_smart_contract',
@@ -1403,12 +1385,7 @@ export function singTransaction(
1403
1385
  .signAndSendTx(tronTransaction, walletAddress, null)
1404
1386
  .then(
1405
1387
  (id) => {
1406
- setStepTransactionIds(
1407
- actions,
1408
- id,
1409
- 'smart_contract_called',
1410
- notifier
1411
- );
1388
+ setStepTransactionIds(actions, id, notifier, 'check_tx_status');
1412
1389
  schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS);
1413
1390
  next();
1414
1391
  onFinish();
@@ -1454,11 +1431,12 @@ export function singTransaction(
1454
1431
  const updateResult = updateSwapStatus({
1455
1432
  getStorage,
1456
1433
  setStorage,
1457
- nextStepStatus: hasAlreadyProceededToSign ? 'failed' : 'running',
1458
- nextStatus: hasAlreadyProceededToSign ? 'failed' : 'running',
1434
+ nextStepStatus: nextStepStatusBasedOnHasAlreadyProceededToSign,
1435
+ nextStatus: nextStepStatusBasedOnHasAlreadyProceededToSign,
1459
1436
  message: executeMessage,
1460
1437
  details: executeDetails,
1461
1438
  hasAlreadyProceededToSign,
1439
+ errorCode: errorCodeBasedOnHasAlreadyProceededToSign,
1462
1440
  });
1463
1441
  const notification = getSwapNotitfication(
1464
1442
  'calling_smart_contract',
@@ -1475,12 +1453,7 @@ export function singTransaction(
1475
1453
  .signAndSendTx(starknetTransaction, walletAddress, null)
1476
1454
  .then(
1477
1455
  (id) => {
1478
- setStepTransactionIds(
1479
- actions,
1480
- id,
1481
- 'smart_contract_called',
1482
- notifier
1483
- );
1456
+ setStepTransactionIds(actions, id, notifier, 'check_tx_status');
1484
1457
  schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS);
1485
1458
  next();
1486
1459
  onFinish();
@@ -1529,6 +1502,7 @@ export function checkWaitingForConnectWalletChange(params: {
1529
1502
  wallet_network: string;
1530
1503
  manager?: Manager;
1531
1504
  evmChains: EvmBlockchainMeta[];
1505
+ notifier: SwapQueueContext['notifier'];
1532
1506
  }): void {
1533
1507
  const { wallet_network, evmChains, manager } = params;
1534
1508
  const [wallet, network] = splitWalletNetwork(wallet_network);
@@ -1549,6 +1523,7 @@ export function checkWaitingForConnectWalletChange(params: {
1549
1523
  const task = q.list.state.tasks[taskId];
1550
1524
  return (
1551
1525
  task.status === Status.BLOCKED &&
1526
+ // TODO double check later
1552
1527
  [BlockReason.WAIT_FOR_CONNECT_WALLET].includes(
1553
1528
  task.blockedFor?.reason
1554
1529
  )
@@ -1573,10 +1548,18 @@ export function checkWaitingForConnectWalletChange(params: {
1573
1548
  silent: true,
1574
1549
  });
1575
1550
 
1576
- markRunningSwapAsSwitchingNetwork({
1551
+ const result = markRunningSwapAsSwitchingNetwork({
1577
1552
  getStorage: queueInstance.getStorage.bind(queueInstance),
1578
1553
  setStorage: queueInstance.setStorage.bind(queueInstance),
1579
1554
  });
1555
+
1556
+ if (result) {
1557
+ params?.notifier({
1558
+ eventType: 'waiting_for_network_change',
1559
+ swap: result.swap,
1560
+ step: result.step,
1561
+ });
1562
+ }
1580
1563
  }
1581
1564
  }
1582
1565
  }
@@ -1617,6 +1600,56 @@ export function checkWaitingForNetworkChange(manager?: Manager): void {
1617
1600
  });
1618
1601
  }
1619
1602
 
1603
+ /**
1604
+ * Get list of all running swaps
1605
+ *
1606
+ * @param manager
1607
+ * @returns list of pending swaps
1608
+ */
1609
+ export function getRunningSwaps(manager: Manager): PendingSwap[] {
1610
+ const queues = manager?.getAll() || new Map<QueueName, QueueInfo>();
1611
+ let result: PendingSwap[] = [];
1612
+ queues.forEach((q) => {
1613
+ // retry only on affected queues
1614
+ const queueStorage = q.list.getStorage() as SwapStorage | undefined;
1615
+ const swap = queueStorage?.swapDetails;
1616
+ if (!swap || swap.status !== 'running') return;
1617
+ result.push(swap);
1618
+ });
1619
+ return result;
1620
+ }
1621
+
1622
+ /**
1623
+ *
1624
+ * Trying to reset notifications for pending swaps to correct message on page load.
1625
+ * We could remove this after supporting auto connect for wallets.
1626
+ *
1627
+ * @param swaps
1628
+ * @param notifier
1629
+ * @returns
1630
+ */
1631
+ export function resetRunningSwapNotifsOnPageLoad(
1632
+ runningSwaps: PendingSwap[],
1633
+ notifier: SwapQueueContext['notifier']
1634
+ ) {
1635
+ runningSwaps.forEach((swap) => {
1636
+ const currentStep = getCurrentStep(swap);
1637
+ let eventType: EventType | undefined;
1638
+ if (currentStep?.networkStatus === PendingSwapNetworkStatus.WaitingForQueue)
1639
+ eventType = 'waiting_for_queue';
1640
+ else if (swap?.status === 'running') {
1641
+ eventType = 'waiting_for_connecting_wallet';
1642
+ }
1643
+ if (!!eventType && !!notifier) {
1644
+ notifier({
1645
+ eventType,
1646
+ swap: swap,
1647
+ step: currentStep,
1648
+ });
1649
+ }
1650
+ });
1651
+ }
1652
+
1620
1653
  /**
1621
1654
  *
1622
1655
  * Try to run blocked tasks by wallet and network name.
@@ -1630,6 +1663,7 @@ export function checkWaitingForNetworkChange(manager?: Manager): void {
1630
1663
  */
1631
1664
  export function retryOn(
1632
1665
  wallet_network: string,
1666
+ notifier: SwapQueueContext['notifier'],
1633
1667
  manager?: Manager,
1634
1668
  options = { fallbackToOnlyWallet: true }
1635
1669
  ): void {
@@ -1651,7 +1685,7 @@ export function retryOn(
1651
1685
  const currentStep = getCurrentStep(swap);
1652
1686
  if (currentStep) {
1653
1687
  if (
1654
- currentStep.fromBlockchain == network &&
1688
+ getCurrentBlockchainOfOrNull(swap, currentStep) == network &&
1655
1689
  queueStorage?.swapDetails.wallets[network]?.walletType === wallet
1656
1690
  ) {
1657
1691
  walletAndNetworkMatched.push(q.list);
@@ -1666,7 +1700,6 @@ export function retryOn(
1666
1700
  }
1667
1701
  });
1668
1702
 
1669
- // const isWaitingForConnectWallet = (status: Status) =>
1670
1703
  let finalQueueToBeRun: QueueType | undefined = undefined;
1671
1704
  if (walletAndNetworkMatched.length > 0) {
1672
1705
  finalQueueToBeRun = walletAndNetworkMatched[0];
@@ -1678,6 +1711,7 @@ export function retryOn(
1678
1711
  markRunningSwapAsDependsOnOtherQueues({
1679
1712
  getStorage: currentQueue.getStorage.bind(currentQueue),
1680
1713
  setStorage: currentQueue.setStorage.bind(currentQueue),
1714
+ notifier: notifier,
1681
1715
  });
1682
1716
  }
1683
1717
  }
@@ -1719,3 +1753,20 @@ export async function throwOnOK(
1719
1753
  throw e;
1720
1754
  }
1721
1755
  }
1756
+
1757
+ export function cancelSwap(swap: QueueInfo): {
1758
+ swap: PendingSwap;
1759
+ step: PendingSwapStep | null;
1760
+ } {
1761
+ swap.actions.cancel();
1762
+ return updateSwapStatus({
1763
+ getStorage: swap.actions.getStorage,
1764
+ setStorage: swap.actions.setStorage,
1765
+ message: 'Swap canceled by user.',
1766
+ details:
1767
+ "Warning: If you've already signed and sent a transaction, it won't be affected, but next swap steps will not be executed.",
1768
+ nextStatus: 'failed',
1769
+ nextStepStatus: 'failed',
1770
+ errorCode: 'USER_CANCEL',
1771
+ });
1772
+ }