@rango-dev/queue-manager-rango-preset 0.0.0-experimental-936229e8-20251208

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +353 -0
  2. package/dist/actions/checkStatus.d.ts +13 -0
  3. package/dist/actions/checkStatus.d.ts.map +1 -0
  4. package/dist/actions/common/checkEnvironmentBeforeExecuteTransaction.d.ts +8 -0
  5. package/dist/actions/common/checkEnvironmentBeforeExecuteTransaction.d.ts.map +1 -0
  6. package/dist/actions/common/produceNextStateForTransaction.d.ts +17 -0
  7. package/dist/actions/common/produceNextStateForTransaction.d.ts.map +1 -0
  8. package/dist/actions/common/utils.d.ts +5 -0
  9. package/dist/actions/common/utils.d.ts.map +1 -0
  10. package/dist/actions/createTransaction.d.ts +12 -0
  11. package/dist/actions/createTransaction.d.ts.map +1 -0
  12. package/dist/actions/executeTransaction/executeTransaction.d.ts +14 -0
  13. package/dist/actions/executeTransaction/executeTransaction.d.ts.map +1 -0
  14. package/dist/actions/executeTransaction/index.d.ts +2 -0
  15. package/dist/actions/executeTransaction/index.d.ts.map +1 -0
  16. package/dist/actions/scheduleNextStep.d.ts +14 -0
  17. package/dist/actions/scheduleNextStep.d.ts.map +1 -0
  18. package/dist/actions/start.d.ts +4 -0
  19. package/dist/actions/start.d.ts.map +1 -0
  20. package/dist/configs.d.ts +14 -0
  21. package/dist/configs.d.ts.map +1 -0
  22. package/dist/constants.d.ts +7 -0
  23. package/dist/constants.d.ts.map +1 -0
  24. package/dist/helpers.d.ts +255 -0
  25. package/dist/helpers.d.ts.map +1 -0
  26. package/dist/hooks.d.ts +19 -0
  27. package/dist/hooks.d.ts.map +1 -0
  28. package/dist/index.d.ts +11 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +2 -0
  31. package/dist/index.js.map +7 -0
  32. package/dist/migration.d.ts +15 -0
  33. package/dist/migration.d.ts.map +1 -0
  34. package/dist/numbers.d.ts +3 -0
  35. package/dist/numbers.d.ts.map +1 -0
  36. package/dist/queue-manager-rango-preset.build.json +1 -0
  37. package/dist/queueDef.d.ts +10 -0
  38. package/dist/queueDef.d.ts.map +1 -0
  39. package/dist/services/eventEmitter.d.ts +10 -0
  40. package/dist/services/eventEmitter.d.ts.map +1 -0
  41. package/dist/services/httpService.d.ts +3 -0
  42. package/dist/services/httpService.d.ts.map +1 -0
  43. package/dist/services/index.d.ts +2 -0
  44. package/dist/services/index.d.ts.map +1 -0
  45. package/dist/shared-errors.d.ts +25 -0
  46. package/dist/shared-errors.d.ts.map +1 -0
  47. package/dist/shared.d.ts +81 -0
  48. package/dist/shared.d.ts.map +1 -0
  49. package/dist/types.d.ts +172 -0
  50. package/dist/types.d.ts.map +1 -0
  51. package/package.json +45 -0
  52. package/readme.md +2 -0
  53. package/src/actions/checkStatus.ts +564 -0
  54. package/src/actions/common/checkEnvironmentBeforeExecuteTransaction.ts +157 -0
  55. package/src/actions/common/produceNextStateForTransaction.ts +167 -0
  56. package/src/actions/common/utils.ts +25 -0
  57. package/src/actions/createTransaction.ts +117 -0
  58. package/src/actions/executeTransaction/executeTransaction.ts +107 -0
  59. package/src/actions/executeTransaction/index.ts +1 -0
  60. package/src/actions/scheduleNextStep.ts +104 -0
  61. package/src/actions/start.ts +16 -0
  62. package/src/configs.ts +38 -0
  63. package/src/constants.ts +18 -0
  64. package/src/helpers.ts +1598 -0
  65. package/src/hooks.ts +94 -0
  66. package/src/index.ts +68 -0
  67. package/src/migration.ts +124 -0
  68. package/src/numbers.ts +68 -0
  69. package/src/queueDef.ts +39 -0
  70. package/src/services/eventEmitter.ts +290 -0
  71. package/src/services/httpService.ts +10 -0
  72. package/src/services/index.ts +1 -0
  73. package/src/shared-errors.ts +165 -0
  74. package/src/shared.ts +473 -0
  75. package/src/types.ts +305 -0
@@ -0,0 +1,165 @@
1
+ import type {
2
+ APIErrorCode,
3
+ SignerErrorCode as SignerErrorCodeType,
4
+ } from 'rango-types';
5
+ import {
6
+ SignerErrorCode,
7
+ SignerError,
8
+ isSignerErrorCode,
9
+ isAPIErrorCode,
10
+ } from 'rango-types';
11
+ import { DEFAULT_ERROR_CODE } from './constants';
12
+
13
+ export type ErrorDetail = {
14
+ extraMessage: string;
15
+ extraMessageDetail?: string | null | undefined;
16
+ extraMessageErrorCode: SignerErrorCodeType | APIErrorCode | null;
17
+ };
18
+
19
+ const ERROR_ASSERTION_FAILED = 'Assertion failed (Unexpected behaviour)';
20
+ const ERROR_CREATE_TRANSACTION = 'Create transaction failed in Rango Server';
21
+ const ERROR_INPUT_WALLET_NOT_FOUND = 'Input wallet not found';
22
+
23
+ type ErrorRoot = string | Record<string, string> | null;
24
+
25
+ export class PrettyError extends Error {
26
+ private readonly detail?: string;
27
+ private readonly root?: ErrorRoot;
28
+ private readonly code?: APIErrorCode;
29
+ public _isPrettyError = true;
30
+
31
+ constructor(
32
+ code: APIErrorCode,
33
+ m: string,
34
+ root?: ErrorRoot,
35
+ detail?: string
36
+ ) {
37
+ super(m);
38
+ Object.setPrototypeOf(this, PrettyError.prototype);
39
+ PrettyError.prototype._isPrettyError = true;
40
+ this.code = code;
41
+ this.detail = detail;
42
+ this.root = root;
43
+ }
44
+
45
+ static isPrettyError(obj: unknown): obj is PrettyError {
46
+ return (
47
+ obj instanceof PrettyError ||
48
+ Object.prototype.hasOwnProperty.call(obj, '_isPrettyError')
49
+ );
50
+ }
51
+
52
+ getErrorDetail(): ErrorDetail {
53
+ const rawMessage =
54
+ typeof this.root === 'object' && this.root && this.root.error
55
+ ? this.root.error
56
+ : JSON.stringify(this.root);
57
+ const rootStr =
58
+ typeof this.root === 'string'
59
+ ? this.root
60
+ : this.root instanceof Error
61
+ ? this.root.message
62
+ : rawMessage;
63
+ return {
64
+ extraMessage: this.message,
65
+ extraMessageDetail: this.detail || rootStr,
66
+ extraMessageErrorCode: this.code || null,
67
+ };
68
+ }
69
+
70
+ static AssertionFailed(m: string): PrettyError {
71
+ return new PrettyError(
72
+ 'CLIENT_UNEXPECTED_BEHAVIOUR',
73
+ ERROR_ASSERTION_FAILED,
74
+ null,
75
+ m
76
+ );
77
+ }
78
+
79
+ static BadStatusCode(
80
+ message: string,
81
+ statusCode: number | string
82
+ ): PrettyError {
83
+ return new PrettyError(
84
+ 'TX_FAIL',
85
+ message,
86
+ null,
87
+ `status code = ${statusCode}`
88
+ );
89
+ }
90
+
91
+ static CreateTransaction(detail: string): PrettyError {
92
+ return new PrettyError(
93
+ 'FETCH_TX_FAILED',
94
+ ERROR_CREATE_TRANSACTION,
95
+ null,
96
+ detail
97
+ );
98
+ }
99
+
100
+ static WalletMissing(): PrettyError {
101
+ return new PrettyError(
102
+ 'CLIENT_UNEXPECTED_BEHAVIOUR',
103
+ ERROR_INPUT_WALLET_NOT_FOUND,
104
+ null,
105
+ 'Server requested for a blockchain or address not selected by user'
106
+ );
107
+ }
108
+
109
+ static BlockchainMissing(): PrettyError {
110
+ return new PrettyError(
111
+ 'CLIENT_UNEXPECTED_BEHAVIOUR',
112
+ ERROR_INPUT_WALLET_NOT_FOUND,
113
+ null,
114
+ 'Server requested for a blockchain or address not selected by user'
115
+ );
116
+ }
117
+ }
118
+
119
+ export function mapAppErrorCodesToAPIErrorCode(
120
+ errorCode: string | null
121
+ ): APIErrorCode {
122
+ try {
123
+ if (!errorCode) return DEFAULT_ERROR_CODE;
124
+ if (isAPIErrorCode(errorCode)) return errorCode;
125
+ if (isSignerErrorCode(errorCode)) {
126
+ const t: { [key in SignerErrorCodeType]: APIErrorCode } = {
127
+ [SignerErrorCode.REJECTED_BY_USER]: 'USER_REJECT',
128
+ [SignerErrorCode.SIGN_TX_ERROR]: 'CALL_WALLET_FAILED',
129
+ [SignerErrorCode.SEND_TX_ERROR]: 'SEND_TX_FAILED',
130
+ [SignerErrorCode.TX_FAILED_IN_BLOCKCHAIN]: 'TX_FAILED_IN_BLOCKCHAIN',
131
+ [SignerErrorCode.NOT_IMPLEMENTED]: DEFAULT_ERROR_CODE,
132
+ [SignerErrorCode.OPERATION_UNSUPPORTED]: DEFAULT_ERROR_CODE,
133
+ [SignerErrorCode.UNEXPECTED_BEHAVIOUR]: DEFAULT_ERROR_CODE,
134
+ };
135
+ return t[errorCode];
136
+ }
137
+ return DEFAULT_ERROR_CODE;
138
+ } catch (err) {
139
+ return DEFAULT_ERROR_CODE;
140
+ }
141
+ }
142
+
143
+ export const prettifyErrorMessage = (obj: unknown): ErrorDetail => {
144
+ if (!obj) return { extraMessage: '', extraMessageErrorCode: null };
145
+ if (PrettyError.isPrettyError(obj)) return obj.getErrorDetail();
146
+ if (SignerError.isSignerError(obj)) {
147
+ const t = obj.getErrorDetail();
148
+ return {
149
+ extraMessage: t.message,
150
+ extraMessageDetail: t.detail,
151
+ extraMessageErrorCode: t.code,
152
+ };
153
+ }
154
+ if (obj instanceof Error)
155
+ return {
156
+ extraMessage: obj.toString(),
157
+ extraMessageErrorCode: null,
158
+ };
159
+ if (typeof obj !== 'string')
160
+ return {
161
+ extraMessage: JSON.stringify(obj),
162
+ extraMessageErrorCode: null,
163
+ };
164
+ return { extraMessage: obj, extraMessageErrorCode: null };
165
+ };
package/src/shared.ts ADDED
@@ -0,0 +1,473 @@
1
+ import type { NamespaceInputForConnect } from '@rango-dev/wallets-core/dist/legacy/types';
2
+ import type { Network, WalletType } from '@rango-dev/wallets-shared';
3
+ import type {
4
+ BlockchainMeta,
5
+ ConfirmRouteResponse,
6
+ MetaResponse,
7
+ SwapResult,
8
+ Token,
9
+ } from 'rango-sdk';
10
+ import type {
11
+ PendingSwap,
12
+ PendingSwapStep,
13
+ SwapSavedSettings,
14
+ SwapStepRoute,
15
+ WalletTypeAndAddress,
16
+ } from 'rango-types';
17
+
18
+ import BigNumber from 'bignumber.js';
19
+
20
+ import { numberToString } from './numbers';
21
+ import { PrettyError } from './shared-errors';
22
+
23
+ export interface PendingSwapWithQueueID {
24
+ id: string;
25
+ swap: PendingSwap;
26
+ }
27
+
28
+ export type WalletBalance = {
29
+ chain: Network;
30
+ symbol: string;
31
+ ticker: string;
32
+ address: string | null;
33
+ rawAmount: string;
34
+ decimal: number | null;
35
+ amount: string;
36
+ logo: string | null;
37
+ usdPrice: number | null;
38
+ };
39
+
40
+ export type Account = {
41
+ address: string;
42
+ loading: boolean;
43
+ walletType: WalletType;
44
+ error: boolean;
45
+ explorerUrl: string | null;
46
+ isConnected?: boolean;
47
+ };
48
+ export type Blockchain = { name: string; accounts: Account[] };
49
+ export type Wallet = { blockchains: Blockchain[] };
50
+
51
+ export type EventType =
52
+ | 'swap_started'
53
+ | 'confirm_contract'
54
+ | 'confirm_transfer'
55
+ | 'task_failed'
56
+ | 'task_completed'
57
+ | 'task_canceled'
58
+ | 'task_paused'
59
+ | 'contract_confirmed'
60
+ | 'confirm_approve_contract'
61
+ | 'contract_rejected'
62
+ | 'check_tx_status'
63
+ | 'check_approve_tx_status'
64
+ | 'transfer_rejected'
65
+ | 'transfer_failed'
66
+ | 'calling_smart_contract'
67
+ | 'smart_contract_called'
68
+ | 'smart_contract_call_failed'
69
+ | 'step_completed_with_output'
70
+ | 'waiting_for_network_change'
71
+ | 'waiting_for_connecting_wallet'
72
+ | 'waiting_for_change_wallet_account'
73
+ | 'network_changed'
74
+ | 'not_enough_balance'
75
+ | 'not_enough_approval'
76
+ | 'waiting_for_queue'
77
+ | 'check_fee_failed'
78
+ | 'route_failed_to_find'
79
+ | 'transaction_expired';
80
+
81
+ export enum MessageSeverity {
82
+ error = 'error',
83
+ warning = 'warning',
84
+ info = 'info',
85
+ success = 'success',
86
+ }
87
+
88
+ export type SwapStatus = 'running' | 'failed' | 'success';
89
+
90
+ export interface TargetNamespace {
91
+ namespace: NamespaceInputForConnect['namespace'];
92
+ network: string;
93
+ }
94
+ export const getCurrentNamespaceOfOrNull = (
95
+ swap: PendingSwap,
96
+ step: PendingSwapStep
97
+ ): TargetNamespace | null => {
98
+ try {
99
+ return getCurrentNamespaceOf(swap, step);
100
+ } catch {
101
+ return null;
102
+ }
103
+ };
104
+
105
+ export const getCurrentNamespaceOf = (
106
+ swap: PendingSwap,
107
+ step: PendingSwapStep
108
+ ): TargetNamespace => {
109
+ const evmNetwork =
110
+ step.evmTransaction?.blockChain || step.evmApprovalTransaction?.blockChain;
111
+ const starknetNetwork =
112
+ step.starknetTransaction?.blockChain ||
113
+ step.starknetApprovalTransaction?.blockChain;
114
+ const tronNetwork =
115
+ step.tronTransaction?.blockChain ||
116
+ step.tronApprovalTransaction?.blockChain;
117
+ const cosmosNetwork = step.cosmosTransaction?.blockChain;
118
+ const solanaNetwork = step.solanaTransaction?.blockChain;
119
+ const tonNetwork = step.tonTransaction?.blockChain;
120
+ const suiNetwork = step.suiTransaction?.blockChain;
121
+
122
+ if (evmNetwork) {
123
+ return {
124
+ namespace: 'EVM',
125
+ network: evmNetwork,
126
+ };
127
+ } else if (starknetNetwork) {
128
+ return {
129
+ namespace: 'Starknet',
130
+ network: starknetNetwork,
131
+ };
132
+ } else if (tronNetwork) {
133
+ return {
134
+ namespace: 'Tron',
135
+ network: tronNetwork,
136
+ };
137
+ } else if (cosmosNetwork) {
138
+ return {
139
+ namespace: 'Cosmos',
140
+ network: cosmosNetwork,
141
+ };
142
+ } else if (solanaNetwork) {
143
+ return {
144
+ namespace: 'Solana',
145
+ network: solanaNetwork,
146
+ };
147
+ } else if (tonNetwork) {
148
+ return {
149
+ namespace: 'Ton',
150
+ network: tonNetwork,
151
+ };
152
+ } else if (suiNetwork) {
153
+ return {
154
+ namespace: 'Sui',
155
+ network: suiNetwork,
156
+ };
157
+ } else if (!!step.transferTransaction) {
158
+ const transferAddress = step.transferTransaction.fromWalletAddress;
159
+ if (!transferAddress) {
160
+ throw PrettyError.BlockchainMissing();
161
+ }
162
+ const utxoNetwork = Object.keys(swap.wallets).find(
163
+ (network) => swap.wallets[network]?.address === transferAddress
164
+ );
165
+ if (!utxoNetwork) {
166
+ throw PrettyError.BlockchainMissing();
167
+ }
168
+
169
+ return {
170
+ namespace: 'UTXO',
171
+ network: utxoNetwork,
172
+ };
173
+ }
174
+
175
+ throw new Error(
176
+ 'Unsupported transaction type has been included in your swap.',
177
+ {
178
+ cause: step,
179
+ }
180
+ );
181
+ };
182
+
183
+ export const getScannerUrl = (
184
+ txHash: string,
185
+ network: Network,
186
+ blockchainMetaMap: { [key: string]: BlockchainMeta }
187
+ ): string | undefined => {
188
+ const blockchainMeta = blockchainMetaMap[network];
189
+ const baseUrl = blockchainMeta.info?.transactionUrl;
190
+ if (!baseUrl) {
191
+ return;
192
+ }
193
+ if (baseUrl.indexOf('/{txHash}') !== -1) {
194
+ return baseUrl.replace('{txHash}', txHash);
195
+ }
196
+ return `${baseUrl}/${txHash}`;
197
+ };
198
+
199
+ export function getNextStep(
200
+ swap: PendingSwap,
201
+ currentStep: PendingSwapStep
202
+ ): PendingSwapStep | null {
203
+ return (
204
+ swap.steps.find(
205
+ (step) =>
206
+ step.status !== 'failed' &&
207
+ step.status !== 'success' &&
208
+ step.id !== currentStep.id
209
+ ) || null
210
+ );
211
+ }
212
+
213
+ /**
214
+ * Returns the wallet type and address, based on the current step of `PendingSwap`.
215
+ *
216
+ * @param {PendingSwap} swap - The swap.
217
+ * @param {PendingSwapStep} step - The current step.
218
+ * @returns {WalletTypeAndAddress} Type and address related to the current step of the swap.
219
+ */
220
+ export const getCurrentWalletTypeAndAddress = (
221
+ swap: PendingSwap,
222
+ step: PendingSwapStep
223
+ ): WalletTypeAndAddress => {
224
+ const result =
225
+ swap.wallets[step.evmTransaction?.blockChain || ''] ||
226
+ swap.wallets[step.evmApprovalTransaction?.blockChain || ''] ||
227
+ swap.wallets[step.tronTransaction?.blockChain || ''] ||
228
+ swap.wallets[step.tronApprovalTransaction?.blockChain || ''] ||
229
+ swap.wallets[step.starknetTransaction?.blockChain || ''] ||
230
+ swap.wallets[step.starknetApprovalTransaction?.blockChain || ''] ||
231
+ swap.wallets[step.cosmosTransaction?.blockChain || ''] ||
232
+ swap.wallets[step.solanaTransaction?.blockChain || ''] ||
233
+ swap.wallets[step.tonTransaction?.blockChain || ''] ||
234
+ swap.wallets[step.suiTransaction?.blockChain || ''] ||
235
+ (step.transferTransaction?.fromWalletAddress
236
+ ? {
237
+ address: step.transferTransaction.fromWalletAddress,
238
+ walletType: Object.values(swap.wallets).find(
239
+ (wallet) =>
240
+ wallet.address === step.transferTransaction?.fromWalletAddress
241
+ )?.walletType,
242
+ }
243
+ : null) ||
244
+ null;
245
+ if (result == null) {
246
+ throw PrettyError.WalletMissing();
247
+ }
248
+ return result;
249
+ };
250
+
251
+ /**
252
+ * Returns the wallet address, based on the current step of `PendingSwap`.
253
+ */
254
+ export const getCurrentAddressOf = (
255
+ swap: PendingSwap,
256
+ step: PendingSwapStep
257
+ ): string => {
258
+ return getCurrentWalletTypeAndAddress(swap, step).address;
259
+ };
260
+
261
+ export function getRelatedWallet(
262
+ swap: PendingSwap,
263
+ currentStep: PendingSwapStep
264
+ ): WalletTypeAndAddress {
265
+ const { address, walletType: type } = getCurrentWalletTypeAndAddress(
266
+ swap,
267
+ currentStep
268
+ );
269
+ const walletKV =
270
+ Object.keys(swap.wallets)
271
+ .map((k) => ({ k, v: swap.wallets[k] }))
272
+ .find(({ v }) => v.address === address && v.walletType === type) || null;
273
+ const blockchain = walletKV?.k || null;
274
+ const wallet = walletKV?.v || null;
275
+
276
+ const walletType = wallet?.walletType;
277
+ if (wallet === null) {
278
+ throw PrettyError.AssertionFailed(
279
+ `Wallet for source ${blockchain} not passed: walletType: ${walletType}`
280
+ );
281
+ }
282
+ return wallet;
283
+ }
284
+
285
+ export function getRelatedWalletOrNull(
286
+ swap: PendingSwap,
287
+ currentStep: PendingSwapStep | null
288
+ ): WalletTypeAndAddress | null {
289
+ if (!currentStep) {
290
+ return null;
291
+ }
292
+ try {
293
+ return getRelatedWallet(swap, currentStep);
294
+ } catch {
295
+ return null;
296
+ }
297
+ }
298
+
299
+ export const getUsdPrice = (
300
+ blockchain: string,
301
+ symbol: string,
302
+ address: string | null,
303
+ allTokens: Token[]
304
+ ): number | null => {
305
+ const token = allTokens?.find(
306
+ (t) =>
307
+ t.blockchain === blockchain &&
308
+ t.symbol?.toUpperCase() === symbol?.toUpperCase() &&
309
+ t.address === address
310
+ );
311
+ return token?.usdPrice || null;
312
+ };
313
+
314
+ export function getUsdFeeOfStep(
315
+ step: SwapResult,
316
+ allTokens: Token[]
317
+ ): BigNumber {
318
+ let totalFeeInUsd = new BigNumber(0);
319
+ for (let i = 0; i < step.fee.length; i++) {
320
+ const fee = step.fee[i];
321
+ if (fee.expenseType === 'DECREASE_FROM_OUTPUT') {
322
+ continue;
323
+ }
324
+
325
+ const unitPrice = getUsdPrice(
326
+ fee.asset.blockchain,
327
+ fee.asset.symbol,
328
+ fee.asset.address,
329
+ allTokens
330
+ );
331
+ totalFeeInUsd = totalFeeInUsd.plus(
332
+ new BigNumber(fee.amount).multipliedBy(unitPrice || 0)
333
+ );
334
+ }
335
+
336
+ return totalFeeInUsd;
337
+ }
338
+
339
+ function mapSwapStepToPendingSwapStep(
340
+ swap: SwapResult,
341
+ meta: Pick<MetaResponse, 'blockchains' | 'tokens'> | null
342
+ ): SwapStepRoute {
343
+ return {
344
+ // from
345
+ fromBlockchain: swap.from.blockchain,
346
+ fromBlockchainLogo: swap.from.blockchainLogo,
347
+ fromLogo: swap.from.logo,
348
+ fromSymbol: swap.from.symbol,
349
+ fromSymbolAddress: swap.from.address,
350
+ fromDecimals: swap.from.decimals,
351
+ fromAmountPrecision: swap.fromAmountPrecision,
352
+ fromAmountMinValue: swap.fromAmountMinValue,
353
+ fromAmountMaxValue: swap.fromAmountMaxValue,
354
+ fromAmountRestrictionType: swap.fromAmountRestrictionType,
355
+ fromUsdPrice: swap.from.usdPrice,
356
+
357
+ // to
358
+ toBlockchain: swap.to.blockchain,
359
+ toBlockchainLogo: swap.to.blockchainLogo,
360
+ toSymbol: swap.to.symbol,
361
+ toSymbolAddress: swap.to.address,
362
+ toDecimals: swap.to.decimals,
363
+ toLogo: swap.to.logo,
364
+ toUsdPrice: swap.to.usdPrice,
365
+
366
+ // swapper
367
+ swapperId: swap.swapperId,
368
+ swapperLogo: swap.swapperLogo,
369
+ swapperType: swap.swapperType,
370
+
371
+ // route
372
+ expectedOutputAmountHumanReadable: swap.toAmount,
373
+ feeInUsd: meta
374
+ ? // eslint-disable-next-line @typescript-eslint/no-magic-numbers
375
+ numberToString(getUsdFeeOfStep(swap, meta?.tokens), null, 8)
376
+ : null,
377
+ estimatedTimeInSeconds: swap.estimatedTimeInSeconds || null,
378
+ internalSteps: null,
379
+ };
380
+ }
381
+
382
+ export function calculatePendingSwap(params: {
383
+ inputAmount: string;
384
+ bestRoute: NonNullable<ConfirmRouteResponse['result']>;
385
+ wallets: { [p: string]: WalletTypeAndAddress };
386
+ settings: SwapSavedSettings;
387
+ validateBalanceOrFee: boolean;
388
+ meta: Pick<MetaResponse, 'blockchains' | 'tokens'> | null;
389
+ swapMode?: 'swap' | 'refuel';
390
+ }): PendingSwap {
391
+ const {
392
+ inputAmount,
393
+ bestRoute,
394
+ wallets,
395
+ settings,
396
+ validateBalanceOrFee,
397
+ meta,
398
+ swapMode = 'swap',
399
+ } = params;
400
+ const simulationResult = bestRoute.result;
401
+ if (!simulationResult) {
402
+ throw Error('Simulation result should not be null');
403
+ }
404
+
405
+ return {
406
+ creationTime: new Date().getTime().toString(),
407
+ finishTime: null,
408
+ requestId: bestRoute.requestId || '',
409
+ inputAmount: inputAmount,
410
+ wallets,
411
+ status: 'running',
412
+ mode: swapMode,
413
+ isPaused: false,
414
+ extraMessage: null,
415
+ extraMessageSeverity: null,
416
+ extraMessageDetail: null,
417
+ extraMessageErrorCode: null,
418
+ networkStatusExtraMessage: null,
419
+ networkStatusExtraMessageDetail: null,
420
+ lastNotificationTime: null,
421
+ settings: settings,
422
+ simulationResult: simulationResult,
423
+ validateBalanceOrFee,
424
+ steps:
425
+ bestRoute.result?.swaps?.map((swap, index) => {
426
+ const stepRoute = mapSwapStepToPendingSwapStep(swap, meta);
427
+ return {
428
+ id: index + 1,
429
+
430
+ // route
431
+ ...stepRoute,
432
+ internalSwaps:
433
+ swap?.internalSwaps?.map((internalSwap) => {
434
+ const stepRoute = mapSwapStepToPendingSwapStep(
435
+ internalSwap,
436
+ meta
437
+ );
438
+ return stepRoute;
439
+ }) || null,
440
+
441
+ // status, tracking
442
+ outputAmount: '',
443
+ status: 'created',
444
+ networkStatus: null,
445
+ startTransactionTime: new Date().getTime(),
446
+ externalTransactionId: null,
447
+ executedTransactionId: null,
448
+ executedTransactionTime: null,
449
+ explorerUrl: null,
450
+ diagnosisUrl: null,
451
+ trackingCode: null,
452
+ internalSteps: null,
453
+
454
+ // transactions
455
+ evmTransaction: null,
456
+ evmApprovalTransaction: null,
457
+ starknetTransaction: null,
458
+ starknetApprovalTransaction: null,
459
+ tronTransaction: null,
460
+ tronApprovalTransaction: null,
461
+ cosmosTransaction: null,
462
+ solanaTransaction: null,
463
+ transferTransaction: null,
464
+ tonTransaction: null,
465
+ suiTransaction: null,
466
+ xrplTransaction: null,
467
+
468
+ // front fields
469
+ hasAlreadyProceededToSign: false,
470
+ };
471
+ }) || [],
472
+ };
473
+ }