@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.
- package/CHANGELOG.md +353 -0
- package/dist/actions/checkStatus.d.ts +13 -0
- package/dist/actions/checkStatus.d.ts.map +1 -0
- package/dist/actions/common/checkEnvironmentBeforeExecuteTransaction.d.ts +8 -0
- package/dist/actions/common/checkEnvironmentBeforeExecuteTransaction.d.ts.map +1 -0
- package/dist/actions/common/produceNextStateForTransaction.d.ts +17 -0
- package/dist/actions/common/produceNextStateForTransaction.d.ts.map +1 -0
- package/dist/actions/common/utils.d.ts +5 -0
- package/dist/actions/common/utils.d.ts.map +1 -0
- package/dist/actions/createTransaction.d.ts +12 -0
- package/dist/actions/createTransaction.d.ts.map +1 -0
- package/dist/actions/executeTransaction/executeTransaction.d.ts +14 -0
- package/dist/actions/executeTransaction/executeTransaction.d.ts.map +1 -0
- package/dist/actions/executeTransaction/index.d.ts +2 -0
- package/dist/actions/executeTransaction/index.d.ts.map +1 -0
- package/dist/actions/scheduleNextStep.d.ts +14 -0
- package/dist/actions/scheduleNextStep.d.ts.map +1 -0
- package/dist/actions/start.d.ts +4 -0
- package/dist/actions/start.d.ts.map +1 -0
- package/dist/configs.d.ts +14 -0
- package/dist/configs.d.ts.map +1 -0
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/helpers.d.ts +255 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/hooks.d.ts +19 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +7 -0
- package/dist/migration.d.ts +15 -0
- package/dist/migration.d.ts.map +1 -0
- package/dist/numbers.d.ts +3 -0
- package/dist/numbers.d.ts.map +1 -0
- package/dist/queue-manager-rango-preset.build.json +1 -0
- package/dist/queueDef.d.ts +10 -0
- package/dist/queueDef.d.ts.map +1 -0
- package/dist/services/eventEmitter.d.ts +10 -0
- package/dist/services/eventEmitter.d.ts.map +1 -0
- package/dist/services/httpService.d.ts +3 -0
- package/dist/services/httpService.d.ts.map +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/shared-errors.d.ts +25 -0
- package/dist/shared-errors.d.ts.map +1 -0
- package/dist/shared.d.ts +81 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/types.d.ts +172 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +45 -0
- package/readme.md +2 -0
- package/src/actions/checkStatus.ts +564 -0
- package/src/actions/common/checkEnvironmentBeforeExecuteTransaction.ts +157 -0
- package/src/actions/common/produceNextStateForTransaction.ts +167 -0
- package/src/actions/common/utils.ts +25 -0
- package/src/actions/createTransaction.ts +117 -0
- package/src/actions/executeTransaction/executeTransaction.ts +107 -0
- package/src/actions/executeTransaction/index.ts +1 -0
- package/src/actions/scheduleNextStep.ts +104 -0
- package/src/actions/start.ts +16 -0
- package/src/configs.ts +38 -0
- package/src/constants.ts +18 -0
- package/src/helpers.ts +1598 -0
- package/src/hooks.ts +94 -0
- package/src/index.ts +68 -0
- package/src/migration.ts +124 -0
- package/src/numbers.ts +68 -0
- package/src/queueDef.ts +39 -0
- package/src/services/eventEmitter.ts +290 -0
- package/src/services/httpService.ts +10 -0
- package/src/services/index.ts +1 -0
- package/src/shared-errors.ts +165 -0
- package/src/shared.ts +473 -0
- package/src/types.ts +305 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import type { ExecuterActions } from '@rango-dev/queue-manager-core';
|
|
2
|
+
import type {
|
|
3
|
+
APIErrorCode,
|
|
4
|
+
SignerErrorCode,
|
|
5
|
+
StepStatus,
|
|
6
|
+
SwapStatus,
|
|
7
|
+
} from 'rango-types';
|
|
8
|
+
|
|
9
|
+
import { Err, Ok, type Result } from 'ts-results';
|
|
10
|
+
|
|
11
|
+
import { DEFAULT_ERROR_CODE } from '../../constants';
|
|
12
|
+
import {
|
|
13
|
+
getCurrentStep,
|
|
14
|
+
getCurrentStepTx,
|
|
15
|
+
getLastFinishedStepInput,
|
|
16
|
+
getLastFinishedStepInputUsd,
|
|
17
|
+
isApprovalCurrentStepTx,
|
|
18
|
+
updateSwapStatus,
|
|
19
|
+
} from '../../helpers';
|
|
20
|
+
import { notifier } from '../../services/eventEmitter';
|
|
21
|
+
import { getRelatedWallet } from '../../shared';
|
|
22
|
+
import {
|
|
23
|
+
StepEventType,
|
|
24
|
+
StepExecutionEventStatus,
|
|
25
|
+
type SwapActionTypes,
|
|
26
|
+
type SwapQueueContext,
|
|
27
|
+
type SwapStorage,
|
|
28
|
+
} from '../../types';
|
|
29
|
+
|
|
30
|
+
export interface NextTransactionState {
|
|
31
|
+
nextStatus?: SwapStatus;
|
|
32
|
+
nextStepStatus: StepStatus;
|
|
33
|
+
|
|
34
|
+
message: string;
|
|
35
|
+
details?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface NextTransactionStateError extends NextTransactionState {
|
|
39
|
+
errorCode: APIErrorCode | SignerErrorCode | null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function produceNextStateForTransaction(
|
|
43
|
+
actions: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>
|
|
44
|
+
): Result<NextTransactionState, NextTransactionStateError> {
|
|
45
|
+
const { getStorage, context } = actions;
|
|
46
|
+
const { isMobileWallet } = context;
|
|
47
|
+
const swap = getStorage().swapDetails;
|
|
48
|
+
|
|
49
|
+
const currentStep = getCurrentStep(swap)!;
|
|
50
|
+
|
|
51
|
+
const sourceWallet = getRelatedWallet(swap, currentStep);
|
|
52
|
+
const mobileWallet = isMobileWallet(sourceWallet?.walletType);
|
|
53
|
+
const tx = getCurrentStepTx(currentStep);
|
|
54
|
+
const isApproval = isApprovalCurrentStepTx(currentStep);
|
|
55
|
+
|
|
56
|
+
if (!tx || !tx.type) {
|
|
57
|
+
return new Err({
|
|
58
|
+
nextStatus: 'failed',
|
|
59
|
+
nextStepStatus: 'failed',
|
|
60
|
+
message: 'Unexpected Error: tx is null!',
|
|
61
|
+
details: undefined,
|
|
62
|
+
errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const hasAlreadyProceededToSign =
|
|
67
|
+
typeof swap.hasAlreadyProceededToSign === 'boolean';
|
|
68
|
+
|
|
69
|
+
if (isApproval) {
|
|
70
|
+
return new Ok({
|
|
71
|
+
nextStatus: undefined,
|
|
72
|
+
nextStepStatus: 'waitingForApproval',
|
|
73
|
+
details:
|
|
74
|
+
'Waiting for approve transaction to be mined and confirmed successfully',
|
|
75
|
+
message: `Waiting for approval of ${currentStep?.fromSymbol} coin ${
|
|
76
|
+
mobileWallet ? 'on your mobile phone!' : ''
|
|
77
|
+
}`,
|
|
78
|
+
});
|
|
79
|
+
} else if (hasAlreadyProceededToSign) {
|
|
80
|
+
return new Err({
|
|
81
|
+
message: 'Transaction is expired. Please try again.',
|
|
82
|
+
nextStepStatus: 'failed',
|
|
83
|
+
nextStatus: 'failed',
|
|
84
|
+
details: '',
|
|
85
|
+
errorCode: 'TX_EXPIRED',
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return new Ok({
|
|
90
|
+
message: 'Executing transaction ...',
|
|
91
|
+
nextStepStatus: 'running',
|
|
92
|
+
nextStatus: 'running',
|
|
93
|
+
details: `${mobileWallet ? 'Check your mobile phone!' : ''}`,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function onNextStateError(
|
|
98
|
+
actions: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>,
|
|
99
|
+
error: NextTransactionStateError
|
|
100
|
+
) {
|
|
101
|
+
const { getStorage, setStorage } = actions;
|
|
102
|
+
const swap = getStorage().swapDetails;
|
|
103
|
+
const currentStep = getCurrentStep(swap)!;
|
|
104
|
+
const isApproval = isApprovalCurrentStepTx(currentStep);
|
|
105
|
+
|
|
106
|
+
const hasAlreadyProceededToSign =
|
|
107
|
+
typeof swap.hasAlreadyProceededToSign === 'boolean';
|
|
108
|
+
|
|
109
|
+
const updatedResult = updateSwapStatus({
|
|
110
|
+
getStorage,
|
|
111
|
+
setStorage,
|
|
112
|
+
|
|
113
|
+
nextStepStatus: error.nextStepStatus,
|
|
114
|
+
nextStatus: error.nextStatus,
|
|
115
|
+
message: error.message,
|
|
116
|
+
details: error.details,
|
|
117
|
+
errorCode: error.errorCode,
|
|
118
|
+
|
|
119
|
+
hasAlreadyProceededToSign: isApproval
|
|
120
|
+
? undefined
|
|
121
|
+
: hasAlreadyProceededToSign,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
notifier({
|
|
125
|
+
event: {
|
|
126
|
+
type: StepEventType.FAILED,
|
|
127
|
+
reason: error.message,
|
|
128
|
+
reasonCode: updatedResult.failureType ?? DEFAULT_ERROR_CODE,
|
|
129
|
+
inputAmount: getLastFinishedStepInput(swap),
|
|
130
|
+
inputAmountUsd: getLastFinishedStepInputUsd(swap),
|
|
131
|
+
},
|
|
132
|
+
...updatedResult,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function onNextStateOk(
|
|
137
|
+
actions: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>,
|
|
138
|
+
ok: NextTransactionState
|
|
139
|
+
) {
|
|
140
|
+
const { getStorage, setStorage } = actions;
|
|
141
|
+
const swap = getStorage().swapDetails;
|
|
142
|
+
const currentStep = getCurrentStep(swap)!;
|
|
143
|
+
const isApproval = isApprovalCurrentStepTx(currentStep);
|
|
144
|
+
|
|
145
|
+
const hasAlreadyProceededToSign =
|
|
146
|
+
typeof swap.hasAlreadyProceededToSign === 'boolean';
|
|
147
|
+
|
|
148
|
+
const updateResult = updateSwapStatus({
|
|
149
|
+
getStorage,
|
|
150
|
+
setStorage,
|
|
151
|
+
nextStepStatus: ok.nextStepStatus,
|
|
152
|
+
nextStatus: ok.nextStatus,
|
|
153
|
+
message: ok.message,
|
|
154
|
+
details: ok.details,
|
|
155
|
+
hasAlreadyProceededToSign: isApproval
|
|
156
|
+
? undefined
|
|
157
|
+
: hasAlreadyProceededToSign,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
notifier({
|
|
161
|
+
event: {
|
|
162
|
+
type: StepEventType.TX_EXECUTION,
|
|
163
|
+
status: StepExecutionEventStatus.SEND_TX,
|
|
164
|
+
},
|
|
165
|
+
...updateResult,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
SwapActionTypes,
|
|
3
|
+
SwapQueueContext,
|
|
4
|
+
SwapStorage,
|
|
5
|
+
} from '../../types';
|
|
6
|
+
import type {
|
|
7
|
+
BlockedReason,
|
|
8
|
+
ExecuterActions,
|
|
9
|
+
} from '@rango-dev/queue-manager-core';
|
|
10
|
+
|
|
11
|
+
export function isClaimedByCurrentQueue(context: SwapQueueContext): boolean {
|
|
12
|
+
return context.claimedBy === context._queue?.id;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function requestBlockQueue(
|
|
16
|
+
actions: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>,
|
|
17
|
+
blockedFor: BlockedReason
|
|
18
|
+
) {
|
|
19
|
+
actions.block(blockedFor);
|
|
20
|
+
|
|
21
|
+
const isClaimed = isClaimedByCurrentQueue(actions.context);
|
|
22
|
+
if (isClaimed && actions.context.resetClaimedBy) {
|
|
23
|
+
actions.context.resetClaimedBy();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { SwapQueueContext, SwapStorage } from '../types';
|
|
2
|
+
import type { ExecuterActions } from '@rango-dev/queue-manager-core';
|
|
3
|
+
import type { CreateTransactionRequest } from 'rango-sdk';
|
|
4
|
+
|
|
5
|
+
import { warn } from '@rango-dev/logging-core';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
createStepFailedEvent,
|
|
9
|
+
getCurrentStep,
|
|
10
|
+
getCurrentStepTx,
|
|
11
|
+
setCurrentStepTx,
|
|
12
|
+
throwOnOK,
|
|
13
|
+
updateSwapStatus,
|
|
14
|
+
} from '../helpers';
|
|
15
|
+
import { httpService } from '../services';
|
|
16
|
+
import { notifier } from '../services/eventEmitter';
|
|
17
|
+
import { prettifyErrorMessage } from '../shared-errors';
|
|
18
|
+
import {
|
|
19
|
+
StepEventType,
|
|
20
|
+
StepExecutionEventStatus,
|
|
21
|
+
SwapActionTypes,
|
|
22
|
+
} from '../types';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* When a user asks for a swap, We first create the transaction by sending a request to server
|
|
27
|
+
* Server will return the transaction that need to be sent to wallet.
|
|
28
|
+
* It can be failed if server goes through an error, If not, we will schedule the `EXECTUTE_TRANSACTION`.
|
|
29
|
+
*
|
|
30
|
+
*/
|
|
31
|
+
export async function createTransaction(
|
|
32
|
+
actions: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>
|
|
33
|
+
): Promise<void> {
|
|
34
|
+
const { setStorage, getStorage, next, schedule } = actions;
|
|
35
|
+
const swap = getStorage().swapDetails;
|
|
36
|
+
|
|
37
|
+
const currentStep = getCurrentStep(swap)!;
|
|
38
|
+
const transaction = getCurrentStepTx(currentStep);
|
|
39
|
+
|
|
40
|
+
if (!transaction) {
|
|
41
|
+
notifier({
|
|
42
|
+
event: {
|
|
43
|
+
type: StepEventType.TX_EXECUTION,
|
|
44
|
+
status: StepExecutionEventStatus.CREATE_TX,
|
|
45
|
+
},
|
|
46
|
+
swap,
|
|
47
|
+
step: currentStep,
|
|
48
|
+
});
|
|
49
|
+
const request: CreateTransactionRequest = {
|
|
50
|
+
requestId: swap.requestId,
|
|
51
|
+
step: currentStep.id,
|
|
52
|
+
userSettings: {
|
|
53
|
+
slippage: swap.settings.slippage,
|
|
54
|
+
infiniteApprove: swap.settings.infiniteApprove,
|
|
55
|
+
},
|
|
56
|
+
validations: {
|
|
57
|
+
balance: swap.validateBalanceOrFee,
|
|
58
|
+
fee: swap.validateBalanceOrFee,
|
|
59
|
+
approve: true,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
try {
|
|
63
|
+
// Getting transcation from server.
|
|
64
|
+
|
|
65
|
+
const { transaction } = await throwOnOK(
|
|
66
|
+
httpService().createTransaction(request)
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
if (transaction) {
|
|
70
|
+
setCurrentStepTx(currentStep, transaction);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
setStorage({ ...getStorage(), swapDetails: swap });
|
|
74
|
+
schedule(SwapActionTypes.EXECUTE_TRANSACTION);
|
|
75
|
+
next();
|
|
76
|
+
} catch (error: unknown) {
|
|
77
|
+
swap.status = 'failed';
|
|
78
|
+
swap.finishTime = new Date().getTime().toString();
|
|
79
|
+
const { extraMessage, extraMessageDetail } = prettifyErrorMessage(error);
|
|
80
|
+
|
|
81
|
+
const updateResult = updateSwapStatus({
|
|
82
|
+
getStorage,
|
|
83
|
+
setStorage,
|
|
84
|
+
nextStatus: 'failed',
|
|
85
|
+
nextStepStatus: 'failed',
|
|
86
|
+
message: extraMessage,
|
|
87
|
+
details: extraMessageDetail,
|
|
88
|
+
errorCode: 'FETCH_TX_FAILED',
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const event = createStepFailedEvent(
|
|
92
|
+
swap,
|
|
93
|
+
extraMessage,
|
|
94
|
+
updateResult.failureType
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
notifier({
|
|
98
|
+
event,
|
|
99
|
+
...updateResult,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
if (error instanceof Error) {
|
|
103
|
+
warn(new Error('create transaction error'), {
|
|
104
|
+
tags: {
|
|
105
|
+
message: error.message,
|
|
106
|
+
requestBody: request,
|
|
107
|
+
reason: event.reason,
|
|
108
|
+
reasonCode: event.reasonCode,
|
|
109
|
+
pendingSwap: swap,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
actions.failed();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
SwapActionTypes,
|
|
3
|
+
SwapQueueContext,
|
|
4
|
+
SwapStorage,
|
|
5
|
+
} from '../../types';
|
|
6
|
+
import type { ExecuterActions } from '@rango-dev/queue-manager-core';
|
|
7
|
+
import type { SignerFactory } from 'rango-types';
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
getCurrentStep,
|
|
11
|
+
getCurrentStepTx,
|
|
12
|
+
handleRejectedSign,
|
|
13
|
+
handleSuccessfulSign,
|
|
14
|
+
isApprovalCurrentStepTx,
|
|
15
|
+
resetNetworkStatus,
|
|
16
|
+
} from '../../helpers';
|
|
17
|
+
import { getCurrentAddressOf, getRelatedWallet } from '../../shared';
|
|
18
|
+
import { checkEnvironmentBeforeExecuteTransaction } from '../common/checkEnvironmentBeforeExecuteTransaction';
|
|
19
|
+
import {
|
|
20
|
+
onNextStateError,
|
|
21
|
+
onNextStateOk,
|
|
22
|
+
produceNextStateForTransaction,
|
|
23
|
+
} from '../common/produceNextStateForTransaction';
|
|
24
|
+
import { requestBlockQueue } from '../common/utils';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
* Excecute a created transaction.
|
|
29
|
+
*
|
|
30
|
+
* This function implemented the parallel mode by `claim` mechanism which means
|
|
31
|
+
* All the queues the meet certain situation (like multiple evm transaction) will go through
|
|
32
|
+
* a `claim` mechanims that decides which queue should be run and it blocks other ones.
|
|
33
|
+
*
|
|
34
|
+
* A queue will be go to sign process, if the wallet and network is matched.
|
|
35
|
+
*/
|
|
36
|
+
export async function executeTransaction(
|
|
37
|
+
actions: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>
|
|
38
|
+
): Promise<void> {
|
|
39
|
+
const checkResult = await checkEnvironmentBeforeExecuteTransaction(actions);
|
|
40
|
+
if (checkResult.err) {
|
|
41
|
+
requestBlockQueue(actions, checkResult.val);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
resetNetworkStatus(actions);
|
|
46
|
+
|
|
47
|
+
// All the conditions are met. We can safely send the tx to wallet for sign.
|
|
48
|
+
const { failed, getStorage, context } = actions;
|
|
49
|
+
const { meta, getSigners } = context;
|
|
50
|
+
|
|
51
|
+
const swap = getStorage().swapDetails;
|
|
52
|
+
const currentStep = getCurrentStep(swap)!;
|
|
53
|
+
const isApproval = isApprovalCurrentStepTx(currentStep);
|
|
54
|
+
|
|
55
|
+
const onFinish = () => {
|
|
56
|
+
// TODO resetClaimedBy is undefined here
|
|
57
|
+
if (actions.context.resetClaimedBy) {
|
|
58
|
+
actions.context.resetClaimedBy();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/*
|
|
63
|
+
* Checking the current transaction state to determine the next step.
|
|
64
|
+
* It will either be Err, indicating process should stop, or Ok, indicating process should continu.
|
|
65
|
+
*/
|
|
66
|
+
const nextStateResult = produceNextStateForTransaction(actions);
|
|
67
|
+
|
|
68
|
+
if (nextStateResult.err) {
|
|
69
|
+
onNextStateError(actions, nextStateResult.val);
|
|
70
|
+
failed();
|
|
71
|
+
onFinish();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// On sucess, we should update Swap object and also call notifier
|
|
76
|
+
onNextStateOk(actions, nextStateResult.val);
|
|
77
|
+
|
|
78
|
+
// when we are producing next step, it will check to tx shouldn't be null. So ! here is safe.
|
|
79
|
+
const tx = getCurrentStepTx(currentStep)!;
|
|
80
|
+
|
|
81
|
+
const sourceWallet = getRelatedWallet(swap, currentStep);
|
|
82
|
+
const walletAddress = getCurrentAddressOf(swap, currentStep);
|
|
83
|
+
|
|
84
|
+
const chainId = meta.blockchains?.[tx.blockChain]?.chainId;
|
|
85
|
+
|
|
86
|
+
let walletSigners: SignerFactory;
|
|
87
|
+
try {
|
|
88
|
+
walletSigners = await getSigners(sourceWallet.walletType);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
handleRejectedSign(actions)(error);
|
|
91
|
+
onFinish();
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const signer = walletSigners.getSigner(tx.type);
|
|
96
|
+
await signer
|
|
97
|
+
.signAndSendTx(tx, walletAddress, chainId)
|
|
98
|
+
.then(
|
|
99
|
+
handleSuccessfulSign(actions, {
|
|
100
|
+
isApproval,
|
|
101
|
+
}),
|
|
102
|
+
handleRejectedSign(actions)
|
|
103
|
+
)
|
|
104
|
+
.finally(() => {
|
|
105
|
+
onFinish();
|
|
106
|
+
});
|
|
107
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { executeTransaction } from './executeTransaction.js';
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { SwapQueueContext, SwapStorage } from '../types';
|
|
2
|
+
import type { ExecuterActions } from '@rango-dev/queue-manager-core';
|
|
3
|
+
import type { PendingSwapStep } from 'rango-types';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
getCurrentStep,
|
|
7
|
+
getLastFinishedStepInput,
|
|
8
|
+
getLastFinishedStepInputUsd,
|
|
9
|
+
getLastSuccessfulStep,
|
|
10
|
+
getLastSuccessfulStepOutputUsd,
|
|
11
|
+
isTxAlreadyCreated,
|
|
12
|
+
} from '../helpers';
|
|
13
|
+
import { notifier } from '../services/eventEmitter';
|
|
14
|
+
import { StepEventType, SwapActionTypes } from '../types';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* This function is responsibe for scheduling the correct `action` based on `PendingSwap` status.
|
|
19
|
+
* It means `action`s schedule this step to decide what should be the next step/task.
|
|
20
|
+
*
|
|
21
|
+
* It's acts like a `while(true)` and will `break` the loop on certain `action`s like `CHECK_STATUS`.
|
|
22
|
+
*
|
|
23
|
+
*
|
|
24
|
+
*/
|
|
25
|
+
export function scheduleNextStep({
|
|
26
|
+
schedule,
|
|
27
|
+
next,
|
|
28
|
+
failed,
|
|
29
|
+
setStorage,
|
|
30
|
+
getStorage,
|
|
31
|
+
}: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>): void {
|
|
32
|
+
const swap = getStorage().swapDetails;
|
|
33
|
+
const currentStep = getCurrentStep(swap);
|
|
34
|
+
const isFailed = swap.steps.find(
|
|
35
|
+
(step: PendingSwapStep) => step.status === 'failed'
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
if (!!currentStep && !isFailed) {
|
|
39
|
+
if (isTxAlreadyCreated(swap, currentStep)) {
|
|
40
|
+
schedule(SwapActionTypes.EXECUTE_TRANSACTION);
|
|
41
|
+
return next();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (currentStep?.executedTransactionId) {
|
|
45
|
+
schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS);
|
|
46
|
+
return next();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
swap.status = 'running';
|
|
50
|
+
|
|
51
|
+
setStorage({ ...getStorage(), swapDetails: swap });
|
|
52
|
+
|
|
53
|
+
notifier({
|
|
54
|
+
event: { type: StepEventType.STARTED },
|
|
55
|
+
swap,
|
|
56
|
+
step: currentStep,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
schedule(SwapActionTypes.CREATE_TRANSACTION);
|
|
60
|
+
next();
|
|
61
|
+
} else {
|
|
62
|
+
swap.status = isFailed ? 'failed' : 'success';
|
|
63
|
+
swap.finishTime = new Date().getTime().toString();
|
|
64
|
+
|
|
65
|
+
setStorage({
|
|
66
|
+
...getStorage(),
|
|
67
|
+
swapDetails: swap,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const inputAmount = getLastFinishedStepInput(swap);
|
|
71
|
+
const inputAmountUsd = getLastFinishedStepInputUsd(swap);
|
|
72
|
+
|
|
73
|
+
notifier({
|
|
74
|
+
...(isFailed
|
|
75
|
+
? {
|
|
76
|
+
event: {
|
|
77
|
+
type: StepEventType.FAILED,
|
|
78
|
+
reason: swap.extraMessage ?? undefined,
|
|
79
|
+
reasonCode: 'CALL_OR_SEND_FAILED',
|
|
80
|
+
inputAmount,
|
|
81
|
+
inputAmountUsd,
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
: {
|
|
85
|
+
event: {
|
|
86
|
+
type: StepEventType.SUCCEEDED,
|
|
87
|
+
inputAmount,
|
|
88
|
+
inputAmountUsd,
|
|
89
|
+
outputAmount:
|
|
90
|
+
getLastSuccessfulStep(swap.steps)?.outputAmount ?? '',
|
|
91
|
+
outputAmountUsd: getLastSuccessfulStepOutputUsd(swap),
|
|
92
|
+
},
|
|
93
|
+
}),
|
|
94
|
+
swap: swap,
|
|
95
|
+
step: null,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
if (isFailed) {
|
|
99
|
+
failed();
|
|
100
|
+
} else {
|
|
101
|
+
next();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ExecuterActions } from '@rango-dev/queue-manager-core';
|
|
2
|
+
import { StepEventType, SwapActionTypes, SwapStorage } from '../types';
|
|
3
|
+
import { notifier } from '../services/eventEmitter';
|
|
4
|
+
|
|
5
|
+
export function start({
|
|
6
|
+
schedule,
|
|
7
|
+
next,
|
|
8
|
+
getStorage,
|
|
9
|
+
}: ExecuterActions<SwapStorage, SwapActionTypes>): void {
|
|
10
|
+
const swap = getStorage().swapDetails;
|
|
11
|
+
|
|
12
|
+
notifier({ event: { type: StepEventType.STARTED }, swap, step: null });
|
|
13
|
+
|
|
14
|
+
schedule(SwapActionTypes.SCHEDULE_NEXT_STEP);
|
|
15
|
+
next();
|
|
16
|
+
}
|
package/src/configs.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { RouteExecutionEvents } from './types';
|
|
2
|
+
|
|
3
|
+
interface Emitter<Events extends Record<string, unknown>> {
|
|
4
|
+
emit<K extends keyof Events>(type: K, event: Events[K]): void;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface Configs {
|
|
8
|
+
API_KEY: string;
|
|
9
|
+
BASE_URL?: string;
|
|
10
|
+
emitter?: Emitter<RouteExecutionEvents>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* this API key is limited and
|
|
15
|
+
* it is only for test purpose
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const RANGO_PUBLIC_API_KEY = 'c6381a79-2817-4602-83bf-6a641a409e32';
|
|
19
|
+
|
|
20
|
+
let configs: Configs = {
|
|
21
|
+
API_KEY: RANGO_PUBLIC_API_KEY,
|
|
22
|
+
BASE_URL: '',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function getConfig<K extends keyof Configs>(name: K): Configs[K] {
|
|
26
|
+
return configs[name];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function setConfig(name: keyof Configs, value: any) {
|
|
30
|
+
configs[name] = value;
|
|
31
|
+
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function initConfig(nextConfigs: Configs) {
|
|
36
|
+
configs = nextConfigs;
|
|
37
|
+
return configs;
|
|
38
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const ERROR_MESSAGE_DEPENDS_ON_OTHER_QUEUES =
|
|
2
|
+
'Waiting for other swaps to complete';
|
|
3
|
+
export const ERROR_MESSAGE_WAIT_FOR_WALLET = 'Waiting for connecting wallet';
|
|
4
|
+
export const ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION_WRONG_WALLET = (
|
|
5
|
+
type: string | null,
|
|
6
|
+
address: string | null
|
|
7
|
+
): string =>
|
|
8
|
+
`Please change your ${type || 'wallet'} account to ${
|
|
9
|
+
address || 'proper address'
|
|
10
|
+
}`;
|
|
11
|
+
export const ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION = (
|
|
12
|
+
type: string | null
|
|
13
|
+
): string => `Please connect your ${type ?? ''} wallet.`;
|
|
14
|
+
export const ERROR_MESSAGE_WAIT_FOR_CHANGE_NETWORK = (
|
|
15
|
+
network: string | null
|
|
16
|
+
): string => `Please change your network to ${network}.`;
|
|
17
|
+
|
|
18
|
+
export const DEFAULT_ERROR_CODE = 'CLIENT_UNEXPECTED_BEHAVIOUR';
|