@lifi/sdk 1.7.2 → 2.0.0-beta.1
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/Lifi.js +97 -85
- package/dist/allowance/checkAllowance.js +12 -21
- package/dist/allowance/tokenApproval.js +20 -29
- package/dist/allowance/utils.js +12 -24
- package/dist/balance/checkBalance.js +5 -14
- package/dist/balance/getTokenBalance.js +12 -21
- package/dist/balance/index.d.ts +11 -0
- package/dist/balance/index.js +8 -0
- package/dist/balance/utils.d.ts +1 -0
- package/dist/balance/utils.js +36 -38
- package/dist/cjs/Lifi.js +97 -85
- package/dist/cjs/allowance/checkAllowance.js +12 -21
- package/dist/cjs/allowance/tokenApproval.js +20 -29
- package/dist/cjs/allowance/utils.js +12 -24
- package/dist/cjs/balance/checkBalance.js +5 -14
- package/dist/cjs/balance/getTokenBalance.js +12 -21
- package/dist/cjs/balance/index.d.ts +11 -0
- package/dist/cjs/balance/index.js +8 -0
- package/dist/cjs/balance/utils.d.ts +1 -0
- package/dist/cjs/balance/utils.js +39 -39
- package/dist/cjs/connectors.js +17 -25
- package/dist/cjs/execution/ExecutionManager.js +27 -33
- package/dist/cjs/execution/StatusManager.js +13 -13
- package/dist/cjs/execution/StepExecutor.js +8 -14
- package/dist/cjs/execution/stepComparison.js +4 -14
- package/dist/cjs/execution/switchChain.js +5 -14
- package/dist/cjs/execution/utils.js +43 -50
- package/dist/cjs/helpers.d.ts +12 -1
- package/dist/cjs/helpers.js +66 -18
- package/dist/cjs/services/ApiService.d.ts +10 -9
- package/dist/cjs/services/ApiService.js +190 -152
- package/dist/cjs/services/ApiService.unit.handlers.d.ts +1 -0
- package/dist/cjs/services/ApiService.unit.handlers.js +50 -0
- package/dist/cjs/services/ChainsService.js +16 -31
- package/dist/cjs/services/ConfigService.js +6 -16
- package/dist/cjs/typeguards.js +1 -1
- package/dist/cjs/types/internal.types.d.ts +4 -1
- package/dist/cjs/utils/errors.d.ts +5 -0
- package/dist/cjs/utils/errors.js +14 -1
- package/dist/cjs/utils/multicall.js +6 -15
- package/dist/cjs/utils/parseError.d.ts +2 -2
- package/dist/cjs/utils/parseError.js +36 -38
- package/dist/cjs/utils/preRestart.js +5 -7
- package/dist/cjs/utils/utils.d.ts +0 -1
- package/dist/cjs/utils/utils.js +21 -28
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/connectors.js +15 -23
- package/dist/execution/ExecutionManager.js +27 -33
- package/dist/execution/StatusManager.js +11 -11
- package/dist/execution/StepExecutor.js +8 -14
- package/dist/execution/stepComparison.js +4 -14
- package/dist/execution/switchChain.js +5 -14
- package/dist/execution/utils.js +43 -50
- package/dist/helpers.d.ts +12 -1
- package/dist/helpers.js +63 -17
- package/dist/services/ApiService.d.ts +10 -9
- package/dist/services/ApiService.js +190 -152
- package/dist/services/ApiService.unit.handlers.d.ts +1 -0
- package/dist/services/ApiService.unit.handlers.js +44 -0
- package/dist/services/ChainsService.js +16 -31
- package/dist/services/ConfigService.js +6 -16
- package/dist/typeguards.js +1 -1
- package/dist/types/internal.types.d.ts +4 -1
- package/dist/utils/errors.d.ts +5 -0
- package/dist/utils/errors.js +12 -0
- package/dist/utils/multicall.js +6 -15
- package/dist/utils/parseError.d.ts +2 -2
- package/dist/utils/parseError.js +36 -38
- package/dist/utils/preRestart.js +5 -7
- package/dist/utils/utils.d.ts +0 -1
- package/dist/utils/utils.js +20 -26
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +22 -24
- package/CHANGELOG.md +0 -492
package/dist/Lifi.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { approveToken, bulkGetTokenApproval, getTokenApproval, revokeTokenApproval, } from './allowance';
|
|
11
2
|
import * as balance from './balance';
|
|
12
3
|
import { getRpcProvider } from './connectors';
|
|
@@ -19,7 +10,6 @@ import ConfigService from './services/ConfigService';
|
|
|
19
10
|
import { isToken } from './typeguards';
|
|
20
11
|
import { ValidationError } from './utils/errors';
|
|
21
12
|
import { handlePreRestart } from './utils/preRestart';
|
|
22
|
-
import { deepClone } from './utils/utils';
|
|
23
13
|
import { name, version } from './version';
|
|
24
14
|
export default class LIFI {
|
|
25
15
|
constructor(configUpdate) {
|
|
@@ -61,84 +51,84 @@ export default class LIFI {
|
|
|
61
51
|
* @return {Promise<PossibilitiesResponse>} Object listing current possibilities for any-to-any cross-chain-swaps based on the provided preferences.
|
|
62
52
|
* @throws {LifiError} Throws a LifiError if request fails.
|
|
63
53
|
*/
|
|
64
|
-
this.getPossibilities = (request, options) =>
|
|
54
|
+
this.getPossibilities = async (request, options) => {
|
|
65
55
|
return ApiService.getPossibilities(request, options);
|
|
66
|
-
}
|
|
56
|
+
};
|
|
67
57
|
/**
|
|
68
58
|
* Fetch information about a Token
|
|
69
59
|
* @param {ChainKey | ChainId} chain - Id or key of the chain that contains the token
|
|
70
60
|
* @param {string} token - Address or symbol of the token on the requested chain
|
|
71
61
|
* @throws {LifiError} - Throws a LifiError if request fails
|
|
72
62
|
*/
|
|
73
|
-
this.getToken = (chain, token, options) =>
|
|
63
|
+
this.getToken = async (chain, token, options) => {
|
|
74
64
|
return ApiService.getToken(chain, token, options);
|
|
75
|
-
}
|
|
65
|
+
};
|
|
76
66
|
/**
|
|
77
67
|
* Get a quote for a token transfer
|
|
78
68
|
* @param {QuoteRequest} request - The configuration of the requested quote
|
|
79
69
|
* @throws {LifiError} - Throws a LifiError if request fails
|
|
80
70
|
*/
|
|
81
|
-
this.getQuote = (request, options) =>
|
|
71
|
+
this.getQuote = async (request, options) => {
|
|
82
72
|
return ApiService.getQuote(request, options);
|
|
83
|
-
}
|
|
73
|
+
};
|
|
84
74
|
/**
|
|
85
75
|
* Get a quote for a destination contract call
|
|
86
76
|
* @param {ContractCallQuoteRequest} request - The configuration of the requested destination call
|
|
87
77
|
* @throws {LifiError} - Throws a LifiError if request fails
|
|
88
78
|
*/
|
|
89
|
-
this.getContractCallQuote = (request, options) =>
|
|
79
|
+
this.getContractCallQuote = async (request, options) => {
|
|
90
80
|
return ApiService.getContractCallQuote(request, options);
|
|
91
|
-
}
|
|
81
|
+
};
|
|
92
82
|
/**
|
|
93
83
|
* Check the status of a transfer. For cross chain transfers, the "bridge" parameter is required.
|
|
94
84
|
* @param {GetStatusRequest} request - Configuration of the requested status
|
|
95
85
|
* @throws {LifiError} - Throws a LifiError if request fails
|
|
96
86
|
*/
|
|
97
|
-
this.getStatus = (request, options) =>
|
|
87
|
+
this.getStatus = async (request, options) => {
|
|
98
88
|
return ApiService.getStatus(request, options);
|
|
99
|
-
}
|
|
89
|
+
};
|
|
100
90
|
/**
|
|
101
91
|
* Get the available tools to bridge and swap tokens.
|
|
102
92
|
* @param {ToolsRequest?} request - The configuration of the requested tools
|
|
103
93
|
* @returns The tools that are available on the requested chains
|
|
104
94
|
*/
|
|
105
|
-
this.getTools = (request, options) =>
|
|
95
|
+
this.getTools = async (request, options) => {
|
|
106
96
|
return ApiService.getTools(request || {}, options);
|
|
107
|
-
}
|
|
97
|
+
};
|
|
108
98
|
/**
|
|
109
99
|
* Get all known tokens.
|
|
110
100
|
* @param {TokensRequest?} request - The configuration of the requested tokens
|
|
111
101
|
* @returns The tokens that are available on the requested chains
|
|
112
102
|
*/
|
|
113
|
-
this.getTokens = (request, options) =>
|
|
103
|
+
this.getTokens = async (request, options) => {
|
|
114
104
|
return ApiService.getTokens(request || {}, options);
|
|
115
|
-
}
|
|
105
|
+
};
|
|
116
106
|
/**
|
|
117
107
|
* Get all available chains
|
|
118
108
|
* @return {Promise<Chain[]>} A list of all available chains
|
|
119
109
|
* @throws {LifiError} Throws a LifiError if request fails.
|
|
120
110
|
*/
|
|
121
|
-
this.getChains = () =>
|
|
111
|
+
this.getChains = async () => {
|
|
122
112
|
return this.chainsService.getChains();
|
|
123
|
-
}
|
|
113
|
+
};
|
|
124
114
|
/**
|
|
125
115
|
* Get a set of routes for a request that describes a transfer of tokens.
|
|
126
116
|
* @param {RoutesRequest} routesRequest - A description of the transfer.
|
|
127
117
|
* @return {Promise<RoutesResponse>} The resulting routes that can be used to realize the described transfer of tokens.
|
|
128
118
|
* @throws {LifiError} Throws a LifiError if request fails.
|
|
129
119
|
*/
|
|
130
|
-
this.getRoutes = (request, options) =>
|
|
120
|
+
this.getRoutes = async (request, options) => {
|
|
131
121
|
return ApiService.getRoutes(request, options);
|
|
132
|
-
}
|
|
122
|
+
};
|
|
133
123
|
/**
|
|
134
124
|
* Get the transaction data for a single step of a route
|
|
135
125
|
* @param {Step} step - The step object.
|
|
136
126
|
* @return {Promise<Step>} The step populated with the transaction data.
|
|
137
127
|
* @throws {LifiError} Throws a LifiError if request fails.
|
|
138
128
|
*/
|
|
139
|
-
this.getStepTransaction = (step, options) =>
|
|
129
|
+
this.getStepTransaction = async (step, options) => {
|
|
140
130
|
return ApiService.getStepTransaction(step, options);
|
|
141
|
-
}
|
|
131
|
+
};
|
|
142
132
|
/**
|
|
143
133
|
* Stops the execution of an active route.
|
|
144
134
|
* @param {Route} route - A route that is currently in execution.
|
|
@@ -148,7 +138,8 @@ export default class LIFI {
|
|
|
148
138
|
if (!this.activeRouteDictionary[route.id]) {
|
|
149
139
|
return route;
|
|
150
140
|
}
|
|
151
|
-
|
|
141
|
+
const { executionData } = this.activeRouteDictionary[route.id];
|
|
142
|
+
for (const executor of executionData.executors) {
|
|
152
143
|
executor.setInteraction({
|
|
153
144
|
allowInteraction: false,
|
|
154
145
|
allowUpdates: false,
|
|
@@ -164,14 +155,17 @@ export default class LIFI {
|
|
|
164
155
|
* @deprecated use updateRouteExecution instead.
|
|
165
156
|
*/
|
|
166
157
|
this.moveExecutionToBackground = (route) => {
|
|
167
|
-
const
|
|
168
|
-
if (!
|
|
158
|
+
const { executionData } = this.activeRouteDictionary[route.id];
|
|
159
|
+
if (!executionData) {
|
|
169
160
|
return;
|
|
170
161
|
}
|
|
171
|
-
for (const executor of
|
|
162
|
+
for (const executor of executionData.executors) {
|
|
172
163
|
executor.setInteraction({ allowInteraction: false, allowUpdates: true });
|
|
173
164
|
}
|
|
174
|
-
|
|
165
|
+
executionData.settings = {
|
|
166
|
+
...executionData.settings,
|
|
167
|
+
executeInBackground: true,
|
|
168
|
+
};
|
|
175
169
|
};
|
|
176
170
|
/**
|
|
177
171
|
* Updates route execution to background or foreground state.
|
|
@@ -179,18 +173,21 @@ export default class LIFI {
|
|
|
179
173
|
* @param {boolean} settings - An object with execution settings.
|
|
180
174
|
*/
|
|
181
175
|
this.updateRouteExecution = (route, settings) => {
|
|
182
|
-
const
|
|
183
|
-
if (!
|
|
176
|
+
const { executionData } = this.activeRouteDictionary[route.id];
|
|
177
|
+
if (!executionData) {
|
|
184
178
|
return;
|
|
185
179
|
}
|
|
186
|
-
for (const executor of
|
|
180
|
+
for (const executor of executionData.executors) {
|
|
187
181
|
executor.setInteraction({
|
|
188
182
|
allowInteraction: !settings.executeInBackground,
|
|
189
183
|
allowUpdates: true,
|
|
190
184
|
});
|
|
191
185
|
}
|
|
192
186
|
// Update active route settings so we know what the current state of execution is
|
|
193
|
-
|
|
187
|
+
executionData.settings = {
|
|
188
|
+
...executionData.settings,
|
|
189
|
+
...settings,
|
|
190
|
+
};
|
|
194
191
|
};
|
|
195
192
|
/**
|
|
196
193
|
* Execute a route.
|
|
@@ -200,16 +197,21 @@ export default class LIFI {
|
|
|
200
197
|
* @return {Promise<Route>} The executed route.
|
|
201
198
|
* @throws {LifiError} Throws a LifiError if the execution fails.
|
|
202
199
|
*/
|
|
203
|
-
this.executeRoute = (signer, route, settings) =>
|
|
200
|
+
this.executeRoute = async (signer, route, settings) => {
|
|
204
201
|
// Deep clone to prevent side effects
|
|
205
|
-
const clonedRoute =
|
|
202
|
+
const clonedRoute = structuredClone(route);
|
|
206
203
|
// Check if route is already running
|
|
207
204
|
if (this.activeRouteDictionary[clonedRoute.id]) {
|
|
208
205
|
// TODO: maybe inform user why nothing happens?
|
|
209
|
-
return clonedRoute;
|
|
206
|
+
return this.activeRouteDictionary[clonedRoute.id].executionPromise;
|
|
210
207
|
}
|
|
211
|
-
|
|
212
|
-
|
|
208
|
+
const executionPromise = this.executeSteps(signer, clonedRoute, settings);
|
|
209
|
+
this.activeRouteDictionary[clonedRoute.id] = {
|
|
210
|
+
...this.activeRouteDictionary[clonedRoute.id],
|
|
211
|
+
executionPromise,
|
|
212
|
+
};
|
|
213
|
+
return executionPromise;
|
|
214
|
+
};
|
|
213
215
|
/**
|
|
214
216
|
* Resume the execution of a route that has been stopped or had an error while executing.
|
|
215
217
|
* @param {Signer} signer - The signer required to send the transactions.
|
|
@@ -218,62 +220,70 @@ export default class LIFI {
|
|
|
218
220
|
* @return {Promise<Route>} The executed route.
|
|
219
221
|
* @throws {LifiError} Throws a LifiError if the execution fails.
|
|
220
222
|
*/
|
|
221
|
-
this.resumeRoute = (signer, route, settings) =>
|
|
223
|
+
this.resumeRoute = async (signer, route, settings) => {
|
|
222
224
|
// Deep clone to prevent side effects
|
|
223
|
-
const clonedRoute =
|
|
224
|
-
const
|
|
225
|
-
if (
|
|
226
|
-
const executionHalted =
|
|
225
|
+
const clonedRoute = structuredClone(route);
|
|
226
|
+
const { executionData, executionPromise } = this.activeRouteDictionary[clonedRoute.id];
|
|
227
|
+
if (executionData) {
|
|
228
|
+
const executionHalted = executionData.executors.some((executor) => executor.executionStopped);
|
|
227
229
|
if (!executionHalted) {
|
|
228
230
|
// Check if we want to resume route execution in the background
|
|
229
231
|
this.updateRouteExecution(route, {
|
|
230
|
-
executeInBackground: settings
|
|
232
|
+
executeInBackground: settings?.executeInBackground,
|
|
231
233
|
});
|
|
232
|
-
return
|
|
234
|
+
return executionPromise;
|
|
233
235
|
}
|
|
234
236
|
}
|
|
235
237
|
handlePreRestart(clonedRoute);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
238
|
+
const newExecutionPromise = this.executeSteps(signer, clonedRoute, settings);
|
|
239
|
+
this.activeRouteDictionary[clonedRoute.id] = {
|
|
240
|
+
...this.activeRouteDictionary[clonedRoute.id],
|
|
241
|
+
executionPromise: newExecutionPromise,
|
|
242
|
+
};
|
|
243
|
+
return newExecutionPromise;
|
|
244
|
+
};
|
|
245
|
+
this.executeSteps = async (signer, route, settings) => {
|
|
240
246
|
const config = this.configService.getConfig();
|
|
241
|
-
const
|
|
247
|
+
const updatedExecutionData = {
|
|
242
248
|
route,
|
|
243
249
|
executors: [],
|
|
244
|
-
settings:
|
|
250
|
+
settings: { ...config.defaultExecutionSettings, ...settings },
|
|
251
|
+
};
|
|
252
|
+
this.activeRouteDictionary[route.id].executionData = {
|
|
253
|
+
...updatedExecutionData,
|
|
245
254
|
};
|
|
246
|
-
this.activeRouteDictionary[route.id]
|
|
247
|
-
const statusManager = new StatusManager(route,
|
|
255
|
+
const { executionData } = this.activeRouteDictionary[route.id];
|
|
256
|
+
const statusManager = new StatusManager(route, executionData.settings, (route) => {
|
|
248
257
|
if (this.activeRouteDictionary[route.id]) {
|
|
249
|
-
|
|
258
|
+
executionData.route = route;
|
|
250
259
|
}
|
|
251
260
|
});
|
|
252
261
|
// Loop over steps and execute them
|
|
253
262
|
for (let index = 0; index < route.steps.length; index++) {
|
|
254
|
-
const
|
|
263
|
+
const { executionData } = this.activeRouteDictionary[route.id];
|
|
255
264
|
// Check if execution has stopped in the meantime
|
|
256
|
-
if (!
|
|
265
|
+
if (!executionData) {
|
|
257
266
|
break;
|
|
258
267
|
}
|
|
259
268
|
const step = route.steps[index];
|
|
260
269
|
const previousStep = route.steps[index - 1];
|
|
261
270
|
// Check if the step is already done
|
|
262
|
-
|
|
271
|
+
//
|
|
272
|
+
if (step.execution?.status === 'DONE') {
|
|
263
273
|
continue;
|
|
264
274
|
}
|
|
265
275
|
// Update amount using output of previous execution. In the future this should be handled by calling `updateRoute`
|
|
266
|
-
if (
|
|
276
|
+
if (previousStep?.execution?.toAmount) {
|
|
267
277
|
step.action.fromAmount = previousStep.execution.toAmount;
|
|
268
278
|
}
|
|
269
279
|
try {
|
|
270
|
-
const stepExecutor = new StepExecutor(statusManager,
|
|
271
|
-
|
|
280
|
+
const stepExecutor = new StepExecutor(statusManager, executionData.settings);
|
|
281
|
+
executionData.executors.push(stepExecutor);
|
|
272
282
|
// Check if we want to execute this step in the background
|
|
273
|
-
this.updateRouteExecution(route,
|
|
274
|
-
const executedStep =
|
|
283
|
+
this.updateRouteExecution(route, executionData.settings);
|
|
284
|
+
const executedStep = await stepExecutor.executeStep(signer, step);
|
|
275
285
|
// We may reach this point if user interaction isn't allowed. We want to stop execution until we resume it
|
|
276
|
-
if (
|
|
286
|
+
if (executedStep.execution?.status !== 'DONE') {
|
|
277
287
|
this.stopExecution(route);
|
|
278
288
|
}
|
|
279
289
|
// Execution stopped during the current step, we don't want to continue to the next step so we return already
|
|
@@ -289,7 +299,7 @@ export default class LIFI {
|
|
|
289
299
|
// Clean up after the execution
|
|
290
300
|
delete this.activeRouteDictionary[route.id];
|
|
291
301
|
return route;
|
|
292
|
-
}
|
|
302
|
+
};
|
|
293
303
|
/**
|
|
294
304
|
* Update the ExecutionSettings for an active route.
|
|
295
305
|
* @param {ExecutionSettings} settings - An object with execution settings.
|
|
@@ -301,14 +311,17 @@ export default class LIFI {
|
|
|
301
311
|
throw new ValidationError("Can't set ExecutionSettings for the inactive route.");
|
|
302
312
|
}
|
|
303
313
|
const config = this.configService.getConfig();
|
|
304
|
-
this.activeRouteDictionary[route.id].settings =
|
|
314
|
+
this.activeRouteDictionary[route.id].executionData.settings = {
|
|
315
|
+
...config.defaultExecutionSettings,
|
|
316
|
+
...settings,
|
|
317
|
+
};
|
|
305
318
|
};
|
|
306
319
|
/**
|
|
307
320
|
* Get the list of active routes.
|
|
308
321
|
* @return {Route[]} A list of routes.
|
|
309
322
|
*/
|
|
310
323
|
this.getActiveRoutes = () => {
|
|
311
|
-
return Object.values(this.activeRouteDictionary).map((dict) => dict.route);
|
|
324
|
+
return Object.values(this.activeRouteDictionary).map((dict) => dict.executionData.route);
|
|
312
325
|
};
|
|
313
326
|
/**
|
|
314
327
|
* Return the current route information for given route. The route has to be active.
|
|
@@ -316,8 +329,7 @@ export default class LIFI {
|
|
|
316
329
|
* @return {Route} The updated route.
|
|
317
330
|
*/
|
|
318
331
|
this.getActiveRoute = (route) => {
|
|
319
|
-
|
|
320
|
-
return (_a = this.activeRouteDictionary[route.id]) === null || _a === void 0 ? void 0 : _a.route;
|
|
332
|
+
return this.activeRouteDictionary[route.id]?.executionData.route;
|
|
321
333
|
};
|
|
322
334
|
/**
|
|
323
335
|
* Returns the balances of a specific token a wallet holds across all aggregated chains.
|
|
@@ -326,7 +338,7 @@ export default class LIFI {
|
|
|
326
338
|
* @return {Promise<TokenAmount | null>} An object containing the token and the amounts on different chains.
|
|
327
339
|
* @throws {ValidationError} Throws a ValidationError if parameters are invalid.
|
|
328
340
|
*/
|
|
329
|
-
this.getTokenBalance = (walletAddress, token) =>
|
|
341
|
+
this.getTokenBalance = async (walletAddress, token) => {
|
|
330
342
|
if (!walletAddress) {
|
|
331
343
|
throw new ValidationError('Missing walletAddress.');
|
|
332
344
|
}
|
|
@@ -334,7 +346,7 @@ export default class LIFI {
|
|
|
334
346
|
throw new ValidationError(`Invalid token passed: address "${token.address}" on chainId "${token.chainId}"`);
|
|
335
347
|
}
|
|
336
348
|
return balance.getTokenBalance(walletAddress, token);
|
|
337
|
-
}
|
|
349
|
+
};
|
|
338
350
|
/**
|
|
339
351
|
* Returns the balances for a list tokens a wallet holds across all aggregated chains.
|
|
340
352
|
* @param {string} walletAddress - A wallet address.
|
|
@@ -342,7 +354,7 @@ export default class LIFI {
|
|
|
342
354
|
* @return {Promise<TokenAmount[]>} A list of objects containing the tokens and the amounts on different chains.
|
|
343
355
|
* @throws {ValidationError} Throws a ValidationError if parameters are invalid.
|
|
344
356
|
*/
|
|
345
|
-
this.getTokenBalances = (walletAddress, tokens) =>
|
|
357
|
+
this.getTokenBalances = async (walletAddress, tokens) => {
|
|
346
358
|
if (!walletAddress) {
|
|
347
359
|
throw new ValidationError('Missing walletAddress.');
|
|
348
360
|
}
|
|
@@ -351,7 +363,7 @@ export default class LIFI {
|
|
|
351
363
|
throw new ValidationError(`Invalid token passed: address "${invalidTokens[0].address}" on chainId "${invalidTokens[0].chainId}"`);
|
|
352
364
|
}
|
|
353
365
|
return balance.getTokenBalances(walletAddress, tokens);
|
|
354
|
-
}
|
|
366
|
+
};
|
|
355
367
|
/**
|
|
356
368
|
* This method queries the balances of tokens for a specific list of chains for a given wallet.
|
|
357
369
|
* @param {string} walletAddress - A walletaddress.
|
|
@@ -359,7 +371,7 @@ export default class LIFI {
|
|
|
359
371
|
* @return {Promise<{ [chainId: number]: TokenAmount[] }>} A list of objects containing the tokens and the amounts on different chains organized by the chosen chains.
|
|
360
372
|
* @throws {ValidationError} Throws a ValidationError if parameters are invalid.
|
|
361
373
|
*/
|
|
362
|
-
this.getTokenBalancesForChains = (walletAddress, tokensByChain) =>
|
|
374
|
+
this.getTokenBalancesForChains = async (walletAddress, tokensByChain) => {
|
|
363
375
|
if (!walletAddress) {
|
|
364
376
|
throw new ValidationError('Missing walletAddress.');
|
|
365
377
|
}
|
|
@@ -369,24 +381,24 @@ export default class LIFI {
|
|
|
369
381
|
throw new ValidationError(`Invalid token passed: address "${invalidTokens[0].address}" on chainId "${invalidTokens[0].chainId}"`);
|
|
370
382
|
}
|
|
371
383
|
return balance.getTokenBalancesForChains(walletAddress, tokensByChain);
|
|
372
|
-
}
|
|
384
|
+
};
|
|
373
385
|
/**
|
|
374
386
|
* Get the current approval for a certain token.
|
|
375
387
|
* @param signer - The signer owning the token
|
|
376
388
|
* @param token - The token that should be checked
|
|
377
389
|
* @param approvalAddress - The address that has be approved
|
|
378
390
|
*/
|
|
379
|
-
this.getTokenApproval = (signer, token, approvalAddress) =>
|
|
391
|
+
this.getTokenApproval = async (signer, token, approvalAddress) => {
|
|
380
392
|
return getTokenApproval(signer, token, approvalAddress);
|
|
381
|
-
}
|
|
393
|
+
};
|
|
382
394
|
/**
|
|
383
395
|
* Get the current approval for a list of token / approval address pairs.
|
|
384
396
|
* @param signer - The signer owning the tokens
|
|
385
397
|
* @param tokenData - A list of token and approval address pairs
|
|
386
398
|
*/
|
|
387
|
-
this.bulkGetTokenApproval = (signer, tokenData) =>
|
|
399
|
+
this.bulkGetTokenApproval = async (signer, tokenData) => {
|
|
388
400
|
return bulkGetTokenApproval(signer, tokenData);
|
|
389
|
-
}
|
|
401
|
+
};
|
|
390
402
|
/**
|
|
391
403
|
* Set approval for a certain token and amount.
|
|
392
404
|
* @param { ApproveTokenRequest } request - The approval request
|
|
@@ -410,6 +422,6 @@ export default class LIFI {
|
|
|
410
422
|
this.chainsService.getChains().then((chains) => {
|
|
411
423
|
this.configService.updateChains(chains);
|
|
412
424
|
});
|
|
413
|
-
checkPackageUpdates(name, version, configUpdate
|
|
425
|
+
checkPackageUpdates(name, version, configUpdate?.disableVersionCheck);
|
|
414
426
|
}
|
|
415
427
|
}
|
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
11
2
|
import BigNumber from 'bignumber.js';
|
|
12
3
|
import { constants } from 'ethers';
|
|
13
4
|
import { getApproved, setApproval } from '../allowance/utils';
|
|
14
5
|
import { getProvider } from '../utils/getProvider';
|
|
15
6
|
import { parseError } from '../utils/parseError';
|
|
16
|
-
export const checkAllowance = (signer, step, statusManager, settings, chain, allowUserInteraction = false) =>
|
|
7
|
+
export const checkAllowance = async (signer, step, statusManager, settings, chain, allowUserInteraction = false) => {
|
|
17
8
|
// Ask the user to set an allowance
|
|
18
9
|
let allowanceProcess = statusManager.findOrCreateProcess(step, 'TOKEN_ALLOWANCE');
|
|
19
10
|
// Check allowance
|
|
@@ -22,11 +13,11 @@ export const checkAllowance = (signer, step, statusManager, settings, chain, all
|
|
|
22
13
|
if (allowanceProcess.status !== 'PENDING') {
|
|
23
14
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING');
|
|
24
15
|
}
|
|
25
|
-
|
|
16
|
+
await getProvider(signer).waitForTransaction(allowanceProcess.txHash);
|
|
26
17
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
|
|
27
18
|
}
|
|
28
19
|
else {
|
|
29
|
-
const approved =
|
|
20
|
+
const approved = await getApproved(signer, step.action.fromToken.address, step.estimate.approvalAddress);
|
|
30
21
|
if (new BigNumber(step.action.fromAmount).gt(approved)) {
|
|
31
22
|
if (!allowUserInteraction) {
|
|
32
23
|
return;
|
|
@@ -34,13 +25,13 @@ export const checkAllowance = (signer, step, statusManager, settings, chain, all
|
|
|
34
25
|
const approvalAmount = settings.infiniteApproval
|
|
35
26
|
? constants.MaxUint256.toString()
|
|
36
27
|
: step.action.fromAmount;
|
|
37
|
-
const approveTx =
|
|
28
|
+
const approveTx = await setApproval(signer, step.action.fromToken.address, step.estimate.approvalAddress, approvalAmount);
|
|
38
29
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING', {
|
|
39
30
|
txHash: approveTx.hash,
|
|
40
31
|
txLink: chain.metamask.blockExplorerUrls[0] + 'tx/' + approveTx.hash,
|
|
41
32
|
});
|
|
42
33
|
// Wait for the transcation
|
|
43
|
-
|
|
34
|
+
await approveTx.wait();
|
|
44
35
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
|
|
45
36
|
}
|
|
46
37
|
else {
|
|
@@ -50,10 +41,10 @@ export const checkAllowance = (signer, step, statusManager, settings, chain, all
|
|
|
50
41
|
}
|
|
51
42
|
catch (e) {
|
|
52
43
|
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
|
|
53
|
-
|
|
44
|
+
await transactionReplaced(e.replacement, allowanceProcess, step, chain, statusManager);
|
|
54
45
|
}
|
|
55
46
|
else {
|
|
56
|
-
const error =
|
|
47
|
+
const error = await parseError(e, step, allowanceProcess);
|
|
57
48
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'FAILED', {
|
|
58
49
|
error: {
|
|
59
50
|
message: error.message,
|
|
@@ -65,20 +56,20 @@ export const checkAllowance = (signer, step, statusManager, settings, chain, all
|
|
|
65
56
|
throw error;
|
|
66
57
|
}
|
|
67
58
|
}
|
|
68
|
-
}
|
|
69
|
-
const transactionReplaced = (replacementTx, allowanceProcess, step, chain, statusManager) =>
|
|
59
|
+
};
|
|
60
|
+
const transactionReplaced = async (replacementTx, allowanceProcess, step, chain, statusManager) => {
|
|
70
61
|
try {
|
|
71
62
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING', {
|
|
72
63
|
txHash: replacementTx.hash,
|
|
73
64
|
txLink: chain.metamask.blockExplorerUrls[0] + 'tx/' + replacementTx.hash,
|
|
74
65
|
});
|
|
75
|
-
|
|
66
|
+
await replacementTx.wait();
|
|
76
67
|
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
|
|
77
68
|
}
|
|
78
69
|
catch (e) {
|
|
79
70
|
if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
|
|
80
|
-
|
|
71
|
+
await transactionReplaced(e.replacement, allowanceProcess, step, chain, statusManager);
|
|
81
72
|
}
|
|
82
73
|
throw e;
|
|
83
74
|
}
|
|
84
|
-
}
|
|
75
|
+
};
|
|
@@ -1,36 +1,27 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import BigNumber from 'bignumber.js';
|
|
11
2
|
import { constants } from 'ethers';
|
|
12
3
|
import { isSameToken } from '../helpers';
|
|
13
4
|
import { isNativeTokenAddress } from '../utils/utils';
|
|
14
5
|
import { getAllowanceViaMulticall, getApproved, groupByChain, setApproval, } from './utils';
|
|
15
|
-
export const getTokenApproval = (signer, token, approvalAddress) =>
|
|
6
|
+
export const getTokenApproval = async (signer, token, approvalAddress) => {
|
|
16
7
|
// native token don't need approval
|
|
17
8
|
if (isNativeTokenAddress(token.address)) {
|
|
18
9
|
return;
|
|
19
10
|
}
|
|
20
|
-
const approved =
|
|
21
|
-
return approved.
|
|
22
|
-
}
|
|
23
|
-
export const bulkGetTokenApproval = (signer, tokenData) =>
|
|
11
|
+
const approved = await getApproved(signer, token.address, approvalAddress);
|
|
12
|
+
return approved.toFixed(0);
|
|
13
|
+
};
|
|
14
|
+
export const bulkGetTokenApproval = async (signer, tokenData) => {
|
|
24
15
|
// filter out native tokens
|
|
25
16
|
const filteredTokenData = tokenData.filter(({ token }) => !isNativeTokenAddress(token.address));
|
|
26
17
|
// group by chain
|
|
27
18
|
const tokenDataByChain = groupByChain(filteredTokenData);
|
|
28
|
-
const approvalPromises = Object.keys(tokenDataByChain).map((chainId) =>
|
|
19
|
+
const approvalPromises = Object.keys(tokenDataByChain).map(async (chainId) => {
|
|
29
20
|
const parsedChainId = Number.parseInt(chainId);
|
|
30
21
|
// get allowances for current chain and token list
|
|
31
22
|
return getAllowanceViaMulticall(signer, parsedChainId, tokenDataByChain[parsedChainId]);
|
|
32
|
-
})
|
|
33
|
-
const approvalsByChain =
|
|
23
|
+
});
|
|
24
|
+
const approvalsByChain = await Promise.all(approvalPromises);
|
|
34
25
|
const approvals = approvalsByChain.flat();
|
|
35
26
|
return tokenData.map(({ token }) => {
|
|
36
27
|
// native token don't need approval
|
|
@@ -38,31 +29,31 @@ export const bulkGetTokenApproval = (signer, tokenData) => __awaiter(void 0, voi
|
|
|
38
29
|
return { token, approval: undefined };
|
|
39
30
|
}
|
|
40
31
|
const approved = approvals.find((approval) => isSameToken(approval.token, token));
|
|
41
|
-
return { token, approval: approved
|
|
32
|
+
return { token, approval: approved?.approvedAmount.toString() };
|
|
42
33
|
});
|
|
43
|
-
}
|
|
44
|
-
export const approveToken = ({ signer, token, approvalAddress, amount, infiniteApproval = false, }) =>
|
|
34
|
+
};
|
|
35
|
+
export const approveToken = async ({ signer, token, approvalAddress, amount, infiniteApproval = false, }) => {
|
|
45
36
|
// native token don't need approval
|
|
46
37
|
if (isNativeTokenAddress(token.address)) {
|
|
47
38
|
return;
|
|
48
39
|
}
|
|
49
|
-
const approvedAmount =
|
|
40
|
+
const approvedAmount = await getApproved(signer, token.address, approvalAddress);
|
|
50
41
|
if (new BigNumber(amount).gt(approvedAmount)) {
|
|
51
42
|
const approvalAmount = infiniteApproval
|
|
52
43
|
? constants.MaxUint256.toString()
|
|
53
44
|
: amount;
|
|
54
|
-
const approveTx =
|
|
55
|
-
|
|
45
|
+
const approveTx = await setApproval(signer, token.address, approvalAddress, approvalAmount);
|
|
46
|
+
await approveTx.wait();
|
|
56
47
|
}
|
|
57
|
-
}
|
|
58
|
-
export const revokeTokenApproval = ({ signer, token, approvalAddress, }) =>
|
|
48
|
+
};
|
|
49
|
+
export const revokeTokenApproval = async ({ signer, token, approvalAddress, }) => {
|
|
59
50
|
// native token don't need approval
|
|
60
51
|
if (isNativeTokenAddress(token.address)) {
|
|
61
52
|
return;
|
|
62
53
|
}
|
|
63
|
-
const approvedAmount =
|
|
54
|
+
const approvedAmount = await getApproved(signer, token.address, approvalAddress);
|
|
64
55
|
if (!approvedAmount.isZero()) {
|
|
65
|
-
const approveTx =
|
|
66
|
-
|
|
56
|
+
const approveTx = await setApproval(signer, token.address, approvalAddress, '0');
|
|
57
|
+
await approveTx.wait();
|
|
67
58
|
}
|
|
68
|
-
}
|
|
59
|
+
};
|