@lifi/sdk 2.0.0-beta.8 → 2.0.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.
Files changed (61) hide show
  1. package/dist/LiFi.d.ts +9 -9
  2. package/dist/LiFi.js +11 -11
  3. package/dist/allowance/checkAllowance.js +18 -2
  4. package/dist/allowance/utils.d.ts +2 -1
  5. package/dist/allowance/utils.js +7 -2
  6. package/dist/cjs/LiFi.d.ts +9 -9
  7. package/dist/cjs/LiFi.js +12 -13
  8. package/dist/cjs/allowance/checkAllowance.js +18 -2
  9. package/dist/cjs/allowance/utils.d.ts +2 -1
  10. package/dist/cjs/allowance/utils.js +7 -2
  11. package/dist/cjs/connectors.d.ts +1 -1
  12. package/dist/cjs/connectors.js +7 -9
  13. package/dist/cjs/execution/RouteExecutionManager.d.ts +1 -1
  14. package/dist/cjs/execution/RouteExecutionManager.js +1 -1
  15. package/dist/cjs/execution/StatusManager.js +1 -1
  16. package/dist/cjs/execution/StepExecutionManager.js +22 -0
  17. package/dist/cjs/execution/StepExecutor.js +13 -5
  18. package/dist/cjs/execution/stepComparison.d.ts +1 -1
  19. package/dist/cjs/execution/stepComparison.js +2 -5
  20. package/dist/cjs/helpers.d.ts +2 -0
  21. package/dist/cjs/helpers.js +6 -1
  22. package/dist/cjs/services/ApiService.d.ts +1 -1
  23. package/dist/cjs/services/ConfigService.d.ts +1 -1
  24. package/dist/cjs/services/ConfigService.js +1 -2
  25. package/dist/cjs/typeguards.d.ts +2 -2
  26. package/dist/cjs/types/internal.types.d.ts +47 -8
  27. package/dist/cjs/utils/errors.d.ts +22 -1
  28. package/dist/cjs/utils/errors.js +28 -4
  29. package/dist/cjs/utils/parseError.js +31 -12
  30. package/dist/cjs/utils/preRestart.d.ts +2 -1
  31. package/dist/cjs/utils/preRestart.js +24 -3
  32. package/dist/cjs/version.d.ts +1 -1
  33. package/dist/cjs/version.js +1 -1
  34. package/dist/connectors.d.ts +1 -1
  35. package/dist/connectors.js +7 -9
  36. package/dist/execution/RouteExecutionManager.d.ts +1 -1
  37. package/dist/execution/RouteExecutionManager.js +1 -1
  38. package/dist/execution/StatusManager.js +1 -1
  39. package/dist/execution/StepExecutionManager.js +22 -0
  40. package/dist/execution/StepExecutor.js +13 -5
  41. package/dist/execution/stepComparison.d.ts +1 -1
  42. package/dist/execution/stepComparison.js +2 -5
  43. package/dist/helpers.d.ts +2 -0
  44. package/dist/helpers.js +4 -0
  45. package/dist/services/ApiService.d.ts +1 -1
  46. package/dist/services/ConfigService.d.ts +1 -1
  47. package/dist/services/ConfigService.js +1 -2
  48. package/dist/typeguards.d.ts +2 -2
  49. package/dist/types/internal.types.d.ts +47 -8
  50. package/dist/utils/errors.d.ts +22 -1
  51. package/dist/utils/errors.js +24 -0
  52. package/dist/utils/parseError.js +32 -13
  53. package/dist/utils/preRestart.d.ts +2 -1
  54. package/dist/utils/preRestart.js +24 -3
  55. package/dist/version.d.ts +1 -1
  56. package/dist/version.js +1 -1
  57. package/package.json +15 -15
  58. package/dist/cjs/services/ApiService.unit.handlers.d.ts +0 -1
  59. package/dist/cjs/services/ApiService.unit.handlers.js +0 -50
  60. package/dist/services/ApiService.unit.handlers.d.ts +0 -1
  61. package/dist/services/ApiService.unit.handlers.js +0 -44
@@ -22,7 +22,28 @@ export declare enum LifiErrorCode {
22
22
  TransactionCanceled = 1010,
23
23
  SlippageError = 1011,
24
24
  TransactionRejected = 1012,
25
- BalanceError = 1013
25
+ BalanceError = 1013,
26
+ AllowanceRequired = 1014,
27
+ InsufficientFunds = 1015
28
+ }
29
+ export declare enum EthersErrorType {
30
+ ActionRejected = "ACTION_REJECTED",
31
+ CallExecption = "CALL_EXCEPTION",
32
+ InsufficientFunds = "INSUFFICIENT_FUNDS"
33
+ }
34
+ export declare enum EthersErrorMessage {
35
+ ERC20Allowance = "ERC20: transfer amount exceeds allowance",
36
+ LowGas = "intrinsic gas too low",
37
+ OutOfGas = "out of gas",
38
+ Underpriced = "underpriced",
39
+ LowReplacementFee = "replacement fee too low"
40
+ }
41
+ export declare enum ErrorMessage {
42
+ UnknownError = "Unknown error occurred.",
43
+ SlippageError = "The slippage is larger than the defined threshold. Please request a new route to get a fresh quote.",
44
+ GasLimitLow = "Gas limit is too low.",
45
+ TransactionUnderpriced = "Transaction is underpriced.",
46
+ Default = "Something went wrong."
26
47
  }
27
48
  export declare enum MetaMaskRPCErrorCode {
28
49
  invalidInput = -32000,
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
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;
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.ErrorMessage = exports.EthersErrorMessage = exports.EthersErrorType = exports.LifiErrorCode = void 0;
4
4
  var ErrorType;
5
5
  (function (ErrorType) {
6
6
  ErrorType["RPCError"] = "RPCError";
@@ -28,7 +28,31 @@ var LifiErrorCode;
28
28
  LifiErrorCode[LifiErrorCode["SlippageError"] = 1011] = "SlippageError";
29
29
  LifiErrorCode[LifiErrorCode["TransactionRejected"] = 1012] = "TransactionRejected";
30
30
  LifiErrorCode[LifiErrorCode["BalanceError"] = 1013] = "BalanceError";
31
- })(LifiErrorCode = exports.LifiErrorCode || (exports.LifiErrorCode = {}));
31
+ LifiErrorCode[LifiErrorCode["AllowanceRequired"] = 1014] = "AllowanceRequired";
32
+ LifiErrorCode[LifiErrorCode["InsufficientFunds"] = 1015] = "InsufficientFunds";
33
+ })(LifiErrorCode || (exports.LifiErrorCode = LifiErrorCode = {}));
34
+ var EthersErrorType;
35
+ (function (EthersErrorType) {
36
+ EthersErrorType["ActionRejected"] = "ACTION_REJECTED";
37
+ EthersErrorType["CallExecption"] = "CALL_EXCEPTION";
38
+ EthersErrorType["InsufficientFunds"] = "INSUFFICIENT_FUNDS";
39
+ })(EthersErrorType || (exports.EthersErrorType = EthersErrorType = {}));
40
+ var EthersErrorMessage;
41
+ (function (EthersErrorMessage) {
42
+ EthersErrorMessage["ERC20Allowance"] = "ERC20: transfer amount exceeds allowance";
43
+ EthersErrorMessage["LowGas"] = "intrinsic gas too low";
44
+ EthersErrorMessage["OutOfGas"] = "out of gas";
45
+ EthersErrorMessage["Underpriced"] = "underpriced";
46
+ EthersErrorMessage["LowReplacementFee"] = "replacement fee too low";
47
+ })(EthersErrorMessage || (exports.EthersErrorMessage = EthersErrorMessage = {}));
48
+ var ErrorMessage;
49
+ (function (ErrorMessage) {
50
+ ErrorMessage["UnknownError"] = "Unknown error occurred.";
51
+ ErrorMessage["SlippageError"] = "The slippage is larger than the defined threshold. Please request a new route to get a fresh quote.";
52
+ ErrorMessage["GasLimitLow"] = "Gas limit is too low.";
53
+ ErrorMessage["TransactionUnderpriced"] = "Transaction is underpriced.";
54
+ ErrorMessage["Default"] = "Something went wrong.";
55
+ })(ErrorMessage || (exports.ErrorMessage = ErrorMessage = {}));
32
56
  var MetaMaskRPCErrorCode;
33
57
  (function (MetaMaskRPCErrorCode) {
34
58
  MetaMaskRPCErrorCode[MetaMaskRPCErrorCode["invalidInput"] = -32000] = "invalidInput";
@@ -42,7 +66,7 @@ var MetaMaskRPCErrorCode;
42
66
  MetaMaskRPCErrorCode[MetaMaskRPCErrorCode["methodNotFound"] = -32601] = "methodNotFound";
43
67
  MetaMaskRPCErrorCode[MetaMaskRPCErrorCode["invalidParams"] = -32602] = "invalidParams";
44
68
  MetaMaskRPCErrorCode[MetaMaskRPCErrorCode["internal"] = -32603] = "internal";
45
- })(MetaMaskRPCErrorCode = exports.MetaMaskRPCErrorCode || (exports.MetaMaskRPCErrorCode = {}));
69
+ })(MetaMaskRPCErrorCode || (exports.MetaMaskRPCErrorCode = MetaMaskRPCErrorCode = {}));
46
70
  var MetaMaskProviderErrorCode;
47
71
  (function (MetaMaskProviderErrorCode) {
48
72
  MetaMaskProviderErrorCode[MetaMaskProviderErrorCode["userRejectedRequest"] = 4001] = "userRejectedRequest";
@@ -50,7 +74,7 @@ var MetaMaskProviderErrorCode;
50
74
  MetaMaskProviderErrorCode[MetaMaskProviderErrorCode["unsupportedMethod"] = 4200] = "unsupportedMethod";
51
75
  MetaMaskProviderErrorCode[MetaMaskProviderErrorCode["disconnected"] = 4900] = "disconnected";
52
76
  MetaMaskProviderErrorCode[MetaMaskProviderErrorCode["chainDisconnected"] = 4901] = "chainDisconnected";
53
- })(MetaMaskProviderErrorCode = exports.MetaMaskProviderErrorCode || (exports.MetaMaskProviderErrorCode = {}));
77
+ })(MetaMaskProviderErrorCode || (exports.MetaMaskProviderErrorCode = MetaMaskProviderErrorCode = {}));
54
78
  class LifiError extends Error {
55
79
  constructor(type, code, message, htmlMessage, stack) {
56
80
  super(message);
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.parseBackendError = exports.parseError = exports.getTransactionFailedMessage = exports.getTransactionNotSentMessage = void 0;
7
7
  const eth_rpc_errors_1 = require("eth-rpc-errors");
8
+ const helpers_1 = require("../helpers");
8
9
  const ChainsService_1 = __importDefault(require("../services/ChainsService"));
9
10
  const errors_1 = require("./errors");
10
11
  const utils_1 = require("./utils");
@@ -79,13 +80,13 @@ const parseError = async (e, step, process) => {
79
80
  // rpc errors
80
81
  // underpriced errors are sent as internal errors, so we need to parse the message manually
81
82
  if (e.code === eth_rpc_errors_1.errorCodes.rpc.internal &&
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);
83
+ (e.message?.includes(errors_1.EthersErrorMessage.Underpriced) ||
84
+ e.message?.includes(errors_1.EthersErrorMessage.LowReplacementFee))) {
85
+ return new errors_1.RPCError(errors_1.LifiErrorCode.TransactionUnderpriced, errors_1.ErrorMessage.TransactionUnderpriced, await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
85
86
  }
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);
87
+ if (e.message?.includes(errors_1.EthersErrorMessage.LowGas) ||
88
+ e.message?.includes(errors_1.EthersErrorMessage.OutOfGas)) {
89
+ return new errors_1.TransactionError(errors_1.LifiErrorCode.GasLimitError, errors_1.ErrorMessage.GasLimitLow, await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
89
90
  }
90
91
  return new errors_1.RPCError(e.code, (0, eth_rpc_errors_1.getMessageFromCode)(e.code), await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
91
92
  }
@@ -96,9 +97,27 @@ const parseError = async (e, step, process) => {
96
97
  }
97
98
  }
98
99
  switch (e.code) {
99
- case 'CALL_EXCEPTION':
100
- return new errors_1.ProviderError(errors_1.LifiErrorCode.TransactionFailed, e.reason, await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
101
- case 'ACTION_REJECTED':
100
+ case errors_1.EthersErrorType.CallExecption:
101
+ const defaultErrorMessage = await (0, exports.getTransactionNotSentMessage)(step, process);
102
+ try {
103
+ if (!step?.action.fromChainId) {
104
+ throw new Error('Signer is not defined.');
105
+ }
106
+ const response = await (0, helpers_1.fetchTxErrorDetails)(e.transactionHash, step?.action.fromChainId);
107
+ const errorMessage = response?.error_message ?? e.reason;
108
+ const isAllowanceError = response?.error_message?.includes(errors_1.EthersErrorMessage.ERC20Allowance) || e.reason?.includes(errors_1.EthersErrorMessage.ERC20Allowance);
109
+ if (isAllowanceError) {
110
+ return new errors_1.TransactionError(errors_1.LifiErrorCode.AllowanceRequired, e.reason, errorMessage, e.stack);
111
+ }
112
+ // Error messages other than allowance error will be handled in catch block
113
+ throw new Error(e);
114
+ }
115
+ catch (error) {
116
+ return new errors_1.ProviderError(errors_1.LifiErrorCode.TransactionFailed, e.reason, defaultErrorMessage, e.stack);
117
+ }
118
+ case errors_1.EthersErrorType.InsufficientFunds:
119
+ return new errors_1.TransactionError(errors_1.LifiErrorCode.InsufficientFunds, e.message, await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
120
+ case errors_1.EthersErrorType.ActionRejected:
102
121
  case errors_1.MetaMaskProviderErrorCode.userRejectedRequest:
103
122
  return new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionRejected, e.message, await (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
104
123
  case errors_1.LifiErrorCode.TransactionUnprepared:
@@ -106,7 +125,7 @@ const parseError = async (e, step, process) => {
106
125
  case errors_1.LifiErrorCode.ValidationError:
107
126
  return new errors_1.TransactionError(errors_1.LifiErrorCode.ValidationError, e.message, e.htmlMessage);
108
127
  default:
109
- return new errors_1.UnknownError(errors_1.LifiErrorCode.InternalError, e.message || 'Unknown error occurred.', undefined, e.stack);
128
+ return new errors_1.UnknownError(errors_1.LifiErrorCode.InternalError, e.message || errors_1.ErrorMessage.UnknownError, undefined, e.stack);
110
129
  }
111
130
  };
112
131
  exports.parseError = parseError;
@@ -125,11 +144,11 @@ const parseBackendError = async (e) => {
125
144
  return new errors_1.NotFoundError(data?.message || e.response?.statusText, undefined, e.stack);
126
145
  }
127
146
  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);
147
+ return new errors_1.SlippageError(data?.message || e.response?.statusText, errors_1.ErrorMessage.SlippageError, e.stack);
129
148
  }
130
149
  if (e.response?.status === 500) {
131
150
  return new errors_1.ServerError(data?.message || e.response?.statusText, undefined, e.stack);
132
151
  }
133
- return new errors_1.ServerError('Something went wrong.', undefined, e.stack);
152
+ return new errors_1.ServerError(errors_1.ErrorMessage.Default, undefined, e.stack);
134
153
  };
135
154
  exports.parseBackendError = parseBackendError;
@@ -1,2 +1,3 @@
1
+ import { Signer } from 'ethers';
1
2
  import { Route } from '../types';
2
- export declare const handlePreRestart: (route: Route) => void;
3
+ export declare const handlePreRestart: (route: Route, signer: Signer) => Promise<void>;
@@ -2,24 +2,45 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.handlePreRestart = void 0;
4
4
  const errors_1 = require("./errors");
5
- const handlePreRestart = (route) => {
5
+ const handlePreRestart = async (route, signer) => {
6
6
  for (let index = 0; index < route.steps.length; index++) {
7
7
  const stepHasFailed = route.steps[index].execution?.status === 'FAILED';
8
8
  if (stepHasFailed) {
9
- handleErrorType(route, index);
9
+ await handleErrorType(route, index, signer);
10
10
  deleteFailedProcesses(route, index);
11
11
  deleteTransactionData(route, index);
12
12
  }
13
13
  }
14
14
  };
15
15
  exports.handlePreRestart = handlePreRestart;
16
- const handleErrorType = (route, index) => {
16
+ const handleErrorType = async (route, index, signer) => {
17
17
  const isGasLimitError = route.steps[index].execution?.process.some((p) => p.error?.code === errors_1.LifiErrorCode.GasLimitError);
18
18
  const isGasPriceError = route.steps[index].execution?.process.some((p) => p.error?.code === errors_1.LifiErrorCode.TransactionUnderpriced);
19
+ const { transactionRequest } = route.steps[index];
19
20
  if (isGasLimitError) {
21
+ if (transactionRequest) {
22
+ let gasLimit = transactionRequest.gasLimit;
23
+ try {
24
+ gasLimit = await signer.estimateGas(transactionRequest);
25
+ }
26
+ catch (error) { }
27
+ if (gasLimit) {
28
+ transactionRequest.gasLimit = `${(BigInt(gasLimit.toString()) * 125n) / 100n}`;
29
+ }
30
+ }
20
31
  route.steps[index].estimate.gasCosts?.forEach((gasCost) => (gasCost.limit = `${Math.round(Number(gasCost.limit) * 1.25)}`));
21
32
  }
22
33
  if (isGasPriceError) {
34
+ if (transactionRequest) {
35
+ let gasPrice = transactionRequest.gasPrice;
36
+ try {
37
+ gasPrice = await signer.getGasPrice();
38
+ }
39
+ catch (error) { }
40
+ if (gasPrice) {
41
+ transactionRequest.gasPrice = `${(BigInt(gasPrice.toString()) * 125n) / 100n}`;
42
+ }
43
+ }
23
44
  route.steps[index].estimate.gasCosts?.forEach((gasCost) => (gasCost.price = `${Math.round(Number(gasCost.price) * 1.25)}`));
24
45
  }
25
46
  };
@@ -1,2 +1,2 @@
1
1
  export declare const name = "@lifi/sdk";
2
- export declare const version = "2.0.0-beta.8";
2
+ export declare const version = "2.0.0";
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = exports.name = void 0;
4
4
  exports.name = '@lifi/sdk';
5
- exports.version = '2.0.0-beta.8';
5
+ exports.version = '2.0.0';
@@ -1,5 +1,5 @@
1
- import { ChainId } from './types';
2
1
  import { FallbackProvider } from '@ethersproject/providers';
2
+ import { ChainId } from './types';
3
3
  export declare const getRpcUrl: (chainId: ChainId, archive?: boolean) => Promise<string>;
4
4
  export declare const getRpcUrls: (chainId: ChainId, archive?: boolean) => Promise<string[]>;
5
5
  export declare const getRpcProvider: (chainId: number, archive?: boolean) => Promise<FallbackProvider>;
@@ -1,7 +1,7 @@
1
- import { providers } from 'ethers';
2
- import { ChainId } from './types';
3
- import ConfigService from './services/ConfigService';
1
+ import { FallbackProvider, StaticJsonRpcProvider, } from '@ethersproject/providers';
4
2
  import { getRandomNumber } from './helpers';
3
+ import ConfigService from './services/ConfigService';
4
+ import { ChainId } from './types';
5
5
  import { ServerError } from './utils/errors';
6
6
  // cached providers
7
7
  const chainProviders = {};
@@ -33,17 +33,15 @@ const getRandomProvider = (providerList) => {
33
33
  export const getRpcProvider = async (chainId, archive = false) => {
34
34
  if (archive && archiveRpcs[chainId]) {
35
35
  // return archive PRC, but don't cache it
36
- return new providers.FallbackProvider([
37
- new providers.StaticJsonRpcProvider(await getRpcUrl(chainId, archive), chainId),
36
+ return new FallbackProvider([
37
+ new StaticJsonRpcProvider(await getRpcUrl(chainId, archive), chainId),
38
38
  ]);
39
39
  }
40
- if (!chainProviders[chainId]) {
40
+ if (!chainProviders[chainId]?.length) {
41
41
  chainProviders[chainId] = [];
42
42
  const urls = await getRpcUrls(chainId, archive);
43
43
  urls.forEach((url) => {
44
- chainProviders[chainId].push(new providers.FallbackProvider([
45
- new providers.StaticJsonRpcProvider(url, chainId),
46
- ]));
44
+ chainProviders[chainId].push(new FallbackProvider([new StaticJsonRpcProvider(url, chainId)]));
47
45
  });
48
46
  }
49
47
  if (!chainProviders[chainId].length) {
@@ -6,7 +6,7 @@ export declare class RouteExecutionManager {
6
6
  private executionDictionary;
7
7
  private executionPromiseDictionary;
8
8
  protected configService: ConfigService;
9
- constructor(configUpdate?: ConfigUpdate);
9
+ constructor(configUpdate: ConfigUpdate);
10
10
  /**
11
11
  * Execute a route.
12
12
  * @param {Signer} signer - The signer required to send the transactions.
@@ -50,7 +50,7 @@ export class RouteExecutionManager {
50
50
  return executionPromise ?? clonedRoute;
51
51
  }
52
52
  }
53
- handlePreRestart(clonedRoute);
53
+ await handlePreRestart(clonedRoute, signer);
54
54
  const executionPromise = this.executeSteps(signer, clonedRoute, settings);
55
55
  this.executionPromiseDictionary[clonedRoute.id] = executionPromise;
56
56
  return executionPromise;
@@ -133,7 +133,7 @@ export class StatusManager {
133
133
  throw new Error("Couldn't find a step to update.");
134
134
  }
135
135
  this.route.steps[stepIndex] = Object.assign(this.route.steps[stepIndex], step);
136
- this.settings.updateCallback(this.route);
136
+ this.settings.updateRouteHook(this.route);
137
137
  this.internalUpdateRouteCallback(this.route);
138
138
  return this.route.steps[stepIndex];
139
139
  };
@@ -75,6 +75,28 @@ export class StepExecutionManager {
75
75
  if (!this.allowUserInteraction) {
76
76
  return step.execution;
77
77
  }
78
+ if (settings.updateTransactionRequestHook) {
79
+ const customConfig = await settings.updateTransactionRequestHook(transactionRequest);
80
+ transactionRequest.gasLimit = customConfig.gasLimit;
81
+ transactionRequest.gasPrice = customConfig.gasPrice;
82
+ transactionRequest.maxPriorityFeePerGas =
83
+ customConfig.maxPriorityFeePerGas;
84
+ transactionRequest.maxFeePerGas = customConfig.maxFeePerGas;
85
+ }
86
+ else {
87
+ try {
88
+ const estimatedGasLimit = await signer.estimateGas(transactionRequest);
89
+ if (estimatedGasLimit) {
90
+ transactionRequest.gasLimit = `${(BigInt(estimatedGasLimit.toString()) * 125n) / 100n}`;
91
+ }
92
+ // Fetch latest gasPrice from provider and use it
93
+ const gasPrice = await signer.getGasPrice();
94
+ if (gasPrice) {
95
+ transactionRequest.gasPrice = gasPrice;
96
+ }
97
+ }
98
+ catch (error) { }
99
+ }
78
100
  // Submit the transaction
79
101
  transaction = await signer.sendTransaction(transactionRequest);
80
102
  // STEP 4: Wait for the transaction
@@ -28,12 +28,20 @@ export class StepExecutor {
28
28
  };
29
29
  this.executeStep = async (signer, step) => {
30
30
  // Make sure that the chain is still correct
31
- const updatedSigner = await switchChain(signer, this.statusManager, step, this.settings.switchChainHook, this.allowUserInteraction);
32
- if (!updatedSigner) {
33
- // Chain switch was not successful, stop execution here
34
- return step;
31
+ // Find if it's bridging and the step is waiting for a transaction on the receiving chain
32
+ const recievingChainProcess = step.execution?.process.find((process) => process.type === 'RECEIVING_CHAIN');
33
+ // If the step is waiting for a transaction on the receiving chain, we do not switch the chain
34
+ // All changes are already done from the source chain
35
+ // Return the step
36
+ if (recievingChainProcess?.substatus !== 'WAIT_DESTINATION_TRANSACTION' ||
37
+ !recievingChainProcess) {
38
+ const updatedSigner = await switchChain(signer, this.statusManager, step, this.settings.switchChainHook, this.allowUserInteraction);
39
+ if (!updatedSigner) {
40
+ // Chain switch was not successful, stop execution here
41
+ return step;
42
+ }
43
+ signer = updatedSigner;
35
44
  }
36
- signer = updatedSigner;
37
45
  const parameters = {
38
46
  signer,
39
47
  step,
@@ -8,7 +8,7 @@ import { InternalExecutionSettings, LifiStep } from '../types';
8
8
  * @param statusManager
9
9
  * @param oldStep
10
10
  * @param newStep
11
- * @param acceptSlippageUpdateHook
11
+ * @param settings
12
12
  * @param allowUserInteraction
13
13
  */
14
14
  export declare const stepComparison: (statusManager: StatusManager, oldStep: LifiStep, newStep: LifiStep, settings: InternalExecutionSettings, allowUserInteraction: boolean) => Promise<LifiStep>;
@@ -8,7 +8,7 @@ import { checkStepSlippageThreshold } from './utils';
8
8
  * @param statusManager
9
9
  * @param oldStep
10
10
  * @param newStep
11
- * @param acceptSlippageUpdateHook
11
+ * @param settings
12
12
  * @param allowUserInteraction
13
13
  */
14
14
  export const stepComparison = async (statusManager, oldStep, newStep, settings, allowUserInteraction) => {
@@ -16,15 +16,12 @@ export const stepComparison = async (statusManager, oldStep, newStep, settings,
16
16
  if (checkStepSlippageThreshold(oldStep, newStep)) {
17
17
  return statusManager.updateStepInRoute(newStep);
18
18
  }
19
- const acceptExchangeRateUpdateHook = settings.acceptExchangeRateUpdateHook ?? settings.acceptSlippageUpdateHook;
20
19
  let allowStepUpdate;
21
20
  if (allowUserInteraction) {
22
- allowStepUpdate = await acceptExchangeRateUpdateHook({
21
+ allowStepUpdate = await settings.acceptExchangeRateUpdateHook({
23
22
  oldToAmount: oldStep.estimate.toAmount,
24
23
  newToAmount: newStep.estimate.toAmount,
25
24
  toToken: newStep.action.toToken,
26
- oldSlippage: oldStep.action.slippage,
27
- newSlippage: newStep.action.slippage,
28
25
  });
29
26
  }
30
27
  if (!allowStepUpdate) {
package/dist/helpers.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { LifiStep, Route, Token } from '@lifi/types';
2
+ import { TenderlyResponse } from './types';
2
3
  /**
3
4
  * Predefined hook that decrypts calldata using EIP-1193 compliant wallet functions.
4
5
  * @param {string} walletAddress - The wallet address of the user that should decrypt the calldata.
@@ -24,3 +25,4 @@ export declare const checkPackageUpdates: (packageName?: string, packageVersion?
24
25
  * @throws {ValidationError} Throws a ValidationError if the step has missing values.
25
26
  */
26
27
  export declare const convertQuoteToRoute: (step: LifiStep) => Route;
28
+ export declare const fetchTxErrorDetails: (txHash: string, chainId: number) => Promise<TenderlyResponse>;
package/dist/helpers.js CHANGED
@@ -100,3 +100,7 @@ export const convertQuoteToRoute = (step) => {
100
100
  };
101
101
  return route;
102
102
  };
103
+ export const fetchTxErrorDetails = async (txHash, chainId) => {
104
+ const response = await request(`https://api.tenderly.co/api/v1/public-contract/${chainId}/tx/${txHash}`);
105
+ return response;
106
+ };
@@ -9,7 +9,7 @@ declare const _default: {
9
9
  getRoutes: (requestConfig: RoutesRequest, options?: RequestOptions | undefined) => Promise<RoutesResponse>;
10
10
  getStatus: (requestConfig: GetStatusRequest, options?: RequestOptions | undefined) => Promise<StatusResponse>;
11
11
  getStepTransaction: (step: LifiStep, options?: RequestOptions | undefined) => Promise<LifiStep>;
12
- getToken: (chain: ChainKey | ChainId, token: string, options?: RequestOptions | undefined) => Promise<Token>;
12
+ getToken: (chain: ChainId | ChainKey, token: string, options?: RequestOptions | undefined) => Promise<Token>;
13
13
  getTokens: (requestConfig?: TokensRequest | undefined, options?: RequestOptions | undefined) => Promise<TokensResponse>;
14
14
  getTools: (requestConfig?: ToolsRequest | undefined, options?: RequestOptions | undefined) => Promise<ToolsResponse>;
15
15
  getAvailableConnections: (connectionRequest: ConnectionsRequest) => Promise<ConnectionsResponse>;
@@ -18,6 +18,6 @@ export default class ConfigService {
18
18
  * Use this if you need access to chain data (RPCs or multicalls)
19
19
  */
20
20
  getConfigAsync: () => Promise<Config>;
21
- updateConfig: (configUpdate: ConfigUpdate) => Config;
21
+ updateConfig: (configUpdate: Partial<ConfigUpdate>) => Config;
22
22
  updateChains: (chains: Chain[]) => Config;
23
23
  }
@@ -1,9 +1,8 @@
1
1
  import { ChainId, } from '../types';
2
2
  const DefaultExecutionSettings = {
3
3
  /* eslint-disable-next-line @typescript-eslint/no-empty-function */
4
- updateCallback: () => { },
4
+ updateRouteHook: () => { },
5
5
  switchChainHook: () => Promise.resolve(undefined),
6
- acceptSlippageUpdateHook: () => Promise.resolve(undefined),
7
6
  acceptExchangeRateUpdateHook: () => Promise.resolve(undefined),
8
7
  infiniteApproval: false,
9
8
  executeInBackground: false,
@@ -1,4 +1,4 @@
1
- import { LifiStep, RoutesRequest, Token } from './types';
1
+ import { LifiStep, RoutesRequest, StaticToken } from './types';
2
2
  export declare const isRoutesRequest: (routesRequest: RoutesRequest) => routesRequest is RoutesRequest;
3
3
  export declare const isStep: (step: LifiStep) => step is LifiStep;
4
- export declare const isToken: (token: Token) => token is Token;
4
+ export declare const isToken: (token: StaticToken) => token is StaticToken;
@@ -1,3 +1,4 @@
1
+ import { TransactionRequest } from '@ethersproject/abstract-provider';
1
2
  import { LifiStep, Route, RouteOptions, Token } from '@lifi/types';
2
3
  import BigNumber from 'bignumber.js';
3
4
  import { Signer } from 'ethers';
@@ -22,7 +23,8 @@ export interface ExecutionParams {
22
23
  statusManager: StatusManager;
23
24
  settings: InternalExecutionSettings;
24
25
  }
25
- export type CallbackFunction = (updatedRoute: Route) => void;
26
+ export type UpdateRouteHook = (updatedRoute: Route) => void;
27
+ export type TransactionRequestUpdateHook = (updatedTxRequest: TransactionRequest) => Promise<TransactionRequest>;
26
28
  export type Config = {
27
29
  apiUrl: string;
28
30
  rpcs: Record<ChainId, string[]>;
@@ -67,16 +69,13 @@ export interface RouteExecutionData {
67
69
  }
68
70
  export type ExecutionSettings = Partial<InternalExecutionSettings>;
69
71
  export interface InternalExecutionSettings {
70
- updateCallback: CallbackFunction;
71
- switchChainHook: SwitchChainHook;
72
- acceptSlippageUpdateHook: AcceptSlippageUpdateHook;
73
72
  acceptExchangeRateUpdateHook: AcceptExchangeRateUpdateHook;
74
- infiniteApproval: boolean;
73
+ switchChainHook: SwitchChainHook;
74
+ updateRouteHook: UpdateRouteHook;
75
+ updateTransactionRequestHook?: TransactionRequestUpdateHook;
75
76
  executeInBackground: boolean;
77
+ infiniteApproval: boolean;
76
78
  }
77
- export type EnforcedObjectProperties<T> = T & {
78
- [P in keyof T]-?: T[P];
79
- };
80
79
  export type RouteExecutionDictionary = Partial<Record<string, RouteExecutionData>>;
81
80
  export type RouteExecutionPromiseDictionary = Partial<Record<string, Promise<Route>>>;
82
81
  export type RevokeTokenData = {
@@ -88,3 +87,43 @@ export interface InteractionSettings {
88
87
  allowUpdates?: boolean;
89
88
  stopExecution?: boolean;
90
89
  }
90
+ export interface TenderlyResponse {
91
+ hash: string;
92
+ block_hash: string;
93
+ block_number: number;
94
+ from: string;
95
+ gas: number;
96
+ gas_price: number;
97
+ gas_fee_cap: number;
98
+ gas_tip_cap: number;
99
+ cumulative_gas_used: number;
100
+ gas_used: number;
101
+ effective_gas_price: number;
102
+ input: string;
103
+ nonce: number;
104
+ to: string;
105
+ index: number;
106
+ value: string;
107
+ access_list: any;
108
+ status: boolean;
109
+ addresses: string[];
110
+ contract_ids: string[];
111
+ network_id: string;
112
+ timestamp: string;
113
+ function_selector: string;
114
+ l1_block_number: number;
115
+ l1_timestamp: number;
116
+ deposit_tx: boolean;
117
+ system_tx: boolean;
118
+ mint: number;
119
+ sig: Signature;
120
+ error_message: string;
121
+ method: string;
122
+ decoded_input: any;
123
+ call_trace: any;
124
+ }
125
+ export interface Signature {
126
+ v: string;
127
+ r: string;
128
+ s: string;
129
+ }
@@ -22,7 +22,28 @@ export declare enum LifiErrorCode {
22
22
  TransactionCanceled = 1010,
23
23
  SlippageError = 1011,
24
24
  TransactionRejected = 1012,
25
- BalanceError = 1013
25
+ BalanceError = 1013,
26
+ AllowanceRequired = 1014,
27
+ InsufficientFunds = 1015
28
+ }
29
+ export declare enum EthersErrorType {
30
+ ActionRejected = "ACTION_REJECTED",
31
+ CallExecption = "CALL_EXCEPTION",
32
+ InsufficientFunds = "INSUFFICIENT_FUNDS"
33
+ }
34
+ export declare enum EthersErrorMessage {
35
+ ERC20Allowance = "ERC20: transfer amount exceeds allowance",
36
+ LowGas = "intrinsic gas too low",
37
+ OutOfGas = "out of gas",
38
+ Underpriced = "underpriced",
39
+ LowReplacementFee = "replacement fee too low"
40
+ }
41
+ export declare enum ErrorMessage {
42
+ UnknownError = "Unknown error occurred.",
43
+ SlippageError = "The slippage is larger than the defined threshold. Please request a new route to get a fresh quote.",
44
+ GasLimitLow = "Gas limit is too low.",
45
+ TransactionUnderpriced = "Transaction is underpriced.",
46
+ Default = "Something went wrong."
26
47
  }
27
48
  export declare enum MetaMaskRPCErrorCode {
28
49
  invalidInput = -32000,
@@ -25,7 +25,31 @@ export var LifiErrorCode;
25
25
  LifiErrorCode[LifiErrorCode["SlippageError"] = 1011] = "SlippageError";
26
26
  LifiErrorCode[LifiErrorCode["TransactionRejected"] = 1012] = "TransactionRejected";
27
27
  LifiErrorCode[LifiErrorCode["BalanceError"] = 1013] = "BalanceError";
28
+ LifiErrorCode[LifiErrorCode["AllowanceRequired"] = 1014] = "AllowanceRequired";
29
+ LifiErrorCode[LifiErrorCode["InsufficientFunds"] = 1015] = "InsufficientFunds";
28
30
  })(LifiErrorCode || (LifiErrorCode = {}));
31
+ export var EthersErrorType;
32
+ (function (EthersErrorType) {
33
+ EthersErrorType["ActionRejected"] = "ACTION_REJECTED";
34
+ EthersErrorType["CallExecption"] = "CALL_EXCEPTION";
35
+ EthersErrorType["InsufficientFunds"] = "INSUFFICIENT_FUNDS";
36
+ })(EthersErrorType || (EthersErrorType = {}));
37
+ export var EthersErrorMessage;
38
+ (function (EthersErrorMessage) {
39
+ EthersErrorMessage["ERC20Allowance"] = "ERC20: transfer amount exceeds allowance";
40
+ EthersErrorMessage["LowGas"] = "intrinsic gas too low";
41
+ EthersErrorMessage["OutOfGas"] = "out of gas";
42
+ EthersErrorMessage["Underpriced"] = "underpriced";
43
+ EthersErrorMessage["LowReplacementFee"] = "replacement fee too low";
44
+ })(EthersErrorMessage || (EthersErrorMessage = {}));
45
+ export var ErrorMessage;
46
+ (function (ErrorMessage) {
47
+ ErrorMessage["UnknownError"] = "Unknown error occurred.";
48
+ ErrorMessage["SlippageError"] = "The slippage is larger than the defined threshold. Please request a new route to get a fresh quote.";
49
+ ErrorMessage["GasLimitLow"] = "Gas limit is too low.";
50
+ ErrorMessage["TransactionUnderpriced"] = "Transaction is underpriced.";
51
+ ErrorMessage["Default"] = "Something went wrong.";
52
+ })(ErrorMessage || (ErrorMessage = {}));
29
53
  export var MetaMaskRPCErrorCode;
30
54
  (function (MetaMaskRPCErrorCode) {
31
55
  MetaMaskRPCErrorCode[MetaMaskRPCErrorCode["invalidInput"] = -32000] = "invalidInput";