@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
|
@@ -18,39 +18,33 @@ const ethers_1 = require("ethers");
|
|
|
18
18
|
const utils_1 = require("../allowance/utils");
|
|
19
19
|
const getProvider_1 = require("../utils/getProvider");
|
|
20
20
|
const parseError_1 = require("../utils/parseError");
|
|
21
|
-
const checkAllowance = (signer, step,
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
//
|
|
25
|
-
// -> set currentExecution
|
|
26
|
-
let allowanceProcess = statusManager.findOrCreateProcess('TOKEN_ALLOWANCE', step);
|
|
27
|
-
// -> check allowance
|
|
21
|
+
const checkAllowance = (signer, step, statusManager, settings, chain, allowUserInteraction = false) => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
+
// Ask the user to set an allowance
|
|
23
|
+
let allowanceProcess = statusManager.findOrCreateProcess(step, 'TOKEN_ALLOWANCE');
|
|
24
|
+
// Check allowance
|
|
28
25
|
try {
|
|
29
|
-
if (allowanceProcess.txHash) {
|
|
30
|
-
|
|
26
|
+
if (allowanceProcess.txHash && allowanceProcess.status !== 'DONE') {
|
|
27
|
+
if (allowanceProcess.status !== 'PENDING') {
|
|
28
|
+
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING');
|
|
29
|
+
}
|
|
31
30
|
yield (0, getProvider_1.getProvider)(signer).waitForTransaction(allowanceProcess.txHash);
|
|
32
31
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
|
|
33
|
-
// TODO: Do we need this check?
|
|
34
|
-
}
|
|
35
|
-
else if (allowanceProcess.status === 'DONE') {
|
|
36
|
-
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
|
|
37
32
|
}
|
|
38
33
|
else {
|
|
39
|
-
const approved = yield (0, utils_1.getApproved)(signer,
|
|
40
|
-
if (new bignumber_js_1.default(
|
|
34
|
+
const approved = yield (0, utils_1.getApproved)(signer, step.action.fromToken.address, step.estimate.approvalAddress);
|
|
35
|
+
if (new bignumber_js_1.default(step.action.fromAmount).gt(approved)) {
|
|
41
36
|
if (!allowUserInteraction) {
|
|
42
37
|
return;
|
|
43
38
|
}
|
|
44
|
-
const approvalAmount = infiniteApproval
|
|
39
|
+
const approvalAmount = settings.infiniteApproval
|
|
45
40
|
? ethers_1.constants.MaxUint256.toString()
|
|
46
|
-
:
|
|
47
|
-
const approveTx = yield (0, utils_1.setApproval)(signer,
|
|
48
|
-
// update currentExecution
|
|
41
|
+
: step.action.fromAmount;
|
|
42
|
+
const approveTx = yield (0, utils_1.setApproval)(signer, step.action.fromToken.address, step.estimate.approvalAddress, approvalAmount);
|
|
49
43
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING', {
|
|
50
44
|
txHash: approveTx.hash,
|
|
51
45
|
txLink: chain.metamask.blockExplorerUrls[0] + 'tx/' + approveTx.hash,
|
|
52
46
|
});
|
|
53
|
-
//
|
|
47
|
+
// Wait for the transcation
|
|
54
48
|
yield approveTx.wait();
|
|
55
49
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
|
|
56
50
|
}
|
|
@@ -60,7 +54,6 @@ const checkAllowance = (signer, step, chain, token, amount, spenderAddress, stat
|
|
|
60
54
|
}
|
|
61
55
|
}
|
|
62
56
|
catch (e) {
|
|
63
|
-
// -> set status
|
|
64
57
|
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
|
|
65
58
|
yield transactionReplaced(e.replacement, allowanceProcess, step, chain, statusManager);
|
|
66
59
|
}
|
|
@@ -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
|
}
|
|
@@ -13,7 +13,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.BridgeExecutionManager = void 0;
|
|
16
|
-
const ethers_1 = require("ethers");
|
|
17
16
|
const ApiService_1 = __importDefault(require("../../services/ApiService"));
|
|
18
17
|
const ChainsService_1 = __importDefault(require("../../services/ChainsService"));
|
|
19
18
|
const errors_1 = require("../../utils/errors");
|
|
@@ -27,97 +26,125 @@ const switchChain_1 = require("../switchChain");
|
|
|
27
26
|
const utils_2 = require("../utils");
|
|
28
27
|
class BridgeExecutionManager {
|
|
29
28
|
constructor() {
|
|
30
|
-
this.
|
|
31
|
-
this.
|
|
32
|
-
this.
|
|
29
|
+
this.allowUserInteraction = true;
|
|
30
|
+
this.allowInteraction = (value) => {
|
|
31
|
+
this.allowUserInteraction = value;
|
|
33
32
|
};
|
|
34
33
|
this.execute = ({ signer, step, statusManager, settings, }) => __awaiter(this, void 0, void 0, function* () {
|
|
35
34
|
var _a, _b, _c, _d;
|
|
36
|
-
const { action, estimate } = step;
|
|
37
35
|
step.execution = statusManager.initExecutionObject(step);
|
|
38
36
|
const chainsService = ChainsService_1.default.getInstance();
|
|
39
|
-
const fromChain = yield chainsService.getChainById(action.fromChainId);
|
|
40
|
-
const toChain = yield chainsService.getChainById(action.toChainId);
|
|
41
|
-
// STEP 1: Check
|
|
42
|
-
// approval still needed?
|
|
37
|
+
const fromChain = yield chainsService.getChainById(step.action.fromChainId);
|
|
38
|
+
const toChain = yield chainsService.getChainById(step.action.toChainId);
|
|
39
|
+
// STEP 1: Check allowance
|
|
43
40
|
const oldCrossProcess = step.execution.process.find((p) => p.type === 'CROSS_CHAIN');
|
|
44
|
-
if
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
41
|
+
// Check token approval only if fromToken is not the native token => no approval needed in that case
|
|
42
|
+
if (!(oldCrossProcess === null || oldCrossProcess === void 0 ? void 0 : oldCrossProcess.txHash) &&
|
|
43
|
+
!(0, utils_1.isZeroAddress)(step.action.fromToken.address)) {
|
|
44
|
+
yield (0, allowance_execute_1.checkAllowance)(signer, step, statusManager, settings, fromChain, this.allowUserInteraction);
|
|
49
45
|
}
|
|
50
|
-
// STEP 2: Get
|
|
51
|
-
let crossChainProcess = statusManager.findOrCreateProcess('CROSS_CHAIN'
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const { transactionRequest } = step;
|
|
66
|
-
if (!transactionRequest) {
|
|
67
|
-
throw new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
|
|
46
|
+
// STEP 2: Get transaction
|
|
47
|
+
let crossChainProcess = statusManager.findOrCreateProcess(step, 'CROSS_CHAIN');
|
|
48
|
+
if (crossChainProcess.status !== 'DONE') {
|
|
49
|
+
try {
|
|
50
|
+
let transaction;
|
|
51
|
+
if (crossChainProcess.txHash) {
|
|
52
|
+
// Make sure that the chain is still correct
|
|
53
|
+
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
|
|
54
|
+
if (!updatedSigner) {
|
|
55
|
+
// Chain switch was not successful, stop execution here
|
|
56
|
+
return step.execution;
|
|
57
|
+
}
|
|
58
|
+
signer = updatedSigner;
|
|
59
|
+
// Load exiting transaction
|
|
60
|
+
transaction = yield (0, getProvider_1.getProvider)(signer).getTransaction(crossChainProcess.txHash);
|
|
68
61
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
//
|
|
74
|
-
|
|
62
|
+
else {
|
|
63
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'STARTED');
|
|
64
|
+
// Check balance
|
|
65
|
+
yield (0, balanceCheck_execute_1.balanceCheck)(signer, step);
|
|
66
|
+
// Create new transaction
|
|
67
|
+
if (!step.transactionRequest) {
|
|
68
|
+
const personalizedStep = yield (0, utils_1.personalizeStep)(signer, step);
|
|
69
|
+
const updatedStep = yield ApiService_1.default.getStepTransaction(personalizedStep);
|
|
70
|
+
step = Object.assign(Object.assign({}, (yield (0, stepComparison_1.stepComparison)(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.allowUserInteraction))), { execution: step.execution });
|
|
71
|
+
}
|
|
72
|
+
const { transactionRequest } = step;
|
|
73
|
+
if (!transactionRequest) {
|
|
74
|
+
throw new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
|
|
75
|
+
}
|
|
76
|
+
// STEP 3: Send the transaction
|
|
77
|
+
// Make sure that the chain is still correct
|
|
78
|
+
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
|
|
79
|
+
if (!updatedSigner) {
|
|
80
|
+
// Chain switch was not successful, stop execution here
|
|
81
|
+
return step.execution;
|
|
82
|
+
}
|
|
83
|
+
signer = updatedSigner;
|
|
84
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'ACTION_REQUIRED');
|
|
85
|
+
if (!this.allowUserInteraction) {
|
|
86
|
+
return step.execution;
|
|
87
|
+
}
|
|
88
|
+
// Submit the transaction
|
|
89
|
+
transaction = yield signer.sendTransaction(transactionRequest);
|
|
90
|
+
// STEP 4: Wait for the transaction
|
|
91
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
|
|
92
|
+
txHash: transaction.hash,
|
|
93
|
+
txLink: fromChain.metamask.blockExplorerUrls[0] +
|
|
94
|
+
'tx/' +
|
|
95
|
+
transaction.hash,
|
|
96
|
+
});
|
|
75
97
|
}
|
|
76
|
-
|
|
77
|
-
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, '
|
|
78
|
-
if (!this.shouldContinue) {
|
|
79
|
-
return step.execution;
|
|
80
|
-
}
|
|
81
|
-
tx = yield signer.sendTransaction(transactionRequest);
|
|
82
|
-
// STEP 4: Wait for Transaction ///////////////////////////////////////////
|
|
83
|
-
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
|
|
84
|
-
txHash: tx.hash,
|
|
85
|
-
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + tx.hash,
|
|
86
|
-
});
|
|
98
|
+
yield transaction.wait();
|
|
99
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE');
|
|
87
100
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
throw error;
|
|
101
|
+
catch (e) {
|
|
102
|
+
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
|
|
103
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE', {
|
|
104
|
+
txHash: e.replacement.hash,
|
|
105
|
+
txLink: fromChain.metamask.blockExplorerUrls[0] +
|
|
106
|
+
'tx/' +
|
|
107
|
+
e.replacement.hash,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const error = yield (0, parseError_1.parseError)(e, step, crossChainProcess);
|
|
112
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'FAILED', {
|
|
113
|
+
error: {
|
|
114
|
+
message: error.message,
|
|
115
|
+
htmlMessage: error.htmlMessage,
|
|
116
|
+
code: error.code,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
statusManager.updateExecution(step, 'FAILED');
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
110
122
|
}
|
|
111
123
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
let receivingChainProcess = statusManager.findOrCreateProcess('RECEIVING_CHAIN', step, 'PENDING');
|
|
124
|
+
// STEP 5: Wait for the receiving chain
|
|
125
|
+
let receivingChainProcess = statusManager.findOrCreateProcess(step, 'RECEIVING_CHAIN', 'PENDING');
|
|
115
126
|
let statusResponse;
|
|
116
127
|
try {
|
|
117
128
|
if (!crossChainProcess.txHash) {
|
|
118
129
|
throw new Error('Transaction hash is undefined.');
|
|
119
130
|
}
|
|
120
131
|
statusResponse = yield (0, utils_2.waitForReceivingTransaction)(crossChainProcess.txHash, statusManager, receivingChainProcess.type, step);
|
|
132
|
+
receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'DONE', {
|
|
133
|
+
substatus: statusResponse.substatus,
|
|
134
|
+
substatusMessage: statusResponse.substatusMessage ||
|
|
135
|
+
(0, utils_2.getSubstatusMessage)(statusResponse.status, statusResponse.substatus),
|
|
136
|
+
txHash: (_a = statusResponse.receiving) === null || _a === void 0 ? void 0 : _a.txHash,
|
|
137
|
+
txLink: toChain.metamask.blockExplorerUrls[0] +
|
|
138
|
+
'tx/' +
|
|
139
|
+
((_b = statusResponse.receiving) === null || _b === void 0 ? void 0 : _b.txHash),
|
|
140
|
+
});
|
|
141
|
+
statusManager.updateExecution(step, 'DONE', {
|
|
142
|
+
fromAmount: statusResponse.sending.amount,
|
|
143
|
+
toAmount: (_c = statusResponse.receiving) === null || _c === void 0 ? void 0 : _c.amount,
|
|
144
|
+
toToken: (_d = statusResponse.receiving) === null || _d === void 0 ? void 0 : _d.token,
|
|
145
|
+
gasUsed: statusResponse.sending.gasUsed,
|
|
146
|
+
gasPrice: statusResponse.sending.gasPrice,
|
|
147
|
+
});
|
|
121
148
|
}
|
|
122
149
|
catch (e) {
|
|
123
150
|
receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'FAILED', {
|
|
@@ -128,24 +155,9 @@ class BridgeExecutionManager {
|
|
|
128
155
|
},
|
|
129
156
|
});
|
|
130
157
|
statusManager.updateExecution(step, 'FAILED');
|
|
158
|
+
console.warn(e);
|
|
131
159
|
throw e;
|
|
132
160
|
}
|
|
133
|
-
receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'DONE', {
|
|
134
|
-
substatus: statusResponse.substatus,
|
|
135
|
-
substatusMessage: statusResponse.substatusMessage ||
|
|
136
|
-
(0, utils_2.getSubstatusMessage)(statusResponse.status, statusResponse.substatus),
|
|
137
|
-
txHash: (_a = statusResponse.receiving) === null || _a === void 0 ? void 0 : _a.txHash,
|
|
138
|
-
txLink: toChain.metamask.blockExplorerUrls[0] +
|
|
139
|
-
'tx/' +
|
|
140
|
-
((_b = statusResponse.receiving) === null || _b === void 0 ? void 0 : _b.txHash),
|
|
141
|
-
});
|
|
142
|
-
statusManager.updateExecution(step, 'DONE', {
|
|
143
|
-
fromAmount: statusResponse.sending.amount,
|
|
144
|
-
toAmount: (_c = statusResponse.receiving) === null || _c === void 0 ? void 0 : _c.amount,
|
|
145
|
-
toToken: (_d = statusResponse.receiving) === null || _d === void 0 ? void 0 : _d.token,
|
|
146
|
-
gasUsed: statusResponse.sending.gasUsed,
|
|
147
|
-
gasPrice: statusResponse.sending.gasPrice,
|
|
148
|
-
});
|
|
149
161
|
// DONE
|
|
150
162
|
return step.execution;
|
|
151
163
|
});
|
|
@@ -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
|
}
|
|
@@ -13,7 +13,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.SwapExecutionManager = void 0;
|
|
16
|
-
const ethers_1 = require("ethers");
|
|
17
16
|
const ApiService_1 = __importDefault(require("../../services/ApiService"));
|
|
18
17
|
const ChainsService_1 = __importDefault(require("../../services/ChainsService"));
|
|
19
18
|
const errors_1 = require("../../utils/errors");
|
|
@@ -27,84 +26,72 @@ const switchChain_1 = require("../switchChain");
|
|
|
27
26
|
const utils_2 = require("../utils");
|
|
28
27
|
class SwapExecutionManager {
|
|
29
28
|
constructor() {
|
|
30
|
-
this.
|
|
31
|
-
this.
|
|
32
|
-
this.
|
|
29
|
+
this.allowUserInteraction = true;
|
|
30
|
+
this.allowInteraction = (value) => {
|
|
31
|
+
this.allowUserInteraction = value;
|
|
33
32
|
};
|
|
34
33
|
this.execute = ({ signer, step, statusManager, settings, }) => __awaiter(this, void 0, void 0, function* () {
|
|
35
|
-
// setup
|
|
36
34
|
var _a, _b, _c, _d;
|
|
37
|
-
const { action, estimate } = step;
|
|
38
35
|
step.execution = statusManager.initExecutionObject(step);
|
|
39
36
|
const chainsService = ChainsService_1.default.getInstance();
|
|
40
|
-
const fromChain = yield chainsService.getChainById(action.fromChainId);
|
|
41
|
-
//
|
|
42
|
-
if (action.fromToken.address
|
|
43
|
-
yield (0, allowance_execute_1.checkAllowance)(signer, step,
|
|
37
|
+
const fromChain = yield chainsService.getChainById(step.action.fromChainId);
|
|
38
|
+
// STEP 1: Check allowance
|
|
39
|
+
if (!(0, utils_1.isZeroAddress)(step.action.fromToken.address)) {
|
|
40
|
+
yield (0, allowance_execute_1.checkAllowance)(signer, step, statusManager, settings, fromChain, this.allowUserInteraction);
|
|
44
41
|
}
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
let
|
|
48
|
-
// -> swapping
|
|
49
|
-
let tx;
|
|
42
|
+
// STEP 2: Get transaction
|
|
43
|
+
let swapProcess = statusManager.findOrCreateProcess(step, 'SWAP');
|
|
44
|
+
let transaction;
|
|
50
45
|
try {
|
|
51
46
|
if (swapProcess.txHash) {
|
|
52
|
-
//
|
|
53
|
-
|
|
47
|
+
// Make sure that the chain is still correct
|
|
48
|
+
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
|
|
49
|
+
if (!updatedSigner) {
|
|
50
|
+
// Chain switch was not successful, stop execution here
|
|
51
|
+
return step.execution;
|
|
52
|
+
}
|
|
53
|
+
signer = updatedSigner;
|
|
54
|
+
// Load exiting transaction
|
|
55
|
+
transaction = yield (0, getProvider_1.getProvider)(signer).getTransaction(swapProcess.txHash);
|
|
54
56
|
}
|
|
55
57
|
else {
|
|
56
|
-
|
|
58
|
+
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'STARTED');
|
|
59
|
+
// Check balance
|
|
57
60
|
yield (0, balanceCheck_execute_1.balanceCheck)(signer, step);
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
// Create new transaction
|
|
62
|
+
if (!step.transactionRequest) {
|
|
63
|
+
const personalizedStep = yield (0, utils_1.personalizeStep)(signer, step);
|
|
64
|
+
const updatedStep = yield ApiService_1.default.getStepTransaction(personalizedStep);
|
|
65
|
+
step = Object.assign(Object.assign({}, (yield (0, stepComparison_1.stepComparison)(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.allowUserInteraction))), { execution: step.execution });
|
|
66
|
+
}
|
|
62
67
|
const { transactionRequest } = step;
|
|
63
68
|
if (!transactionRequest) {
|
|
64
69
|
throw new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
|
|
65
70
|
}
|
|
66
|
-
//
|
|
67
|
-
|
|
71
|
+
// STEP 3: Send the transaction
|
|
72
|
+
// Make sure that the chain is still correct
|
|
73
|
+
const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
|
|
68
74
|
if (!updatedSigner) {
|
|
69
|
-
//
|
|
75
|
+
// Chain switch was not successful, stop execution here
|
|
70
76
|
return step.execution;
|
|
71
77
|
}
|
|
72
78
|
signer = updatedSigner;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return step.execution; // stop before user interaction is needed
|
|
79
|
+
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'ACTION_REQUIRED');
|
|
80
|
+
if (!this.allowUserInteraction) {
|
|
81
|
+
return step.execution;
|
|
77
82
|
}
|
|
78
|
-
//
|
|
79
|
-
|
|
83
|
+
// Submit the transaction
|
|
84
|
+
transaction = yield signer.sendTransaction(transactionRequest);
|
|
80
85
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
error: {
|
|
86
|
-
message: error.message,
|
|
87
|
-
htmlMessage: error.htmlMessage,
|
|
88
|
-
code: error.code,
|
|
89
|
-
},
|
|
86
|
+
// STEP 4: Wait for the transaction
|
|
87
|
+
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {
|
|
88
|
+
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + transaction.hash,
|
|
89
|
+
txHash: transaction.hash,
|
|
90
90
|
});
|
|
91
|
-
|
|
92
|
-
throw error;
|
|
93
|
-
}
|
|
94
|
-
// Wait for Transaction
|
|
95
|
-
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {
|
|
96
|
-
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + tx.hash,
|
|
97
|
-
txHash: tx.hash,
|
|
98
|
-
});
|
|
99
|
-
// -> waiting
|
|
100
|
-
let receipt;
|
|
101
|
-
try {
|
|
102
|
-
receipt = yield tx.wait();
|
|
91
|
+
yield transaction.wait();
|
|
103
92
|
}
|
|
104
93
|
catch (e) {
|
|
105
|
-
// -> set status
|
|
106
94
|
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
|
|
107
|
-
receipt = e.replacement;
|
|
108
95
|
swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {
|
|
109
96
|
txHash: e.replacement.hash,
|
|
110
97
|
txLink: fromChain.metamask.blockExplorerUrls[0] +
|
|
@@ -125,6 +112,7 @@ class SwapExecutionManager {
|
|
|
125
112
|
throw error;
|
|
126
113
|
}
|
|
127
114
|
}
|
|
115
|
+
// STEP 5: Wait for the receiving chain
|
|
128
116
|
let statusResponse;
|
|
129
117
|
try {
|
|
130
118
|
if (!swapProcess.txHash) {
|
|
@@ -29,8 +29,8 @@ const switchChain = (signer, statusManager, step, switchChainHook, allowUserInte
|
|
|
29
29
|
}
|
|
30
30
|
// -> set status message
|
|
31
31
|
step.execution = statusManager.initExecutionObject(step);
|
|
32
|
-
statusManager.updateExecution(step, '
|
|
33
|
-
let switchProcess = statusManager.findOrCreateProcess('SWITCH_CHAIN',
|
|
32
|
+
statusManager.updateExecution(step, 'ACTION_REQUIRED');
|
|
33
|
+
let switchProcess = statusManager.findOrCreateProcess(step, 'SWITCH_CHAIN', 'ACTION_REQUIRED');
|
|
34
34
|
if (!allowUserInteraction) {
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
@@ -48,7 +48,7 @@ const switchChain = (signer, statusManager, step, switchChainHook, allowUserInte
|
|
|
48
48
|
switchProcess = statusManager.updateProcess(step, switchProcess.type, 'FAILED', {
|
|
49
49
|
error: {
|
|
50
50
|
message: error.message,
|
|
51
|
-
code:
|
|
51
|
+
code: errors_1.LifiErrorCode.ChainSwitchError,
|
|
52
52
|
},
|
|
53
53
|
});
|
|
54
54
|
statusManager.updateExecution(step, 'FAILED');
|
package/dist/cjs/helpers.js
CHANGED
|
@@ -13,7 +13,7 @@ exports.checkPackageUpdates = exports.isSameToken = exports.getRandomNumber = ex
|
|
|
13
13
|
const version_1 = require("./version");
|
|
14
14
|
const ethereumRequest = (method, params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
15
|
// If ethereum.request() exists, the provider is probably EIP-1193 compliant.
|
|
16
|
-
if (!ethereum ||
|
|
16
|
+
if (!(ethereum === null || ethereum === void 0 ? void 0 : ethereum.request)) {
|
|
17
17
|
throw new Error('Provider not available.');
|
|
18
18
|
}
|
|
19
19
|
return ethereum.request({
|
|
@@ -16,6 +16,7 @@ const DefaultExecutionSettings = {
|
|
|
16
16
|
switchChainHook: () => Promise.resolve(undefined),
|
|
17
17
|
acceptSlippageUpdateHook: () => Promise.resolve(undefined),
|
|
18
18
|
infiniteApproval: false,
|
|
19
|
+
executeInBackground: false,
|
|
19
20
|
};
|
|
20
21
|
class ConfigService {
|
|
21
22
|
constructor() {
|
|
@@ -49,11 +50,11 @@ class ConfigService {
|
|
|
49
50
|
return this.config;
|
|
50
51
|
};
|
|
51
52
|
this.updateChains = (chains) => {
|
|
52
|
-
var _a;
|
|
53
|
+
var _a, _b;
|
|
53
54
|
for (const chain of chains) {
|
|
54
55
|
const chainId = chain.id;
|
|
55
56
|
// set RPCs if they were not configured by the user before
|
|
56
|
-
if (!this.config.rpcs[chainId].length) {
|
|
57
|
+
if (!((_a = this.config.rpcs[chainId]) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
57
58
|
this.config.rpcs[chainId] = chain.metamask.rpcUrls;
|
|
58
59
|
}
|
|
59
60
|
// set multicall addresses if they exist and were not configured by the user before
|
|
@@ -61,7 +62,7 @@ class ConfigService {
|
|
|
61
62
|
this.config.multicallAddresses[chainId] = chain.multicallAddress;
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
|
-
(
|
|
65
|
+
(_b = this.resolveSetupPromise) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
65
66
|
return this.config;
|
|
66
67
|
};
|
|
67
68
|
this.config = ConfigService.getDefaultConfig();
|
|
@@ -64,12 +64,14 @@ export interface ExecutionSettings {
|
|
|
64
64
|
switchChainHook?: SwitchChainHook;
|
|
65
65
|
acceptSlippageUpdateHook?: AcceptSlippageUpdateHook;
|
|
66
66
|
infiniteApproval?: boolean;
|
|
67
|
+
executeInBackground?: boolean;
|
|
67
68
|
}
|
|
68
69
|
export interface InternalExecutionSettings extends ExecutionSettings {
|
|
69
70
|
updateCallback: CallbackFunction;
|
|
70
71
|
switchChainHook: SwitchChainHook;
|
|
71
72
|
acceptSlippageUpdateHook: AcceptSlippageUpdateHook;
|
|
72
73
|
infiniteApproval: boolean;
|
|
74
|
+
executeInBackground: boolean;
|
|
73
75
|
}
|
|
74
76
|
export declare type EnforcedObjectProperties<T> = T & {
|
|
75
77
|
[P in keyof T]-?: T[P];
|
|
@@ -81,7 +83,9 @@ export declare type RevokeTokenData = {
|
|
|
81
83
|
token: Token;
|
|
82
84
|
approvalAddress: string;
|
|
83
85
|
};
|
|
84
|
-
export interface
|
|
86
|
+
export interface InteractionSettings {
|
|
87
|
+
allowInteraction?: boolean;
|
|
85
88
|
allowUpdates?: boolean;
|
|
89
|
+
stopExecution?: boolean;
|
|
86
90
|
}
|
|
87
91
|
export {};
|
|
@@ -77,7 +77,7 @@ const getTransactionFailedMessage = (step, txLink) => {
|
|
|
77
77
|
};
|
|
78
78
|
exports.getTransactionFailedMessage = getTransactionFailedMessage;
|
|
79
79
|
const parseError = (e, step, process) => __awaiter(void 0, void 0, void 0, function* () {
|
|
80
|
-
var _a, _b;
|
|
80
|
+
var _a, _b, _c;
|
|
81
81
|
if (e instanceof errors_1.LifiError) {
|
|
82
82
|
return e;
|
|
83
83
|
}
|
|
@@ -88,12 +88,11 @@ const parseError = (e, step, process) => __awaiter(void 0, void 0, void 0, funct
|
|
|
88
88
|
// rpc errors
|
|
89
89
|
// underpriced errors are sent as internal errors, so we need to parse the message manually
|
|
90
90
|
if (e.code === eth_rpc_errors_1.errorCodes.rpc.internal &&
|
|
91
|
-
e.message
|
|
92
|
-
e.message.includes('underpriced')) {
|
|
91
|
+
((_a = e.message) === null || _a === void 0 ? void 0 : _a.includes('underpriced'))) {
|
|
93
92
|
return new errors_1.RPCError(errors_1.LifiErrorCode.TransactionUnderpriced, 'Transaction is underpriced.', yield (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
|
|
94
93
|
}
|
|
95
|
-
if (((
|
|
96
|
-
((
|
|
94
|
+
if (((_b = e.message) === null || _b === void 0 ? void 0 : _b.includes('intrinsic gas too low')) ||
|
|
95
|
+
((_c = e.message) === null || _c === void 0 ? void 0 : _c.includes('out of gas'))) {
|
|
97
96
|
return new errors_1.TransactionError(errors_1.LifiErrorCode.GasLimitError, 'Gas limit is too low.', yield (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
|
|
98
97
|
}
|
|
99
98
|
return new errors_1.RPCError(e.code, (0, eth_rpc_errors_1.getMessageFromCode)(e.code), yield (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
|
|
@@ -9,6 +9,7 @@ const handlePreRestart = (route) => {
|
|
|
9
9
|
if (stepHasFailed) {
|
|
10
10
|
handleErrorType(route, index);
|
|
11
11
|
deleteFailedProcesses(route, index);
|
|
12
|
+
deleteTransactionData(route, index);
|
|
12
13
|
}
|
|
13
14
|
}
|
|
14
15
|
};
|
|
@@ -26,6 +27,9 @@ const handleErrorType = (route, index) => {
|
|
|
26
27
|
};
|
|
27
28
|
const deleteFailedProcesses = (route, index) => {
|
|
28
29
|
if (route.steps[index].execution) {
|
|
29
|
-
route.steps[index].execution.process = route.steps[index].execution.process.filter((process) => process.status
|
|
30
|
+
route.steps[index].execution.process = route.steps[index].execution.process.filter((process) => process.status === 'DONE');
|
|
30
31
|
}
|
|
31
32
|
};
|
|
33
|
+
const deleteTransactionData = (route, index) => {
|
|
34
|
+
route.steps[index].transactionRequest = undefined;
|
|
35
|
+
};
|
package/dist/cjs/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const name = "@lifi/sdk";
|
|
2
|
-
export declare const version = "1.
|
|
2
|
+
export declare const version = "1.5.0";
|
package/dist/cjs/version.js
CHANGED