@lifi/sdk 1.1.2 → 1.1.5

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.
Files changed (96) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/Lifi.js +179 -285
  3. package/dist/allowance/index.js +56 -148
  4. package/dist/allowance/utils.js +51 -116
  5. package/dist/balances/index.js +29 -92
  6. package/dist/balances/utils.js +108 -218
  7. package/dist/cjs/Lifi.d.ts +200 -0
  8. package/dist/cjs/Lifi.js +376 -0
  9. package/dist/cjs/allowance/index.d.ts +22 -0
  10. package/dist/cjs/allowance/index.js +78 -0
  11. package/dist/cjs/allowance/utils.d.ts +14 -0
  12. package/dist/cjs/allowance/utils.js +82 -0
  13. package/dist/cjs/balances/index.d.ts +11 -0
  14. package/dist/cjs/balances/index.js +46 -0
  15. package/dist/cjs/balances/utils.d.ts +5 -0
  16. package/dist/cjs/balances/utils.js +150 -0
  17. package/dist/cjs/connectors.d.ts +6 -0
  18. package/dist/cjs/connectors.js +77 -0
  19. package/dist/cjs/execution/StatusManager.d.ts +65 -0
  20. package/dist/cjs/execution/StatusManager.js +167 -0
  21. package/dist/cjs/execution/StepExecutor.d.ts +15 -0
  22. package/dist/cjs/execution/StepExecutor.js +74 -0
  23. package/dist/cjs/execution/allowance.execute.d.ts +4 -0
  24. package/dist/cjs/execution/allowance.execute.js +97 -0
  25. package/dist/cjs/execution/balanceCheck.execute.d.ts +3 -0
  26. package/dist/cjs/execution/balanceCheck.execute.js +48 -0
  27. package/dist/cjs/execution/bridges/bridge.execute.d.ts +7 -0
  28. package/dist/cjs/execution/bridges/bridge.execute.js +154 -0
  29. package/dist/cjs/execution/exchanges/swap.execute.d.ts +7 -0
  30. package/dist/cjs/execution/exchanges/swap.execute.js +164 -0
  31. package/dist/cjs/execution/index.d.ts +1 -0
  32. package/dist/cjs/execution/index.js +17 -0
  33. package/dist/cjs/execution/stepComparison.d.ts +14 -0
  34. package/dist/cjs/execution/stepComparison.js +46 -0
  35. package/dist/cjs/execution/switchChain.d.ts +16 -0
  36. package/dist/cjs/execution/switchChain.js +58 -0
  37. package/dist/cjs/execution/utils.d.ts +6 -0
  38. package/dist/cjs/execution/utils.js +137 -0
  39. package/dist/cjs/helpers.d.ts +18 -0
  40. package/dist/cjs/helpers.js +54 -0
  41. package/dist/cjs/index.d.ts +6 -0
  42. package/dist/cjs/index.js +27 -0
  43. package/dist/cjs/services/ApiService.d.ts +15 -0
  44. package/dist/cjs/services/ApiService.js +272 -0
  45. package/dist/cjs/services/ChainsService.d.ts +11 -0
  46. package/dist/cjs/services/ChainsService.js +54 -0
  47. package/dist/cjs/services/ConfigService.d.ts +23 -0
  48. package/dist/cjs/services/ConfigService.js +98 -0
  49. package/dist/cjs/typeguards.d.ts +4 -0
  50. package/dist/cjs/typeguards.js +53 -0
  51. package/dist/cjs/types/ERC20.d.ts +22 -0
  52. package/dist/cjs/types/ERC20.js +53 -0
  53. package/dist/cjs/types/index.d.ts +4 -0
  54. package/dist/cjs/types/index.js +22 -0
  55. package/dist/cjs/types/internal.types.d.ts +85 -0
  56. package/dist/cjs/types/internal.types.js +2 -0
  57. package/dist/cjs/utils/errors.d.ts +75 -0
  58. package/dist/cjs/utils/errors.js +115 -0
  59. package/dist/cjs/utils/getProvider.d.ts +3 -0
  60. package/dist/cjs/utils/getProvider.js +11 -0
  61. package/dist/cjs/utils/multicall.d.ts +10 -0
  62. package/dist/cjs/utils/multicall.js +77 -0
  63. package/dist/cjs/utils/multicallAbi.json +313 -0
  64. package/dist/cjs/utils/parseError.d.ts +38 -0
  65. package/dist/cjs/utils/parseError.js +141 -0
  66. package/dist/cjs/utils/preRestart.d.ts +2 -0
  67. package/dist/cjs/utils/preRestart.js +31 -0
  68. package/dist/cjs/utils/utils.d.ts +26 -0
  69. package/dist/cjs/utils/utils.js +120 -0
  70. package/dist/connectors.js +50 -133
  71. package/dist/execution/StatusManager.js +34 -41
  72. package/dist/execution/StepExecutor.js +54 -123
  73. package/dist/execution/allowance.execute.js +76 -142
  74. package/dist/execution/balanceCheck.execute.js +29 -74
  75. package/dist/execution/bridges/bridge.execute.js +132 -221
  76. package/dist/execution/exchanges/swap.execute.js +142 -225
  77. package/dist/execution/index.js +1 -17
  78. package/dist/execution/stepComparison.js +22 -61
  79. package/dist/execution/switchChain.js +33 -81
  80. package/dist/execution/utils.js +60 -119
  81. package/dist/helpers.js +15 -53
  82. package/dist/index.js +6 -25
  83. package/dist/services/ApiService.js +248 -385
  84. package/dist/services/ChainsService.js +29 -89
  85. package/dist/services/ConfigService.js +47 -86
  86. package/dist/typeguards.js +13 -21
  87. package/dist/types/ERC20.js +1 -4
  88. package/dist/types/index.js +4 -22
  89. package/dist/types/internal.types.js +1 -2
  90. package/dist/utils/errors.js +47 -93
  91. package/dist/utils/getProvider.js +3 -7
  92. package/dist/utils/multicall.js +61 -117
  93. package/dist/utils/parseError.js +73 -141
  94. package/dist/utils/preRestart.js +14 -21
  95. package/dist/utils/utils.js +47 -130
  96. package/package.json +34 -11
@@ -0,0 +1,150 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
16
+ const ethers_1 = require("ethers");
17
+ const connectors_1 = require("../connectors");
18
+ const multicall_1 = require("../utils/multicall");
19
+ const utils_1 = require("../utils/utils");
20
+ const balanceAbi = [
21
+ {
22
+ constant: true,
23
+ inputs: [{ name: 'who', type: 'address' }],
24
+ name: 'balanceOf',
25
+ outputs: [{ name: '', type: 'uint256' }],
26
+ payable: false,
27
+ stateMutability: 'view',
28
+ type: 'function',
29
+ },
30
+ {
31
+ constant: true,
32
+ inputs: [{ name: 'addr', type: 'address' }],
33
+ name: 'getEthBalance',
34
+ outputs: [{ name: 'balance', type: 'uint256' }],
35
+ payable: false,
36
+ stateMutability: 'view',
37
+ type: 'function',
38
+ },
39
+ ];
40
+ const getBalances = (walletAddress, tokens) => __awaiter(void 0, void 0, void 0, function* () {
41
+ if (tokens.length === 0) {
42
+ return [];
43
+ }
44
+ const { chainId } = tokens[0];
45
+ tokens.forEach((token) => {
46
+ if (token.chainId !== chainId) {
47
+ // eslint-disable-next-line no-console
48
+ console.warn(`Requested tokens have to be on same chain.`);
49
+ return [];
50
+ }
51
+ });
52
+ if ((yield (0, connectors_1.getMulticallAddress)(chainId)) && tokens.length > 1) {
53
+ return getBalancesFromProviderUsingMulticall(walletAddress, tokens);
54
+ }
55
+ else {
56
+ return getBalancesFromProvider(walletAddress, tokens);
57
+ }
58
+ });
59
+ const getBalancesFromProviderUsingMulticall = (walletAddress, tokens) => __awaiter(void 0, void 0, void 0, function* () {
60
+ // Configuration
61
+ const { chainId } = tokens[0];
62
+ const multicallAddress = yield (0, connectors_1.getMulticallAddress)(chainId);
63
+ if (!multicallAddress) {
64
+ throw new Error('No multicallAddress found for the given chain.');
65
+ }
66
+ return executeMulticall(walletAddress, tokens, multicallAddress, chainId);
67
+ });
68
+ const executeMulticall = (walletAddress, tokens, multicallAddress, chainId) => __awaiter(void 0, void 0, void 0, function* () {
69
+ // Collect calls we want to make
70
+ const calls = [];
71
+ tokens.map((token) => {
72
+ if ((0, utils_1.isZeroAddress)(token.address)) {
73
+ calls.push({
74
+ address: multicallAddress,
75
+ name: 'getEthBalance',
76
+ params: [walletAddress],
77
+ });
78
+ }
79
+ else {
80
+ calls.push({
81
+ address: token.address,
82
+ name: 'balanceOf',
83
+ params: [walletAddress],
84
+ });
85
+ }
86
+ });
87
+ const res = yield fetchViaMulticall(calls, balanceAbi, chainId, multicallAddress);
88
+ if (!res.length) {
89
+ return [];
90
+ }
91
+ return tokens.map((token, i) => {
92
+ const amount = new bignumber_js_1.default(res[i].amount.toString() || '0')
93
+ .shiftedBy(-token.decimals)
94
+ .toFixed();
95
+ return Object.assign(Object.assign({}, token), { amount: amount || '0', blockNumber: res[i].blockNumber });
96
+ });
97
+ });
98
+ const fetchViaMulticall = (calls, abi, chainId, multicallAddress) => __awaiter(void 0, void 0, void 0, function* () {
99
+ const result = yield (0, multicall_1.fetchDataUsingMulticall)(calls, abi, chainId, multicallAddress);
100
+ return result.map(({ data, blockNumber }) => ({
101
+ amount: data ? data : new bignumber_js_1.default(0),
102
+ blockNumber,
103
+ }));
104
+ });
105
+ const getBalancesFromProvider = (walletAddress, tokens) => __awaiter(void 0, void 0, void 0, function* () {
106
+ const chainId = tokens[0].chainId;
107
+ const rpc = yield (0, connectors_1.getRpcProvider)(chainId);
108
+ const tokenAmountPromises = tokens.map((token) => __awaiter(void 0, void 0, void 0, function* () {
109
+ let amount = '0';
110
+ let blockNumber;
111
+ try {
112
+ const balance = yield getBalanceFromProvider(walletAddress, token.address, chainId, rpc);
113
+ amount = new bignumber_js_1.default(balance.amount.toString())
114
+ .shiftedBy(-token.decimals)
115
+ .toString();
116
+ blockNumber = balance.blockNumber;
117
+ }
118
+ catch (e) {
119
+ // eslint-disable-next-line no-console
120
+ console.warn(e);
121
+ }
122
+ return Object.assign(Object.assign({}, token), { amount,
123
+ blockNumber });
124
+ }));
125
+ return Promise.all(tokenAmountPromises);
126
+ });
127
+ const getBalanceFromProvider = (walletAddress, assetId, chainId, provider) => __awaiter(void 0, void 0, void 0, function* () {
128
+ const blockNumber = yield getCurrentBlockNumber(chainId);
129
+ let balance;
130
+ if ((0, utils_1.isZeroAddress)(assetId)) {
131
+ balance = yield provider.getBalance(walletAddress, blockNumber);
132
+ }
133
+ else {
134
+ const contract = new ethers_1.ethers.Contract(assetId, ['function balanceOf(address owner) view returns (uint256)'], provider);
135
+ balance = yield contract.balanceOf(walletAddress, {
136
+ blockTag: blockNumber,
137
+ });
138
+ }
139
+ return {
140
+ amount: balance,
141
+ blockNumber,
142
+ };
143
+ });
144
+ const getCurrentBlockNumber = (chainId) => __awaiter(void 0, void 0, void 0, function* () {
145
+ const rpc = yield (0, connectors_1.getRpcProvider)(chainId);
146
+ return rpc.getBlockNumber();
147
+ });
148
+ exports.default = {
149
+ getBalances,
150
+ };
@@ -0,0 +1,6 @@
1
+ import { ChainId } from './types';
2
+ import { FallbackProvider } from '@ethersproject/providers';
3
+ export declare const getRpcUrl: (chainId: ChainId, archive?: boolean) => Promise<string>;
4
+ export declare const getRpcUrls: (chainId: ChainId, archive?: boolean) => Promise<string[]>;
5
+ export declare const getRpcProvider: (chainId: number, archive?: boolean) => Promise<FallbackProvider>;
6
+ export declare const getMulticallAddress: (chainId: ChainId) => Promise<string | undefined>;
@@ -0,0 +1,77 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.getMulticallAddress = exports.getRpcProvider = exports.getRpcUrls = exports.getRpcUrl = void 0;
16
+ const ethers_1 = require("ethers");
17
+ const _1 = require(".");
18
+ const types_1 = require("./types");
19
+ const ConfigService_1 = __importDefault(require("./services/ConfigService"));
20
+ // cached providers
21
+ const chainProviders = {};
22
+ // Archive RPC Provider
23
+ const archiveRpcs = {
24
+ [types_1.ChainId.ETH]: 'https://speedy-nodes-nyc.moralis.io/5ed6053dc39eba789ff466c9/eth/mainnet/archive',
25
+ [types_1.ChainId.BSC]: 'https://speedy-nodes-nyc.moralis.io/5ed6053dc39eba789ff466c9/bsc/mainnet/archive',
26
+ [types_1.ChainId.POL]: 'https://speedy-nodes-nyc.moralis.io/5ed6053dc39eba789ff466c9/polygon/mainnet/archive',
27
+ [types_1.ChainId.FTM]: 'https://speedy-nodes-nyc.moralis.io/5ed6053dc39eba789ff466c9/fantom/mainnet',
28
+ };
29
+ // RPC Urls
30
+ const getRpcUrl = (chainId, archive = false) => __awaiter(void 0, void 0, void 0, function* () {
31
+ const rpcUrls = yield (0, exports.getRpcUrls)(chainId, archive);
32
+ return rpcUrls[0];
33
+ });
34
+ exports.getRpcUrl = getRpcUrl;
35
+ const getRpcUrls = (chainId, archive = false) => __awaiter(void 0, void 0, void 0, function* () {
36
+ if (archive && archiveRpcs[chainId]) {
37
+ return [archiveRpcs[chainId]];
38
+ }
39
+ const configService = ConfigService_1.default.getInstance();
40
+ const config = yield configService.getConfigAsync();
41
+ return config.rpcs[chainId];
42
+ });
43
+ exports.getRpcUrls = getRpcUrls;
44
+ const getRandomProvider = (providerList) => {
45
+ const index = (0, _1.getRandomNumber)(0, providerList.length - 1);
46
+ return providerList[index];
47
+ };
48
+ // Provider
49
+ const getRpcProvider = (chainId, archive = false) => __awaiter(void 0, void 0, void 0, function* () {
50
+ if (archive && archiveRpcs[chainId]) {
51
+ // return archive PRC, but don't cache it
52
+ return new ethers_1.providers.FallbackProvider([
53
+ new ethers_1.providers.StaticJsonRpcProvider(yield (0, exports.getRpcUrl)(chainId, archive), chainId),
54
+ ]);
55
+ }
56
+ if (!chainProviders[chainId]) {
57
+ chainProviders[chainId] = [];
58
+ const urls = yield (0, exports.getRpcUrls)(chainId, archive);
59
+ urls.forEach((url) => {
60
+ chainProviders[chainId].push(new ethers_1.providers.FallbackProvider([
61
+ new ethers_1.providers.StaticJsonRpcProvider(url, chainId),
62
+ ]));
63
+ });
64
+ }
65
+ if (!chainProviders[chainId].length) {
66
+ throw new _1.ServerError(`Unable to configure provider for chain ${chainId}`);
67
+ }
68
+ return getRandomProvider(chainProviders[chainId]);
69
+ });
70
+ exports.getRpcProvider = getRpcProvider;
71
+ // Multicall
72
+ const getMulticallAddress = (chainId) => __awaiter(void 0, void 0, void 0, function* () {
73
+ const configService = ConfigService_1.default.getInstance();
74
+ const config = yield configService.getConfigAsync();
75
+ return config.multicallAddresses[chainId];
76
+ });
77
+ exports.getMulticallAddress = getMulticallAddress;
@@ -0,0 +1,65 @@
1
+ import { Execution, InternalExecutionSettings, Process, ProcessType, Route, Status, Step, Token } from '../types';
2
+ interface Receipt {
3
+ fromAmount?: string;
4
+ toAmount?: string;
5
+ toToken?: Token;
6
+ gasUsed?: string;
7
+ gasPrice?: string;
8
+ }
9
+ declare type InternalUpdateRouteCallback = (route: Route) => void;
10
+ declare type OptionalParameters = Partial<Pick<Process, 'doneAt' | 'failedAt' | 'txHash' | 'txLink' | 'error' | 'substatus' | 'substatusMessage'>>;
11
+ /**
12
+ * Manages status updates of a route and provides various functions for tracking processes
13
+ * @param {Route} route The route this StatusManger belongs to.
14
+ * @param {InternalExecutionSettings} settings The ExecutionSettings for this route.
15
+ * @param {InternalUpdateRouteCallback} internalUpdateRouteCallback Internal callback to propage route changes.
16
+ * @return {StatusManager} An instance of StatusManager.
17
+ */
18
+ export declare class StatusManager {
19
+ private readonly route;
20
+ private readonly settings;
21
+ private readonly internalUpdateRouteCallback;
22
+ private shouldUpdate;
23
+ constructor(route: Route, settings: InternalExecutionSettings, internalUpdateRouteCallback: InternalUpdateRouteCallback);
24
+ /**
25
+ * Initializes the execution object of a Step.
26
+ * @param {Step} step The current step in execution
27
+ * @return {Execution} The initialized execution object for this step and a function to update this step
28
+ */
29
+ initExecutionObject: (step: Step) => Execution;
30
+ /**
31
+ * Updates the execution object of a Step.
32
+ * @param {Step} step The current step in execution
33
+ * @param {Status} status The status for the execution
34
+ * @param {Receipt} receipt Optional. Information about received tokens
35
+ * @return {Step} The step with the updated execution object
36
+ */
37
+ updateExecution(step: Step, status: Status, receipt?: Receipt): Step;
38
+ /**
39
+ * Create and push a new process into the execution.
40
+ * @param {ProcessType} type Type of the process. Used to identify already existing processes.
41
+ * @param {Step} step The step that should contain the new process.
42
+ * @param {Status} status By default created procces is set to the STARTED status. We can override new process with the needed status.
43
+ * @return {Process}
44
+ */
45
+ findOrCreateProcess: (type: ProcessType, step: Step, status?: Status) => Process;
46
+ /**
47
+ * Update a process object.
48
+ * @param {Step} step The step where the process should be updated
49
+ * @param {ProcessType} type The process type to update
50
+ * @param {Status} status The status the process gets.
51
+ * @param {object} [params] Additional parameters to append to the process.
52
+ * @return {Process} The update process
53
+ */
54
+ updateProcess: (step: Step, type: ProcessType, status: Status, params?: OptionalParameters) => Process;
55
+ /**
56
+ * Remove a process from the execution
57
+ * @param {Step} step The step where the process should be removed from
58
+ * @param {ProcessType} type The process type to remove
59
+ * @return {void}
60
+ */
61
+ removeProcess: (step: Step, type: ProcessType) => void;
62
+ updateStepInRoute: (step: Step) => Step;
63
+ setShouldUpdate(value: boolean): void;
64
+ }
65
+ export {};
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StatusManager = void 0;
4
+ const types_1 = require("../types");
5
+ const utils_1 = require("../utils/utils");
6
+ const utils_2 = require("./utils");
7
+ /**
8
+ * Manages status updates of a route and provides various functions for tracking processes
9
+ * @param {Route} route The route this StatusManger belongs to.
10
+ * @param {InternalExecutionSettings} settings The ExecutionSettings for this route.
11
+ * @param {InternalUpdateRouteCallback} internalUpdateRouteCallback Internal callback to propage route changes.
12
+ * @return {StatusManager} An instance of StatusManager.
13
+ */
14
+ class StatusManager {
15
+ constructor(route, settings, internalUpdateRouteCallback) {
16
+ this.shouldUpdate = true;
17
+ /**
18
+ * Initializes the execution object of a Step.
19
+ * @param {Step} step The current step in execution
20
+ * @return {Execution} The initialized execution object for this step and a function to update this step
21
+ */
22
+ this.initExecutionObject = (step) => {
23
+ const currentExecution = step.execution || (0, utils_1.deepClone)(types_1.emptyExecution);
24
+ if (!step.execution) {
25
+ step.execution = currentExecution;
26
+ step.execution.status = 'PENDING';
27
+ this.updateStepInRoute(step);
28
+ }
29
+ // Change status to PENDING after resuming from FAILED
30
+ if (currentExecution.status === 'FAILED') {
31
+ currentExecution.status = 'PENDING';
32
+ this.updateStepInRoute(step);
33
+ }
34
+ return currentExecution;
35
+ };
36
+ /**
37
+ * Create and push a new process into the execution.
38
+ * @param {ProcessType} type Type of the process. Used to identify already existing processes.
39
+ * @param {Step} step The step that should contain the new process.
40
+ * @param {Status} status By default created procces is set to the STARTED status. We can override new process with the needed status.
41
+ * @return {Process}
42
+ */
43
+ this.findOrCreateProcess = (type, step, status) => {
44
+ if (!step.execution || !step.execution.process) {
45
+ throw new Error("Execution hasn't been initialized.");
46
+ }
47
+ const process = step.execution.process.find((p) => p.type === type);
48
+ if (process) {
49
+ return process;
50
+ }
51
+ const newProcess = {
52
+ type: type,
53
+ startedAt: Date.now(),
54
+ message: (0, utils_2.getProcessMessage)(type, status !== null && status !== void 0 ? status : 'STARTED'),
55
+ status: status !== null && status !== void 0 ? status : 'STARTED',
56
+ };
57
+ step.execution.process.push(newProcess);
58
+ this.updateStepInRoute(step);
59
+ return newProcess;
60
+ };
61
+ /**
62
+ * Update a process object.
63
+ * @param {Step} step The step where the process should be updated
64
+ * @param {ProcessType} type The process type to update
65
+ * @param {Status} status The status the process gets.
66
+ * @param {object} [params] Additional parameters to append to the process.
67
+ * @return {Process} The update process
68
+ */
69
+ this.updateProcess = (step, type, status, params) => {
70
+ var _a;
71
+ if (!step.execution) {
72
+ throw new Error("Can't update an empty step execution.");
73
+ }
74
+ const currentProcess = (_a = step === null || step === void 0 ? void 0 : step.execution) === null || _a === void 0 ? void 0 : _a.process.find((p) => p.type === type);
75
+ if (!currentProcess) {
76
+ throw new Error("Can't find a process for the given type.");
77
+ }
78
+ switch (status) {
79
+ case 'CANCELLED':
80
+ currentProcess.doneAt = Date.now();
81
+ break;
82
+ case 'FAILED':
83
+ currentProcess.doneAt = Date.now();
84
+ step.execution.status = 'FAILED';
85
+ break;
86
+ case 'DONE':
87
+ currentProcess.doneAt = Date.now();
88
+ break;
89
+ case 'PENDING':
90
+ step.execution.status = 'PENDING';
91
+ break;
92
+ case 'ACTION_REQUIRED':
93
+ step.execution.status = 'ACTION_REQUIRED';
94
+ break;
95
+ case 'CHAIN_SWITCH_REQUIRED':
96
+ step.execution.status = 'CHAIN_SWITCH_REQUIRED';
97
+ break;
98
+ default:
99
+ break;
100
+ }
101
+ currentProcess.status = status;
102
+ currentProcess.message = (0, utils_2.getProcessMessage)(type, status);
103
+ // set extra parameters or overwritte the standard params set in the switch statement
104
+ if (params) {
105
+ for (const [key, value] of Object.entries(params)) {
106
+ currentProcess[key] = value;
107
+ }
108
+ }
109
+ this.updateStepInRoute(step); // updates the step in the route
110
+ return currentProcess;
111
+ };
112
+ /**
113
+ * Remove a process from the execution
114
+ * @param {Step} step The step where the process should be removed from
115
+ * @param {ProcessType} type The process type to remove
116
+ * @return {void}
117
+ */
118
+ this.removeProcess = (step, type) => {
119
+ if (!step.execution) {
120
+ throw new Error("Execution hasn't been initialized.");
121
+ }
122
+ const index = step.execution.process.findIndex((p) => p.type === type);
123
+ step.execution.process.splice(index, 1);
124
+ this.updateStepInRoute(step);
125
+ };
126
+ this.updateStepInRoute = (step) => {
127
+ if (!this.shouldUpdate) {
128
+ return step;
129
+ }
130
+ const stepIndex = this.route.steps.findIndex((routeStep) => routeStep.id === step.id);
131
+ if (stepIndex === -1) {
132
+ throw new Error("Couldn't find a step to update.");
133
+ }
134
+ this.route.steps[stepIndex] = Object.assign(this.route.steps[stepIndex], step);
135
+ this.settings.updateCallback(this.route);
136
+ this.internalUpdateRouteCallback(this.route);
137
+ return this.route.steps[stepIndex];
138
+ };
139
+ this.route = route;
140
+ this.settings = settings;
141
+ this.internalUpdateRouteCallback = internalUpdateRouteCallback;
142
+ }
143
+ /**
144
+ * Updates the execution object of a Step.
145
+ * @param {Step} step The current step in execution
146
+ * @param {Status} status The status for the execution
147
+ * @param {Receipt} receipt Optional. Information about received tokens
148
+ * @return {Step} The step with the updated execution object
149
+ */
150
+ updateExecution(step, status, receipt) {
151
+ if (!step.execution) {
152
+ throw Error("Can't update empty execution.");
153
+ }
154
+ step.execution.status = status;
155
+ if (receipt) {
156
+ step.execution.fromAmount = receipt.fromAmount;
157
+ step.execution.toAmount = receipt.toAmount;
158
+ step.execution.toToken = receipt.toToken;
159
+ }
160
+ this.updateStepInRoute(step);
161
+ return step;
162
+ }
163
+ setShouldUpdate(value) {
164
+ this.shouldUpdate = value;
165
+ }
166
+ }
167
+ exports.StatusManager = StatusManager;
@@ -0,0 +1,15 @@
1
+ import { Signer } from 'ethers';
2
+ import { HaltingSettings, InternalExecutionSettings, Step } from '../types';
3
+ import { StatusManager } from './StatusManager';
4
+ export declare class StepExecutor {
5
+ settings: InternalExecutionSettings;
6
+ statusManager: StatusManager;
7
+ private swapExecutionManager;
8
+ private bridgeExecutionManager;
9
+ executionStopped: boolean;
10
+ constructor(statusManager: StatusManager, settings: InternalExecutionSettings);
11
+ stopStepExecution: (settings?: HaltingSettings) => void;
12
+ executeStep: (signer: Signer, step: Step) => Promise<Step>;
13
+ private executeSwap;
14
+ private executeCross;
15
+ }
@@ -0,0 +1,74 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.StepExecutor = void 0;
13
+ const bridge_execute_1 = require("./bridges/bridge.execute");
14
+ const swap_execute_1 = require("./exchanges/swap.execute");
15
+ const switchChain_1 = require("./switchChain");
16
+ const defaultExecutionHaltSettings = {
17
+ allowUpdates: true,
18
+ };
19
+ class StepExecutor {
20
+ constructor(statusManager, settings) {
21
+ this.swapExecutionManager = new swap_execute_1.SwapExecutionManager();
22
+ this.bridgeExecutionManager = new bridge_execute_1.BridgeExecutionManager();
23
+ this.executionStopped = false;
24
+ this.stopStepExecution = (settings) => {
25
+ const haltingSettings = Object.assign(Object.assign({}, defaultExecutionHaltSettings), settings);
26
+ this.swapExecutionManager.setShouldContinue(false);
27
+ this.bridgeExecutionManager.setShouldContinue(false);
28
+ this.statusManager.setShouldUpdate(haltingSettings.allowUpdates);
29
+ this.executionStopped = true;
30
+ };
31
+ this.executeStep = (signer, step) => __awaiter(this, void 0, void 0, function* () {
32
+ // check if signer is for correct chain
33
+ const updatedSigner = yield (0, switchChain_1.switchChain)(signer, this.statusManager, step, this.settings.switchChainHook, !this.executionStopped);
34
+ if (!updatedSigner) {
35
+ // chain switch was not successful, stop execution here
36
+ return step;
37
+ }
38
+ signer = updatedSigner;
39
+ switch (step.type) {
40
+ case 'lifi':
41
+ case 'cross':
42
+ yield this.executeCross(signer, step);
43
+ break;
44
+ case 'swap':
45
+ yield this.executeSwap(signer, step);
46
+ break;
47
+ default:
48
+ throw new Error('Unsupported step type.');
49
+ }
50
+ return step;
51
+ });
52
+ this.executeSwap = (signer, step) => __awaiter(this, void 0, void 0, function* () {
53
+ const swapParams = {
54
+ signer,
55
+ step,
56
+ settings: this.settings,
57
+ statusManager: this.statusManager,
58
+ };
59
+ return yield this.swapExecutionManager.execute(swapParams);
60
+ });
61
+ this.executeCross = (signer, step) => __awaiter(this, void 0, void 0, function* () {
62
+ const crossParams = {
63
+ signer,
64
+ step,
65
+ settings: this.settings,
66
+ statusManager: this.statusManager,
67
+ };
68
+ return yield this.bridgeExecutionManager.execute(crossParams);
69
+ });
70
+ this.statusManager = statusManager;
71
+ this.settings = settings;
72
+ }
73
+ }
74
+ exports.StepExecutor = StepExecutor;
@@ -0,0 +1,4 @@
1
+ import { Signer } from 'ethers';
2
+ import { Chain, Step, Token } from '../types';
3
+ import { StatusManager } from './StatusManager';
4
+ export declare const checkAllowance: (signer: Signer, step: Step, chain: Chain, token: Token, amount: string, spenderAddress: string, statusManager: StatusManager, infiniteApproval?: boolean, allowUserInteraction?: boolean) => Promise<void>;
@@ -0,0 +1,97 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.checkAllowance = void 0;
16
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
17
+ const ethers_1 = require("ethers");
18
+ const utils_1 = require("../allowance/utils");
19
+ const getProvider_1 = require("../utils/getProvider");
20
+ const parseError_1 = require("../utils/parseError");
21
+ const checkAllowance = (signer, step, chain, token, amount, spenderAddress, statusManager, infiniteApproval = false, allowUserInteraction = false
22
+ // eslint-disable-next-line max-params
23
+ ) => __awaiter(void 0, void 0, void 0, function* () {
24
+ // Ask user to set allowance
25
+ // -> set currentExecution
26
+ let allowanceProcess = statusManager.findOrCreateProcess('TOKEN_ALLOWANCE', step);
27
+ // -> check allowance
28
+ try {
29
+ if (allowanceProcess.txHash) {
30
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING');
31
+ yield (0, getProvider_1.getProvider)(signer).waitForTransaction(allowanceProcess.txHash);
32
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
33
+ // TODO: Do we need this check?
34
+ }
35
+ else if (allowanceProcess.status === 'DONE') {
36
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
37
+ }
38
+ else {
39
+ const approved = yield (0, utils_1.getApproved)(signer, token.address, spenderAddress);
40
+ if (new bignumber_js_1.default(amount).gt(approved)) {
41
+ if (!allowUserInteraction) {
42
+ return;
43
+ }
44
+ const approvalAmount = infiniteApproval
45
+ ? ethers_1.constants.MaxUint256.toString()
46
+ : amount;
47
+ const approveTx = yield (0, utils_1.setApproval)(signer, token.address, spenderAddress, approvalAmount);
48
+ // update currentExecution
49
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING', {
50
+ txHash: approveTx.hash,
51
+ txLink: chain.metamask.blockExplorerUrls[0] + 'tx/' + approveTx.hash,
52
+ });
53
+ // wait for transcation
54
+ yield approveTx.wait();
55
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
56
+ }
57
+ else {
58
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
59
+ }
60
+ }
61
+ }
62
+ catch (e) {
63
+ // -> set status
64
+ if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
65
+ yield transactionReplaced(e.replacement, allowanceProcess, step, chain, statusManager);
66
+ }
67
+ else {
68
+ const error = yield (0, parseError_1.parseError)(e, step, allowanceProcess);
69
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'FAILED', {
70
+ error: {
71
+ message: error.message,
72
+ htmlMessage: error.htmlMessage,
73
+ code: error.code,
74
+ },
75
+ });
76
+ statusManager.updateExecution(step, 'FAILED');
77
+ throw error;
78
+ }
79
+ }
80
+ });
81
+ exports.checkAllowance = checkAllowance;
82
+ const transactionReplaced = (replacementTx, allowanceProcess, step, chain, statusManager) => __awaiter(void 0, void 0, void 0, function* () {
83
+ try {
84
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING', {
85
+ txHash: replacementTx.hash,
86
+ txLink: chain.metamask.blockExplorerUrls[0] + 'tx/' + replacementTx.hash,
87
+ });
88
+ yield replacementTx.wait();
89
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
90
+ }
91
+ catch (e) {
92
+ if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
93
+ yield transactionReplaced(e.replacement, allowanceProcess, step, chain, statusManager);
94
+ }
95
+ throw e;
96
+ }
97
+ });
@@ -0,0 +1,3 @@
1
+ import { ethers } from 'ethers';
2
+ import { Step } from '..';
3
+ export declare const balanceCheck: (signer: ethers.Signer, step: Step) => Promise<void>;