@lifi/sdk 1.7.1 → 2.0.0-beta.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/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 +68 -19
- 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 +65 -18
- 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 +23 -25
- package/CHANGELOG.md +0 -490
|
@@ -77,4 +77,9 @@ export declare class NotFoundError extends LifiError {
|
|
|
77
77
|
export declare class UnknownError extends LifiError {
|
|
78
78
|
constructor(code: ErrorCode, message: string, htmlMessage?: string, stack?: string);
|
|
79
79
|
}
|
|
80
|
+
export declare class HTTPError extends Error {
|
|
81
|
+
response: Response;
|
|
82
|
+
status: number;
|
|
83
|
+
constructor(response: Response);
|
|
84
|
+
}
|
|
80
85
|
export {};
|
package/dist/cjs/utils/errors.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.UnknownError = exports.NotFoundError = exports.BalanceError = exports.SlippageError = exports.TransactionError = exports.ValidationError = exports.ServerError = exports.ProviderError = exports.RPCError = exports.LifiError = exports.MetaMaskProviderErrorCode = exports.MetaMaskRPCErrorCode = exports.LifiErrorCode = void 0;
|
|
3
|
+
exports.HTTPError = exports.UnknownError = exports.NotFoundError = exports.BalanceError = exports.SlippageError = exports.TransactionError = exports.ValidationError = exports.ServerError = exports.ProviderError = exports.RPCError = exports.LifiError = exports.MetaMaskProviderErrorCode = exports.MetaMaskRPCErrorCode = exports.LifiErrorCode = void 0;
|
|
4
4
|
var ErrorType;
|
|
5
5
|
(function (ErrorType) {
|
|
6
6
|
ErrorType["RPCError"] = "RPCError";
|
|
@@ -121,3 +121,16 @@ class UnknownError extends LifiError {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
exports.UnknownError = UnknownError;
|
|
124
|
+
class HTTPError extends Error {
|
|
125
|
+
constructor(response) {
|
|
126
|
+
const code = response.status || response.status === 0 ? response.status : '';
|
|
127
|
+
const title = response.statusText || '';
|
|
128
|
+
const status = `${code} ${title}`.trim();
|
|
129
|
+
const reason = status ? `status code ${status}` : 'an unknown error';
|
|
130
|
+
super(`Request failed with ${reason}`);
|
|
131
|
+
this.name = 'HTTPError';
|
|
132
|
+
this.response = response;
|
|
133
|
+
this.status = response.status;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.HTTPError = HTTPError;
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -19,21 +10,21 @@ const connectors_1 = require("../connectors");
|
|
|
19
10
|
const utils_1 = require("./utils");
|
|
20
11
|
const multicallAbi_json_1 = __importDefault(require("./multicallAbi.json"));
|
|
21
12
|
const MAX_MULTICALL_SIZE = 100;
|
|
22
|
-
const fetchDataUsingMulticall = (calls, abi, chainId, multicallAddress, requireSuccess = false) =>
|
|
13
|
+
const fetchDataUsingMulticall = async (calls, abi, chainId, multicallAddress, requireSuccess = false) => {
|
|
23
14
|
// 1. create contract using multicall contract address and abi...
|
|
24
|
-
const provider =
|
|
15
|
+
const provider = await (0, connectors_1.getRpcProvider)(chainId);
|
|
25
16
|
const multicallContract = new contracts_1.Contract(multicallAddress, multicallAbi_json_1.default, provider);
|
|
26
17
|
const abiInterface = new abi_1.Interface(abi);
|
|
27
18
|
// split up lists into chunks to stay below multicall limit
|
|
28
19
|
const chunkedList = (0, utils_1.splitListIntoChunks)(calls, MAX_MULTICALL_SIZE);
|
|
29
|
-
const chunkedResults =
|
|
20
|
+
const chunkedResults = await Promise.all(chunkedList.map(async (chunkedCalls) => {
|
|
30
21
|
const callData = chunkedCalls.map((call) => [
|
|
31
22
|
call.address.toLowerCase(),
|
|
32
23
|
abiInterface.encodeFunctionData(call.name, call.params),
|
|
33
24
|
]);
|
|
34
25
|
try {
|
|
35
26
|
// 3. get bytes array from multicall contract by process aggregate method...
|
|
36
|
-
const { blockNumber, returnData } =
|
|
27
|
+
const { blockNumber, returnData } = await multicallContract.tryBlockAndAggregate(requireSuccess, callData);
|
|
37
28
|
// 4. decode bytes array to useful data array...
|
|
38
29
|
return returnData
|
|
39
30
|
.map(({ success, returnData }, i) => {
|
|
@@ -71,7 +62,7 @@ const fetchDataUsingMulticall = (calls, abi, chainId, multicallAddress, requireS
|
|
|
71
62
|
console.error(`Multicall failed on chainId "${chainId}"`, chunkedList, e);
|
|
72
63
|
return [];
|
|
73
64
|
}
|
|
74
|
-
}))
|
|
65
|
+
}));
|
|
75
66
|
return chunkedResults.flat();
|
|
76
|
-
}
|
|
67
|
+
};
|
|
77
68
|
exports.fetchDataUsingMulticall = fetchDataUsingMulticall;
|
|
@@ -32,6 +32,6 @@ import { LifiError } from './errors';
|
|
|
32
32
|
* https://eips.ethereum.org/EIPS/eip-1193#provider-errors
|
|
33
33
|
*/
|
|
34
34
|
export declare const getTransactionNotSentMessage: (step?: Step, process?: Process) => Promise<string>;
|
|
35
|
-
export declare const getTransactionFailedMessage: (step: Step, txLink?: string) => string
|
|
35
|
+
export declare const getTransactionFailedMessage: (step: Step, txLink?: string) => Promise<string>;
|
|
36
36
|
export declare const parseError: (e: any, step?: Step, process?: Process) => Promise<LifiError>;
|
|
37
|
-
export declare const parseBackendError: (e: any) => LifiError
|
|
37
|
+
export declare const parseBackendError: (e: any) => Promise<LifiError>;
|
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
14
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
6
|
exports.parseBackendError = exports.parseError = exports.getTransactionFailedMessage = exports.getTransactionNotSentMessage = void 0;
|
|
16
|
-
const types_1 = require("@lifi/types");
|
|
17
7
|
const eth_rpc_errors_1 = require("eth-rpc-errors");
|
|
18
8
|
const ChainsService_1 = __importDefault(require("../services/ChainsService"));
|
|
19
9
|
const errors_1 = require("./errors");
|
|
@@ -49,12 +39,12 @@ const utils_1 = require("./utils");
|
|
|
49
39
|
* https://eips.ethereum.org/EIPS/eip-1474#error-codes
|
|
50
40
|
* https://eips.ethereum.org/EIPS/eip-1193#provider-errors
|
|
51
41
|
*/
|
|
52
|
-
const getTransactionNotSentMessage = (step, process) =>
|
|
42
|
+
const getTransactionNotSentMessage = async (step, process) => {
|
|
53
43
|
let transactionNotSend = 'Transaction was not sent, your funds are still in your wallet';
|
|
54
44
|
// add information about funds if available
|
|
55
45
|
if (step) {
|
|
56
46
|
const chainService = ChainsService_1.default.getInstance();
|
|
57
|
-
const chain =
|
|
47
|
+
const chain = await chainService.getChainById(step.action.fromChainId);
|
|
58
48
|
transactionNotSend += ` (${(0, utils_1.formatTokenAmountOnly)(step.action.fromToken, step.action.fromAmount)} ${step.action.fromToken.symbol} on ${chain.name})`;
|
|
59
49
|
}
|
|
60
50
|
transactionNotSend +=
|
|
@@ -65,19 +55,20 @@ const getTransactionNotSentMessage = (step, process) => __awaiter(void 0, void 0
|
|
|
65
55
|
? `<br>You can check the failed transaction <a href="${process.txLink}" target="_blank" rel="nofollow noreferrer">here</a>.`
|
|
66
56
|
: '';
|
|
67
57
|
return transactionNotSend;
|
|
68
|
-
}
|
|
58
|
+
};
|
|
69
59
|
exports.getTransactionNotSentMessage = getTransactionNotSentMessage;
|
|
70
|
-
const getTransactionFailedMessage = (step, txLink) => {
|
|
60
|
+
const getTransactionFailedMessage = async (step, txLink) => {
|
|
61
|
+
const chainsService = ChainsService_1.default.getInstance();
|
|
62
|
+
const chain = await chainsService.getChainById(step.action.toChainId);
|
|
71
63
|
const baseString = `It appears that your transaction may not have been successful.
|
|
72
|
-
However, to confirm this, please check your ${
|
|
64
|
+
However, to confirm this, please check your ${chain.name} wallet for ${step.action.toToken.symbol}.`;
|
|
73
65
|
return txLink
|
|
74
66
|
? `${baseString}
|
|
75
67
|
You can also check the <a href="${txLink}" target="_blank" rel="nofollow noreferrer">block explorer</a> for more information.`
|
|
76
68
|
: baseString;
|
|
77
69
|
};
|
|
78
70
|
exports.getTransactionFailedMessage = getTransactionFailedMessage;
|
|
79
|
-
const parseError = (e, step, process) =>
|
|
80
|
-
var _a, _b, _c;
|
|
71
|
+
const parseError = async (e, step, process) => {
|
|
81
72
|
if (e instanceof errors_1.LifiError) {
|
|
82
73
|
return e;
|
|
83
74
|
}
|
|
@@ -88,49 +79,56 @@ const parseError = (e, step, process) => __awaiter(void 0, void 0, void 0, funct
|
|
|
88
79
|
// rpc errors
|
|
89
80
|
// underpriced errors are sent as internal errors, so we need to parse the message manually
|
|
90
81
|
if (e.code === eth_rpc_errors_1.errorCodes.rpc.internal &&
|
|
91
|
-
(
|
|
92
|
-
|
|
82
|
+
(e.message?.includes('underpriced') ||
|
|
83
|
+
e.message?.includes('replacement fee too low'))) {
|
|
84
|
+
return new errors_1.RPCError(errors_1.LifiErrorCode.TransactionUnderpriced, 'Transaction is underpriced.', await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
|
|
93
85
|
}
|
|
94
|
-
if (
|
|
95
|
-
|
|
96
|
-
return new errors_1.TransactionError(errors_1.LifiErrorCode.GasLimitError, 'Gas limit is too low.',
|
|
86
|
+
if (e.message?.includes('intrinsic gas too low') ||
|
|
87
|
+
e.message?.includes('out of gas')) {
|
|
88
|
+
return new errors_1.TransactionError(errors_1.LifiErrorCode.GasLimitError, 'Gas limit is too low.', await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
|
|
97
89
|
}
|
|
98
|
-
return new errors_1.RPCError(e.code, (0, eth_rpc_errors_1.getMessageFromCode)(e.code),
|
|
90
|
+
return new errors_1.RPCError(e.code, (0, eth_rpc_errors_1.getMessageFromCode)(e.code), await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
|
|
99
91
|
}
|
|
100
92
|
// provider errors
|
|
101
93
|
if (Object.values(eth_rpc_errors_1.errorCodes.provider).includes(e.code)) {
|
|
102
|
-
return new errors_1.ProviderError(e.code, (0, eth_rpc_errors_1.getMessageFromCode)(e.code),
|
|
94
|
+
return new errors_1.ProviderError(e.code, (0, eth_rpc_errors_1.getMessageFromCode)(e.code), await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
|
|
103
95
|
}
|
|
104
96
|
}
|
|
105
97
|
}
|
|
106
98
|
switch (e.code) {
|
|
107
99
|
case 'CALL_EXCEPTION':
|
|
108
|
-
return new errors_1.ProviderError(errors_1.LifiErrorCode.TransactionFailed, e.reason,
|
|
100
|
+
return new errors_1.ProviderError(errors_1.LifiErrorCode.TransactionFailed, e.reason, await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
|
|
109
101
|
case 'ACTION_REJECTED':
|
|
110
102
|
case errors_1.MetaMaskProviderErrorCode.userRejectedRequest:
|
|
111
|
-
return new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionRejected, e.message,
|
|
103
|
+
return new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionRejected, e.message, await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
|
|
112
104
|
case errors_1.LifiErrorCode.TransactionUnprepared:
|
|
113
|
-
return new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionUnprepared, e.message,
|
|
105
|
+
return new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionUnprepared, e.message, await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
|
|
114
106
|
case errors_1.LifiErrorCode.ValidationError:
|
|
115
107
|
return new errors_1.TransactionError(errors_1.LifiErrorCode.ValidationError, e.message, e.htmlMessage);
|
|
116
108
|
default:
|
|
117
109
|
return new errors_1.UnknownError(errors_1.LifiErrorCode.InternalError, e.message || 'Unknown error occurred.', undefined, e.stack);
|
|
118
110
|
}
|
|
119
|
-
}
|
|
111
|
+
};
|
|
120
112
|
exports.parseError = parseError;
|
|
121
|
-
const parseBackendError = (e) => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
113
|
+
const parseBackendError = async (e) => {
|
|
114
|
+
let data;
|
|
115
|
+
try {
|
|
116
|
+
data = await e.response?.json();
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
// ignore
|
|
120
|
+
}
|
|
121
|
+
if (e.response?.status === 400) {
|
|
122
|
+
return new errors_1.ValidationError(data?.message || e.response?.statusText, undefined, e.stack);
|
|
125
123
|
}
|
|
126
|
-
if (
|
|
127
|
-
return new errors_1.NotFoundError(
|
|
124
|
+
if (e.response?.status === 404) {
|
|
125
|
+
return new errors_1.NotFoundError(data?.message || e.response?.statusText, undefined, e.stack);
|
|
128
126
|
}
|
|
129
|
-
if (
|
|
130
|
-
return new errors_1.SlippageError(
|
|
127
|
+
if (e.response?.status === 409) {
|
|
128
|
+
return new errors_1.SlippageError(data?.message || e.response?.statusText, 'The slippage is larger than the defined threshold. Please request a new route to get a fresh quote.', e.stack);
|
|
131
129
|
}
|
|
132
|
-
if (
|
|
133
|
-
return new errors_1.ServerError(
|
|
130
|
+
if (e.response?.status === 500) {
|
|
131
|
+
return new errors_1.ServerError(data?.message || e.response?.statusText, undefined, e.stack);
|
|
134
132
|
}
|
|
135
133
|
return new errors_1.ServerError('Something went wrong.', undefined, e.stack);
|
|
136
134
|
};
|
|
@@ -3,9 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.handlePreRestart = void 0;
|
|
4
4
|
const errors_1 = require("./errors");
|
|
5
5
|
const handlePreRestart = (route) => {
|
|
6
|
-
var _a;
|
|
7
6
|
for (let index = 0; index < route.steps.length; index++) {
|
|
8
|
-
const stepHasFailed =
|
|
7
|
+
const stepHasFailed = route.steps[index].execution?.status === 'FAILED';
|
|
9
8
|
if (stepHasFailed) {
|
|
10
9
|
handleErrorType(route, index);
|
|
11
10
|
deleteFailedProcesses(route, index);
|
|
@@ -15,14 +14,13 @@ const handlePreRestart = (route) => {
|
|
|
15
14
|
};
|
|
16
15
|
exports.handlePreRestart = handlePreRestart;
|
|
17
16
|
const handleErrorType = (route, index) => {
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const isGasPriceError = (_b = route.steps[index].execution) === null || _b === void 0 ? void 0 : _b.process.some((p) => { var _a; return ((_a = p.error) === null || _a === void 0 ? void 0 : _a.code) === errors_1.LifiErrorCode.TransactionUnderpriced; });
|
|
17
|
+
const isGasLimitError = route.steps[index].execution?.process.some((p) => p.error?.code === errors_1.LifiErrorCode.GasLimitError);
|
|
18
|
+
const isGasPriceError = route.steps[index].execution?.process.some((p) => p.error?.code === errors_1.LifiErrorCode.TransactionUnderpriced);
|
|
21
19
|
if (isGasLimitError) {
|
|
22
|
-
|
|
20
|
+
route.steps[index].estimate.gasCosts?.forEach((gasCost) => (gasCost.limit = `${Math.round(Number(gasCost.limit) * 1.25)}`));
|
|
23
21
|
}
|
|
24
22
|
if (isGasPriceError) {
|
|
25
|
-
|
|
23
|
+
route.steps[index].estimate.gasCosts?.forEach((gasCost) => (gasCost.price = `${Math.round(Number(gasCost.price) * 1.25)}`));
|
|
26
24
|
}
|
|
27
25
|
};
|
|
28
26
|
const deleteFailedProcesses = (route, index) => {
|
|
@@ -3,7 +3,6 @@ import { Token } from '@lifi/types';
|
|
|
3
3
|
import BigNumber from 'bignumber.js';
|
|
4
4
|
import { Signer } from 'ethers';
|
|
5
5
|
import { ChainId, Step } from '../types';
|
|
6
|
-
export declare const deepClone: <T>(src: T) => T;
|
|
7
6
|
export declare const sleep: (mills: number) => Promise<undefined>;
|
|
8
7
|
export declare const personalizeStep: (signer: Signer, step: Step) => Promise<Step>;
|
|
9
8
|
export declare const splitListIntoChunks: <T>(list: T[], chunkSize: number) => T[][];
|
package/dist/cjs/utils/utils.js
CHANGED
|
@@ -1,41 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
14
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.isNativeTokenAddress = exports.isZeroAddress = exports.loadTransactionReceipt = exports.repeatUntilDone = exports.formatTokenAmountOnly = exports.splitListIntoChunks = exports.personalizeStep = exports.sleep =
|
|
6
|
+
exports.isNativeTokenAddress = exports.isZeroAddress = exports.loadTransactionReceipt = exports.repeatUntilDone = exports.formatTokenAmountOnly = exports.splitListIntoChunks = exports.personalizeStep = exports.sleep = void 0;
|
|
16
7
|
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
17
8
|
const ethers_1 = require("ethers");
|
|
18
9
|
const connectors_1 = require("../connectors");
|
|
19
|
-
const deepClone = (src) => {
|
|
20
|
-
return JSON.parse(JSON.stringify(src));
|
|
21
|
-
};
|
|
22
|
-
exports.deepClone = deepClone;
|
|
23
10
|
const sleep = (mills) => {
|
|
24
11
|
return new Promise((resolve) => {
|
|
25
12
|
setTimeout(resolve, mills);
|
|
26
13
|
});
|
|
27
14
|
};
|
|
28
15
|
exports.sleep = sleep;
|
|
29
|
-
const personalizeStep = (signer, step) =>
|
|
16
|
+
const personalizeStep = async (signer, step) => {
|
|
30
17
|
if (step.action.toAddress && step.action.fromAddress) {
|
|
31
18
|
return step;
|
|
32
19
|
}
|
|
33
|
-
const address =
|
|
20
|
+
const address = await signer.getAddress();
|
|
34
21
|
const fromAddress = step.action.fromAddress || address;
|
|
35
22
|
const toAddress = step.action.toAddress || address;
|
|
36
|
-
return
|
|
37
|
-
|
|
38
|
-
|
|
23
|
+
return {
|
|
24
|
+
...step,
|
|
25
|
+
action: {
|
|
26
|
+
...step.action,
|
|
27
|
+
fromAddress,
|
|
28
|
+
toAddress,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
};
|
|
39
32
|
exports.personalizeStep = personalizeStep;
|
|
40
33
|
const splitListIntoChunks = (list, chunkSize) => list.reduce((resultList, item, index) => {
|
|
41
34
|
const chunkIndex = Math.floor(index / chunkSize);
|
|
@@ -65,7 +58,7 @@ const formatTokenAmountOnly = (token, amount) => {
|
|
|
65
58
|
}
|
|
66
59
|
// show at least 4 decimal places and at least two non-zero digests
|
|
67
60
|
let decimalPlaces = 3;
|
|
68
|
-
while (floated.lt(1 /
|
|
61
|
+
while (floated.lt(1 / 10 ** decimalPlaces)) {
|
|
69
62
|
decimalPlaces++;
|
|
70
63
|
}
|
|
71
64
|
return floated.toFixed(decimalPlaces + 1, 1);
|
|
@@ -77,16 +70,16 @@ exports.formatTokenAmountOnly = formatTokenAmountOnly;
|
|
|
77
70
|
* @param timeout The timeout in milliseconds between retries, defaults to 5000
|
|
78
71
|
* @returns The result of the toRepeat function
|
|
79
72
|
*/
|
|
80
|
-
const repeatUntilDone = (toRepeat, timeout = 5000) =>
|
|
73
|
+
const repeatUntilDone = async (toRepeat, timeout = 5000) => {
|
|
81
74
|
let result;
|
|
82
75
|
while (!result) {
|
|
83
|
-
result =
|
|
76
|
+
result = await toRepeat();
|
|
84
77
|
if (!result) {
|
|
85
|
-
|
|
78
|
+
await (0, exports.sleep)(timeout);
|
|
86
79
|
}
|
|
87
80
|
}
|
|
88
81
|
return result;
|
|
89
|
-
}
|
|
82
|
+
};
|
|
90
83
|
exports.repeatUntilDone = repeatUntilDone;
|
|
91
84
|
/**
|
|
92
85
|
* Loads a transaction receipt using the rpc for the given chain id
|
|
@@ -94,11 +87,11 @@ exports.repeatUntilDone = repeatUntilDone;
|
|
|
94
87
|
* @param txHash The hash of the transaction
|
|
95
88
|
* @returns TransactionReceipt
|
|
96
89
|
*/
|
|
97
|
-
const loadTransactionReceipt = (chainId, txHash) =>
|
|
98
|
-
const rpc =
|
|
99
|
-
const tx =
|
|
90
|
+
const loadTransactionReceipt = async (chainId, txHash) => {
|
|
91
|
+
const rpc = await (0, connectors_1.getRpcProvider)(chainId);
|
|
92
|
+
const tx = await rpc.getTransaction(txHash);
|
|
100
93
|
return tx.wait();
|
|
101
|
-
}
|
|
94
|
+
};
|
|
102
95
|
exports.loadTransactionReceipt = loadTransactionReceipt;
|
|
103
96
|
const isZeroAddress = (address) => {
|
|
104
97
|
if (address === ethers_1.constants.AddressZero ||
|
package/dist/cjs/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const name = "@lifi/sdk";
|
|
2
|
-
export declare const version = "
|
|
2
|
+
export declare const version = "2.0.0-beta.0";
|
package/dist/cjs/version.js
CHANGED
package/dist/connectors.js
CHANGED
|
@@ -1,16 +1,8 @@
|
|
|
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 { providers } from 'ethers';
|
|
11
|
-
import { getRandomNumber, ServerError } from '.';
|
|
12
2
|
import { ChainId } from './types';
|
|
13
3
|
import ConfigService from './services/ConfigService';
|
|
4
|
+
import { getRandomNumber } from './helpers';
|
|
5
|
+
import { ServerError } from './utils/errors';
|
|
14
6
|
// cached providers
|
|
15
7
|
const chainProviders = {};
|
|
16
8
|
// Archive RPC Provider
|
|
@@ -21,33 +13,33 @@ const archiveRpcs = {
|
|
|
21
13
|
[ChainId.FTM]: 'https://speedy-nodes-nyc.moralis.io/5ed6053dc39eba789ff466c9/fantom/mainnet',
|
|
22
14
|
};
|
|
23
15
|
// RPC Urls
|
|
24
|
-
export const getRpcUrl = (chainId, archive = false) =>
|
|
25
|
-
const rpcUrls =
|
|
16
|
+
export const getRpcUrl = async (chainId, archive = false) => {
|
|
17
|
+
const rpcUrls = await getRpcUrls(chainId, archive);
|
|
26
18
|
return rpcUrls[0];
|
|
27
|
-
}
|
|
28
|
-
export const getRpcUrls = (chainId, archive = false) =>
|
|
19
|
+
};
|
|
20
|
+
export const getRpcUrls = async (chainId, archive = false) => {
|
|
29
21
|
if (archive && archiveRpcs[chainId]) {
|
|
30
22
|
return [archiveRpcs[chainId]];
|
|
31
23
|
}
|
|
32
24
|
const configService = ConfigService.getInstance();
|
|
33
|
-
const config =
|
|
25
|
+
const config = await configService.getConfigAsync();
|
|
34
26
|
return config.rpcs[chainId];
|
|
35
|
-
}
|
|
27
|
+
};
|
|
36
28
|
const getRandomProvider = (providerList) => {
|
|
37
29
|
const index = getRandomNumber(0, providerList.length - 1);
|
|
38
30
|
return providerList[index];
|
|
39
31
|
};
|
|
40
32
|
// Provider
|
|
41
|
-
export const getRpcProvider = (chainId, archive = false) =>
|
|
33
|
+
export const getRpcProvider = async (chainId, archive = false) => {
|
|
42
34
|
if (archive && archiveRpcs[chainId]) {
|
|
43
35
|
// return archive PRC, but don't cache it
|
|
44
36
|
return new providers.FallbackProvider([
|
|
45
|
-
new providers.StaticJsonRpcProvider(
|
|
37
|
+
new providers.StaticJsonRpcProvider(await getRpcUrl(chainId, archive), chainId),
|
|
46
38
|
]);
|
|
47
39
|
}
|
|
48
40
|
if (!chainProviders[chainId]) {
|
|
49
41
|
chainProviders[chainId] = [];
|
|
50
|
-
const urls =
|
|
42
|
+
const urls = await getRpcUrls(chainId, archive);
|
|
51
43
|
urls.forEach((url) => {
|
|
52
44
|
chainProviders[chainId].push(new providers.FallbackProvider([
|
|
53
45
|
new providers.StaticJsonRpcProvider(url, chainId),
|
|
@@ -58,10 +50,10 @@ export const getRpcProvider = (chainId, archive = false) => __awaiter(void 0, vo
|
|
|
58
50
|
throw new ServerError(`Unable to configure provider for chain ${chainId}`);
|
|
59
51
|
}
|
|
60
52
|
return getRandomProvider(chainProviders[chainId]);
|
|
61
|
-
}
|
|
53
|
+
};
|
|
62
54
|
// Multicall
|
|
63
|
-
export const getMulticallAddress = (chainId) =>
|
|
55
|
+
export const getMulticallAddress = async (chainId) => {
|
|
64
56
|
const configService = ConfigService.getInstance();
|
|
65
|
-
const config =
|
|
57
|
+
const config = await configService.getConfigAsync();
|
|
66
58
|
return config.multicallAddresses[chainId];
|
|
67
|
-
}
|
|
59
|
+
};
|
|
@@ -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 { checkAllowance } from '../allowance';
|
|
11
2
|
import { checkBalance } from '../balance';
|
|
12
3
|
import ApiService from '../services/ApiService';
|
|
@@ -24,20 +15,19 @@ export class ExecutionManager {
|
|
|
24
15
|
this.allowInteraction = (value) => {
|
|
25
16
|
this.allowUserInteraction = value;
|
|
26
17
|
};
|
|
27
|
-
this.execute = ({ signer, step, statusManager, settings, }) =>
|
|
28
|
-
var _a, _b, _c, _d;
|
|
18
|
+
this.execute = async ({ signer, step, statusManager, settings, }) => {
|
|
29
19
|
step.execution = statusManager.initExecutionObject(step);
|
|
30
20
|
const chainsService = ChainsService.getInstance();
|
|
31
|
-
const fromChain =
|
|
32
|
-
const toChain =
|
|
21
|
+
const fromChain = await chainsService.getChainById(step.action.fromChainId);
|
|
22
|
+
const toChain = await chainsService.getChainById(step.action.toChainId);
|
|
33
23
|
const isBridgeExecution = fromChain.id !== toChain.id;
|
|
34
24
|
const currentProcessType = isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP';
|
|
35
25
|
// STEP 1: Check allowance
|
|
36
26
|
const existingProcess = step.execution.process.find((p) => p.type === currentProcessType);
|
|
37
27
|
// Check token approval only if fromToken is not the native token => no approval needed in that case
|
|
38
|
-
if (!
|
|
28
|
+
if (!existingProcess?.txHash &&
|
|
39
29
|
!isZeroAddress(step.action.fromToken.address)) {
|
|
40
|
-
|
|
30
|
+
await checkAllowance(signer, step, statusManager, settings, fromChain, this.allowUserInteraction);
|
|
41
31
|
}
|
|
42
32
|
// STEP 2: Get transaction
|
|
43
33
|
let process = statusManager.findOrCreateProcess(step, currentProcessType);
|
|
@@ -46,25 +36,28 @@ export class ExecutionManager {
|
|
|
46
36
|
let transaction;
|
|
47
37
|
if (process.txHash) {
|
|
48
38
|
// Make sure that the chain is still correct
|
|
49
|
-
const updatedSigner =
|
|
39
|
+
const updatedSigner = await switchChain(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
|
|
50
40
|
if (!updatedSigner) {
|
|
51
41
|
// Chain switch was not successful, stop execution here
|
|
52
42
|
return step.execution;
|
|
53
43
|
}
|
|
54
44
|
signer = updatedSigner;
|
|
55
45
|
// Load exiting transaction
|
|
56
|
-
transaction =
|
|
46
|
+
transaction = await getProvider(signer).getTransaction(process.txHash);
|
|
57
47
|
}
|
|
58
48
|
else {
|
|
59
49
|
process = statusManager.updateProcess(step, process.type, 'STARTED');
|
|
60
50
|
// Check balance
|
|
61
|
-
|
|
51
|
+
await checkBalance(signer, step);
|
|
62
52
|
// Create new transaction
|
|
63
53
|
if (!step.transactionRequest) {
|
|
64
|
-
const personalizedStep =
|
|
65
|
-
const updatedStep =
|
|
66
|
-
const comparedStep =
|
|
67
|
-
step =
|
|
54
|
+
const personalizedStep = await personalizeStep(signer, step);
|
|
55
|
+
const updatedStep = await ApiService.getStepTransaction(personalizedStep);
|
|
56
|
+
const comparedStep = await stepComparison(statusManager, personalizedStep, updatedStep, settings, this.allowUserInteraction);
|
|
57
|
+
step = {
|
|
58
|
+
...comparedStep,
|
|
59
|
+
execution: step.execution,
|
|
60
|
+
};
|
|
68
61
|
}
|
|
69
62
|
const { transactionRequest } = step;
|
|
70
63
|
if (!transactionRequest) {
|
|
@@ -72,7 +65,7 @@ export class ExecutionManager {
|
|
|
72
65
|
}
|
|
73
66
|
// STEP 3: Send the transaction
|
|
74
67
|
// Make sure that the chain is still correct
|
|
75
|
-
const updatedSigner =
|
|
68
|
+
const updatedSigner = await switchChain(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
|
|
76
69
|
if (!updatedSigner) {
|
|
77
70
|
// Chain switch was not successful, stop execution here
|
|
78
71
|
return step.execution;
|
|
@@ -83,7 +76,7 @@ export class ExecutionManager {
|
|
|
83
76
|
return step.execution;
|
|
84
77
|
}
|
|
85
78
|
// Submit the transaction
|
|
86
|
-
transaction =
|
|
79
|
+
transaction = await signer.sendTransaction(transactionRequest);
|
|
87
80
|
// STEP 4: Wait for the transaction
|
|
88
81
|
process = statusManager.updateProcess(step, process.type, 'PENDING', {
|
|
89
82
|
txHash: transaction.hash,
|
|
@@ -92,7 +85,7 @@ export class ExecutionManager {
|
|
|
92
85
|
transaction.hash,
|
|
93
86
|
});
|
|
94
87
|
}
|
|
95
|
-
|
|
88
|
+
await transaction.wait();
|
|
96
89
|
process = statusManager.updateProcess(step, process.type, 'PENDING', {
|
|
97
90
|
txHash: transaction.hash,
|
|
98
91
|
txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + transaction.hash,
|
|
@@ -111,7 +104,7 @@ export class ExecutionManager {
|
|
|
111
104
|
});
|
|
112
105
|
}
|
|
113
106
|
else {
|
|
114
|
-
const error =
|
|
107
|
+
const error = await parseError(e, step, process);
|
|
115
108
|
process = statusManager.updateProcess(step, process.type, 'FAILED', {
|
|
116
109
|
error: {
|
|
117
110
|
message: error.message,
|
|
@@ -134,20 +127,20 @@ export class ExecutionManager {
|
|
|
134
127
|
if (!processTxHash) {
|
|
135
128
|
throw new Error('Transaction hash is undefined.');
|
|
136
129
|
}
|
|
137
|
-
statusResponse =
|
|
130
|
+
statusResponse = await waitForReceivingTransaction(processTxHash, statusManager, process.type, step);
|
|
138
131
|
process = statusManager.updateProcess(step, process.type, 'DONE', {
|
|
139
132
|
substatus: statusResponse.substatus,
|
|
140
133
|
substatusMessage: statusResponse.substatusMessage ||
|
|
141
134
|
getSubstatusMessage(statusResponse.status, statusResponse.substatus),
|
|
142
|
-
txHash:
|
|
135
|
+
txHash: statusResponse.receiving?.txHash,
|
|
143
136
|
txLink: toChain.metamask.blockExplorerUrls[0] +
|
|
144
137
|
'tx/' +
|
|
145
|
-
|
|
138
|
+
statusResponse.receiving?.txHash,
|
|
146
139
|
});
|
|
147
140
|
statusManager.updateExecution(step, 'DONE', {
|
|
148
141
|
fromAmount: statusResponse.sending.amount,
|
|
149
|
-
toAmount:
|
|
150
|
-
toToken:
|
|
142
|
+
toAmount: statusResponse.receiving?.amount,
|
|
143
|
+
toToken: statusResponse.receiving?.token,
|
|
151
144
|
gasAmount: statusResponse.sending.gasAmount,
|
|
152
145
|
gasAmountUSD: statusResponse.sending.gasAmountUSD,
|
|
153
146
|
gasPrice: statusResponse.sending.gasPrice,
|
|
@@ -156,11 +149,12 @@ export class ExecutionManager {
|
|
|
156
149
|
});
|
|
157
150
|
}
|
|
158
151
|
catch (e) {
|
|
152
|
+
const htmlMessage = await getTransactionFailedMessage(step, process.txLink);
|
|
159
153
|
process = statusManager.updateProcess(step, process.type, 'FAILED', {
|
|
160
154
|
error: {
|
|
161
155
|
code: LifiErrorCode.TransactionFailed,
|
|
162
156
|
message: 'Failed while waiting for receiving chain.',
|
|
163
|
-
htmlMessage
|
|
157
|
+
htmlMessage,
|
|
164
158
|
},
|
|
165
159
|
});
|
|
166
160
|
statusManager.updateExecution(step, 'FAILED');
|
|
@@ -169,6 +163,6 @@ export class ExecutionManager {
|
|
|
169
163
|
}
|
|
170
164
|
// DONE
|
|
171
165
|
return step.execution;
|
|
172
|
-
}
|
|
166
|
+
};
|
|
173
167
|
}
|
|
174
168
|
}
|