@lifi/sdk 1.1.0 → 1.1.3
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 +21 -0
- package/dist/Lifi.d.ts +1 -1
- package/dist/Lifi.js +179 -285
- package/dist/allowance/index.js +56 -148
- package/dist/allowance/utils.js +51 -116
- package/dist/balances/index.js +29 -92
- package/dist/balances/utils.js +108 -218
- package/dist/connectors.js +50 -133
- package/dist/execution/StatusManager.js +38 -40
- package/dist/execution/StepExecutor.js +54 -123
- package/dist/execution/allowance.execute.js +77 -143
- package/dist/execution/balanceCheck.execute.js +29 -74
- package/dist/execution/bridges/bridge.execute.js +132 -221
- package/dist/execution/exchanges/swap.execute.js +142 -225
- package/dist/execution/index.js +1 -17
- package/dist/execution/stepComparison.js +22 -61
- package/dist/execution/switchChain.js +33 -81
- package/dist/execution/utils.js +60 -119
- package/dist/helpers.js +15 -53
- package/dist/index.js +6 -25
- package/dist/services/ApiService.js +248 -385
- package/dist/services/ChainsService.js +29 -89
- package/dist/services/ConfigService.js +47 -86
- package/dist/typeguards.js +13 -21
- package/dist/types/ERC20.js +1 -4
- package/dist/types/index.js +4 -22
- package/dist/types/internal.types.js +1 -2
- package/dist/utils/errors.js +47 -93
- package/dist/utils/getProvider.js +3 -7
- package/dist/utils/multicall.js +61 -117
- package/dist/utils/parseError.js +73 -141
- package/dist/utils/preRestart.js +14 -21
- package/dist/utils/utils.js +47 -130
- package/package.json +3 -3
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
2
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
3
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -8,79 +7,35 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
8
|
});
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
10
|
+
import BigNumber from 'bignumber.js';
|
|
11
|
+
import balances from '../balances';
|
|
12
|
+
import { ValidationError } from '../utils/errors';
|
|
13
|
+
export const balanceCheck = (signer, step) => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
|
+
const tokenAmount = yield balances.getTokenBalance(yield signer.getAddress(), step.action.fromToken);
|
|
15
|
+
if (tokenAmount) {
|
|
16
|
+
const currentBalance = new BigNumber(tokenAmount.amount).shiftedBy(tokenAmount.decimals);
|
|
17
|
+
const neededBalance = new BigNumber(step.action.fromAmount);
|
|
18
|
+
if (currentBalance.lt(neededBalance)) {
|
|
19
|
+
if (neededBalance.multipliedBy(1 - step.action.slippage).lte(currentBalance)) {
|
|
20
|
+
// adjust amount in slippage limits
|
|
21
|
+
step.action.fromAmount = currentBalance.toFixed(0);
|
|
32
22
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
var balanceCheck = function (signer, step) { return __awaiter(void 0, void 0, void 0, function () {
|
|
47
|
-
var tokenAmount, _a, _b, currentBalance, neededBalance, neeeded, current, errorMessage;
|
|
48
|
-
return __generator(this, function (_c) {
|
|
49
|
-
switch (_c.label) {
|
|
50
|
-
case 0:
|
|
51
|
-
_b = (_a = balances_1.default).getTokenBalance;
|
|
52
|
-
return [4 /*yield*/, signer.getAddress()];
|
|
53
|
-
case 1: return [4 /*yield*/, _b.apply(_a, [_c.sent(), step.action.fromToken])];
|
|
54
|
-
case 2:
|
|
55
|
-
tokenAmount = _c.sent();
|
|
56
|
-
if (tokenAmount) {
|
|
57
|
-
currentBalance = new bignumber_js_1.default(tokenAmount.amount).shiftedBy(tokenAmount.decimals);
|
|
58
|
-
neededBalance = new bignumber_js_1.default(step.action.fromAmount);
|
|
59
|
-
if (currentBalance.lt(neededBalance)) {
|
|
60
|
-
if (neededBalance.multipliedBy(1 - step.action.slippage).lte(currentBalance)) {
|
|
61
|
-
// adjust amount in slippage limits
|
|
62
|
-
step.action.fromAmount = currentBalance.toFixed(0);
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
neeeded = neededBalance.shiftedBy(-tokenAmount.decimals).toFixed();
|
|
66
|
-
current = currentBalance
|
|
67
|
-
.shiftedBy(-tokenAmount.decimals)
|
|
68
|
-
.toFixed();
|
|
69
|
-
errorMessage = "Your ".concat(tokenAmount.symbol, " balance is too low, ") +
|
|
70
|
-
"you try to transfer ".concat(neeeded, " ").concat(tokenAmount.symbol, ", ") +
|
|
71
|
-
"but your wallet only holds ".concat(current, " ").concat(tokenAmount.symbol, ". ") +
|
|
72
|
-
"No funds have been sent. ";
|
|
73
|
-
if (!currentBalance.isZero()) {
|
|
74
|
-
errorMessage +=
|
|
75
|
-
"If the problem consists, please delete this transfer and " +
|
|
76
|
-
"start a new one with a maximum of ".concat(current, " ").concat(tokenAmount.symbol, ".");
|
|
77
|
-
}
|
|
78
|
-
throw new errors_1.ValidationError('The balance is too low.', errorMessage);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
23
|
+
else {
|
|
24
|
+
const neeeded = neededBalance.shiftedBy(-tokenAmount.decimals).toFixed();
|
|
25
|
+
const current = currentBalance
|
|
26
|
+
.shiftedBy(-tokenAmount.decimals)
|
|
27
|
+
.toFixed();
|
|
28
|
+
let errorMessage = `Your ${tokenAmount.symbol} balance is too low, ` +
|
|
29
|
+
`you try to transfer ${neeeded} ${tokenAmount.symbol}, ` +
|
|
30
|
+
`but your wallet only holds ${current} ${tokenAmount.symbol}. ` +
|
|
31
|
+
`No funds have been sent. `;
|
|
32
|
+
if (!currentBalance.isZero()) {
|
|
33
|
+
errorMessage +=
|
|
34
|
+
`If the problem consists, please delete this transfer and ` +
|
|
35
|
+
`start a new one with a maximum of ${current} ${tokenAmount.symbol}.`;
|
|
81
36
|
}
|
|
82
|
-
|
|
37
|
+
throw new ValidationError('The balance is too low.', errorMessage);
|
|
38
|
+
}
|
|
83
39
|
}
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
exports.balanceCheck = balanceCheck;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
1
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
2
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
3
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -19,218 +7,141 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
19
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
8
|
});
|
|
21
9
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
default:
|
|
37
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
-
if (t[2]) _.ops.pop();
|
|
42
|
-
_.trys.pop(); continue;
|
|
43
|
-
}
|
|
44
|
-
op = body.call(thisArg, _);
|
|
45
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
50
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
51
|
-
};
|
|
52
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
-
exports.BridgeExecutionManager = void 0;
|
|
54
|
-
var ethers_1 = require("ethers");
|
|
55
|
-
var ApiService_1 = __importDefault(require("../../services/ApiService"));
|
|
56
|
-
var ChainsService_1 = __importDefault(require("../../services/ChainsService"));
|
|
57
|
-
var errors_1 = require("../../utils/errors");
|
|
58
|
-
var getProvider_1 = require("../../utils/getProvider");
|
|
59
|
-
var parseError_1 = require("../../utils/parseError");
|
|
60
|
-
var utils_1 = require("../../utils/utils");
|
|
61
|
-
var allowance_execute_1 = require("../allowance.execute");
|
|
62
|
-
var balanceCheck_execute_1 = require("../balanceCheck.execute");
|
|
63
|
-
var stepComparison_1 = require("../stepComparison");
|
|
64
|
-
var switchChain_1 = require("../switchChain");
|
|
65
|
-
var utils_2 = require("../utils");
|
|
66
|
-
var BridgeExecutionManager = /** @class */ (function () {
|
|
67
|
-
function BridgeExecutionManager() {
|
|
68
|
-
var _this = this;
|
|
10
|
+
import { constants } from 'ethers';
|
|
11
|
+
import ApiService from '../../services/ApiService';
|
|
12
|
+
import ChainsService from '../../services/ChainsService';
|
|
13
|
+
import { LifiErrorCode, TransactionError } from '../../utils/errors';
|
|
14
|
+
import { getProvider } from '../../utils/getProvider';
|
|
15
|
+
import { getTransactionFailedMessage, parseError } from '../../utils/parseError';
|
|
16
|
+
import { personalizeStep } from '../../utils/utils';
|
|
17
|
+
import { checkAllowance } from '../allowance.execute';
|
|
18
|
+
import { balanceCheck } from '../balanceCheck.execute';
|
|
19
|
+
import { stepComparison } from '../stepComparison';
|
|
20
|
+
import { switchChain } from '../switchChain';
|
|
21
|
+
import { getSubstatusMessage, waitForReceivingTransaction } from '../utils';
|
|
22
|
+
export class BridgeExecutionManager {
|
|
23
|
+
constructor() {
|
|
69
24
|
this.shouldContinue = true;
|
|
70
|
-
this.setShouldContinue =
|
|
71
|
-
|
|
25
|
+
this.setShouldContinue = (val) => {
|
|
26
|
+
this.shouldContinue = val;
|
|
72
27
|
};
|
|
73
|
-
this.execute = function (
|
|
74
|
-
var
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
case 7:
|
|
115
|
-
// check balance
|
|
116
|
-
return [4 /*yield*/, (0, balanceCheck_execute_1.balanceCheck)(signer, step)
|
|
117
|
-
// create new transaction
|
|
118
|
-
];
|
|
119
|
-
case 8:
|
|
120
|
-
// check balance
|
|
121
|
-
_g.sent();
|
|
122
|
-
return [4 /*yield*/, (0, utils_1.personalizeStep)(signer, step)];
|
|
123
|
-
case 9:
|
|
124
|
-
personalizedStep = _g.sent();
|
|
125
|
-
return [4 /*yield*/, ApiService_1.default.getStepTransaction(personalizedStep)];
|
|
126
|
-
case 10:
|
|
127
|
-
updatedStep = _g.sent();
|
|
128
|
-
_b = [{}];
|
|
129
|
-
return [4 /*yield*/, (0, stepComparison_1.stepComparison)(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.shouldContinue)];
|
|
130
|
-
case 11:
|
|
131
|
-
step = __assign.apply(void 0, [__assign.apply(void 0, _b.concat([(_g.sent())])), { execution: step.execution }]);
|
|
132
|
-
transactionRequest = step.transactionRequest;
|
|
133
|
-
if (!transactionRequest) {
|
|
134
|
-
throw new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
|
|
135
|
-
}
|
|
136
|
-
return [4 /*yield*/, (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.shouldContinue)];
|
|
137
|
-
case 12:
|
|
138
|
-
updatedSigner = _g.sent();
|
|
139
|
-
if (!updatedSigner) {
|
|
140
|
-
// chain switch was not successful, stop execution here
|
|
141
|
-
return [2 /*return*/, step.execution];
|
|
142
|
-
}
|
|
143
|
-
signer = updatedSigner;
|
|
144
|
-
statusManager.updateProcess(step, crossChainProcess.type, 'ACTION_REQUIRED');
|
|
145
|
-
if (!this.shouldContinue) {
|
|
146
|
-
return [2 /*return*/, step.execution];
|
|
147
|
-
}
|
|
148
|
-
return [4 /*yield*/, signer.sendTransaction(transactionRequest)
|
|
149
|
-
// STEP 4: Wait for Transaction ///////////////////////////////////////////
|
|
150
|
-
];
|
|
151
|
-
case 13:
|
|
152
|
-
tx = _g.sent();
|
|
153
|
-
// STEP 4: Wait for Transaction ///////////////////////////////////////////
|
|
154
|
-
statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
|
|
155
|
-
txHash: tx.hash,
|
|
156
|
-
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + tx.hash,
|
|
157
|
-
});
|
|
158
|
-
_g.label = 14;
|
|
159
|
-
case 14: return [4 /*yield*/, tx.wait()];
|
|
160
|
-
case 15:
|
|
161
|
-
_g.sent();
|
|
162
|
-
return [3 /*break*/, 20];
|
|
163
|
-
case 16:
|
|
164
|
-
e_1 = _g.sent();
|
|
165
|
-
if (!(e_1.code === 'TRANSACTION_REPLACED' && e_1.replacement)) return [3 /*break*/, 17];
|
|
166
|
-
statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
|
|
167
|
-
txHash: e_1.replacement.hash,
|
|
168
|
-
txLink: fromChain.metamask.blockExplorerUrls[0] +
|
|
169
|
-
'tx/' +
|
|
170
|
-
e_1.replacement.hash,
|
|
171
|
-
});
|
|
172
|
-
return [3 /*break*/, 19];
|
|
173
|
-
case 17: return [4 /*yield*/, (0, parseError_1.parseError)(e_1, step, crossChainProcess)];
|
|
174
|
-
case 18:
|
|
175
|
-
error = _g.sent();
|
|
176
|
-
statusManager.updateProcess(step, crossChainProcess.type, 'FAILED', {
|
|
177
|
-
error: {
|
|
178
|
-
message: error.message,
|
|
179
|
-
htmlMessage: error.htmlMessage,
|
|
180
|
-
code: error.code,
|
|
181
|
-
},
|
|
182
|
-
});
|
|
183
|
-
statusManager.updateExecution(step, 'FAILED');
|
|
184
|
-
throw error;
|
|
185
|
-
case 19: return [3 /*break*/, 20];
|
|
186
|
-
case 20:
|
|
187
|
-
statusManager.updateProcess(step, crossChainProcess.type, 'DONE');
|
|
188
|
-
receivingChainProcess = statusManager.findOrCreateProcess('RECEIVING_CHAIN', step, 'PENDING');
|
|
189
|
-
_g.label = 21;
|
|
190
|
-
case 21:
|
|
191
|
-
_g.trys.push([21, 23, , 24]);
|
|
192
|
-
if (!crossChainProcess.txHash) {
|
|
193
|
-
throw new Error('Transaction hash is undefined.');
|
|
194
|
-
}
|
|
195
|
-
return [4 /*yield*/, (0, utils_2.waitForReceivingTransaction)(crossChainProcess.txHash, statusManager, receivingChainProcess.type, step)];
|
|
196
|
-
case 22:
|
|
197
|
-
statusResponse = _g.sent();
|
|
198
|
-
return [3 /*break*/, 24];
|
|
199
|
-
case 23:
|
|
200
|
-
e_2 = _g.sent();
|
|
201
|
-
statusManager.updateProcess(step, receivingChainProcess.type, 'FAILED', {
|
|
202
|
-
error: {
|
|
203
|
-
code: errors_1.LifiErrorCode.TransactionFailed,
|
|
204
|
-
message: 'Failed while waiting for receiving chain.',
|
|
205
|
-
htmlMessage: (0, parseError_1.getTransactionFailedMessage)(step, crossChainProcess.txLink),
|
|
206
|
-
},
|
|
207
|
-
});
|
|
208
|
-
statusManager.updateExecution(step, 'FAILED');
|
|
209
|
-
throw e_2;
|
|
210
|
-
case 24:
|
|
211
|
-
statusManager.updateProcess(step, receivingChainProcess.type, 'DONE', {
|
|
212
|
-
substatus: statusResponse.substatus,
|
|
213
|
-
substatusMessage: statusResponse.substatusMessage ||
|
|
214
|
-
(0, utils_2.getSubstatusMessage)(statusResponse.status, statusResponse.substatus),
|
|
215
|
-
txHash: (_c = statusResponse.receiving) === null || _c === void 0 ? void 0 : _c.txHash,
|
|
216
|
-
txLink: toChain.metamask.blockExplorerUrls[0] +
|
|
217
|
-
'tx/' +
|
|
218
|
-
((_d = statusResponse.receiving) === null || _d === void 0 ? void 0 : _d.txHash),
|
|
219
|
-
});
|
|
220
|
-
statusManager.updateExecution(step, 'DONE', {
|
|
221
|
-
fromAmount: statusResponse.sending.amount,
|
|
222
|
-
toAmount: (_e = statusResponse.receiving) === null || _e === void 0 ? void 0 : _e.amount,
|
|
223
|
-
toToken: (_f = statusResponse.receiving) === null || _f === void 0 ? void 0 : _f.token,
|
|
224
|
-
gasUsed: statusResponse.sending.gasUsed,
|
|
225
|
-
gasPrice: statusResponse.sending.gasPrice,
|
|
226
|
-
});
|
|
227
|
-
// DONE
|
|
228
|
-
return [2 /*return*/, step.execution];
|
|
28
|
+
this.execute = ({ signer, step, statusManager, settings, }) => __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
var _a, _b, _c, _d;
|
|
30
|
+
const { action, estimate } = step;
|
|
31
|
+
step.execution = statusManager.initExecutionObject(step);
|
|
32
|
+
const chainsService = ChainsService.getInstance();
|
|
33
|
+
const fromChain = yield chainsService.getChainById(action.fromChainId);
|
|
34
|
+
const toChain = yield chainsService.getChainById(action.toChainId);
|
|
35
|
+
// STEP 1: Check Allowance ////////////////////////////////////////////////
|
|
36
|
+
// approval still needed?
|
|
37
|
+
const oldCrossProcess = step.execution.process.find((p) => p.type === 'CROSS_CHAIN');
|
|
38
|
+
if (!(oldCrossProcess === null || oldCrossProcess === void 0 ? void 0 : oldCrossProcess.txHash)) {
|
|
39
|
+
if (action.fromToken.address !== constants.AddressZero) {
|
|
40
|
+
// Check Token Approval only if fromToken is not the native token => no approval needed in that case
|
|
41
|
+
yield checkAllowance(signer, step, fromChain, action.fromToken, action.fromAmount, estimate.approvalAddress, statusManager, settings.infiniteApproval, this.shouldContinue);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// STEP 2: Get Transaction ////////////////////////////////////////////////
|
|
45
|
+
let crossChainProcess = statusManager.findOrCreateProcess('CROSS_CHAIN', step);
|
|
46
|
+
try {
|
|
47
|
+
let tx;
|
|
48
|
+
if (crossChainProcess.txHash) {
|
|
49
|
+
// load exiting transaction
|
|
50
|
+
tx = yield getProvider(signer).getTransaction(crossChainProcess.txHash);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// check balance
|
|
54
|
+
yield balanceCheck(signer, step);
|
|
55
|
+
// create new transaction
|
|
56
|
+
const personalizedStep = yield personalizeStep(signer, step);
|
|
57
|
+
const updatedStep = yield ApiService.getStepTransaction(personalizedStep);
|
|
58
|
+
step = Object.assign(Object.assign({}, (yield stepComparison(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.shouldContinue))), { execution: step.execution });
|
|
59
|
+
const { transactionRequest } = step;
|
|
60
|
+
if (!transactionRequest) {
|
|
61
|
+
throw new TransactionError(LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
|
|
62
|
+
}
|
|
63
|
+
// STEP 3: Send Transaction ///////////////////////////////////////////////
|
|
64
|
+
// make sure that chain is still correct
|
|
65
|
+
const updatedSigner = yield switchChain(signer, statusManager, step, settings.switchChainHook, this.shouldContinue);
|
|
66
|
+
if (!updatedSigner) {
|
|
67
|
+
// chain switch was not successful, stop execution here
|
|
68
|
+
return step.execution;
|
|
229
69
|
}
|
|
70
|
+
signer = updatedSigner;
|
|
71
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'ACTION_REQUIRED');
|
|
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
|
+
});
|
|
81
|
+
}
|
|
82
|
+
yield tx.wait();
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
|
|
86
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
|
|
87
|
+
txHash: e.replacement.hash,
|
|
88
|
+
txLink: fromChain.metamask.blockExplorerUrls[0] +
|
|
89
|
+
'tx/' +
|
|
90
|
+
e.replacement.hash,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
const error = yield parseError(e, step, crossChainProcess);
|
|
95
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'FAILED', {
|
|
96
|
+
error: {
|
|
97
|
+
message: error.message,
|
|
98
|
+
htmlMessage: error.htmlMessage,
|
|
99
|
+
code: error.code,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
statusManager.updateExecution(step, 'FAILED');
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE');
|
|
107
|
+
// STEP 5: Wait for Receiver //////////////////////////////////////
|
|
108
|
+
let receivingChainProcess = statusManager.findOrCreateProcess('RECEIVING_CHAIN', step, 'PENDING');
|
|
109
|
+
let statusResponse;
|
|
110
|
+
try {
|
|
111
|
+
if (!crossChainProcess.txHash) {
|
|
112
|
+
throw new Error('Transaction hash is undefined.');
|
|
113
|
+
}
|
|
114
|
+
statusResponse = yield waitForReceivingTransaction(crossChainProcess.txHash, statusManager, receivingChainProcess.type, step);
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'FAILED', {
|
|
118
|
+
error: {
|
|
119
|
+
code: LifiErrorCode.TransactionFailed,
|
|
120
|
+
message: 'Failed while waiting for receiving chain.',
|
|
121
|
+
htmlMessage: getTransactionFailedMessage(step, crossChainProcess.txLink),
|
|
122
|
+
},
|
|
230
123
|
});
|
|
124
|
+
statusManager.updateExecution(step, 'FAILED');
|
|
125
|
+
throw e;
|
|
126
|
+
}
|
|
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),
|
|
231
135
|
});
|
|
232
|
-
|
|
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
|
+
// DONE
|
|
144
|
+
return step.execution;
|
|
145
|
+
});
|
|
233
146
|
}
|
|
234
|
-
|
|
235
|
-
}());
|
|
236
|
-
exports.BridgeExecutionManager = BridgeExecutionManager;
|
|
147
|
+
}
|