@rango-dev/queue-manager-rango-preset 0.1.10-next.77
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/dist/actions/checkStatus.d.ts +12 -0
- package/dist/actions/checkStatus.d.ts.map +1 -0
- package/dist/actions/createTransaction.d.ts +11 -0
- package/dist/actions/createTransaction.d.ts.map +1 -0
- package/dist/actions/executeTransaction.d.ts +13 -0
- package/dist/actions/executeTransaction.d.ts.map +1 -0
- package/dist/actions/scheduleNextStep.d.ts +13 -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/constants.d.ts +9 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/helpers.d.ts +159 -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 +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/migration.d.ts +15 -0
- package/dist/migration.d.ts.map +1 -0
- package/dist/queue-manager-rango-preset.cjs.development.js +2249 -0
- package/dist/queue-manager-rango-preset.cjs.development.js.map +1 -0
- package/dist/queue-manager-rango-preset.cjs.production.min.js +2 -0
- package/dist/queue-manager-rango-preset.cjs.production.min.js.map +1 -0
- package/dist/queue-manager-rango-preset.esm.js +2242 -0
- package/dist/queue-manager-rango-preset.esm.js.map +1 -0
- package/dist/queueDef.d.ts +10 -0
- package/dist/queueDef.d.ts.map +1 -0
- package/dist/shared-api.d.ts +10 -0
- package/dist/shared-api.d.ts.map +1 -0
- package/dist/shared-errors.d.ts +56 -0
- package/dist/shared-errors.d.ts.map +1 -0
- package/dist/shared-sentry.d.ts +4 -0
- package/dist/shared-sentry.d.ts.map +1 -0
- package/dist/shared.d.ts +149 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/types.d.ts +46 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +59 -0
- package/readme.md +9 -0
- package/src/actions/checkStatus.ts +213 -0
- package/src/actions/createTransaction.ts +101 -0
- package/src/actions/executeTransaction.ts +117 -0
- package/src/actions/scheduleNextStep.ts +60 -0
- package/src/actions/start.ts +10 -0
- package/src/constants.ts +23 -0
- package/src/helpers.ts +1252 -0
- package/src/hooks.ts +75 -0
- package/src/index.ts +39 -0
- package/src/migration.ts +112 -0
- package/src/queueDef.ts +39 -0
- package/src/shared-api.ts +175 -0
- package/src/shared-errors.ts +156 -0
- package/src/shared-sentry.ts +24 -0
- package/src/shared.ts +333 -0
- package/src/types.ts +76 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { QueueStorage, QueueDef } from '@rango-dev/queue-manager-core';
|
|
2
|
+
import { QueueContext } from '@rango-dev/queue-manager-core/dist/queue';
|
|
3
|
+
import { ConnectResult, Providers } from '@rango-dev/wallets-core';
|
|
4
|
+
import { EvmBlockchainMeta, Meta, Network, WalletSigners, WalletState, WalletType } from '@rango-dev/wallets-shared';
|
|
5
|
+
import { PendingSwap, SwapProgressNotification, Wallet } from './shared';
|
|
6
|
+
export declare type SwapQueueDef = QueueDef<SwapStorage, SwapActionTypes, SwapQueueContext>;
|
|
7
|
+
export interface SwapStorage extends QueueStorage {
|
|
8
|
+
swapDetails: PendingSwap;
|
|
9
|
+
}
|
|
10
|
+
export declare enum SwapActionTypes {
|
|
11
|
+
START = "START",
|
|
12
|
+
SCHEDULE_NEXT_STEP = "SCHEDULE_NEXT_STEP",
|
|
13
|
+
CREATE_TRANSACTION = "CREATE_TRANSACTION",
|
|
14
|
+
EXECUTE_TRANSACTION = "EXECUTE_TRANSACTION",
|
|
15
|
+
CHECK_TRANSACTION_STATUS = "CHECK_TRANSACTION_STATUS"
|
|
16
|
+
}
|
|
17
|
+
export declare type GetCurrentAddress = (type: WalletType, network: Network) => string | undefined;
|
|
18
|
+
export declare enum BlockReason {
|
|
19
|
+
WAIT_FOR_CONNECT_WALLET = "waiting_for_connecting_wallet",
|
|
20
|
+
WAIT_FOR_NETWORK_CHANGE = "waiting_for_network_change",
|
|
21
|
+
DEPENDS_ON_OTHER_QUEUES = "depends_on_other_queues"
|
|
22
|
+
}
|
|
23
|
+
export interface Block<T = any> {
|
|
24
|
+
reason: BlockReason;
|
|
25
|
+
description: string;
|
|
26
|
+
details?: T;
|
|
27
|
+
}
|
|
28
|
+
export interface SwapQueueContext extends QueueContext {
|
|
29
|
+
meta: Meta;
|
|
30
|
+
wallets: Wallet | null;
|
|
31
|
+
providers: Providers;
|
|
32
|
+
getSigners: (type: WalletType) => WalletSigners;
|
|
33
|
+
switchNetwork: (wallet: WalletType, network: Network) => Promise<ConnectResult> | undefined;
|
|
34
|
+
connect: (wallet: WalletType, network: Network) => Promise<ConnectResult> | undefined;
|
|
35
|
+
state: (type: WalletType) => WalletState;
|
|
36
|
+
notifier: (data: SwapProgressNotification) => void;
|
|
37
|
+
claimedBy?: string;
|
|
38
|
+
resetClaimedBy?: () => void;
|
|
39
|
+
}
|
|
40
|
+
export interface UseQueueManagerParams {
|
|
41
|
+
lastConnectedWallet: string;
|
|
42
|
+
disconnectedWallet: WalletType | undefined;
|
|
43
|
+
clearDisconnectedWallet: () => void;
|
|
44
|
+
evmChains: EvmBlockchainMeta[];
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EACL,iBAAiB,EACjB,IAAI,EACJ,OAAO,EACP,aAAa,EACb,WAAW,EACX,UAAU,EACX,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEzE,oBAAY,YAAY,GAAG,QAAQ,CACjC,WAAW,EACX,eAAe,EACf,gBAAgB,CACjB,CAAC;AAEF,MAAM,WAAW,WAAY,SAAQ,YAAY;IAC/C,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,oBAAY,eAAe;IACzB,KAAK,UAAU;IACf,kBAAkB,uBAAuB;IACzC,kBAAkB,uBAAuB;IACzC,mBAAmB,wBAAwB;IAC3C,wBAAwB,6BAA6B;CACtD;AAED,oBAAY,iBAAiB,GAAG,CAC9B,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,OAAO,KACb,MAAM,GAAG,SAAS,CAAC;AAExB,oBAAY,WAAW;IACrB,uBAAuB,kCAAkC;IACzD,uBAAuB,+BAA+B;IACtD,uBAAuB,4BAA4B;CACpD;AAGD,MAAM,WAAW,KAAK,CAAC,CAAC,GAAG,GAAG;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,CAAC;CACb;AAED,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,aAAa,CAAC;IAChD,aAAa,EAAE,CACb,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,OAAO,KACb,OAAO,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC;IACxC,OAAO,EAAE,CACP,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,OAAO,KACb,OAAO,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC;IACxC,KAAK,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,WAAW,CAAC;IACzC,QAAQ,EAAE,CAAC,IAAI,EAAE,wBAAwB,KAAK,IAAI,CAAC;IAGnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,UAAU,GAAG,SAAS,CAAC;IAC3C,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC,SAAS,EAAE,iBAAiB,EAAE,CAAC;CAChC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rango-dev/queue-manager-rango-preset",
|
|
3
|
+
"version": "0.1.10-next.77",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"module": "dist/queue-manager-rango-preset.esm.js",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"typings": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"src"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"dev": "tsdx watch",
|
|
14
|
+
"build": "tsdx build",
|
|
15
|
+
"test": "tsdx test",
|
|
16
|
+
"lint": "tsdx lint",
|
|
17
|
+
"size": "size-limit",
|
|
18
|
+
"analyze": "size-limit --why"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@rango-dev/queue-manager-core": "*",
|
|
22
|
+
"@rango-dev/wallets-core": "*",
|
|
23
|
+
"@rango-dev/wallets-shared": "*",
|
|
24
|
+
"@sentry/browser": "*",
|
|
25
|
+
"bignumber.js": "*",
|
|
26
|
+
"uuid": "*"
|
|
27
|
+
},
|
|
28
|
+
"husky": {
|
|
29
|
+
"hooks": {
|
|
30
|
+
"pre-commit": "tsdx lint"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"prettier": {
|
|
34
|
+
"printWidth": 80,
|
|
35
|
+
"semi": true,
|
|
36
|
+
"singleQuote": true,
|
|
37
|
+
"trailingComma": "es5"
|
|
38
|
+
},
|
|
39
|
+
"size-limit": [
|
|
40
|
+
{
|
|
41
|
+
"path": "dist/queue-manager-rango-preset.cjs.production.min.js",
|
|
42
|
+
"limit": "10 KB"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"path": "dist/queue-manager-rango-preset.esm.js",
|
|
46
|
+
"limit": "10 KB"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/uuid": "^8.3.4"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"rango-sdk": "^0.1.17",
|
|
54
|
+
"uuid": "^9.0.0"
|
|
55
|
+
},
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public"
|
|
58
|
+
}
|
|
59
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import BigNumber from 'bignumber.js';
|
|
2
|
+
import { ExecuterActions } from '@rango-dev/queue-manager-core';
|
|
3
|
+
import {
|
|
4
|
+
delay,
|
|
5
|
+
getCurrentStep,
|
|
6
|
+
isCosmosTransaction,
|
|
7
|
+
isEvmTransaction,
|
|
8
|
+
isSolanaTransaction,
|
|
9
|
+
isStarknetTransaction,
|
|
10
|
+
isTrasnferTransaction,
|
|
11
|
+
isTronTransaction,
|
|
12
|
+
resetNetworkStatus,
|
|
13
|
+
} from '../helpers';
|
|
14
|
+
import { SwapActionTypes, SwapQueueContext, SwapStorage } from '../types';
|
|
15
|
+
import { getNextStep, MessageSeverity, SwapperStatusResponse } from '../shared';
|
|
16
|
+
import { checkApproved, checkSwapStatus } from '../shared-api';
|
|
17
|
+
|
|
18
|
+
const INTERVAL_FOR_CHECK = 2000;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Subscribe to status of swap transaction by checking from server periodically.
|
|
22
|
+
* After getting the status, notify the user and schedule `SCHEDULE_NEXT_STEP`.
|
|
23
|
+
*/
|
|
24
|
+
async function checkTransactionStatus({
|
|
25
|
+
getStorage,
|
|
26
|
+
setStorage,
|
|
27
|
+
next,
|
|
28
|
+
schedule,
|
|
29
|
+
retry,
|
|
30
|
+
context,
|
|
31
|
+
}: ExecuterActions<
|
|
32
|
+
SwapStorage,
|
|
33
|
+
SwapActionTypes,
|
|
34
|
+
SwapQueueContext
|
|
35
|
+
>): Promise<void> {
|
|
36
|
+
const swap = getStorage().swapDetails;
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
38
|
+
const currentStep = getCurrentStep(swap)!;
|
|
39
|
+
const txId = currentStep.executedTransactionId;
|
|
40
|
+
|
|
41
|
+
let status: SwapperStatusResponse | null = null;
|
|
42
|
+
try {
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
44
|
+
status = await checkSwapStatus(swap.requestId, txId!, currentStep.id);
|
|
45
|
+
} catch (e) {
|
|
46
|
+
await delay(INTERVAL_FOR_CHECK);
|
|
47
|
+
retry();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const outputAmount: BigNumber | null =
|
|
52
|
+
status?.outputAmount ||
|
|
53
|
+
(!!currentStep.outputAmount
|
|
54
|
+
? new BigNumber(currentStep.outputAmount)
|
|
55
|
+
: null);
|
|
56
|
+
const prevOutputAmount = currentStep.outputAmount;
|
|
57
|
+
swap.extraMessage = status?.extraMessage || swap.extraMessage;
|
|
58
|
+
swap.extraMessageSeverity = MessageSeverity.info;
|
|
59
|
+
swap.extraMessageDetail = '';
|
|
60
|
+
|
|
61
|
+
currentStep.status = status?.status || currentStep.status;
|
|
62
|
+
currentStep.diagnosisUrl =
|
|
63
|
+
status?.diagnosisUrl || currentStep.diagnosisUrl || null;
|
|
64
|
+
currentStep.outputAmount =
|
|
65
|
+
outputAmount?.toFixed() || currentStep.outputAmount;
|
|
66
|
+
currentStep.explorerUrl = status?.explorerUrl || currentStep.explorerUrl;
|
|
67
|
+
currentStep.internalSteps = status?.steps || null;
|
|
68
|
+
|
|
69
|
+
const newTransaction = status?.newTx;
|
|
70
|
+
|
|
71
|
+
if (!!newTransaction) {
|
|
72
|
+
currentStep.status = 'created';
|
|
73
|
+
currentStep.executedTransactionId = null;
|
|
74
|
+
currentStep.transferTransaction = null;
|
|
75
|
+
currentStep.cosmosTransaction = null;
|
|
76
|
+
currentStep.evmTransaction = null;
|
|
77
|
+
currentStep.solanaTransaction = null;
|
|
78
|
+
currentStep.evmApprovalTransaction = null;
|
|
79
|
+
currentStep.starknetApprovalTransaction = null;
|
|
80
|
+
currentStep.starknetTransaction = null;
|
|
81
|
+
currentStep.tronApprovalTransaction = null;
|
|
82
|
+
currentStep.tronTransaction = null;
|
|
83
|
+
|
|
84
|
+
if (isEvmTransaction(newTransaction)) {
|
|
85
|
+
if (newTransaction.isApprovalTx)
|
|
86
|
+
currentStep.evmApprovalTransaction = newTransaction;
|
|
87
|
+
else currentStep.evmTransaction = newTransaction;
|
|
88
|
+
} else if (isCosmosTransaction(newTransaction)) {
|
|
89
|
+
currentStep.cosmosTransaction = newTransaction;
|
|
90
|
+
} else if (isSolanaTransaction(newTransaction)) {
|
|
91
|
+
currentStep.solanaTransaction = newTransaction;
|
|
92
|
+
} else if (isTrasnferTransaction(newTransaction)) {
|
|
93
|
+
currentStep.transferTransaction = newTransaction;
|
|
94
|
+
} else if (isStarknetTransaction(newTransaction)) {
|
|
95
|
+
if (newTransaction.isApprovalTx)
|
|
96
|
+
currentStep.starknetApprovalTransaction = newTransaction;
|
|
97
|
+
else currentStep.starknetTransaction = newTransaction;
|
|
98
|
+
} else if (isTronTransaction(newTransaction)) {
|
|
99
|
+
if (newTransaction.isApprovalTx)
|
|
100
|
+
currentStep.tronApprovalTransaction = newTransaction;
|
|
101
|
+
else currentStep.tronTransaction = newTransaction;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (prevOutputAmount === null && outputAmount !== null)
|
|
106
|
+
context.notifier({
|
|
107
|
+
eventType: 'step_completed_with_output',
|
|
108
|
+
swap: swap,
|
|
109
|
+
step: currentStep,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
if (currentStep.status === 'success') {
|
|
113
|
+
const nextStep = getNextStep(swap, currentStep);
|
|
114
|
+
swap.extraMessageDetail = '';
|
|
115
|
+
swap.extraMessage = !!nextStep
|
|
116
|
+
? `starting next step: ${nextStep.swapperId}: ${nextStep.fromBlockchain} -> ${nextStep.toBlockchain}`
|
|
117
|
+
: '';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Sync data with storage
|
|
121
|
+
setStorage({ ...getStorage(), swapDetails: swap });
|
|
122
|
+
|
|
123
|
+
if (
|
|
124
|
+
status?.status === 'failed' ||
|
|
125
|
+
status?.status === 'success' ||
|
|
126
|
+
(status?.status === 'running' && !!status.newTx)
|
|
127
|
+
) {
|
|
128
|
+
schedule(SwapActionTypes.SCHEDULE_NEXT_STEP);
|
|
129
|
+
next();
|
|
130
|
+
} else {
|
|
131
|
+
await delay(INTERVAL_FOR_CHECK);
|
|
132
|
+
retry();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Subscribe to status of approval transaction by checking from server periodically.
|
|
138
|
+
* After getting the status, notify the user and schedule `SCHEDULE_NEXT_STEP`.
|
|
139
|
+
*/
|
|
140
|
+
async function checkApprovalStatus({
|
|
141
|
+
getStorage,
|
|
142
|
+
setStorage,
|
|
143
|
+
next,
|
|
144
|
+
schedule,
|
|
145
|
+
retry,
|
|
146
|
+
context,
|
|
147
|
+
}: ExecuterActions<
|
|
148
|
+
SwapStorage,
|
|
149
|
+
SwapActionTypes,
|
|
150
|
+
SwapQueueContext
|
|
151
|
+
>): Promise<void> {
|
|
152
|
+
const swap = getStorage().swapDetails as SwapStorage['swapDetails'];
|
|
153
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
154
|
+
const currentStep = getCurrentStep(swap)!;
|
|
155
|
+
let isApproved = false;
|
|
156
|
+
try {
|
|
157
|
+
const response = await checkApproved(swap.requestId);
|
|
158
|
+
isApproved = response.isApproved;
|
|
159
|
+
} catch (e) {
|
|
160
|
+
console.error('Failed to check getApprovedAmount', e);
|
|
161
|
+
}
|
|
162
|
+
if (isApproved) {
|
|
163
|
+
currentStep.status = 'approved';
|
|
164
|
+
swap.extraMessage = `Spending ${currentStep.fromSymbol} approved successfully.`;
|
|
165
|
+
swap.extraMessageDetail = null;
|
|
166
|
+
swap.extraMessageSeverity = MessageSeverity.success;
|
|
167
|
+
currentStep.evmApprovalTransaction = null;
|
|
168
|
+
currentStep.executedTransactionId = null;
|
|
169
|
+
|
|
170
|
+
setStorage({
|
|
171
|
+
...getStorage(),
|
|
172
|
+
swapDetails: swap,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
context.notifier({
|
|
176
|
+
eventType: 'contract_confirmed',
|
|
177
|
+
swap: swap,
|
|
178
|
+
step: currentStep,
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
schedule(SwapActionTypes.SCHEDULE_NEXT_STEP);
|
|
182
|
+
next();
|
|
183
|
+
} else {
|
|
184
|
+
await delay(2000);
|
|
185
|
+
retry();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
*
|
|
191
|
+
* For doing a swap the user needs to accept a `contract` so it can use the user balance.
|
|
192
|
+
* There is two types of check status:
|
|
193
|
+
* 1. Checking approval transaction (Give permission to a contract)
|
|
194
|
+
* 2. Checking swap transaction.
|
|
195
|
+
*
|
|
196
|
+
*/
|
|
197
|
+
export async function checkStatus(
|
|
198
|
+
actions: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>
|
|
199
|
+
): Promise<void> {
|
|
200
|
+
const swap = actions.getStorage().swapDetails;
|
|
201
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
202
|
+
const currentStep = getCurrentStep(swap)!;
|
|
203
|
+
|
|
204
|
+
// Reset network status
|
|
205
|
+
// Because when check status is on `loading` or `failed` status, it shows previous message that isn't related to current state.
|
|
206
|
+
resetNetworkStatus(actions);
|
|
207
|
+
|
|
208
|
+
if (currentStep.status === 'running') {
|
|
209
|
+
await checkTransactionStatus(actions);
|
|
210
|
+
} else if (currentStep.status === 'waitingForApproval') {
|
|
211
|
+
await checkApprovalStatus(actions);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { ExecuterActions } from '@rango-dev/queue-manager-core';
|
|
2
|
+
import { SwapActionTypes, SwapQueueContext, SwapStorage } from '../types';
|
|
3
|
+
import {
|
|
4
|
+
getCurrentStep,
|
|
5
|
+
isCosmosTransaction,
|
|
6
|
+
isEvmTransaction,
|
|
7
|
+
isSolanaTransaction,
|
|
8
|
+
isTrasnferTransaction,
|
|
9
|
+
updateSwapStatus,
|
|
10
|
+
} from '../helpers';
|
|
11
|
+
import { createTransaction as requestTransaction } from '../shared-api';
|
|
12
|
+
import { APIErrorCode } from '../shared-errors';
|
|
13
|
+
import { prettifyErrorMessage } from '../shared';
|
|
14
|
+
import { CreateTransactionRequest } from 'rango-sdk';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* When a user asks for a swap, We first create the transaction by sending a request to server
|
|
19
|
+
* Server will return the transaction that need to be sent to wallet.
|
|
20
|
+
* It can be failed if server goes through an error, If not, we will schedule the `EXECTUTE_TRANSACTION`.
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
23
|
+
export async function createTransaction(
|
|
24
|
+
actions: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>
|
|
25
|
+
): Promise<void> {
|
|
26
|
+
const { setStorage, getStorage, next, schedule, context } = actions;
|
|
27
|
+
const swap = getStorage().swapDetails;
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
29
|
+
const currentStep = getCurrentStep(swap)!;
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
evmTransaction,
|
|
33
|
+
cosmosTransaction,
|
|
34
|
+
transferTransaction,
|
|
35
|
+
evmApprovalTransaction,
|
|
36
|
+
solanaTransaction,
|
|
37
|
+
} = currentStep;
|
|
38
|
+
|
|
39
|
+
if (
|
|
40
|
+
!evmTransaction &&
|
|
41
|
+
!cosmosTransaction &&
|
|
42
|
+
!transferTransaction &&
|
|
43
|
+
!evmApprovalTransaction &&
|
|
44
|
+
!solanaTransaction
|
|
45
|
+
) {
|
|
46
|
+
const request: CreateTransactionRequest = {
|
|
47
|
+
requestId: swap.requestId,
|
|
48
|
+
step: currentStep.id,
|
|
49
|
+
userSettings: {
|
|
50
|
+
slippage: swap.settings.slippage,
|
|
51
|
+
infiniteApprove: swap.settings.infiniteApprove,
|
|
52
|
+
},
|
|
53
|
+
validations: {
|
|
54
|
+
balance: swap.validateBalanceOrFee,
|
|
55
|
+
fee: swap.validateBalanceOrFee,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
try {
|
|
59
|
+
// Getting transcation from server.
|
|
60
|
+
const { transaction } = await requestTransaction(request);
|
|
61
|
+
|
|
62
|
+
if (transaction) {
|
|
63
|
+
if (isEvmTransaction(transaction)) {
|
|
64
|
+
if (transaction.isApprovalTx)
|
|
65
|
+
currentStep.evmApprovalTransaction = transaction;
|
|
66
|
+
else currentStep.evmTransaction = transaction;
|
|
67
|
+
} else if (isCosmosTransaction(transaction)) {
|
|
68
|
+
currentStep.cosmosTransaction = transaction;
|
|
69
|
+
} else if (isSolanaTransaction(transaction)) {
|
|
70
|
+
currentStep.solanaTransaction = transaction;
|
|
71
|
+
} else if (isTrasnferTransaction(transaction)) {
|
|
72
|
+
currentStep.transferTransaction = transaction;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
setStorage({ ...getStorage(), swapDetails: swap });
|
|
77
|
+
schedule(SwapActionTypes.EXECUTE_TRANSACTION);
|
|
78
|
+
next();
|
|
79
|
+
} catch (error) {
|
|
80
|
+
swap.status = 'failed';
|
|
81
|
+
swap.finishTime = new Date().getTime().toString();
|
|
82
|
+
const { extraMessage, extraMessageDetail } = prettifyErrorMessage(error);
|
|
83
|
+
|
|
84
|
+
const updateResult = updateSwapStatus({
|
|
85
|
+
getStorage,
|
|
86
|
+
setStorage,
|
|
87
|
+
nextStatus: 'failed',
|
|
88
|
+
nextStepStatus: 'failed',
|
|
89
|
+
message: extraMessage,
|
|
90
|
+
details: extraMessageDetail,
|
|
91
|
+
errorCode: APIErrorCode.FETCH_TX_FAILED,
|
|
92
|
+
});
|
|
93
|
+
context.notifier({
|
|
94
|
+
eventType: 'task_failed',
|
|
95
|
+
...updateResult,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
actions.failed();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { ExecuterActions } from '@rango-dev/queue-manager-core';
|
|
2
|
+
import {
|
|
3
|
+
ERROR_MESSAGE_WAIT_FOR_CHANGE_NETWORK,
|
|
4
|
+
ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION,
|
|
5
|
+
ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION_WRONG_WALLET,
|
|
6
|
+
} from '../constants';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
getCurrentStep,
|
|
10
|
+
isNetworkMatchedForTransaction,
|
|
11
|
+
isRequiredWalletConnected,
|
|
12
|
+
updateNetworkStatus,
|
|
13
|
+
singTransaction,
|
|
14
|
+
resetNetworkStatus,
|
|
15
|
+
getRequiredWallet,
|
|
16
|
+
isNeedBlockQueueForParallel,
|
|
17
|
+
} from '../helpers';
|
|
18
|
+
import { getCurrentBlockchainOf, PendingSwapNetworkStatus } from '../shared';
|
|
19
|
+
import {
|
|
20
|
+
BlockReason,
|
|
21
|
+
SwapActionTypes,
|
|
22
|
+
SwapQueueContext,
|
|
23
|
+
SwapStorage,
|
|
24
|
+
} from '../types';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Excecute a created transaction.
|
|
28
|
+
*
|
|
29
|
+
* This function implemented the parallel mode by `claim` mechanism which means
|
|
30
|
+
* All the queues the meet certain situation (like multiple evm transaction) will go through
|
|
31
|
+
* a `claim` mechanims that decides which queue should be run and it blocks other ones.
|
|
32
|
+
*
|
|
33
|
+
* A queue will be go to sign process, if the wallet and network is matched.
|
|
34
|
+
*/
|
|
35
|
+
export async function executeTransaction(
|
|
36
|
+
actions: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>
|
|
37
|
+
): Promise<void> {
|
|
38
|
+
const { getStorage, context } = actions;
|
|
39
|
+
const { meta, wallets, providers } = context;
|
|
40
|
+
|
|
41
|
+
const isClaimed = context.claimedBy === context._queue?.id;
|
|
42
|
+
const requestBlock: typeof actions.block = (blockedFor) => {
|
|
43
|
+
actions.block(blockedFor);
|
|
44
|
+
if (isClaimed && actions.context.resetClaimedBy) {
|
|
45
|
+
actions.context.resetClaimedBy();
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const swap = getStorage().swapDetails;
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
51
|
+
const currentStep = getCurrentStep(swap)!;
|
|
52
|
+
|
|
53
|
+
// Resetting network status, so we will set it again during the running of this task.
|
|
54
|
+
resetNetworkStatus(actions);
|
|
55
|
+
|
|
56
|
+
/* Make sure wallet is connected and also the connected wallet is matched with tx by checking address. */
|
|
57
|
+
const isWrongAddress = !isRequiredWalletConnected(swap, context.state);
|
|
58
|
+
if (isWrongAddress) {
|
|
59
|
+
const { type, address } = getRequiredWallet(swap);
|
|
60
|
+
const description = !wallets
|
|
61
|
+
? ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION(type)
|
|
62
|
+
: ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION_WRONG_WALLET(type, address);
|
|
63
|
+
|
|
64
|
+
const blockedFor = {
|
|
65
|
+
reason: BlockReason.WAIT_FOR_CONNECT_WALLET,
|
|
66
|
+
description,
|
|
67
|
+
};
|
|
68
|
+
requestBlock(blockedFor);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/*
|
|
73
|
+
For avoiding conflict by making too many requests to wallet, we need to make sure
|
|
74
|
+
We only run one request at a time (In parallel mode).
|
|
75
|
+
*/
|
|
76
|
+
const needsToBlockQueue = isNeedBlockQueueForParallel(currentStep);
|
|
77
|
+
|
|
78
|
+
if (needsToBlockQueue && !isClaimed && context.claimedBy) {
|
|
79
|
+
const blockedFor = {
|
|
80
|
+
reason: BlockReason.DEPENDS_ON_OTHER_QUEUES,
|
|
81
|
+
description: 'Waiting for other running tasks to be finished',
|
|
82
|
+
details: {},
|
|
83
|
+
};
|
|
84
|
+
requestBlock(blockedFor);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* Wallet should be on correct network */
|
|
89
|
+
const networkMatched = await isNetworkMatchedForTransaction(
|
|
90
|
+
swap,
|
|
91
|
+
currentStep,
|
|
92
|
+
wallets,
|
|
93
|
+
meta,
|
|
94
|
+
providers
|
|
95
|
+
);
|
|
96
|
+
if (!networkMatched) {
|
|
97
|
+
const fromBlockchain = getCurrentBlockchainOf(swap, currentStep);
|
|
98
|
+
const details = ERROR_MESSAGE_WAIT_FOR_CHANGE_NETWORK(fromBlockchain);
|
|
99
|
+
|
|
100
|
+
const blockedFor = {
|
|
101
|
+
reason: BlockReason.WAIT_FOR_NETWORK_CHANGE,
|
|
102
|
+
details: details,
|
|
103
|
+
};
|
|
104
|
+
requestBlock(blockedFor);
|
|
105
|
+
return;
|
|
106
|
+
} else {
|
|
107
|
+
// Update network to mark it as network changed successfully.
|
|
108
|
+
updateNetworkStatus(actions, {
|
|
109
|
+
message: '',
|
|
110
|
+
details: 'Wallet network changed successfully',
|
|
111
|
+
status: PendingSwapNetworkStatus.NetworkChanged,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// All the conditions are met. We can safely send the tx to wallet for sign.
|
|
116
|
+
singTransaction(actions);
|
|
117
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ExecuterActions } from '@rango-dev/queue-manager-core';
|
|
2
|
+
import { SwapActionTypes, SwapQueueContext, SwapStorage } from '../types';
|
|
3
|
+
import { getCurrentStep, isTxAlreadyCreated } from '../helpers';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* This function is responsibe for scheduling the correct `action` based on `PendingSwap` status.
|
|
8
|
+
* It means `action`s schedule this step to decide what should be the next step/task.
|
|
9
|
+
*
|
|
10
|
+
* It's acts like a `while(true)` and will `break` the loop on certain `action`s like `CHECK_STATUS`.
|
|
11
|
+
*
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
export function scheduleNextStep({
|
|
15
|
+
schedule,
|
|
16
|
+
next,
|
|
17
|
+
failed,
|
|
18
|
+
setStorage,
|
|
19
|
+
getStorage,
|
|
20
|
+
context,
|
|
21
|
+
}: ExecuterActions<SwapStorage, SwapActionTypes, SwapQueueContext>): void {
|
|
22
|
+
const swap = getStorage().swapDetails;
|
|
23
|
+
const currentStep = getCurrentStep(swap);
|
|
24
|
+
if (!!currentStep) {
|
|
25
|
+
if (isTxAlreadyCreated(swap, currentStep)) {
|
|
26
|
+
schedule(SwapActionTypes.EXECUTE_TRANSACTION);
|
|
27
|
+
return next();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (currentStep?.executedTransactionId) {
|
|
31
|
+
schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS);
|
|
32
|
+
return next();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
swap.status = 'running';
|
|
36
|
+
|
|
37
|
+
setStorage({ ...getStorage(), swapDetails: swap });
|
|
38
|
+
|
|
39
|
+
schedule(SwapActionTypes.CREATE_TRANSACTION);
|
|
40
|
+
next();
|
|
41
|
+
} else {
|
|
42
|
+
const isFailed = swap.steps.find((step) => step.status === 'failed');
|
|
43
|
+
swap.status = isFailed ? 'failed' : 'success';
|
|
44
|
+
swap.finishTime = new Date().getTime().toString();
|
|
45
|
+
|
|
46
|
+
setStorage({
|
|
47
|
+
...getStorage(),
|
|
48
|
+
swapDetails: swap,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
context.notifier({
|
|
52
|
+
eventType: isFailed ? 'task_failed' : 'task_completed',
|
|
53
|
+
swap: swap,
|
|
54
|
+
step: null,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (isFailed) failed();
|
|
58
|
+
else next();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ExecuterActions } from '@rango-dev/queue-manager-core';
|
|
2
|
+
import { SwapActionTypes, SwapStorage } from '../types';
|
|
3
|
+
|
|
4
|
+
export function start({
|
|
5
|
+
schedule,
|
|
6
|
+
next,
|
|
7
|
+
}: ExecuterActions<SwapStorage, SwapActionTypes>): void {
|
|
8
|
+
schedule(SwapActionTypes.SCHEDULE_NEXT_STEP);
|
|
9
|
+
next();
|
|
10
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const RANGO_DAPP_ID_QUERY = process.env.REACT_APP_RANGO_DAPP_ID_QUERY;
|
|
2
|
+
export const BASE_URL = process.env.REACT_APP_BASE_URL;
|
|
3
|
+
export const RANGO_COOKIE_HEADER = 'X-Rango-Id';
|
|
4
|
+
|
|
5
|
+
export const ERROR_MESSAGE_DEPENDS_ON_OTHER_QUEUES =
|
|
6
|
+
'Waiting for other running tasks to be finished';
|
|
7
|
+
export const ERROR_MESSAGE_WAIT_FOR_WALLET = 'Waiting for connecting wallet';
|
|
8
|
+
export const ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION_WRONG_WALLET = (
|
|
9
|
+
type: string | null,
|
|
10
|
+
address: string | null
|
|
11
|
+
): string =>
|
|
12
|
+
`Please change your ${type || 'wallet'} account to ${
|
|
13
|
+
address || 'proper address'
|
|
14
|
+
}`;
|
|
15
|
+
export const ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION = (
|
|
16
|
+
type: string | null
|
|
17
|
+
): string =>
|
|
18
|
+
`Please connect to ${
|
|
19
|
+
type || 'your wallet'
|
|
20
|
+
} by using bellow button or top right button on page.`;
|
|
21
|
+
export const ERROR_MESSAGE_WAIT_FOR_CHANGE_NETWORK = (
|
|
22
|
+
network: string | null
|
|
23
|
+
): string => `Please change your network to ${network}.`;
|