@lifi/sdk 1.3.1 → 1.5.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 (42) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/Lifi.d.ts +7 -0
  3. package/dist/Lifi.js +72 -30
  4. package/dist/cjs/Lifi.d.ts +7 -0
  5. package/dist/cjs/Lifi.js +72 -30
  6. package/dist/cjs/execution/StatusManager.d.ts +2 -2
  7. package/dist/cjs/execution/StatusManager.js +14 -7
  8. package/dist/cjs/execution/StepExecutor.d.ts +4 -2
  9. package/dist/cjs/execution/StepExecutor.js +27 -16
  10. package/dist/cjs/execution/allowance.execute.d.ts +2 -2
  11. package/dist/cjs/execution/allowance.execute.js +14 -21
  12. package/dist/cjs/execution/bridges/bridge.execute.d.ts +2 -2
  13. package/dist/cjs/execution/bridges/bridge.execute.js +102 -90
  14. package/dist/cjs/execution/exchanges/swap.execute.d.ts +2 -2
  15. package/dist/cjs/execution/exchanges/swap.execute.js +42 -54
  16. package/dist/cjs/execution/switchChain.js +3 -3
  17. package/dist/cjs/helpers.js +1 -1
  18. package/dist/cjs/services/ConfigService.js +4 -3
  19. package/dist/cjs/types/internal.types.d.ts +5 -1
  20. package/dist/cjs/utils/parseError.js +4 -5
  21. package/dist/cjs/utils/preRestart.js +5 -1
  22. package/dist/cjs/version.d.ts +1 -1
  23. package/dist/cjs/version.js +1 -1
  24. package/dist/execution/StatusManager.d.ts +2 -2
  25. package/dist/execution/StatusManager.js +14 -7
  26. package/dist/execution/StepExecutor.d.ts +4 -2
  27. package/dist/execution/StepExecutor.js +27 -16
  28. package/dist/execution/allowance.execute.d.ts +2 -2
  29. package/dist/execution/allowance.execute.js +14 -21
  30. package/dist/execution/bridges/bridge.execute.d.ts +2 -2
  31. package/dist/execution/bridges/bridge.execute.js +103 -91
  32. package/dist/execution/exchanges/swap.execute.d.ts +2 -2
  33. package/dist/execution/exchanges/swap.execute.js +43 -55
  34. package/dist/execution/switchChain.js +3 -3
  35. package/dist/helpers.js +1 -1
  36. package/dist/services/ConfigService.js +4 -3
  37. package/dist/types/internal.types.d.ts +5 -1
  38. package/dist/utils/parseError.js +4 -5
  39. package/dist/utils/preRestart.js +5 -1
  40. package/dist/version.d.ts +1 -1
  41. package/dist/version.js +1 -1
  42. package/package.json +10 -10
@@ -18,39 +18,33 @@ const ethers_1 = require("ethers");
18
18
  const utils_1 = require("../allowance/utils");
19
19
  const getProvider_1 = require("../utils/getProvider");
20
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
21
+ const checkAllowance = (signer, step, statusManager, settings, chain, allowUserInteraction = false) => __awaiter(void 0, void 0, void 0, function* () {
22
+ // Ask the user to set an allowance
23
+ let allowanceProcess = statusManager.findOrCreateProcess(step, 'TOKEN_ALLOWANCE');
24
+ // Check allowance
28
25
  try {
29
- if (allowanceProcess.txHash) {
30
- allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING');
26
+ if (allowanceProcess.txHash && allowanceProcess.status !== 'DONE') {
27
+ if (allowanceProcess.status !== 'PENDING') {
28
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING');
29
+ }
31
30
  yield (0, getProvider_1.getProvider)(signer).waitForTransaction(allowanceProcess.txHash);
32
31
  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
32
  }
38
33
  else {
39
- const approved = yield (0, utils_1.getApproved)(signer, token.address, spenderAddress);
40
- if (new bignumber_js_1.default(amount).gt(approved)) {
34
+ const approved = yield (0, utils_1.getApproved)(signer, step.action.fromToken.address, step.estimate.approvalAddress);
35
+ if (new bignumber_js_1.default(step.action.fromAmount).gt(approved)) {
41
36
  if (!allowUserInteraction) {
42
37
  return;
43
38
  }
44
- const approvalAmount = infiniteApproval
39
+ const approvalAmount = settings.infiniteApproval
45
40
  ? ethers_1.constants.MaxUint256.toString()
46
- : amount;
47
- const approveTx = yield (0, utils_1.setApproval)(signer, token.address, spenderAddress, approvalAmount);
48
- // update currentExecution
41
+ : step.action.fromAmount;
42
+ const approveTx = yield (0, utils_1.setApproval)(signer, step.action.fromToken.address, step.estimate.approvalAddress, approvalAmount);
49
43
  allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'PENDING', {
50
44
  txHash: approveTx.hash,
51
45
  txLink: chain.metamask.blockExplorerUrls[0] + 'tx/' + approveTx.hash,
52
46
  });
53
- // wait for transcation
47
+ // Wait for the transcation
54
48
  yield approveTx.wait();
55
49
  allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
56
50
  }
@@ -60,7 +54,6 @@ const checkAllowance = (signer, step, chain, token, amount, spenderAddress, stat
60
54
  }
61
55
  }
62
56
  catch (e) {
63
- // -> set status
64
57
  if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
65
58
  yield transactionReplaced(e.replacement, allowanceProcess, step, chain, statusManager);
66
59
  }
@@ -1,7 +1,7 @@
1
1
  import { Execution } from '@lifi/types';
2
2
  import { ExecuteCrossParams } from '../../types';
3
3
  export declare class BridgeExecutionManager {
4
- shouldContinue: boolean;
5
- setShouldContinue: (val: boolean) => void;
4
+ allowUserInteraction: boolean;
5
+ allowInteraction: (value: boolean) => void;
6
6
  execute: ({ signer, step, statusManager, settings, }: ExecuteCrossParams) => Promise<Execution>;
7
7
  }
@@ -13,7 +13,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.BridgeExecutionManager = void 0;
16
- const ethers_1 = require("ethers");
17
16
  const ApiService_1 = __importDefault(require("../../services/ApiService"));
18
17
  const ChainsService_1 = __importDefault(require("../../services/ChainsService"));
19
18
  const errors_1 = require("../../utils/errors");
@@ -27,97 +26,125 @@ const switchChain_1 = require("../switchChain");
27
26
  const utils_2 = require("../utils");
28
27
  class BridgeExecutionManager {
29
28
  constructor() {
30
- this.shouldContinue = true;
31
- this.setShouldContinue = (val) => {
32
- this.shouldContinue = val;
29
+ this.allowUserInteraction = true;
30
+ this.allowInteraction = (value) => {
31
+ this.allowUserInteraction = value;
33
32
  };
34
33
  this.execute = ({ signer, step, statusManager, settings, }) => __awaiter(this, void 0, void 0, function* () {
35
34
  var _a, _b, _c, _d;
36
- const { action, estimate } = step;
37
35
  step.execution = statusManager.initExecutionObject(step);
38
36
  const chainsService = ChainsService_1.default.getInstance();
39
- const fromChain = yield chainsService.getChainById(action.fromChainId);
40
- const toChain = yield chainsService.getChainById(action.toChainId);
41
- // STEP 1: Check Allowance ////////////////////////////////////////////////
42
- // approval still needed?
37
+ const fromChain = yield chainsService.getChainById(step.action.fromChainId);
38
+ const toChain = yield chainsService.getChainById(step.action.toChainId);
39
+ // STEP 1: Check allowance
43
40
  const oldCrossProcess = step.execution.process.find((p) => p.type === 'CROSS_CHAIN');
44
- if (!(oldCrossProcess === null || oldCrossProcess === void 0 ? void 0 : oldCrossProcess.txHash)) {
45
- if (action.fromToken.address !== ethers_1.constants.AddressZero) {
46
- // Check Token Approval only if fromToken is not the native token => no approval needed in that case
47
- yield (0, allowance_execute_1.checkAllowance)(signer, step, fromChain, action.fromToken, action.fromAmount, estimate.approvalAddress, statusManager, settings.infiniteApproval, this.shouldContinue);
48
- }
41
+ // Check token approval only if fromToken is not the native token => no approval needed in that case
42
+ if (!(oldCrossProcess === null || oldCrossProcess === void 0 ? void 0 : oldCrossProcess.txHash) &&
43
+ !(0, utils_1.isZeroAddress)(step.action.fromToken.address)) {
44
+ yield (0, allowance_execute_1.checkAllowance)(signer, step, statusManager, settings, fromChain, this.allowUserInteraction);
49
45
  }
50
- // STEP 2: Get Transaction ////////////////////////////////////////////////
51
- let crossChainProcess = statusManager.findOrCreateProcess('CROSS_CHAIN', step);
52
- try {
53
- let tx;
54
- if (crossChainProcess.txHash) {
55
- // load exiting transaction
56
- tx = yield (0, getProvider_1.getProvider)(signer).getTransaction(crossChainProcess.txHash);
57
- }
58
- else {
59
- // check balance
60
- yield (0, balanceCheck_execute_1.balanceCheck)(signer, step);
61
- // create new transaction
62
- const personalizedStep = yield (0, utils_1.personalizeStep)(signer, step);
63
- const updatedStep = yield ApiService_1.default.getStepTransaction(personalizedStep);
64
- step = Object.assign(Object.assign({}, (yield (0, stepComparison_1.stepComparison)(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.shouldContinue))), { execution: step.execution });
65
- const { transactionRequest } = step;
66
- if (!transactionRequest) {
67
- throw new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
46
+ // STEP 2: Get transaction
47
+ let crossChainProcess = statusManager.findOrCreateProcess(step, 'CROSS_CHAIN');
48
+ if (crossChainProcess.status !== 'DONE') {
49
+ try {
50
+ let transaction;
51
+ if (crossChainProcess.txHash) {
52
+ // Make sure that the chain is still correct
53
+ const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
54
+ if (!updatedSigner) {
55
+ // Chain switch was not successful, stop execution here
56
+ return step.execution;
57
+ }
58
+ signer = updatedSigner;
59
+ // Load exiting transaction
60
+ transaction = yield (0, getProvider_1.getProvider)(signer).getTransaction(crossChainProcess.txHash);
68
61
  }
69
- // STEP 3: Send Transaction ///////////////////////////////////////////////
70
- // make sure that chain is still correct
71
- const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.shouldContinue);
72
- if (!updatedSigner) {
73
- // chain switch was not successful, stop execution here
74
- return step.execution;
62
+ else {
63
+ crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'STARTED');
64
+ // Check balance
65
+ yield (0, balanceCheck_execute_1.balanceCheck)(signer, step);
66
+ // Create new transaction
67
+ if (!step.transactionRequest) {
68
+ const personalizedStep = yield (0, utils_1.personalizeStep)(signer, step);
69
+ const updatedStep = yield ApiService_1.default.getStepTransaction(personalizedStep);
70
+ step = Object.assign(Object.assign({}, (yield (0, stepComparison_1.stepComparison)(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.allowUserInteraction))), { execution: step.execution });
71
+ }
72
+ const { transactionRequest } = step;
73
+ if (!transactionRequest) {
74
+ throw new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
75
+ }
76
+ // STEP 3: Send the transaction
77
+ // Make sure that the chain is still correct
78
+ const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
79
+ if (!updatedSigner) {
80
+ // Chain switch was not successful, stop execution here
81
+ return step.execution;
82
+ }
83
+ signer = updatedSigner;
84
+ crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'ACTION_REQUIRED');
85
+ if (!this.allowUserInteraction) {
86
+ return step.execution;
87
+ }
88
+ // Submit the transaction
89
+ transaction = yield signer.sendTransaction(transactionRequest);
90
+ // STEP 4: Wait for the transaction
91
+ crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
92
+ txHash: transaction.hash,
93
+ txLink: fromChain.metamask.blockExplorerUrls[0] +
94
+ 'tx/' +
95
+ transaction.hash,
96
+ });
75
97
  }
76
- signer = updatedSigner;
77
- crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'ACTION_REQUIRED');
78
- if (!this.shouldContinue) {
79
- return step.execution;
80
- }
81
- tx = yield signer.sendTransaction(transactionRequest);
82
- // STEP 4: Wait for Transaction ///////////////////////////////////////////
83
- crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
84
- txHash: tx.hash,
85
- txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + tx.hash,
86
- });
98
+ yield transaction.wait();
99
+ crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE');
87
100
  }
88
- yield tx.wait();
89
- }
90
- catch (e) {
91
- if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
92
- crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'PENDING', {
93
- txHash: e.replacement.hash,
94
- txLink: fromChain.metamask.blockExplorerUrls[0] +
95
- 'tx/' +
96
- e.replacement.hash,
97
- });
98
- }
99
- else {
100
- const error = yield (0, parseError_1.parseError)(e, step, crossChainProcess);
101
- crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'FAILED', {
102
- error: {
103
- message: error.message,
104
- htmlMessage: error.htmlMessage,
105
- code: error.code,
106
- },
107
- });
108
- statusManager.updateExecution(step, 'FAILED');
109
- throw error;
101
+ catch (e) {
102
+ if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
103
+ crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE', {
104
+ txHash: e.replacement.hash,
105
+ txLink: fromChain.metamask.blockExplorerUrls[0] +
106
+ 'tx/' +
107
+ e.replacement.hash,
108
+ });
109
+ }
110
+ else {
111
+ const error = yield (0, parseError_1.parseError)(e, step, crossChainProcess);
112
+ crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'FAILED', {
113
+ error: {
114
+ message: error.message,
115
+ htmlMessage: error.htmlMessage,
116
+ code: error.code,
117
+ },
118
+ });
119
+ statusManager.updateExecution(step, 'FAILED');
120
+ throw error;
121
+ }
110
122
  }
111
123
  }
112
- crossChainProcess = statusManager.updateProcess(step, crossChainProcess.type, 'DONE');
113
- // STEP 5: Wait for Receiver //////////////////////////////////////
114
- let receivingChainProcess = statusManager.findOrCreateProcess('RECEIVING_CHAIN', step, 'PENDING');
124
+ // STEP 5: Wait for the receiving chain
125
+ let receivingChainProcess = statusManager.findOrCreateProcess(step, 'RECEIVING_CHAIN', 'PENDING');
115
126
  let statusResponse;
116
127
  try {
117
128
  if (!crossChainProcess.txHash) {
118
129
  throw new Error('Transaction hash is undefined.');
119
130
  }
120
131
  statusResponse = yield (0, utils_2.waitForReceivingTransaction)(crossChainProcess.txHash, statusManager, receivingChainProcess.type, step);
132
+ receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'DONE', {
133
+ substatus: statusResponse.substatus,
134
+ substatusMessage: statusResponse.substatusMessage ||
135
+ (0, utils_2.getSubstatusMessage)(statusResponse.status, statusResponse.substatus),
136
+ txHash: (_a = statusResponse.receiving) === null || _a === void 0 ? void 0 : _a.txHash,
137
+ txLink: toChain.metamask.blockExplorerUrls[0] +
138
+ 'tx/' +
139
+ ((_b = statusResponse.receiving) === null || _b === void 0 ? void 0 : _b.txHash),
140
+ });
141
+ statusManager.updateExecution(step, 'DONE', {
142
+ fromAmount: statusResponse.sending.amount,
143
+ toAmount: (_c = statusResponse.receiving) === null || _c === void 0 ? void 0 : _c.amount,
144
+ toToken: (_d = statusResponse.receiving) === null || _d === void 0 ? void 0 : _d.token,
145
+ gasUsed: statusResponse.sending.gasUsed,
146
+ gasPrice: statusResponse.sending.gasPrice,
147
+ });
121
148
  }
122
149
  catch (e) {
123
150
  receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'FAILED', {
@@ -128,24 +155,9 @@ class BridgeExecutionManager {
128
155
  },
129
156
  });
130
157
  statusManager.updateExecution(step, 'FAILED');
158
+ console.warn(e);
131
159
  throw e;
132
160
  }
133
- receivingChainProcess = statusManager.updateProcess(step, receivingChainProcess.type, 'DONE', {
134
- substatus: statusResponse.substatus,
135
- substatusMessage: statusResponse.substatusMessage ||
136
- (0, utils_2.getSubstatusMessage)(statusResponse.status, statusResponse.substatus),
137
- txHash: (_a = statusResponse.receiving) === null || _a === void 0 ? void 0 : _a.txHash,
138
- txLink: toChain.metamask.blockExplorerUrls[0] +
139
- 'tx/' +
140
- ((_b = statusResponse.receiving) === null || _b === void 0 ? void 0 : _b.txHash),
141
- });
142
- statusManager.updateExecution(step, 'DONE', {
143
- fromAmount: statusResponse.sending.amount,
144
- toAmount: (_c = statusResponse.receiving) === null || _c === void 0 ? void 0 : _c.amount,
145
- toToken: (_d = statusResponse.receiving) === null || _d === void 0 ? void 0 : _d.token,
146
- gasUsed: statusResponse.sending.gasUsed,
147
- gasPrice: statusResponse.sending.gasPrice,
148
- });
149
161
  // DONE
150
162
  return step.execution;
151
163
  });
@@ -1,7 +1,7 @@
1
1
  import { Execution } from '@lifi/types';
2
2
  import { ExecuteSwapParams } from '../../types';
3
3
  export declare class SwapExecutionManager {
4
- shouldContinue: boolean;
5
- setShouldContinue: (val: boolean) => void;
4
+ allowUserInteraction: boolean;
5
+ allowInteraction: (value: boolean) => void;
6
6
  execute: ({ signer, step, statusManager, settings, }: ExecuteSwapParams) => Promise<Execution>;
7
7
  }
@@ -13,7 +13,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.SwapExecutionManager = void 0;
16
- const ethers_1 = require("ethers");
17
16
  const ApiService_1 = __importDefault(require("../../services/ApiService"));
18
17
  const ChainsService_1 = __importDefault(require("../../services/ChainsService"));
19
18
  const errors_1 = require("../../utils/errors");
@@ -27,84 +26,72 @@ const switchChain_1 = require("../switchChain");
27
26
  const utils_2 = require("../utils");
28
27
  class SwapExecutionManager {
29
28
  constructor() {
30
- this.shouldContinue = true;
31
- this.setShouldContinue = (val) => {
32
- this.shouldContinue = val;
29
+ this.allowUserInteraction = true;
30
+ this.allowInteraction = (value) => {
31
+ this.allowUserInteraction = value;
33
32
  };
34
33
  this.execute = ({ signer, step, statusManager, settings, }) => __awaiter(this, void 0, void 0, function* () {
35
- // setup
36
34
  var _a, _b, _c, _d;
37
- const { action, estimate } = step;
38
35
  step.execution = statusManager.initExecutionObject(step);
39
36
  const chainsService = ChainsService_1.default.getInstance();
40
- const fromChain = yield chainsService.getChainById(action.fromChainId);
41
- // Approval
42
- if (action.fromToken.address !== ethers_1.constants.AddressZero) {
43
- yield (0, allowance_execute_1.checkAllowance)(signer, step, fromChain, action.fromToken, action.fromAmount, estimate.approvalAddress, statusManager, settings.infiniteApproval, this.shouldContinue);
37
+ const fromChain = yield chainsService.getChainById(step.action.fromChainId);
38
+ // STEP 1: Check allowance
39
+ if (!(0, utils_1.isZeroAddress)(step.action.fromToken.address)) {
40
+ yield (0, allowance_execute_1.checkAllowance)(signer, step, statusManager, settings, fromChain, this.allowUserInteraction);
44
41
  }
45
- // Start Swap
46
- // -> set step.execution
47
- let swapProcess = statusManager.findOrCreateProcess('SWAP', step);
48
- // -> swapping
49
- let tx;
42
+ // STEP 2: Get transaction
43
+ let swapProcess = statusManager.findOrCreateProcess(step, 'SWAP');
44
+ let transaction;
50
45
  try {
51
46
  if (swapProcess.txHash) {
52
- // -> restore existing tx
53
- tx = yield (0, getProvider_1.getProvider)(signer).getTransaction(swapProcess.txHash);
47
+ // Make sure that the chain is still correct
48
+ const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
49
+ if (!updatedSigner) {
50
+ // Chain switch was not successful, stop execution here
51
+ return step.execution;
52
+ }
53
+ signer = updatedSigner;
54
+ // Load exiting transaction
55
+ transaction = yield (0, getProvider_1.getProvider)(signer).getTransaction(swapProcess.txHash);
54
56
  }
55
57
  else {
56
- // -> check balance
58
+ swapProcess = statusManager.updateProcess(step, swapProcess.type, 'STARTED');
59
+ // Check balance
57
60
  yield (0, balanceCheck_execute_1.balanceCheck)(signer, step);
58
- // -> get tx from backend
59
- const personalizedStep = yield (0, utils_1.personalizeStep)(signer, step);
60
- const updatedStep = yield ApiService_1.default.getStepTransaction(personalizedStep);
61
- step = Object.assign(Object.assign({}, (yield (0, stepComparison_1.stepComparison)(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.shouldContinue))), { execution: step.execution });
61
+ // Create new transaction
62
+ if (!step.transactionRequest) {
63
+ const personalizedStep = yield (0, utils_1.personalizeStep)(signer, step);
64
+ const updatedStep = yield ApiService_1.default.getStepTransaction(personalizedStep);
65
+ step = Object.assign(Object.assign({}, (yield (0, stepComparison_1.stepComparison)(statusManager, personalizedStep, updatedStep, settings.acceptSlippageUpdateHook, this.allowUserInteraction))), { execution: step.execution });
66
+ }
62
67
  const { transactionRequest } = step;
63
68
  if (!transactionRequest) {
64
69
  throw new errors_1.TransactionError(errors_1.LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
65
70
  }
66
- // make sure that chain is still correct
67
- const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.shouldContinue);
71
+ // STEP 3: Send the transaction
72
+ // Make sure that the chain is still correct
73
+ const updatedSigner = yield (0, switchChain_1.switchChain)(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
68
74
  if (!updatedSigner) {
69
- // chain switch was not successful, stop execution here
75
+ // Chain switch was not successful, stop execution here
70
76
  return step.execution;
71
77
  }
72
78
  signer = updatedSigner;
73
- // -> set step.execution
74
- swapProcess = swapProcess = statusManager.updateProcess(step, swapProcess.type, 'ACTION_REQUIRED');
75
- if (!this.shouldContinue) {
76
- return step.execution; // stop before user interaction is needed
79
+ swapProcess = statusManager.updateProcess(step, swapProcess.type, 'ACTION_REQUIRED');
80
+ if (!this.allowUserInteraction) {
81
+ return step.execution;
77
82
  }
78
- // -> submit tx
79
- tx = yield signer.sendTransaction(transactionRequest);
83
+ // Submit the transaction
84
+ transaction = yield signer.sendTransaction(transactionRequest);
80
85
  }
81
- }
82
- catch (e) {
83
- const error = yield (0, parseError_1.parseError)(e, step, swapProcess);
84
- swapProcess = statusManager.updateProcess(step, swapProcess.type, 'FAILED', {
85
- error: {
86
- message: error.message,
87
- htmlMessage: error.htmlMessage,
88
- code: error.code,
89
- },
86
+ // STEP 4: Wait for the transaction
87
+ swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {
88
+ txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + transaction.hash,
89
+ txHash: transaction.hash,
90
90
  });
91
- statusManager.updateExecution(step, 'FAILED');
92
- throw error;
93
- }
94
- // Wait for Transaction
95
- swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {
96
- txLink: fromChain.metamask.blockExplorerUrls[0] + 'tx/' + tx.hash,
97
- txHash: tx.hash,
98
- });
99
- // -> waiting
100
- let receipt;
101
- try {
102
- receipt = yield tx.wait();
91
+ yield transaction.wait();
103
92
  }
104
93
  catch (e) {
105
- // -> set status
106
94
  if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
107
- receipt = e.replacement;
108
95
  swapProcess = statusManager.updateProcess(step, swapProcess.type, 'PENDING', {
109
96
  txHash: e.replacement.hash,
110
97
  txLink: fromChain.metamask.blockExplorerUrls[0] +
@@ -125,6 +112,7 @@ class SwapExecutionManager {
125
112
  throw error;
126
113
  }
127
114
  }
115
+ // STEP 5: Wait for the receiving chain
128
116
  let statusResponse;
129
117
  try {
130
118
  if (!swapProcess.txHash) {
@@ -29,8 +29,8 @@ const switchChain = (signer, statusManager, step, switchChainHook, allowUserInte
29
29
  }
30
30
  // -> set status message
31
31
  step.execution = statusManager.initExecutionObject(step);
32
- statusManager.updateExecution(step, 'CHAIN_SWITCH_REQUIRED');
33
- let switchProcess = statusManager.findOrCreateProcess('SWITCH_CHAIN', step, 'PENDING');
32
+ statusManager.updateExecution(step, 'ACTION_REQUIRED');
33
+ let switchProcess = statusManager.findOrCreateProcess(step, 'SWITCH_CHAIN', 'ACTION_REQUIRED');
34
34
  if (!allowUserInteraction) {
35
35
  return;
36
36
  }
@@ -48,7 +48,7 @@ const switchChain = (signer, statusManager, step, switchChainHook, allowUserInte
48
48
  switchProcess = statusManager.updateProcess(step, switchProcess.type, 'FAILED', {
49
49
  error: {
50
50
  message: error.message,
51
- code: error.code,
51
+ code: errors_1.LifiErrorCode.ChainSwitchError,
52
52
  },
53
53
  });
54
54
  statusManager.updateExecution(step, 'FAILED');
@@ -13,7 +13,7 @@ exports.checkPackageUpdates = exports.isSameToken = exports.getRandomNumber = ex
13
13
  const version_1 = require("./version");
14
14
  const ethereumRequest = (method, params) => __awaiter(void 0, void 0, void 0, function* () {
15
15
  // If ethereum.request() exists, the provider is probably EIP-1193 compliant.
16
- if (!ethereum || !ethereum.request) {
16
+ if (!(ethereum === null || ethereum === void 0 ? void 0 : ethereum.request)) {
17
17
  throw new Error('Provider not available.');
18
18
  }
19
19
  return ethereum.request({
@@ -16,6 +16,7 @@ const DefaultExecutionSettings = {
16
16
  switchChainHook: () => Promise.resolve(undefined),
17
17
  acceptSlippageUpdateHook: () => Promise.resolve(undefined),
18
18
  infiniteApproval: false,
19
+ executeInBackground: false,
19
20
  };
20
21
  class ConfigService {
21
22
  constructor() {
@@ -49,11 +50,11 @@ class ConfigService {
49
50
  return this.config;
50
51
  };
51
52
  this.updateChains = (chains) => {
52
- var _a;
53
+ var _a, _b;
53
54
  for (const chain of chains) {
54
55
  const chainId = chain.id;
55
56
  // set RPCs if they were not configured by the user before
56
- if (!this.config.rpcs[chainId].length) {
57
+ if (!((_a = this.config.rpcs[chainId]) === null || _a === void 0 ? void 0 : _a.length)) {
57
58
  this.config.rpcs[chainId] = chain.metamask.rpcUrls;
58
59
  }
59
60
  // set multicall addresses if they exist and were not configured by the user before
@@ -61,7 +62,7 @@ class ConfigService {
61
62
  this.config.multicallAddresses[chainId] = chain.multicallAddress;
62
63
  }
63
64
  }
64
- (_a = this.resolveSetupPromise) === null || _a === void 0 ? void 0 : _a.call(this);
65
+ (_b = this.resolveSetupPromise) === null || _b === void 0 ? void 0 : _b.call(this);
65
66
  return this.config;
66
67
  };
67
68
  this.config = ConfigService.getDefaultConfig();
@@ -64,12 +64,14 @@ export interface ExecutionSettings {
64
64
  switchChainHook?: SwitchChainHook;
65
65
  acceptSlippageUpdateHook?: AcceptSlippageUpdateHook;
66
66
  infiniteApproval?: boolean;
67
+ executeInBackground?: boolean;
67
68
  }
68
69
  export interface InternalExecutionSettings extends ExecutionSettings {
69
70
  updateCallback: CallbackFunction;
70
71
  switchChainHook: SwitchChainHook;
71
72
  acceptSlippageUpdateHook: AcceptSlippageUpdateHook;
72
73
  infiniteApproval: boolean;
74
+ executeInBackground: boolean;
73
75
  }
74
76
  export declare type EnforcedObjectProperties<T> = T & {
75
77
  [P in keyof T]-?: T[P];
@@ -81,7 +83,9 @@ export declare type RevokeTokenData = {
81
83
  token: Token;
82
84
  approvalAddress: string;
83
85
  };
84
- export interface HaltingSettings {
86
+ export interface InteractionSettings {
87
+ allowInteraction?: boolean;
85
88
  allowUpdates?: boolean;
89
+ stopExecution?: boolean;
86
90
  }
87
91
  export {};
@@ -77,7 +77,7 @@ const getTransactionFailedMessage = (step, txLink) => {
77
77
  };
78
78
  exports.getTransactionFailedMessage = getTransactionFailedMessage;
79
79
  const parseError = (e, step, process) => __awaiter(void 0, void 0, void 0, function* () {
80
- var _a, _b;
80
+ var _a, _b, _c;
81
81
  if (e instanceof errors_1.LifiError) {
82
82
  return e;
83
83
  }
@@ -88,12 +88,11 @@ const parseError = (e, step, process) => __awaiter(void 0, void 0, void 0, funct
88
88
  // rpc errors
89
89
  // underpriced errors are sent as internal errors, so we need to parse the message manually
90
90
  if (e.code === eth_rpc_errors_1.errorCodes.rpc.internal &&
91
- e.message &&
92
- e.message.includes('underpriced')) {
91
+ ((_a = e.message) === null || _a === void 0 ? void 0 : _a.includes('underpriced'))) {
93
92
  return new errors_1.RPCError(errors_1.LifiErrorCode.TransactionUnderpriced, 'Transaction is underpriced.', yield (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
94
93
  }
95
- if (((_a = e.message) === null || _a === void 0 ? void 0 : _a.includes('intrinsic gas too low')) ||
96
- ((_b = e.message) === null || _b === void 0 ? void 0 : _b.includes('out of gas'))) {
94
+ if (((_b = e.message) === null || _b === void 0 ? void 0 : _b.includes('intrinsic gas too low')) ||
95
+ ((_c = e.message) === null || _c === void 0 ? void 0 : _c.includes('out of gas'))) {
97
96
  return new errors_1.TransactionError(errors_1.LifiErrorCode.GasLimitError, 'Gas limit is too low.', yield (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
98
97
  }
99
98
  return new errors_1.RPCError(e.code, (0, eth_rpc_errors_1.getMessageFromCode)(e.code), yield (0, exports.getTransactionNotSentMessage)(step, process), e.stack);
@@ -9,6 +9,7 @@ const handlePreRestart = (route) => {
9
9
  if (stepHasFailed) {
10
10
  handleErrorType(route, index);
11
11
  deleteFailedProcesses(route, index);
12
+ deleteTransactionData(route, index);
12
13
  }
13
14
  }
14
15
  };
@@ -26,6 +27,9 @@ const handleErrorType = (route, index) => {
26
27
  };
27
28
  const deleteFailedProcesses = (route, index) => {
28
29
  if (route.steps[index].execution) {
29
- route.steps[index].execution.process = route.steps[index].execution.process.filter((process) => process.status !== 'FAILED');
30
+ route.steps[index].execution.process = route.steps[index].execution.process.filter((process) => process.status === 'DONE');
30
31
  }
31
32
  };
33
+ const deleteTransactionData = (route, index) => {
34
+ route.steps[index].transactionRequest = undefined;
35
+ };
@@ -1,2 +1,2 @@
1
1
  export declare const name = "@lifi/sdk";
2
- export declare const version = "1.3.1";
2
+ export declare const version = "1.5.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 = '1.3.1';
5
+ exports.version = '1.5.0';