@lifi/sdk 2.2.3 → 3.0.0-alpha.2

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 (183) hide show
  1. package/dist/LiFi.d.ts +69 -62
  2. package/dist/LiFi.js +71 -60
  3. package/dist/allowance/getAllowance.d.ts +6 -0
  4. package/dist/allowance/getAllowance.js +78 -0
  5. package/dist/allowance/index.d.ts +3 -2
  6. package/dist/allowance/index.js +3 -2
  7. package/dist/allowance/setAllowance.d.ts +5 -0
  8. package/dist/allowance/setAllowance.js +50 -0
  9. package/dist/allowance/types.d.ts +27 -0
  10. package/dist/allowance/types.js +1 -0
  11. package/dist/balance/getBalance.d.ts +2 -0
  12. package/dist/balance/getBalance.js +93 -0
  13. package/dist/balance/getTokenBalance.d.ts +2 -2
  14. package/dist/balance/getTokenBalance.js +4 -4
  15. package/dist/balance/index.d.ts +1 -12
  16. package/dist/balance/index.js +1 -9
  17. package/dist/cjs/LiFi.d.ts +69 -62
  18. package/dist/cjs/LiFi.js +69 -58
  19. package/dist/cjs/allowance/getAllowance.d.ts +6 -0
  20. package/dist/cjs/allowance/getAllowance.js +85 -0
  21. package/dist/cjs/allowance/index.d.ts +3 -2
  22. package/dist/cjs/allowance/index.js +3 -2
  23. package/dist/cjs/allowance/setAllowance.d.ts +5 -0
  24. package/dist/cjs/allowance/setAllowance.js +56 -0
  25. package/dist/cjs/allowance/types.d.ts +27 -0
  26. package/dist/cjs/allowance/types.js +2 -0
  27. package/dist/cjs/balance/getBalance.d.ts +2 -0
  28. package/dist/cjs/balance/getBalance.js +97 -0
  29. package/dist/cjs/balance/getTokenBalance.d.ts +2 -2
  30. package/dist/cjs/balance/getTokenBalance.js +6 -9
  31. package/dist/cjs/balance/index.d.ts +1 -12
  32. package/dist/cjs/balance/index.js +1 -9
  33. package/dist/cjs/connectors.d.ts +7 -5
  34. package/dist/cjs/connectors.js +45 -37
  35. package/dist/cjs/constants.d.ts +6 -0
  36. package/dist/cjs/constants.js +9 -0
  37. package/dist/cjs/execution/RouteExecutionManager.d.ts +24 -30
  38. package/dist/cjs/execution/RouteExecutionManager.js +27 -45
  39. package/dist/cjs/execution/StatusManager.d.ts +22 -23
  40. package/dist/cjs/execution/StatusManager.js +21 -22
  41. package/dist/cjs/execution/StepExecutionManager.d.ts +3 -3
  42. package/dist/cjs/execution/StepExecutionManager.js +118 -125
  43. package/dist/cjs/execution/StepExecutor.d.ts +4 -4
  44. package/dist/cjs/execution/StepExecutor.js +6 -6
  45. package/dist/cjs/execution/checkAllowance.d.ts +4 -0
  46. package/dist/cjs/execution/checkAllowance.js +77 -0
  47. package/dist/cjs/execution/checkBalance.d.ts +2 -0
  48. package/dist/cjs/execution/checkBalance.js +42 -0
  49. package/dist/cjs/execution/multisig.d.ts +4 -3
  50. package/dist/cjs/execution/multisig.js +9 -11
  51. package/dist/cjs/execution/prepareRestart.d.ts +3 -0
  52. package/dist/cjs/execution/prepareRestart.js +65 -0
  53. package/dist/cjs/execution/stepComparison.d.ts +3 -3
  54. package/dist/cjs/execution/stepComparison.js +2 -2
  55. package/dist/cjs/execution/switchChain.d.ts +13 -8
  56. package/dist/cjs/execution/switchChain.js +16 -11
  57. package/dist/cjs/execution/utils.d.ts +9 -3
  58. package/dist/cjs/execution/utils.js +19 -66
  59. package/dist/cjs/execution/waitForReceivingTransaction.d.ts +3 -0
  60. package/dist/cjs/execution/waitForReceivingTransaction.js +58 -0
  61. package/dist/cjs/helpers.d.ts +7 -17
  62. package/dist/cjs/helpers.js +6 -38
  63. package/dist/cjs/request.js +1 -1
  64. package/dist/cjs/services/ApiService.d.ts +2 -2
  65. package/dist/cjs/services/ApiService.js +4 -2
  66. package/dist/cjs/services/ChainsService.d.ts +1 -1
  67. package/dist/cjs/services/ConfigService.d.ts +1 -1
  68. package/dist/cjs/services/ConfigService.js +1 -2
  69. package/dist/cjs/typeguards.d.ts +1 -1
  70. package/dist/cjs/types/abi.d.ts +5 -0
  71. package/dist/cjs/types/abi.js +45 -0
  72. package/dist/cjs/types/index.d.ts +2 -2
  73. package/dist/cjs/types/index.js +3 -3
  74. package/dist/cjs/types/internal.types.d.ts +24 -31
  75. package/dist/cjs/utils/errors.d.ts +15 -14
  76. package/dist/cjs/utils/errors.js +38 -37
  77. package/dist/cjs/utils/getMaxPriorityFeePerGas.d.ts +2 -0
  78. package/dist/cjs/utils/getMaxPriorityFeePerGas.js +22 -0
  79. package/dist/cjs/utils/index.d.ts +5 -0
  80. package/dist/cjs/utils/index.js +21 -0
  81. package/dist/cjs/utils/median.d.ts +1 -0
  82. package/dist/cjs/utils/median.js +15 -0
  83. package/dist/cjs/utils/parseError.d.ts +4 -4
  84. package/dist/cjs/utils/parseError.js +41 -38
  85. package/dist/cjs/utils/utils.d.ts +1 -16
  86. package/dist/cjs/utils/utils.js +9 -78
  87. package/dist/cjs/version.d.ts +1 -1
  88. package/dist/cjs/version.js +1 -1
  89. package/dist/connectors.d.ts +7 -5
  90. package/dist/connectors.js +19 -35
  91. package/dist/constants.d.ts +6 -0
  92. package/dist/constants.js +6 -0
  93. package/dist/execution/RouteExecutionManager.d.ts +24 -30
  94. package/dist/execution/RouteExecutionManager.js +27 -45
  95. package/dist/execution/StatusManager.d.ts +22 -23
  96. package/dist/execution/StatusManager.js +22 -23
  97. package/dist/execution/StepExecutionManager.d.ts +3 -3
  98. package/dist/execution/StepExecutionManager.js +116 -123
  99. package/dist/execution/StepExecutor.d.ts +4 -4
  100. package/dist/execution/StepExecutor.js +6 -6
  101. package/dist/execution/checkAllowance.d.ts +4 -0
  102. package/dist/execution/checkAllowance.js +73 -0
  103. package/dist/execution/checkBalance.d.ts +2 -0
  104. package/dist/execution/checkBalance.js +38 -0
  105. package/dist/execution/multisig.d.ts +4 -3
  106. package/dist/execution/multisig.js +10 -12
  107. package/dist/execution/prepareRestart.d.ts +3 -0
  108. package/dist/execution/prepareRestart.js +61 -0
  109. package/dist/execution/stepComparison.d.ts +3 -3
  110. package/dist/execution/stepComparison.js +3 -3
  111. package/dist/execution/switchChain.d.ts +13 -8
  112. package/dist/execution/switchChain.js +17 -12
  113. package/dist/execution/utils.d.ts +9 -3
  114. package/dist/execution/utils.js +18 -61
  115. package/dist/execution/waitForReceivingTransaction.d.ts +3 -0
  116. package/dist/execution/waitForReceivingTransaction.js +51 -0
  117. package/dist/helpers.d.ts +7 -17
  118. package/dist/helpers.js +5 -34
  119. package/dist/request.js +2 -2
  120. package/dist/services/ApiService.d.ts +2 -2
  121. package/dist/services/ApiService.js +4 -2
  122. package/dist/services/ChainsService.d.ts +1 -1
  123. package/dist/services/ConfigService.d.ts +1 -1
  124. package/dist/services/ConfigService.js +2 -3
  125. package/dist/typeguards.d.ts +1 -1
  126. package/dist/types/abi.d.ts +5 -0
  127. package/dist/types/abi.js +42 -0
  128. package/dist/types/index.d.ts +2 -2
  129. package/dist/types/index.js +2 -2
  130. package/dist/types/internal.types.d.ts +24 -31
  131. package/dist/utils/errors.d.ts +15 -14
  132. package/dist/utils/errors.js +36 -35
  133. package/dist/utils/getMaxPriorityFeePerGas.d.ts +2 -0
  134. package/dist/utils/getMaxPriorityFeePerGas.js +18 -0
  135. package/dist/utils/index.d.ts +5 -0
  136. package/dist/utils/index.js +5 -0
  137. package/dist/utils/median.d.ts +1 -0
  138. package/dist/utils/median.js +11 -0
  139. package/dist/utils/parseError.d.ts +4 -4
  140. package/dist/utils/parseError.js +42 -39
  141. package/dist/utils/utils.d.ts +1 -16
  142. package/dist/utils/utils.js +7 -69
  143. package/dist/version.d.ts +1 -1
  144. package/dist/version.js +1 -1
  145. package/package.json +43 -40
  146. package/dist/allowance/checkAllowance.d.ts +0 -4
  147. package/dist/allowance/checkAllowance.js +0 -96
  148. package/dist/allowance/tokenApproval.d.ts +0 -22
  149. package/dist/allowance/tokenApproval.js +0 -59
  150. package/dist/allowance/utils.d.ts +0 -15
  151. package/dist/allowance/utils.js +0 -77
  152. package/dist/balance/checkBalance.d.ts +0 -3
  153. package/dist/balance/checkBalance.js +0 -38
  154. package/dist/balance/utils.d.ts +0 -6
  155. package/dist/balance/utils.js +0 -143
  156. package/dist/cjs/allowance/checkAllowance.d.ts +0 -4
  157. package/dist/cjs/allowance/checkAllowance.js +0 -103
  158. package/dist/cjs/allowance/tokenApproval.d.ts +0 -22
  159. package/dist/cjs/allowance/tokenApproval.js +0 -69
  160. package/dist/cjs/allowance/utils.d.ts +0 -15
  161. package/dist/cjs/allowance/utils.js +0 -87
  162. package/dist/cjs/balance/checkBalance.d.ts +0 -3
  163. package/dist/cjs/balance/checkBalance.js +0 -45
  164. package/dist/cjs/balance/utils.d.ts +0 -6
  165. package/dist/cjs/balance/utils.js +0 -150
  166. package/dist/cjs/types/ERC20.d.ts +0 -22
  167. package/dist/cjs/types/ERC20.js +0 -53
  168. package/dist/cjs/utils/getProvider.d.ts +0 -3
  169. package/dist/cjs/utils/getProvider.js +0 -11
  170. package/dist/cjs/utils/multicall.d.ts +0 -10
  171. package/dist/cjs/utils/multicall.js +0 -68
  172. package/dist/cjs/utils/multicallAbi.json +0 -313
  173. package/dist/cjs/utils/preRestart.d.ts +0 -3
  174. package/dist/cjs/utils/preRestart.js +0 -56
  175. package/dist/types/ERC20.d.ts +0 -22
  176. package/dist/types/ERC20.js +0 -50
  177. package/dist/utils/getProvider.d.ts +0 -3
  178. package/dist/utils/getProvider.js +0 -7
  179. package/dist/utils/multicall.d.ts +0 -10
  180. package/dist/utils/multicall.js +0 -61
  181. package/dist/utils/multicallAbi.json +0 -313
  182. package/dist/utils/preRestart.d.ts +0 -3
  183. package/dist/utils/preRestart.js +0 -52
@@ -1,7 +1,7 @@
1
- import { Execution } from '@lifi/types';
2
- import { ExecutionParams } from '../types';
1
+ import type { Execution } from '@lifi/types';
2
+ import type { ExecutionParams } from '../types';
3
3
  export declare class StepExecutionManager {
4
4
  allowUserInteraction: boolean;
5
5
  allowInteraction: (value: boolean) => void;
6
- execute: ({ signer, step, statusManager, settings, }: ExecutionParams) => Promise<Execution>;
6
+ execute: ({ walletClient, step, statusManager, settings, }: ExecutionParams) => Promise<Execution>;
7
7
  }
@@ -1,29 +1,31 @@
1
- import { BigNumber } from 'ethers';
2
- import { checkAllowance } from '../allowance';
3
- import { checkBalance } from '../balance';
1
+ import { publicActions } from 'viem';
4
2
  import ApiService from '../services/ApiService';
5
3
  import ChainsService from '../services/ChainsService';
6
- import { LifiErrorCode, TransactionError, ValidationError, } from '../utils/errors';
7
- import { getProvider } from '../utils/getProvider';
4
+ import ConfigService from '../services/ConfigService';
5
+ import { getMaxPriorityFeePerGas } from '../utils';
6
+ import { LiFiErrorCode, TransactionError, ValidationError, } from '../utils/errors';
8
7
  import { getTransactionFailedMessage, parseError } from '../utils/parseError';
9
- import { isZeroAddress, personalizeStep } from '../utils/utils';
8
+ import { isZeroAddress } from '../utils/utils';
9
+ import { checkAllowance } from './checkAllowance';
10
+ import { checkBalance } from './checkBalance';
11
+ import { updateMultisigRouteProcess } from './multisig';
10
12
  import { stepComparison } from './stepComparison';
11
13
  import { switchChain } from './switchChain';
12
- import { getSubstatusMessage, waitForReceivingTransaction } from './utils';
13
- import ConfigService from '../services/ConfigService';
14
- import { updateMultisigRouteProcess } from './multisig';
14
+ import { getSubstatusMessage } from './utils';
15
+ import { waitForReceivingTransaction } from './waitForReceivingTransaction';
15
16
  export class StepExecutionManager {
16
17
  constructor() {
17
18
  this.allowUserInteraction = true;
18
19
  this.allowInteraction = (value) => {
19
20
  this.allowUserInteraction = value;
20
21
  };
21
- this.execute = async ({ signer, step, statusManager, settings, }) => {
22
+ this.execute = async ({ walletClient, step, statusManager, settings, }) => {
23
+ const client = walletClient.extend(publicActions);
22
24
  const config = ConfigService.getInstance().getConfig();
23
- const isMultisigSigner = !!config.multisigConfig?.isMultisigSigner;
25
+ const isMultisigWalletClient = !!config.multisig?.isMultisigWalletClient;
24
26
  const multisigBatchTransactions = [];
25
- const shouldBatchTransactions = config.multisigConfig?.shouldBatchTransactions &&
26
- !!config.multisigConfig.sendBatchTransaction;
27
+ const shouldBatchTransactions = config.multisig?.shouldBatchTransactions &&
28
+ !!config.multisig.sendBatchTransaction;
27
29
  step.execution = statusManager.initExecutionObject(step);
28
30
  const chainsService = ChainsService.getInstance();
29
31
  const fromChain = await chainsService.getChainById(step.action.fromChainId);
@@ -35,20 +37,16 @@ export class StepExecutionManager {
35
37
  // Check token approval only if fromToken is not the native token => no approval needed in that case
36
38
  const checkForAllowance = !existingProcess?.txHash &&
37
39
  !isZeroAddress(step.action.fromToken.address) &&
38
- (shouldBatchTransactions || !isMultisigSigner);
40
+ (shouldBatchTransactions || !isMultisigWalletClient);
39
41
  if (checkForAllowance) {
40
- const populatedTransaction = await checkAllowance(signer, step, statusManager, settings, fromChain, this.allowUserInteraction, shouldBatchTransactions);
41
- if (populatedTransaction) {
42
- const { to, data } = populatedTransaction;
43
- if (to && data) {
44
- // allowance doesn't need value
45
- const cleanedPopulatedTransaction = {
46
- value: BigNumber.from(0).toString(),
47
- to,
48
- data,
49
- };
50
- multisigBatchTransactions.push(cleanedPopulatedTransaction);
51
- }
42
+ const data = await checkAllowance(client, step, statusManager, settings, fromChain, this.allowUserInteraction, shouldBatchTransactions);
43
+ if (data) {
44
+ // allowance doesn't need value
45
+ const baseTransaction = {
46
+ to: step.action.fromToken.address,
47
+ data,
48
+ };
49
+ multisigBatchTransactions.push(baseTransaction);
52
50
  }
53
51
  }
54
52
  // STEP 2: Get transaction
@@ -56,136 +54,143 @@ export class StepExecutionManager {
56
54
  if (process.status !== 'DONE') {
57
55
  const multisigProcess = step.execution.process.find((p) => !!p.multisigTxHash);
58
56
  try {
59
- if (isMultisigSigner && multisigProcess) {
60
- if (!multisigProcess) {
61
- throw new ValidationError('Multisig process is undefined.');
62
- }
63
- if (!config.multisigConfig?.getMultisigTransactionDetails) {
64
- throw new ValidationError('"getMultisigTransactionDetails()" is missing in Multisig config.');
65
- }
57
+ if (isMultisigWalletClient && multisigProcess) {
66
58
  const multisigTxHash = multisigProcess.multisigTxHash;
67
59
  if (!multisigTxHash) {
68
- // need to check what happens in failed tx
69
60
  throw new ValidationError('Multisig internal transaction hash is undefined.');
70
61
  }
71
- await updateMultisigRouteProcess(multisigTxHash, step, statusManager, process, fromChain);
62
+ await updateMultisigRouteProcess(multisigTxHash, step, statusManager, process.type, fromChain);
72
63
  }
73
- let transaction;
64
+ let txHash;
74
65
  if (process.txHash) {
75
66
  // Make sure that the chain is still correct
76
- const updatedSigner = await switchChain(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
77
- if (!updatedSigner) {
67
+ const updatedWalletClient = await switchChain(walletClient, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
68
+ if (!updatedWalletClient) {
78
69
  // Chain switch was not successful, stop execution here
79
70
  return step.execution;
80
71
  }
81
- signer = updatedSigner;
72
+ walletClient = updatedWalletClient;
82
73
  // Load exiting transaction
83
- transaction = await getProvider(signer).getTransaction(process.txHash);
74
+ txHash = process.txHash;
84
75
  }
85
76
  else {
86
77
  process = statusManager.updateProcess(step, process.type, 'STARTED');
87
78
  // Check balance
88
- await checkBalance(signer, step);
79
+ await checkBalance(client.account.address, step);
89
80
  // Create new transaction
90
81
  if (!step.transactionRequest) {
91
- const personalizedStep = await personalizeStep(signer, step);
92
- const updatedStep = await ApiService.getStepTransaction(personalizedStep);
93
- const comparedStep = await stepComparison(statusManager, personalizedStep, updatedStep, settings, this.allowUserInteraction);
82
+ const updatedStep = await ApiService.getStepTransaction(step);
83
+ const comparedStep = await stepComparison(statusManager, step, updatedStep, settings, this.allowUserInteraction);
94
84
  step = {
95
85
  ...comparedStep,
96
86
  execution: step.execution,
97
87
  };
98
88
  }
99
- const { transactionRequest } = step;
89
+ let transactionRequest = {
90
+ to: step.transactionRequest?.to,
91
+ from: step.transactionRequest?.from,
92
+ data: step.transactionRequest?.data,
93
+ value: step.transactionRequest?.value
94
+ ? BigInt(step.transactionRequest.value)
95
+ : undefined,
96
+ maxPriorityFeePerGas: walletClient.account?.type === 'local'
97
+ ? await getMaxPriorityFeePerGas(client)
98
+ : undefined,
99
+ // gas: step.transactionRequest?.gasLimit
100
+ // ? BigInt(step.transactionRequest.gasLimit as string)
101
+ // : undefined,
102
+ // gasPrice: step.transactionRequest?.gasPrice
103
+ // ? BigInt(step.transactionRequest.gasPrice as string)
104
+ // : undefined,
105
+ // maxFeePerGas: step.transactionRequest?.maxFeePerGas
106
+ // ? BigInt(step.transactionRequest.maxFeePerGas as string)
107
+ // : undefined,
108
+ // maxPriorityFeePerGas: step.transactionRequest?.maxPriorityFeePerGas
109
+ // ? BigInt(step.transactionRequest.maxPriorityFeePerGas as string)
110
+ // : undefined,
111
+ };
100
112
  if (!transactionRequest) {
101
- throw new TransactionError(LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
113
+ throw new TransactionError(LiFiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
102
114
  }
103
115
  // STEP 3: Send the transaction
104
116
  // Make sure that the chain is still correct
105
- const updatedSigner = await switchChain(signer, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
106
- if (!updatedSigner) {
117
+ const updatedWalletClient = await switchChain(walletClient, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
118
+ if (!updatedWalletClient) {
107
119
  // Chain switch was not successful, stop execution here
108
120
  return step.execution;
109
121
  }
110
- signer = updatedSigner;
122
+ walletClient = updatedWalletClient;
111
123
  process = statusManager.updateProcess(step, process.type, 'ACTION_REQUIRED');
112
124
  if (!this.allowUserInteraction) {
113
125
  return step.execution;
114
126
  }
115
127
  if (settings.updateTransactionRequestHook) {
116
- const customConfig = await settings.updateTransactionRequestHook(transactionRequest);
117
- transactionRequest.gasLimit = customConfig.gasLimit;
118
- transactionRequest.gasPrice = customConfig.gasPrice;
119
- transactionRequest.maxPriorityFeePerGas =
120
- customConfig.maxPriorityFeePerGas;
121
- transactionRequest.maxFeePerGas = customConfig.maxFeePerGas;
122
- }
123
- else {
124
- try {
125
- const estimatedGasLimit = await signer.estimateGas(transactionRequest);
126
- if (estimatedGasLimit) {
127
- transactionRequest.gasLimit = BigNumber.from(`${(BigInt(estimatedGasLimit.toString()) * 125n) / 100n}`);
128
- }
129
- // Fetch latest gasPrice from provider and use it
130
- const gasPrice = await signer.getGasPrice();
131
- if (gasPrice) {
132
- transactionRequest.gasPrice = gasPrice;
133
- }
134
- }
135
- catch (error) { }
128
+ const customizedTransactionRequest = await settings.updateTransactionRequestHook(transactionRequest);
129
+ transactionRequest = {
130
+ ...transactionRequest,
131
+ ...customizedTransactionRequest,
132
+ };
136
133
  }
137
- // Submit the transaction
138
134
  if (shouldBatchTransactions &&
139
- config.multisigConfig?.sendBatchTransaction) {
140
- const { to, data, value } = await signer.populateTransaction(transactionRequest);
141
- const isValidTransaction = to && data;
142
- if (isValidTransaction) {
135
+ config.multisig?.sendBatchTransaction) {
136
+ if (transactionRequest.to && transactionRequest.data) {
143
137
  const populatedTransaction = {
144
- value: value?.toString() ?? BigNumber.from(0).toString(),
145
- to,
146
- data: data.toString(),
138
+ value: transactionRequest.value,
139
+ to: transactionRequest.to,
140
+ data: transactionRequest.data,
147
141
  };
148
142
  multisigBatchTransactions.push(populatedTransaction);
149
- transaction = await config.multisigConfig?.sendBatchTransaction(multisigBatchTransactions);
143
+ txHash = await config.multisig?.sendBatchTransaction(multisigBatchTransactions);
150
144
  }
151
145
  else {
152
- throw new TransactionError(LifiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
146
+ throw new TransactionError(LiFiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
153
147
  }
154
148
  }
155
149
  else {
156
- transaction = await signer.sendTransaction(transactionRequest);
150
+ txHash = await walletClient.sendTransaction({
151
+ to: transactionRequest.to,
152
+ account: walletClient.account,
153
+ data: transactionRequest.data,
154
+ maxPriorityFeePerGas: transactionRequest.maxPriorityFeePerGas,
155
+ chain: null,
156
+ });
157
157
  }
158
158
  // STEP 4: Wait for the transaction
159
- if (isMultisigSigner) {
159
+ if (isMultisigWalletClient) {
160
160
  process = statusManager.updateProcess(step, process.type, 'ACTION_REQUIRED', {
161
- multisigTxHash: transaction.hash,
161
+ multisigTxHash: txHash,
162
162
  });
163
163
  }
164
164
  else {
165
165
  process = statusManager.updateProcess(step, process.type, 'PENDING', {
166
- txHash: transaction.hash,
167
- txLink: fromChain.metamask.blockExplorerUrls[0] +
168
- 'tx/' +
169
- transaction.hash,
166
+ txHash: txHash,
167
+ txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${txHash}`,
170
168
  });
171
169
  }
172
170
  }
173
- await transaction.wait?.();
174
- // if it's multisig signer and the process is in ACTION_REQUIRED
171
+ let replacementReason;
172
+ const transactionReceipt = await client.waitForTransactionReceipt({
173
+ hash: txHash,
174
+ onReplaced(response) {
175
+ replacementReason = response.reason;
176
+ statusManager.updateProcess(step, process.type, 'PENDING', {
177
+ txHash: response.transaction.hash,
178
+ txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${response.transaction.hash}`,
179
+ });
180
+ },
181
+ });
182
+ if (replacementReason === 'cancelled') {
183
+ throw new TransactionError(LiFiErrorCode.TransactionCanceled, 'User canceled transaction.');
184
+ }
185
+ // if it's multisig wallet client and the process is in ACTION_REQUIRED
175
186
  // then signatures are still needed
176
- if (isMultisigSigner &&
177
- process.status === 'ACTION_REQUIRED' &&
178
- transaction.hash) {
179
- // Return the execution object without updating the process
180
- // The execution would progress once all multisigs signer approve
181
- await updateMultisigRouteProcess(transaction.hash, step, statusManager, process, fromChain);
187
+ if (isMultisigWalletClient && process.status === 'ACTION_REQUIRED') {
188
+ await updateMultisigRouteProcess(transactionReceipt.transactionHash, step, statusManager, process.type, fromChain);
182
189
  }
183
- if (!isMultisigSigner) {
190
+ if (!isMultisigWalletClient) {
184
191
  process = statusManager.updateProcess(step, process.type, 'PENDING', {
185
- txHash: transaction.hash,
186
- txLink: fromChain.metamask.blockExplorerUrls[0] +
187
- 'tx/' +
188
- transaction.hash,
192
+ txHash: transactionReceipt.transactionHash,
193
+ txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${transactionReceipt.transactionHash}`,
189
194
  });
190
195
  }
191
196
  if (isBridgeExecution) {
@@ -193,26 +198,16 @@ export class StepExecutionManager {
193
198
  }
194
199
  }
195
200
  catch (e) {
196
- if (e.code === 'TRANSACTION_REPLACED' && e.replacement) {
197
- process = statusManager.updateProcess(step, process.type, 'DONE', {
198
- txHash: e.replacement.hash,
199
- txLink: fromChain.metamask.blockExplorerUrls[0] +
200
- 'tx/' +
201
- e.replacement.hash,
202
- });
203
- }
204
- else {
205
- const error = await parseError(e, step, process);
206
- process = statusManager.updateProcess(step, process.type, 'FAILED', {
207
- error: {
208
- message: error.message,
209
- htmlMessage: error.htmlMessage,
210
- code: error.code,
211
- },
212
- });
213
- statusManager.updateExecution(step, 'FAILED');
214
- throw error;
215
- }
201
+ const error = await parseError(e, step, process);
202
+ process = statusManager.updateProcess(step, process.type, 'FAILED', {
203
+ error: {
204
+ message: error.message,
205
+ htmlMessage: error.htmlMessage,
206
+ code: error.code,
207
+ },
208
+ });
209
+ statusManager.updateExecution(step, 'FAILED');
210
+ throw error;
216
211
  }
217
212
  }
218
213
  // STEP 5: Wait for the receiving chain
@@ -232,9 +227,7 @@ export class StepExecutionManager {
232
227
  substatusMessage: statusResponse.substatusMessage ||
233
228
  getSubstatusMessage(statusResponse.status, statusResponse.substatus),
234
229
  txHash: statusReceiving?.txHash,
235
- txLink: toChain.metamask.blockExplorerUrls[0] +
236
- 'tx/' +
237
- statusReceiving?.txHash,
230
+ txLink: `${toChain.metamask.blockExplorerUrls[0]}tx/${statusReceiving?.txHash}`,
238
231
  });
239
232
  statusManager.updateExecution(step, 'DONE', {
240
233
  fromAmount: statusResponse.sending.amount,
@@ -251,7 +244,7 @@ export class StepExecutionManager {
251
244
  const htmlMessage = await getTransactionFailedMessage(step, process.txLink);
252
245
  process = statusManager.updateProcess(step, process.type, 'FAILED', {
253
246
  error: {
254
- code: LifiErrorCode.TransactionFailed,
247
+ code: LiFiErrorCode.TransactionFailed,
255
248
  message: 'Failed while waiting for receiving chain.',
256
249
  htmlMessage,
257
250
  },
@@ -1,6 +1,6 @@
1
- import { Signer } from 'ethers';
2
- import { InteractionSettings, InternalExecutionSettings, LifiStep } from '../types';
3
- import { StatusManager } from './StatusManager';
1
+ import type { WalletClient } from 'viem';
2
+ import type { InteractionSettings, InternalExecutionSettings, LifiStep } from '../types';
3
+ import type { StatusManager } from './StatusManager';
4
4
  import { StepExecutionManager } from './StepExecutionManager';
5
5
  export declare class StepExecutor {
6
6
  stepExecutionManager: StepExecutionManager;
@@ -11,5 +11,5 @@ export declare class StepExecutor {
11
11
  constructor(statusManager: StatusManager, settings: InternalExecutionSettings);
12
12
  setInteraction: (settings?: InteractionSettings) => void;
13
13
  checkChain: () => never;
14
- executeStep: (signer: Signer, step: LifiStep) => Promise<LifiStep>;
14
+ executeStep: (walletClient: WalletClient, step: LifiStep) => Promise<LifiStep>;
15
15
  }
@@ -20,13 +20,13 @@ export class StepExecutor {
20
20
  this.statusManager.allowUpdates(interactionSettings.allowUpdates);
21
21
  this.executionStopped = interactionSettings.stopExecution;
22
22
  };
23
- // TODO: add checkChain method and update signer inside executors
23
+ // TODO: add checkChain method and update wallet client inside executors
24
24
  // This can come in handy when we execute multiple routes simultaneously and
25
25
  // should be sure that we are on the right chain when waiting for transactions.
26
26
  this.checkChain = () => {
27
27
  throw new Error('checkChain is not implemented.');
28
28
  };
29
- this.executeStep = async (signer, step) => {
29
+ this.executeStep = async (walletClient, step) => {
30
30
  // Make sure that the chain is still correct
31
31
  // Find if it's bridging and the step is waiting for a transaction on the receiving chain
32
32
  const recievingChainProcess = step.execution?.process.find((process) => process.type === 'RECEIVING_CHAIN');
@@ -35,15 +35,15 @@ export class StepExecutor {
35
35
  // Return the step
36
36
  if (recievingChainProcess?.substatus !== 'WAIT_DESTINATION_TRANSACTION' ||
37
37
  !recievingChainProcess) {
38
- const updatedSigner = await switchChain(signer, this.statusManager, step, this.settings.switchChainHook, this.allowUserInteraction);
39
- if (!updatedSigner) {
38
+ const updatedWalletClient = await switchChain(walletClient, this.statusManager, step, this.settings.switchChainHook, this.allowUserInteraction);
39
+ if (!updatedWalletClient) {
40
40
  // Chain switch was not successful, stop execution here
41
41
  return step;
42
42
  }
43
- signer = updatedSigner;
43
+ walletClient = updatedWalletClient;
44
44
  }
45
45
  const parameters = {
46
- signer,
46
+ walletClient,
47
47
  step,
48
48
  settings: this.settings,
49
49
  statusManager: this.statusManager,
@@ -0,0 +1,4 @@
1
+ import type { Hash, WalletClient } from 'viem';
2
+ import type { StatusManager } from '../execution/StatusManager';
3
+ import type { Chain, InternalExecutionSettings, LifiStep } from '../types';
4
+ export declare const checkAllowance: (walletClient: WalletClient, step: LifiStep, statusManager: StatusManager, settings: InternalExecutionSettings, chain: Chain, allowUserInteraction?: boolean, shouldBatchTransactions?: boolean) => Promise<Hash | void>;
@@ -0,0 +1,73 @@
1
+ import { maxUint256, publicActions } from 'viem';
2
+ import { getAllowance, setAllowance } from '../allowance';
3
+ import { LiFiErrorCode, TransactionError } from '../utils';
4
+ import { parseError } from '../utils/parseError';
5
+ export const checkAllowance = async (walletClient, step, statusManager, settings, chain, allowUserInteraction = false, shouldBatchTransactions = false) => {
6
+ // Ask the user to set an allowance
7
+ let allowanceProcess = statusManager.findOrCreateProcess(step, 'TOKEN_ALLOWANCE');
8
+ // Check allowance
9
+ try {
10
+ if (allowanceProcess.txHash && allowanceProcess.status !== 'DONE') {
11
+ await waitForApprovalTransaction(walletClient, allowanceProcess.txHash, allowanceProcess.type, step, chain, statusManager);
12
+ }
13
+ else {
14
+ const approved = await getAllowance(chain.id, step.action.fromToken.address, walletClient.account.address, step.estimate.approvalAddress);
15
+ const fromAmount = BigInt(step.action.fromAmount);
16
+ if (fromAmount > approved) {
17
+ if (!allowUserInteraction) {
18
+ return;
19
+ }
20
+ const approvalAmount = settings.infiniteApproval
21
+ ? maxUint256
22
+ : fromAmount;
23
+ if (shouldBatchTransactions) {
24
+ const approveTxHash = await setAllowance(walletClient, step.action.fromToken.address, step.estimate.approvalAddress, approvalAmount, true);
25
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
26
+ return approveTxHash;
27
+ }
28
+ const approveTxHash = await setAllowance(walletClient, step.action.fromToken.address, step.estimate.approvalAddress, approvalAmount);
29
+ await waitForApprovalTransaction(walletClient, approveTxHash, allowanceProcess.type, step, chain, statusManager);
30
+ }
31
+ else {
32
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
33
+ }
34
+ }
35
+ }
36
+ catch (e) {
37
+ const error = await parseError(e, step, allowanceProcess);
38
+ allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'FAILED', {
39
+ error: {
40
+ message: error.message,
41
+ htmlMessage: error.htmlMessage,
42
+ code: error.code,
43
+ },
44
+ });
45
+ statusManager.updateExecution(step, 'FAILED');
46
+ throw error;
47
+ }
48
+ };
49
+ const waitForApprovalTransaction = async (walletClient, txHash, processType, step, chain, statusManager) => {
50
+ const client = walletClient.extend(publicActions);
51
+ statusManager.updateProcess(step, processType, 'PENDING', {
52
+ txHash,
53
+ txLink: `${chain.metamask.blockExplorerUrls[0]}tx/${txHash}`,
54
+ });
55
+ let replacementReason;
56
+ const transactionReceipt = await client.waitForTransactionReceipt({
57
+ hash: txHash,
58
+ onReplaced(response) {
59
+ replacementReason = response.reason;
60
+ statusManager.updateProcess(step, processType, 'PENDING', {
61
+ txHash: response.transaction.hash,
62
+ txLink: `${chain.metamask.blockExplorerUrls[0]}tx/${response.transaction.hash}`,
63
+ });
64
+ },
65
+ });
66
+ if (replacementReason === 'cancelled') {
67
+ throw new TransactionError(LiFiErrorCode.TransactionCanceled, 'User canceled transaction.');
68
+ }
69
+ statusManager.updateProcess(step, processType, 'DONE', {
70
+ txHash: transactionReceipt.transactionHash,
71
+ txLink: `${chain.metamask.blockExplorerUrls[0]}tx/${transactionReceipt.transactionHash}`,
72
+ });
73
+ };
@@ -0,0 +1,2 @@
1
+ import type { LifiStep } from '..';
2
+ export declare const checkBalance: (walletAddress: string, step: LifiStep, depth?: number) => Promise<void>;
@@ -0,0 +1,38 @@
1
+ import { formatUnits } from 'viem';
2
+ import { getTokenBalance } from '../balance';
3
+ import { BalanceError } from '../utils/errors';
4
+ export const checkBalance = async (walletAddress, step, depth = 0) => {
5
+ const token = await getTokenBalance(walletAddress, step.action.fromToken);
6
+ if (token) {
7
+ const currentBalance = token.amount ?? 0n;
8
+ const neededBalance = BigInt(step.action.fromAmount);
9
+ if (currentBalance < neededBalance) {
10
+ if (depth <= 3) {
11
+ await new Promise((resolve) => {
12
+ setTimeout(resolve, 200);
13
+ });
14
+ await checkBalance(walletAddress, step, depth + 1);
15
+ }
16
+ else if ((neededBalance * BigInt((1 - step.action.slippage) * 1000000000)) /
17
+ 1000000000n <=
18
+ currentBalance) {
19
+ // adjust amount in slippage limits
20
+ step.action.fromAmount = currentBalance.toString();
21
+ }
22
+ else {
23
+ const neeeded = formatUnits(neededBalance, token.decimals);
24
+ const current = formatUnits(currentBalance, token.decimals);
25
+ let errorMessage = `Your ${token.symbol} balance is too low, ` +
26
+ `you try to transfer ${neeeded} ${token.symbol}, ` +
27
+ `but your wallet only holds ${current} ${token.symbol}. ` +
28
+ `No funds have been sent.`;
29
+ if (currentBalance !== 0n) {
30
+ errorMessage +=
31
+ `If the problem consists, please delete this transfer and ` +
32
+ `start a new one with a maximum of ${current} ${token.symbol}.`;
33
+ }
34
+ throw new BalanceError('The balance is too low.', errorMessage);
35
+ }
36
+ }
37
+ }
38
+ };
@@ -1,3 +1,4 @@
1
- import { ExtendedChain, LifiStep, Process } from '@lifi/types';
2
- import { StatusManager } from '.';
3
- export declare const updateMultisigRouteProcess: (internalTxHash: string, step: LifiStep, statusManager: StatusManager, process: Process, fromChain: ExtendedChain) => Promise<void>;
1
+ import type { ExtendedChain, LifiStep, ProcessType } from '@lifi/types';
2
+ import type { Hash } from 'viem';
3
+ import type { StatusManager } from './StatusManager';
4
+ export declare const updateMultisigRouteProcess: (internalTxHash: Hash, step: LifiStep, statusManager: StatusManager, processType: ProcessType, fromChain: ExtendedChain) => Promise<void>;
@@ -1,27 +1,25 @@
1
1
  import ConfigService from '../services/ConfigService';
2
- import { LifiErrorCode, TransactionError } from '../utils/errors';
3
- export const updateMultisigRouteProcess = async (internalTxHash, step, statusManager, process, fromChain) => {
2
+ import { LiFiErrorCode, TransactionError } from '../utils/errors';
3
+ export const updateMultisigRouteProcess = async (internalTxHash, step, statusManager, processType, fromChain) => {
4
4
  const config = ConfigService.getInstance().getConfig();
5
- if (!config.multisigConfig?.getMultisigTransactionDetails) {
6
- throw new Error('"getMultisigTransactionDetails()" is missing in Multisig config.');
5
+ if (!config.multisig?.getMultisigTransactionDetails) {
6
+ throw new Error('getMultisigTransactionDetails is missing in multisig config.');
7
7
  }
8
8
  const updateIntermediateMultisigStatus = () => {
9
- process = statusManager.updateProcess(step, process.type, 'PENDING');
9
+ statusManager.updateProcess(step, processType, 'PENDING');
10
10
  };
11
- const multisigStatusResponse = await config.multisigConfig?.getMultisigTransactionDetails(internalTxHash, fromChain.id, updateIntermediateMultisigStatus);
11
+ const multisigStatusResponse = await config.multisig?.getMultisigTransactionDetails(internalTxHash, fromChain.id, updateIntermediateMultisigStatus);
12
12
  if (multisigStatusResponse.status === 'DONE') {
13
- process = statusManager.updateProcess(step, process.type, 'PENDING', {
13
+ statusManager.updateProcess(step, processType, 'PENDING', {
14
14
  txHash: multisigStatusResponse.txHash,
15
15
  multisigTxHash: undefined,
16
- txLink: fromChain.metamask.blockExplorerUrls[0] +
17
- 'tx/' +
18
- multisigStatusResponse.txHash,
16
+ txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${multisigStatusResponse.txHash}`,
19
17
  });
20
18
  }
21
19
  if (multisigStatusResponse.status === 'FAILED') {
22
- throw new TransactionError(LifiErrorCode.TransactionFailed, 'Multisig transaction failed.');
20
+ throw new TransactionError(LiFiErrorCode.TransactionFailed, 'Multisig transaction failed.');
23
21
  }
24
22
  if (multisigStatusResponse.status === 'CANCELLED') {
25
- throw new TransactionError(LifiErrorCode.TransactionRejected, 'Transaction was rejected by users.');
23
+ throw new TransactionError(LiFiErrorCode.SignatureRejected, 'Transaction was rejected by user.');
26
24
  }
27
25
  };
@@ -0,0 +1,3 @@
1
+ import { type WalletClient } from 'viem';
2
+ import type { Route } from '../types';
3
+ export declare const prepareRestart: (route: Route, walletClient: WalletClient) => Promise<void>;