@lifi/sdk 1.3.1 → 1.5.0
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 +16 -0
- package/dist/Lifi.d.ts +7 -0
- package/dist/Lifi.js +72 -30
- package/dist/cjs/Lifi.d.ts +7 -0
- package/dist/cjs/Lifi.js +72 -30
- package/dist/cjs/execution/StatusManager.d.ts +2 -2
- package/dist/cjs/execution/StatusManager.js +14 -7
- package/dist/cjs/execution/StepExecutor.d.ts +4 -2
- package/dist/cjs/execution/StepExecutor.js +27 -16
- package/dist/cjs/execution/allowance.execute.d.ts +2 -2
- package/dist/cjs/execution/allowance.execute.js +14 -21
- package/dist/cjs/execution/bridges/bridge.execute.d.ts +2 -2
- package/dist/cjs/execution/bridges/bridge.execute.js +102 -90
- package/dist/cjs/execution/exchanges/swap.execute.d.ts +2 -2
- package/dist/cjs/execution/exchanges/swap.execute.js +42 -54
- package/dist/cjs/execution/switchChain.js +3 -3
- package/dist/cjs/helpers.js +1 -1
- package/dist/cjs/services/ConfigService.js +4 -3
- package/dist/cjs/types/internal.types.d.ts +5 -1
- package/dist/cjs/utils/parseError.js +4 -5
- package/dist/cjs/utils/preRestart.js +5 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/execution/StatusManager.d.ts +2 -2
- package/dist/execution/StatusManager.js +14 -7
- package/dist/execution/StepExecutor.d.ts +4 -2
- package/dist/execution/StepExecutor.js +27 -16
- package/dist/execution/allowance.execute.d.ts +2 -2
- package/dist/execution/allowance.execute.js +14 -21
- package/dist/execution/bridges/bridge.execute.d.ts +2 -2
- package/dist/execution/bridges/bridge.execute.js +103 -91
- package/dist/execution/exchanges/swap.execute.d.ts +2 -2
- package/dist/execution/exchanges/swap.execute.js +43 -55
- package/dist/execution/switchChain.js +3 -3
- package/dist/helpers.js +1 -1
- package/dist/services/ConfigService.js +4 -3
- package/dist/types/internal.types.d.ts +5 -1
- package/dist/utils/parseError.js +4 -5
- package/dist/utils/preRestart.js +5 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +10 -10
|
@@ -42,7 +42,7 @@ export declare class StatusManager {
|
|
|
42
42
|
* @param {Status} status By default created procces is set to the STARTED status. We can override new process with the needed status.
|
|
43
43
|
* @return {Process}
|
|
44
44
|
*/
|
|
45
|
-
findOrCreateProcess: (
|
|
45
|
+
findOrCreateProcess: (step: Step, type: ProcessType, status?: Status) => Process;
|
|
46
46
|
/**
|
|
47
47
|
* Update a process object.
|
|
48
48
|
* @param {Step} step The step where the process should be updated
|
|
@@ -60,6 +60,6 @@ export declare class StatusManager {
|
|
|
60
60
|
*/
|
|
61
61
|
removeProcess: (step: Step, type: ProcessType) => void;
|
|
62
62
|
updateStepInRoute: (step: Step) => Step;
|
|
63
|
-
|
|
63
|
+
allowUpdates(value: boolean): void;
|
|
64
64
|
}
|
|
65
65
|
export {};
|
|
@@ -37,12 +37,17 @@ export class StatusManager {
|
|
|
37
37
|
* @param {Status} status By default created procces is set to the STARTED status. We can override new process with the needed status.
|
|
38
38
|
* @return {Process}
|
|
39
39
|
*/
|
|
40
|
-
this.findOrCreateProcess = (
|
|
41
|
-
|
|
40
|
+
this.findOrCreateProcess = (step, type, status) => {
|
|
41
|
+
var _a;
|
|
42
|
+
if (!((_a = step.execution) === null || _a === void 0 ? void 0 : _a.process)) {
|
|
42
43
|
throw new Error("Execution hasn't been initialized.");
|
|
43
44
|
}
|
|
44
45
|
const process = step.execution.process.find((p) => p.type === type);
|
|
45
46
|
if (process) {
|
|
47
|
+
if (status && process.status !== status) {
|
|
48
|
+
process.status = status;
|
|
49
|
+
this.updateStepInRoute(step);
|
|
50
|
+
}
|
|
46
51
|
return process;
|
|
47
52
|
}
|
|
48
53
|
const newProcess = {
|
|
@@ -64,7 +69,7 @@ export class StatusManager {
|
|
|
64
69
|
* @return {Process} The update process
|
|
65
70
|
*/
|
|
66
71
|
this.updateProcess = (step, type, status, params) => {
|
|
67
|
-
var _a;
|
|
72
|
+
var _a, _b, _c;
|
|
68
73
|
if (!step.execution) {
|
|
69
74
|
throw new Error("Can't update an empty step execution.");
|
|
70
75
|
}
|
|
@@ -89,9 +94,6 @@ export class StatusManager {
|
|
|
89
94
|
case 'ACTION_REQUIRED':
|
|
90
95
|
step.execution.status = 'ACTION_REQUIRED';
|
|
91
96
|
break;
|
|
92
|
-
case 'CHAIN_SWITCH_REQUIRED':
|
|
93
|
-
step.execution.status = 'CHAIN_SWITCH_REQUIRED';
|
|
94
|
-
break;
|
|
95
97
|
default:
|
|
96
98
|
break;
|
|
97
99
|
}
|
|
@@ -103,6 +105,11 @@ export class StatusManager {
|
|
|
103
105
|
currentProcess[key] = value;
|
|
104
106
|
}
|
|
105
107
|
}
|
|
108
|
+
// Sort processes, the ones with DONE status go first
|
|
109
|
+
step.execution.process = [
|
|
110
|
+
...(_b = step === null || step === void 0 ? void 0 : step.execution) === null || _b === void 0 ? void 0 : _b.process.filter((process) => process.status === 'DONE'),
|
|
111
|
+
...(_c = step === null || step === void 0 ? void 0 : step.execution) === null || _c === void 0 ? void 0 : _c.process.filter((process) => process.status !== 'DONE'),
|
|
112
|
+
];
|
|
106
113
|
this.updateStepInRoute(step); // updates the step in the route
|
|
107
114
|
return currentProcess;
|
|
108
115
|
};
|
|
@@ -157,7 +164,7 @@ export class StatusManager {
|
|
|
157
164
|
this.updateStepInRoute(step);
|
|
158
165
|
return step;
|
|
159
166
|
}
|
|
160
|
-
|
|
167
|
+
allowUpdates(value) {
|
|
161
168
|
this.shouldUpdate = value;
|
|
162
169
|
}
|
|
163
170
|
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { Signer } from 'ethers';
|
|
2
|
-
import {
|
|
2
|
+
import { InteractionSettings, InternalExecutionSettings, Step } from '../types';
|
|
3
3
|
import { StatusManager } from './StatusManager';
|
|
4
4
|
export declare class StepExecutor {
|
|
5
5
|
settings: InternalExecutionSettings;
|
|
6
6
|
statusManager: StatusManager;
|
|
7
7
|
private swapExecutionManager;
|
|
8
8
|
private bridgeExecutionManager;
|
|
9
|
+
allowUserInteraction: boolean;
|
|
9
10
|
executionStopped: boolean;
|
|
10
11
|
constructor(statusManager: StatusManager, settings: InternalExecutionSettings);
|
|
11
|
-
|
|
12
|
+
setInteraction: (settings?: InteractionSettings) => void;
|
|
13
|
+
checkChain: () => never;
|
|
12
14
|
executeStep: (signer: Signer, step: Step) => Promise<Step>;
|
|
13
15
|
private executeSwap;
|
|
14
16
|
private executeCross;
|
|
@@ -10,26 +10,37 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { BridgeExecutionManager } from './bridges/bridge.execute';
|
|
11
11
|
import { SwapExecutionManager } from './exchanges/swap.execute';
|
|
12
12
|
import { switchChain } from './switchChain';
|
|
13
|
-
|
|
13
|
+
// Please be careful when changing the defaults as it may break the behavior (e.g., background execution)
|
|
14
|
+
const defaultInteractionSettings = {
|
|
15
|
+
allowInteraction: true,
|
|
14
16
|
allowUpdates: true,
|
|
17
|
+
stopExecution: false,
|
|
15
18
|
};
|
|
16
19
|
export class StepExecutor {
|
|
17
20
|
constructor(statusManager, settings) {
|
|
18
21
|
this.swapExecutionManager = new SwapExecutionManager();
|
|
19
22
|
this.bridgeExecutionManager = new BridgeExecutionManager();
|
|
23
|
+
this.allowUserInteraction = true;
|
|
20
24
|
this.executionStopped = false;
|
|
21
|
-
this.
|
|
22
|
-
const
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
25
|
+
this.setInteraction = (settings) => {
|
|
26
|
+
const interactionSettings = Object.assign(Object.assign({}, defaultInteractionSettings), settings);
|
|
27
|
+
this.allowUserInteraction = interactionSettings.allowInteraction;
|
|
28
|
+
this.swapExecutionManager.allowInteraction(interactionSettings.allowInteraction);
|
|
29
|
+
this.bridgeExecutionManager.allowInteraction(interactionSettings.allowInteraction);
|
|
30
|
+
this.statusManager.allowUpdates(interactionSettings.allowUpdates);
|
|
31
|
+
this.executionStopped = interactionSettings.stopExecution;
|
|
32
|
+
};
|
|
33
|
+
// TODO: add checkChain method and update signer inside executors
|
|
34
|
+
// This can come in handy when we execute multiple routes simultaneously and
|
|
35
|
+
// should be sure that we are on the right chain when waiting for transactions.
|
|
36
|
+
this.checkChain = () => {
|
|
37
|
+
throw new Error('checkChain is not implemented.');
|
|
27
38
|
};
|
|
28
39
|
this.executeStep = (signer, step) => __awaiter(this, void 0, void 0, function* () {
|
|
29
|
-
//
|
|
30
|
-
const updatedSigner = yield switchChain(signer, this.statusManager, step, this.settings.switchChainHook,
|
|
40
|
+
// Make sure that the chain is still correct
|
|
41
|
+
const updatedSigner = yield switchChain(signer, this.statusManager, step, this.settings.switchChainHook, this.allowUserInteraction);
|
|
31
42
|
if (!updatedSigner) {
|
|
32
|
-
//
|
|
43
|
+
// Chain switch was not successful, stop execution here
|
|
33
44
|
return step;
|
|
34
45
|
}
|
|
35
46
|
signer = updatedSigner;
|
|
@@ -46,24 +57,24 @@ export class StepExecutor {
|
|
|
46
57
|
}
|
|
47
58
|
return step;
|
|
48
59
|
});
|
|
49
|
-
this.executeSwap = (signer, step) =>
|
|
60
|
+
this.executeSwap = (signer, step) => {
|
|
50
61
|
const swapParams = {
|
|
51
62
|
signer,
|
|
52
63
|
step,
|
|
53
64
|
settings: this.settings,
|
|
54
65
|
statusManager: this.statusManager,
|
|
55
66
|
};
|
|
56
|
-
return
|
|
57
|
-
}
|
|
58
|
-
this.executeCross = (signer, step) =>
|
|
67
|
+
return this.swapExecutionManager.execute(swapParams);
|
|
68
|
+
};
|
|
69
|
+
this.executeCross = (signer, step) => {
|
|
59
70
|
const crossParams = {
|
|
60
71
|
signer,
|
|
61
72
|
step,
|
|
62
73
|
settings: this.settings,
|
|
63
74
|
statusManager: this.statusManager,
|
|
64
75
|
};
|
|
65
|
-
return
|
|
66
|
-
}
|
|
76
|
+
return this.bridgeExecutionManager.execute(crossParams);
|
|
77
|
+
};
|
|
67
78
|
this.statusManager = statusManager;
|
|
68
79
|
this.settings = settings;
|
|
69
80
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Signer } from 'ethers';
|
|
2
|
-
import { Chain,
|
|
2
|
+
import { Chain, InternalExecutionSettings, Step } from '../types';
|
|
3
3
|
import { StatusManager } from './StatusManager';
|
|
4
|
-
export declare const checkAllowance: (signer: Signer, step: Step,
|
|
4
|
+
export declare const checkAllowance: (signer: Signer, step: Step, statusManager: StatusManager, settings: InternalExecutionSettings, chain: Chain, allowUserInteraction?: boolean) => Promise<void>;
|
|
@@ -12,39 +12,33 @@ import { constants } from 'ethers';
|
|
|
12
12
|
import { getApproved, setApproval } from '../allowance/utils';
|
|
13
13
|
import { getProvider } from '../utils/getProvider';
|
|
14
14
|
import { parseError } from '../utils/parseError';
|
|
15
|
-
export const checkAllowance = (signer, step,
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
// -> set currentExecution
|
|
20
|
-
let allowanceProcess = statusManager.findOrCreateProcess('TOKEN_ALLOWANCE', step);
|
|
21
|
-
// -> check allowance
|
|
15
|
+
export const checkAllowance = (signer, step, statusManager, settings, chain, allowUserInteraction = false) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
|
+
// Ask the user to set an allowance
|
|
17
|
+
let allowanceProcess = statusManager.findOrCreateProcess(step, 'TOKEN_ALLOWANCE');
|
|
18
|
+
// Check allowance
|
|
22
19
|
try {
|
|
23
|
-
if (allowanceProcess.txHash) {
|
|
24
|
-
|
|
20
|
+
if (allowanceProcess.txHash && allowanceProcess.status !== 'DONE') {
|
|
21
|
+
if (allowanceProcess.status !== 'PENDING') {
|
|
22
|
+
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING');
|
|
23
|
+
}
|
|
25
24
|
yield getProvider(signer).waitForTransaction(allowanceProcess.txHash);
|
|
26
25
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
|
|
27
|
-
// TODO: Do we need this check?
|
|
28
|
-
}
|
|
29
|
-
else if (allowanceProcess.status === 'DONE') {
|
|
30
|
-
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
|
|
31
26
|
}
|
|
32
27
|
else {
|
|
33
|
-
const approved = yield getApproved(signer,
|
|
34
|
-
if (new BigNumber(
|
|
28
|
+
const approved = yield getApproved(signer, step.action.fromToken.address, step.estimate.approvalAddress);
|
|
29
|
+
if (new BigNumber(step.action.fromAmount).gt(approved)) {
|
|
35
30
|
if (!allowUserInteraction) {
|
|
36
31
|
return;
|
|
37
32
|
}
|
|
38
|
-
const approvalAmount = infiniteApproval
|
|
33
|
+
const approvalAmount = settings.infiniteApproval
|
|
39
34
|
? constants.MaxUint256.toString()
|
|
40
|
-
:
|
|
41
|
-
const approveTx = yield setApproval(signer,
|
|
42
|
-
// update currentExecution
|
|
35
|
+
: step.action.fromAmount;
|
|
36
|
+
const approveTx = yield setApproval(signer, step.action.fromToken.address, step.estimate.approvalAddress, approvalAmount);
|
|
43
37
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING', {
|
|
44
38
|
txHash: approveTx.hash,
|
|
45
39
|
txLink: chain.metamask.blockExplorerUrls[0] + 'tx/' + approveTx.hash,
|
|
46
40
|
});
|
|
47
|
-
//
|
|
41
|
+
// Wait for the transcation
|
|
48
42
|
yield approveTx.wait();
|
|
49
43
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
|
|
50
44
|
}
|
|
@@ -54,7 +48,6 @@ export const checkAllowance = (signer, step, chain, token, amount, spenderAddres
|
|
|
54
48
|
}
|
|
55
49
|
}
|
|
56
50
|
catch (e) {
|
|
57
|
-
// -> set status
|
|
58
51
|
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
|
|
59
52
|
yield transactionReplaced(e.replacement, allowanceProcess, step, chain, statusManager);
|
|
60
53
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Execution } from '@lifi/types';
|
|
2
2
|
import { ExecuteCrossParams } from '../../types';
|
|
3
3
|
export declare class BridgeExecutionManager {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
allowUserInteraction: boolean;
|
|
5
|
+
allowInteraction: (value: boolean) => void;
|
|
6
6
|
execute: ({ signer, step, statusManager, settings, }: ExecuteCrossParams) => Promise<Execution>;
|
|
7
7
|
}
|
|
@@ -7,13 +7,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { constants } from 'ethers';
|
|
11
10
|
import ApiService from '../../services/ApiService';
|
|
12
11
|
import ChainsService from '../../services/ChainsService';
|
|
13
12
|
import { LifiErrorCode, TransactionError } from '../../utils/errors';
|
|
14
13
|
import { getProvider } from '../../utils/getProvider';
|
|
15
14
|
import { getTransactionFailedMessage, parseError } from '../../utils/parseError';
|
|
16
|
-
import { personalizeStep } from '../../utils/utils';
|
|
15
|
+
import { isZeroAddress, personalizeStep } from '../../utils/utils';
|
|
17
16
|
import { checkAllowance } from '../allowance.execute';
|
|
18
17
|
import { balanceCheck } from '../balanceCheck.execute';
|
|
19
18
|
import { stepComparison } from '../stepComparison';
|
|
@@ -21,97 +20,125 @@ import { switchChain } from '../switchChain';
|
|
|
21
20
|
import { getSubstatusMessage, waitForReceivingTransaction } from '../utils';
|
|
22
21
|
export class BridgeExecutionManager {
|
|
23
22
|
constructor() {
|
|
24
|
-
this.
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
23
|
+
this.allowUserInteraction = true;
|
|
24
|
+
this.allowInteraction = (value) => {
|
|
25
|
+
this.allowUserInteraction = value;
|
|
27
26
|
};
|
|
28
27
|
this.execute = ({ signer, step, statusManager, settings, }) => __awaiter(this, void 0, void 0, function* () {
|
|
29
28
|
var _a, _b, _c, _d;
|
|
30
|
-
const { action, estimate } = step;
|
|
31
29
|
step.execution = statusManager.initExecutionObject(step);
|
|
32
30
|
const chainsService = ChainsService.getInstance();
|
|
33
|
-
const fromChain = yield chainsService.getChainById(action.fromChainId);
|
|
34
|
-
const toChain = yield chainsService.getChainById(action.toChainId);
|
|
35
|
-
// STEP 1: Check
|
|
36
|
-
// approval still needed?
|
|
31
|
+
const fromChain = yield chainsService.getChainById(step.action.fromChainId);
|
|
32
|
+
const toChain = yield chainsService.getChainById(step.action.toChainId);
|
|
33
|
+
// STEP 1: Check allowance
|
|
37
34
|
const oldCrossProcess = step.execution.process.find((p) => p.type === 'CROSS_CHAIN');
|
|
38
|
-
if
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
35
|
+
// Check token approval only if fromToken is not the native token => no approval needed in that case
|
|
36
|
+
if (!(oldCrossProcess === null || oldCrossProcess === void 0 ? void 0 : oldCrossProcess.txHash) &&
|
|
37
|
+
!isZeroAddress(step.action.fromToken.address)) {
|
|
38
|
+
yield checkAllowance(signer, step, statusManager, settings, fromChain, this.allowUserInteraction);
|
|
43
39
|
}
|
|
44
|
-
// STEP 2: Get
|
|
45
|
-
let crossChainProcess = statusManager.findOrCreateProcess('CROSS_CHAIN'
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const { transactionRequest } = step;
|
|
60
|
-
if (!transactionRequest) {
|
|
61
|
-
throw new TransactionError(LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
|
|
40
|
+
// STEP 2: Get transaction
|
|
41
|
+
let crossChainProcess = statusManager.findOrCreateProcess(step, 'CROSS_CHAIN');
|
|
42
|
+
if (crossChainProcess.status !== 'DONE') {
|
|
43
|
+
try {
|
|
44
|
+
let transaction;
|
|
45
|
+
if (crossChainProcess.txHash) {
|
|
46
|
+
// Make sure that the chain is still correct
|
|
47
|
+
const updatedSigner = yield switchChain(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
|
|
48
|
+
if (!updatedSigner) {
|
|
49
|
+
// Chain switch was not successful, stop execution here
|
|
50
|
+
return step.execution;
|
|
51
|
+
}
|
|
52
|
+
signer = updatedSigner;
|
|
53
|
+
// Load exiting transaction
|
|
54
|
+
transaction = yield getProvider(signer).getTransaction(crossChainProcess.txHash);
|
|
62
55
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
//
|
|
68
|
-
|
|
56
|
+
else {
|
|
57
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'STARTED');
|
|
58
|
+
// Check balance
|
|
59
|
+
yield balanceCheck(signer, step);
|
|
60
|
+
// Create new transaction
|
|
61
|
+
if (!step.transactionRequest) {
|
|
62
|
+
const personalizedStep = yield personalizeStep(signer, step);
|
|
63
|
+
const updatedStep = yield ApiService.getStepTransaction(personalizedStep);
|
|
64
|
+
step = Object.assign(Object.assign({}, (yield stepComparison(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.allowUserInteraction))), { execution: step.execution });
|
|
65
|
+
}
|
|
66
|
+
const { transactionRequest } = step;
|
|
67
|
+
if (!transactionRequest) {
|
|
68
|
+
throw new TransactionError(LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
|
|
69
|
+
}
|
|
70
|
+
// STEP 3: Send the transaction
|
|
71
|
+
// Make sure that the chain is still correct
|
|
72
|
+
const updatedSigner = yield switchChain(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
|
|
73
|
+
if (!updatedSigner) {
|
|
74
|
+
// Chain switch was not successful, stop execution here
|
|
75
|
+
return step.execution;
|
|
76
|
+
}
|
|
77
|
+
signer = updatedSigner;
|
|
78
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'ACTION_REQUIRED');
|
|
79
|
+
if (!this.allowUserInteraction) {
|
|
80
|
+
return step.execution;
|
|
81
|
+
}
|
|
82
|
+
// Submit the transaction
|
|
83
|
+
transaction = yield signer.sendTransaction(transactionRequest);
|
|
84
|
+
// STEP 4: Wait for the transaction
|
|
85
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
|
|
86
|
+
txHash: transaction.hash,
|
|
87
|
+
txLink: fromChain.metamask.blockExplorerUrls[0] +
|
|
88
|
+
'tx/' +
|
|
89
|
+
transaction.hash,
|
|
90
|
+
});
|
|
69
91
|
}
|
|
70
|
-
|
|
71
|
-
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, '
|
|
72
|
-
if (!this.shouldContinue) {
|
|
73
|
-
return step.execution;
|
|
74
|
-
}
|
|
75
|
-
tx = yield signer.sendTransaction(transactionRequest);
|
|
76
|
-
// STEP 4: Wait for Transaction ///////////////////////////////////////////
|
|
77
|
-
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
|
|
78
|
-
txHash: tx.hash,
|
|
79
|
-
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + tx.hash,
|
|
80
|
-
});
|
|
92
|
+
yield transaction.wait();
|
|
93
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE');
|
|
81
94
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
throw error;
|
|
95
|
+
catch (e) {
|
|
96
|
+
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
|
|
97
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE', {
|
|
98
|
+
txHash: e.replacement.hash,
|
|
99
|
+
txLink: fromChain.metamask.blockExplorerUrls[0] +
|
|
100
|
+
'tx/' +
|
|
101
|
+
e.replacement.hash,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const error = yield parseError(e, step, crossChainProcess);
|
|
106
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'FAILED', {
|
|
107
|
+
error: {
|
|
108
|
+
message: error.message,
|
|
109
|
+
htmlMessage: error.htmlMessage,
|
|
110
|
+
code: error.code,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
statusManager.updateExecution(step, 'FAILED');
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
104
116
|
}
|
|
105
117
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
let receivingChainProcess = statusManager.findOrCreateProcess('RECEIVING_CHAIN', step, 'PENDING');
|
|
118
|
+
// STEP 5: Wait for the receiving chain
|
|
119
|
+
let receivingChainProcess = statusManager.findOrCreateProcess(step, 'RECEIVING_CHAIN', 'PENDING');
|
|
109
120
|
let statusResponse;
|
|
110
121
|
try {
|
|
111
122
|
if (!crossChainProcess.txHash) {
|
|
112
123
|
throw new Error('Transaction hash is undefined.');
|
|
113
124
|
}
|
|
114
125
|
statusResponse = yield waitForReceivingTransaction(crossChainProcess.txHash, statusManager, receivingChainProcess.type, step);
|
|
126
|
+
receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'DONE', {
|
|
127
|
+
substatus: statusResponse.substatus,
|
|
128
|
+
substatusMessage: statusResponse.substatusMessage ||
|
|
129
|
+
getSubstatusMessage(statusResponse.status, statusResponse.substatus),
|
|
130
|
+
txHash: (_a = statusResponse.receiving) === null || _a === void 0 ? void 0 : _a.txHash,
|
|
131
|
+
txLink: toChain.metamask.blockExplorerUrls[0] +
|
|
132
|
+
'tx/' +
|
|
133
|
+
((_b = statusResponse.receiving) === null || _b === void 0 ? void 0 : _b.txHash),
|
|
134
|
+
});
|
|
135
|
+
statusManager.updateExecution(step, 'DONE', {
|
|
136
|
+
fromAmount: statusResponse.sending.amount,
|
|
137
|
+
toAmount: (_c = statusResponse.receiving) === null || _c === void 0 ? void 0 : _c.amount,
|
|
138
|
+
toToken: (_d = statusResponse.receiving) === null || _d === void 0 ? void 0 : _d.token,
|
|
139
|
+
gasUsed: statusResponse.sending.gasUsed,
|
|
140
|
+
gasPrice: statusResponse.sending.gasPrice,
|
|
141
|
+
});
|
|
115
142
|
}
|
|
116
143
|
catch (e) {
|
|
117
144
|
receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'FAILED', {
|
|
@@ -122,24 +149,9 @@ export class BridgeExecutionManager {
|
|
|
122
149
|
},
|
|
123
150
|
});
|
|
124
151
|
statusManager.updateExecution(step, 'FAILED');
|
|
152
|
+
console.warn(e);
|
|
125
153
|
throw e;
|
|
126
154
|
}
|
|
127
|
-
receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'DONE', {
|
|
128
|
-
substatus: statusResponse.substatus,
|
|
129
|
-
substatusMessage: statusResponse.substatusMessage ||
|
|
130
|
-
getSubstatusMessage(statusResponse.status, statusResponse.substatus),
|
|
131
|
-
txHash: (_a = statusResponse.receiving) === null || _a === void 0 ? void 0 : _a.txHash,
|
|
132
|
-
txLink: toChain.metamask.blockExplorerUrls[0] +
|
|
133
|
-
'tx/' +
|
|
134
|
-
((_b = statusResponse.receiving) === null || _b === void 0 ? void 0 : _b.txHash),
|
|
135
|
-
});
|
|
136
|
-
statusManager.updateExecution(step, 'DONE', {
|
|
137
|
-
fromAmount: statusResponse.sending.amount,
|
|
138
|
-
toAmount: (_c = statusResponse.receiving) === null || _c === void 0 ? void 0 : _c.amount,
|
|
139
|
-
toToken: (_d = statusResponse.receiving) === null || _d === void 0 ? void 0 : _d.token,
|
|
140
|
-
gasUsed: statusResponse.sending.gasUsed,
|
|
141
|
-
gasPrice: statusResponse.sending.gasPrice,
|
|
142
|
-
});
|
|
143
155
|
// DONE
|
|
144
156
|
return step.execution;
|
|
145
157
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Execution } from '@lifi/types';
|
|
2
2
|
import { ExecuteSwapParams } from '../../types';
|
|
3
3
|
export declare class SwapExecutionManager {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
allowUserInteraction: boolean;
|
|
5
|
+
allowInteraction: (value: boolean) => void;
|
|
6
6
|
execute: ({ signer, step, statusManager, settings, }: ExecuteSwapParams) => Promise<Execution>;
|
|
7
7
|
}
|