@lifi/sdk 4.0.0-alpha.9 → 4.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/dist/cjs/actions/getQuote.js +2 -1
  2. package/dist/cjs/actions/getQuote.js.map +1 -1
  3. package/dist/cjs/actions/getRelayedTransactionStatus.js +1 -1
  4. package/dist/cjs/actions/getRelayedTransactionStatus.js.map +1 -1
  5. package/dist/cjs/actions/getRelayerQuote.js +2 -1
  6. package/dist/cjs/actions/getRelayerQuote.js.map +1 -1
  7. package/dist/cjs/actions/getStepTransaction.js +18 -1
  8. package/dist/cjs/actions/getStepTransaction.js.map +1 -1
  9. package/dist/cjs/core/BaseStepExecutionTask.d.ts +5 -0
  10. package/dist/cjs/core/BaseStepExecutionTask.js +10 -0
  11. package/dist/cjs/core/BaseStepExecutionTask.js.map +1 -0
  12. package/dist/cjs/core/BaseStepExecutor.d.ts +10 -3
  13. package/dist/cjs/core/BaseStepExecutor.js +53 -0
  14. package/dist/cjs/core/BaseStepExecutor.js.map +1 -1
  15. package/dist/cjs/core/StatusManager.d.ts +12 -10
  16. package/dist/cjs/core/StatusManager.js +35 -33
  17. package/dist/cjs/core/StatusManager.js.map +1 -1
  18. package/dist/cjs/core/TaskPipeline.d.ts +7 -0
  19. package/dist/cjs/core/TaskPipeline.js +27 -0
  20. package/dist/cjs/core/TaskPipeline.js.map +1 -0
  21. package/dist/cjs/core/actionMessages.js +19 -3
  22. package/dist/cjs/core/actionMessages.js.map +1 -1
  23. package/dist/cjs/core/execution.js +13 -1
  24. package/dist/cjs/core/execution.js.map +1 -1
  25. package/dist/cjs/core/prepareRestart.js +3 -3
  26. package/dist/cjs/core/prepareRestart.js.map +1 -1
  27. package/dist/cjs/core/storage.d.ts +17 -0
  28. package/dist/cjs/core/storage.js +36 -0
  29. package/dist/cjs/core/storage.js.map +1 -0
  30. package/dist/cjs/core/tasks/CheckBalanceTask.d.ts +5 -0
  31. package/dist/cjs/core/tasks/CheckBalanceTask.js +26 -0
  32. package/dist/cjs/core/tasks/CheckBalanceTask.js.map +1 -0
  33. package/dist/cjs/core/tasks/PrepareTransactionTask.d.ts +5 -0
  34. package/dist/cjs/core/tasks/PrepareTransactionTask.js +36 -0
  35. package/dist/cjs/core/tasks/PrepareTransactionTask.js.map +1 -0
  36. package/dist/cjs/core/tasks/WaitForTransactionStatusTask.d.ts +8 -0
  37. package/dist/cjs/core/tasks/WaitForTransactionStatusTask.js +73 -0
  38. package/dist/cjs/core/tasks/WaitForTransactionStatusTask.js.map +1 -0
  39. package/dist/cjs/core/{checkBalance.d.ts → tasks/helpers/checkBalance.d.ts} +1 -1
  40. package/dist/cjs/core/{checkBalance.js → tasks/helpers/checkBalance.js} +4 -4
  41. package/dist/cjs/core/tasks/helpers/checkBalance.js.map +1 -0
  42. package/dist/cjs/core/tasks/helpers/getTransactionRequestData.d.ts +2 -0
  43. package/dist/cjs/core/tasks/helpers/getTransactionRequestData.js +30 -0
  44. package/dist/cjs/core/tasks/helpers/getTransactionRequestData.js.map +1 -0
  45. package/dist/cjs/core/{stepComparison.d.ts → tasks/helpers/stepComparison.d.ts} +2 -2
  46. package/dist/cjs/core/{stepComparison.js → tasks/helpers/stepComparison.js} +3 -3
  47. package/dist/cjs/core/tasks/helpers/stepComparison.js.map +1 -0
  48. package/dist/cjs/core/{waitForTransactionStatus.d.ts → tasks/helpers/waitForTransactionStatus.d.ts} +2 -2
  49. package/dist/cjs/core/{waitForTransactionStatus.js → tasks/helpers/waitForTransactionStatus.js} +7 -5
  50. package/dist/cjs/core/tasks/helpers/waitForTransactionStatus.js.map +1 -0
  51. package/dist/cjs/core/utils.d.ts +6 -1
  52. package/dist/cjs/errors/constants.d.ts +2 -1
  53. package/dist/cjs/errors/constants.js +1 -0
  54. package/dist/cjs/errors/constants.js.map +1 -1
  55. package/dist/cjs/errors/errors.d.ts +5 -0
  56. package/dist/cjs/errors/errors.js +9 -1
  57. package/dist/cjs/errors/errors.js.map +1 -1
  58. package/dist/cjs/index.d.ts +15 -6
  59. package/dist/cjs/index.js +26 -7
  60. package/dist/cjs/index.js.map +1 -1
  61. package/dist/cjs/types/core.d.ts +15 -6
  62. package/dist/cjs/types/execution.d.ts +22 -0
  63. package/dist/cjs/types/execution.js +3 -0
  64. package/dist/cjs/types/execution.js.map +1 -0
  65. package/dist/cjs/utils/waitForResult.d.ts +1 -1
  66. package/dist/cjs/utils/waitForResult.js +6 -2
  67. package/dist/cjs/utils/waitForResult.js.map +1 -1
  68. package/dist/cjs/utils/withDedupe.d.ts +5 -0
  69. package/dist/cjs/utils/withDedupe.js +2 -0
  70. package/dist/cjs/utils/withDedupe.js.map +1 -1
  71. package/dist/cjs/version.d.ts +1 -1
  72. package/dist/cjs/version.js +1 -1
  73. package/dist/cjs/version.js.map +1 -1
  74. package/dist/esm/actions/getQuote.js +2 -1
  75. package/dist/esm/actions/getQuote.js.map +1 -1
  76. package/dist/esm/actions/getRelayedTransactionStatus.js +1 -1
  77. package/dist/esm/actions/getRelayedTransactionStatus.js.map +1 -1
  78. package/dist/esm/actions/getRelayerQuote.js +2 -1
  79. package/dist/esm/actions/getRelayerQuote.js.map +1 -1
  80. package/dist/esm/actions/getStepTransaction.js +18 -1
  81. package/dist/esm/actions/getStepTransaction.js.map +1 -1
  82. package/dist/esm/core/BaseStepExecutionTask.d.ts +5 -0
  83. package/dist/esm/core/BaseStepExecutionTask.js +6 -0
  84. package/dist/esm/core/BaseStepExecutionTask.js.map +1 -0
  85. package/dist/esm/core/BaseStepExecutor.d.ts +10 -3
  86. package/dist/esm/core/BaseStepExecutor.js +53 -0
  87. package/dist/esm/core/BaseStepExecutor.js.map +1 -1
  88. package/dist/esm/core/StatusManager.d.ts +29 -27
  89. package/dist/esm/core/StatusManager.js +52 -50
  90. package/dist/esm/core/StatusManager.js.map +1 -1
  91. package/dist/esm/core/TaskPipeline.d.ts +7 -0
  92. package/dist/esm/core/TaskPipeline.js +23 -0
  93. package/dist/esm/core/TaskPipeline.js.map +1 -0
  94. package/dist/esm/core/actionMessages.js +19 -3
  95. package/dist/esm/core/actionMessages.js.map +1 -1
  96. package/dist/esm/core/execution.js +14 -3
  97. package/dist/esm/core/execution.js.map +1 -1
  98. package/dist/esm/core/prepareRestart.js +4 -3
  99. package/dist/esm/core/prepareRestart.js.map +1 -1
  100. package/dist/esm/core/storage.d.ts +17 -0
  101. package/dist/esm/core/storage.js +30 -0
  102. package/dist/esm/core/storage.js.map +1 -0
  103. package/dist/esm/core/tasks/CheckBalanceTask.d.ts +5 -0
  104. package/dist/esm/core/tasks/CheckBalanceTask.js +22 -0
  105. package/dist/esm/core/tasks/CheckBalanceTask.js.map +1 -0
  106. package/dist/esm/core/tasks/PrepareTransactionTask.d.ts +5 -0
  107. package/dist/esm/core/tasks/PrepareTransactionTask.js +32 -0
  108. package/dist/esm/core/tasks/PrepareTransactionTask.js.map +1 -0
  109. package/dist/esm/core/tasks/WaitForTransactionStatusTask.d.ts +8 -0
  110. package/dist/esm/core/tasks/WaitForTransactionStatusTask.js +74 -0
  111. package/dist/esm/core/tasks/WaitForTransactionStatusTask.js.map +1 -0
  112. package/dist/esm/core/{checkBalance.d.ts → tasks/helpers/checkBalance.d.ts} +1 -1
  113. package/dist/esm/core/{checkBalance.js → tasks/helpers/checkBalance.js} +4 -4
  114. package/dist/esm/core/tasks/helpers/checkBalance.js.map +1 -0
  115. package/dist/esm/core/tasks/helpers/getTransactionRequestData.d.ts +2 -0
  116. package/dist/esm/core/tasks/helpers/getTransactionRequestData.js +26 -0
  117. package/dist/esm/core/tasks/helpers/getTransactionRequestData.js.map +1 -0
  118. package/dist/esm/core/{stepComparison.d.ts → tasks/helpers/stepComparison.d.ts} +2 -2
  119. package/dist/esm/core/{stepComparison.js → tasks/helpers/stepComparison.js} +3 -3
  120. package/dist/esm/core/tasks/helpers/stepComparison.js.map +1 -0
  121. package/dist/esm/core/{waitForTransactionStatus.d.ts → tasks/helpers/waitForTransactionStatus.d.ts} +2 -2
  122. package/dist/esm/core/{waitForTransactionStatus.js → tasks/helpers/waitForTransactionStatus.js} +7 -5
  123. package/dist/esm/core/tasks/helpers/waitForTransactionStatus.js.map +1 -0
  124. package/dist/esm/core/utils.d.ts +6 -1
  125. package/dist/esm/errors/constants.d.ts +2 -1
  126. package/dist/esm/errors/constants.js +1 -0
  127. package/dist/esm/errors/constants.js.map +1 -1
  128. package/dist/esm/errors/errors.d.ts +10 -0
  129. package/dist/esm/errors/errors.js +12 -0
  130. package/dist/esm/errors/errors.js.map +1 -1
  131. package/dist/esm/index.d.ts +15 -6
  132. package/dist/esm/index.js +12 -5
  133. package/dist/esm/index.js.map +1 -1
  134. package/dist/esm/types/core.d.ts +19 -6
  135. package/dist/esm/types/execution.d.ts +23 -0
  136. package/dist/esm/types/execution.js +2 -0
  137. package/dist/esm/types/execution.js.map +1 -0
  138. package/dist/esm/utils/waitForResult.d.ts +2 -2
  139. package/dist/esm/utils/waitForResult.js +7 -3
  140. package/dist/esm/utils/waitForResult.js.map +1 -1
  141. package/dist/esm/utils/withDedupe.d.ts +10 -0
  142. package/dist/esm/utils/withDedupe.js +1 -1
  143. package/dist/esm/utils/withDedupe.js.map +1 -1
  144. package/dist/esm/version.d.ts +1 -1
  145. package/dist/esm/version.js +1 -1
  146. package/dist/esm/version.js.map +1 -1
  147. package/dist/types/actions/getRelayerQuote.d.ts.map +1 -1
  148. package/dist/types/actions/getStepTransaction.d.ts.map +1 -1
  149. package/dist/types/core/BaseStepExecutionTask.d.ts +6 -0
  150. package/dist/types/core/BaseStepExecutionTask.d.ts.map +1 -0
  151. package/dist/types/core/BaseStepExecutor.d.ts +10 -3
  152. package/dist/types/core/BaseStepExecutor.d.ts.map +1 -1
  153. package/dist/types/core/StatusManager.d.ts +29 -27
  154. package/dist/types/core/StatusManager.d.ts.map +1 -1
  155. package/dist/types/core/TaskPipeline.d.ts +8 -0
  156. package/dist/types/core/TaskPipeline.d.ts.map +1 -0
  157. package/dist/types/core/actionMessages.d.ts.map +1 -1
  158. package/dist/types/core/execution.d.ts.map +1 -1
  159. package/dist/types/core/prepareRestart.d.ts.map +1 -1
  160. package/dist/types/core/storage.d.ts +18 -0
  161. package/dist/types/core/storage.d.ts.map +1 -0
  162. package/dist/types/core/tasks/CheckBalanceTask.d.ts +6 -0
  163. package/dist/types/core/tasks/CheckBalanceTask.d.ts.map +1 -0
  164. package/dist/types/core/tasks/PrepareTransactionTask.d.ts +6 -0
  165. package/dist/types/core/tasks/PrepareTransactionTask.d.ts.map +1 -0
  166. package/dist/types/core/tasks/WaitForTransactionStatusTask.d.ts +9 -0
  167. package/dist/types/core/tasks/WaitForTransactionStatusTask.d.ts.map +1 -0
  168. package/dist/types/core/{checkBalance.d.ts → tasks/helpers/checkBalance.d.ts} +1 -1
  169. package/dist/types/core/tasks/helpers/checkBalance.d.ts.map +1 -0
  170. package/dist/types/core/tasks/helpers/getTransactionRequestData.d.ts +3 -0
  171. package/dist/types/core/tasks/helpers/getTransactionRequestData.d.ts.map +1 -0
  172. package/dist/types/core/{stepComparison.d.ts → tasks/helpers/stepComparison.d.ts} +2 -2
  173. package/dist/types/core/tasks/helpers/stepComparison.d.ts.map +1 -0
  174. package/dist/types/core/{waitForTransactionStatus.d.ts → tasks/helpers/waitForTransactionStatus.d.ts} +2 -2
  175. package/dist/types/core/tasks/helpers/waitForTransactionStatus.d.ts.map +1 -0
  176. package/dist/types/core/utils.d.ts +6 -1
  177. package/dist/types/core/utils.d.ts.map +1 -1
  178. package/dist/types/errors/constants.d.ts +2 -1
  179. package/dist/types/errors/constants.d.ts.map +1 -1
  180. package/dist/types/errors/errors.d.ts +10 -0
  181. package/dist/types/errors/errors.d.ts.map +1 -1
  182. package/dist/types/index.d.ts +15 -6
  183. package/dist/types/index.d.ts.map +1 -1
  184. package/dist/types/types/core.d.ts +19 -6
  185. package/dist/types/types/core.d.ts.map +1 -1
  186. package/dist/types/types/execution.d.ts +24 -0
  187. package/dist/types/types/execution.d.ts.map +1 -0
  188. package/dist/types/utils/waitForResult.d.ts +2 -2
  189. package/dist/types/utils/waitForResult.d.ts.map +1 -1
  190. package/dist/types/utils/withDedupe.d.ts +10 -0
  191. package/dist/types/utils/withDedupe.d.ts.map +1 -1
  192. package/dist/types/version.d.ts +1 -1
  193. package/dist/types/version.d.ts.map +1 -1
  194. package/package.json +2 -2
  195. package/src/actions/getQuote.ts +4 -1
  196. package/src/actions/getRelayedTransactionStatus.ts +1 -1
  197. package/src/actions/getRelayerQuote.ts +4 -1
  198. package/src/actions/getStepTransaction.ts +27 -11
  199. package/src/core/BaseStepExecutionTask.ts +9 -0
  200. package/src/core/BaseStepExecutor.ts +91 -2
  201. package/src/core/StatusManager.ts +66 -61
  202. package/src/core/TaskPipeline.ts +28 -0
  203. package/src/core/actionMessages.ts +20 -3
  204. package/src/core/execution.ts +17 -3
  205. package/src/core/prepareRestart.ts +4 -3
  206. package/src/core/storage.ts +42 -0
  207. package/src/core/tasks/CheckBalanceTask.ts +29 -0
  208. package/src/core/tasks/PrepareTransactionTask.ts +62 -0
  209. package/src/core/tasks/WaitForTransactionStatusTask.ts +114 -0
  210. package/src/core/{checkBalance.ts → tasks/helpers/checkBalance.ts} +5 -5
  211. package/src/core/tasks/helpers/getTransactionRequestData.ts +47 -0
  212. package/src/core/{stepComparison.ts → tasks/helpers/stepComparison.ts} +5 -5
  213. package/src/core/{waitForTransactionStatus.ts → tasks/helpers/waitForTransactionStatus.ts} +9 -7
  214. package/src/errors/constants.ts +1 -0
  215. package/src/errors/errors.ts +24 -0
  216. package/src/index.ts +24 -4
  217. package/src/types/core.ts +23 -13
  218. package/src/types/execution.ts +32 -0
  219. package/src/utils/waitForResult.ts +9 -4
  220. package/src/utils/withDedupe.ts +1 -1
  221. package/src/version.ts +1 -1
  222. package/dist/cjs/core/checkBalance.js.map +0 -1
  223. package/dist/cjs/core/stepComparison.js.map +0 -1
  224. package/dist/cjs/core/waitForDestinationChainTransaction.d.ts +0 -4
  225. package/dist/cjs/core/waitForDestinationChainTransaction.js +0 -71
  226. package/dist/cjs/core/waitForDestinationChainTransaction.js.map +0 -1
  227. package/dist/cjs/core/waitForTransactionStatus.js.map +0 -1
  228. package/dist/esm/core/checkBalance.js.map +0 -1
  229. package/dist/esm/core/stepComparison.js.map +0 -1
  230. package/dist/esm/core/waitForDestinationChainTransaction.d.ts +0 -4
  231. package/dist/esm/core/waitForDestinationChainTransaction.js +0 -74
  232. package/dist/esm/core/waitForDestinationChainTransaction.js.map +0 -1
  233. package/dist/esm/core/waitForTransactionStatus.js.map +0 -1
  234. package/dist/types/core/checkBalance.d.ts.map +0 -1
  235. package/dist/types/core/stepComparison.d.ts.map +0 -1
  236. package/dist/types/core/waitForDestinationChainTransaction.d.ts +0 -5
  237. package/dist/types/core/waitForDestinationChainTransaction.d.ts.map +0 -1
  238. package/dist/types/core/waitForTransactionStatus.d.ts.map +0 -1
  239. package/src/core/waitForDestinationChainTransaction.ts +0 -112
@@ -85,7 +85,10 @@ export async function getQuote(
85
85
  params.preferExchanges ??= client.config.routeOptions?.exchanges?.prefer
86
86
 
87
87
  for (const key of Object.keys(params)) {
88
- if (!params[key as keyof QuoteRequest]) {
88
+ if (
89
+ params[key as keyof QuoteRequest] === undefined ||
90
+ params[key as keyof QuoteRequest] === null
91
+ ) {
89
92
  delete params[key as keyof QuoteRequest]
90
93
  }
91
94
  }
@@ -39,7 +39,7 @@ export const getRelayedTransactionStatus = async (
39
39
 
40
40
  const decodedTaskId = decodeTaskId(taskId)
41
41
  // Temporary solution during the transition between status endpoints
42
- if (decodedTaskId.length === 3) {
42
+ if (decodedTaskId.length >= 3) {
43
43
  return (await getStatus(
44
44
  client,
45
45
  params,
@@ -56,7 +56,10 @@ export const getRelayerQuote = async (
56
56
  params.preferExchanges ??= client.config.routeOptions?.exchanges?.prefer
57
57
 
58
58
  for (const key of Object.keys(params)) {
59
- if (!params[key as keyof QuoteRequest]) {
59
+ if (
60
+ params[key as keyof QuoteRequest] === undefined ||
61
+ params[key as keyof QuoteRequest] === null
62
+ ) {
60
63
  delete params[key as keyof QuoteRequest]
61
64
  }
62
65
  }
@@ -1,4 +1,5 @@
1
1
  import type { LiFiStep, RequestOptions, SignedLiFiStep } from '@lifi/types'
2
+ import { ChainId } from '@lifi/types'
2
3
  import type { SDKClient } from '../types/core.js'
3
4
  import { isStep } from '../utils/isStep.js'
4
5
  import { request } from '../utils/request.js'
@@ -21,16 +22,31 @@ export const getStepTransaction = async (
21
22
  console.warn('SDK Validation: Invalid Step', step)
22
23
  }
23
24
 
24
- return await request<LiFiStep>(
25
- client.config,
26
- `${client.config.apiUrl}/advanced/stepTransaction`,
27
- {
28
- method: 'POST',
29
- headers: {
30
- 'Content-Type': 'application/json',
31
- },
32
- body: JSON.stringify(step),
33
- signal: options?.signal,
25
+ const { config } = client
26
+
27
+ let requestUrl = `${config.apiUrl}/advanced/stepTransaction`
28
+ const jitoBundle = config.routeOptions?.jitoBundle
29
+ const svmSponsor = config.routeOptions?.svmSponsor
30
+
31
+ if (step.action.fromChainId === ChainId.SOL) {
32
+ const queryParams = new URLSearchParams()
33
+ if (jitoBundle) {
34
+ queryParams.set('jitoBundle', jitoBundle.toString())
35
+ }
36
+ if (svmSponsor) {
37
+ queryParams.set('svmSponsor', svmSponsor)
34
38
  }
35
- )
39
+ if (queryParams.size > 0) {
40
+ requestUrl = `${requestUrl}?${queryParams}`
41
+ }
42
+ }
43
+
44
+ return await request<LiFiStep>(config, requestUrl, {
45
+ method: 'POST',
46
+ headers: {
47
+ 'Content-Type': 'application/json',
48
+ },
49
+ body: JSON.stringify(step),
50
+ signal: options?.signal,
51
+ })
36
52
  }
@@ -0,0 +1,9 @@
1
+ import type { StepExecutorContext, TaskResult } from '../types/execution.js'
2
+
3
+ export abstract class BaseStepExecutionTask {
4
+ shouldRun(_context: StepExecutorContext): Promise<boolean> {
5
+ return Promise.resolve(true)
6
+ }
7
+
8
+ abstract run(context: StepExecutorContext): Promise<TaskResult>
9
+ }
@@ -1,12 +1,21 @@
1
- import type { LiFiStep } from '@lifi/types'
1
+ import { ExecuteStepRetryError } from '../errors/errors.js'
2
+ import type { SDKError } from '../errors/SDKError.js'
2
3
  import type {
4
+ ExecuteStepRetryParams,
5
+ ExecutionAction,
3
6
  ExecutionOptions,
4
7
  InteractionSettings,
8
+ LiFiStepExtended,
5
9
  SDKClient,
6
10
  StepExecutor,
7
11
  StepExecutorOptions,
8
12
  } from '../types/core.js'
13
+ import type {
14
+ StepExecutorBaseContext,
15
+ StepExecutorContext,
16
+ } from '../types/execution.js'
9
17
  import { StatusManager } from './StatusManager.js'
18
+ import type { TaskPipeline } from './TaskPipeline.js'
10
19
 
11
20
  // Please be careful when changing the defaults as it may break the behavior (e.g., background execution)
12
21
  const defaultInteractionSettings = {
@@ -37,5 +46,85 @@ export abstract class BaseStepExecutor implements StepExecutor {
37
46
  this.allowExecution = interactionSettings.allowExecution
38
47
  }
39
48
 
40
- abstract executeStep(client: SDKClient, step: LiFiStep): Promise<LiFiStep>
49
+ private createBaseContext = async (
50
+ client: SDKClient,
51
+ step: LiFiStepExtended,
52
+ retryParams?: ExecuteStepRetryParams
53
+ ): Promise<StepExecutorBaseContext> => {
54
+ const fromChain = await client.getChainById(step.action.fromChainId)
55
+ const toChain = await client.getChainById(step.action.toChainId)
56
+
57
+ const isBridgeExecution = fromChain.id !== toChain.id
58
+
59
+ return {
60
+ client,
61
+ step,
62
+ fromChain,
63
+ toChain,
64
+ isBridgeExecution,
65
+ retryParams,
66
+ statusManager: this.statusManager,
67
+ executionOptions: this.executionOptions,
68
+ allowUserInteraction: this.allowUserInteraction,
69
+ }
70
+ }
71
+
72
+ abstract createContext(
73
+ baseContext: StepExecutorBaseContext
74
+ ): Promise<StepExecutorContext>
75
+
76
+ abstract createPipeline(context: StepExecutorContext): TaskPipeline
77
+
78
+ abstract parseErrors(
79
+ error: Error,
80
+ step?: LiFiStepExtended,
81
+ action?: ExecutionAction,
82
+ retryParams?: ExecuteStepRetryParams
83
+ ): Promise<SDKError | ExecuteStepRetryError>
84
+
85
+ executeStep = async (
86
+ client: SDKClient,
87
+ step: LiFiStepExtended,
88
+ retryParams?: ExecuteStepRetryParams
89
+ ): Promise<LiFiStepExtended> => {
90
+ try {
91
+ step.execution = this.statusManager.initializeExecution(step)
92
+
93
+ const baseContext = await this.createBaseContext(
94
+ client,
95
+ step,
96
+ retryParams
97
+ )
98
+ const context = await this.createContext(baseContext)
99
+ const pipeline = this.createPipeline(context)
100
+
101
+ await pipeline.run(context)
102
+
103
+ return step
104
+ } catch (error: any) {
105
+ const action = step.execution?.lastActionType
106
+ ? this.statusManager.findAction(step, step.execution.lastActionType)
107
+ : undefined
108
+ const parsed = await this.parseErrors(error, step, action, retryParams)
109
+ if (!(parsed instanceof ExecuteStepRetryError)) {
110
+ if (action) {
111
+ this.statusManager.updateAction(step, action.type, 'FAILED', {
112
+ error: {
113
+ message: parsed.cause?.message,
114
+ code: parsed.code,
115
+ },
116
+ })
117
+ } else {
118
+ this.statusManager.updateExecution(step, {
119
+ status: 'FAILED',
120
+ error: {
121
+ message: parsed.cause?.message,
122
+ code: parsed.code,
123
+ },
124
+ })
125
+ }
126
+ }
127
+ throw parsed
128
+ }
129
+ }
41
130
  }
@@ -4,23 +4,20 @@ import type {
4
4
  ExecutionAction,
5
5
  ExecutionActionStatus,
6
6
  ExecutionActionType,
7
- ExecutionStatus,
8
7
  LiFiStepExtended,
9
8
  } from '../types/core.js'
10
9
  import { getActionMessage } from './actionMessages.js'
11
10
  import { executionState } from './executionState.js'
12
11
 
13
- type FindOrCreateActionProps = {
12
+ type ActionProps = {
14
13
  step: LiFiStepExtended
15
14
  type: ExecutionActionType
16
- chainId?: ChainId
17
- status?: ExecutionActionStatus
15
+ chainId: ChainId
16
+ status: ExecutionActionStatus
18
17
  }
19
18
 
20
19
  /**
21
- * Manages status updates of a route and provides various functions for tracking actions
22
- * @param {string} routeId The route dd this StatusManger belongs to.
23
- * @returns {StatusManager} An instance of StatusManager.
20
+ * Manages status updates of a route and provides various functions for tracking actions.
24
21
  */
25
22
  export class StatusManager {
26
23
  private readonly routeId: string
@@ -32,10 +29,10 @@ export class StatusManager {
32
29
 
33
30
  /**
34
31
  * Initializes the execution object of a Step.
35
- * @param step The current step in execution
36
- * @returns The initialized execution object for this step and a function to update this step
32
+ * @param step The current step in execution
33
+ * @returns The initialized execution object for this step
37
34
  */
38
- initExecutionObject = (step: LiFiStepExtended): Execution => {
35
+ initializeExecution = (step: LiFiStepExtended): Execution => {
39
36
  if (!step.execution) {
40
37
  step.execution = {
41
38
  startedAt: Date.now(),
@@ -50,6 +47,8 @@ export class StatusManager {
50
47
  step.execution.startedAt = Date.now()
51
48
  step.execution.status = 'PENDING'
52
49
  step.execution.signedAt = undefined
50
+ step.execution.lastActionType = undefined
51
+ step.execution.error = undefined
53
52
  this.updateStepInRoute(step)
54
53
  }
55
54
 
@@ -58,25 +57,20 @@ export class StatusManager {
58
57
 
59
58
  /**
60
59
  * Updates the execution object of a Step.
61
- * @param step The current step in execution
62
- * @param status The status for the execution
63
- * @param execution Optional. Information about received tokens
60
+ * @param step The current step in execution
61
+ * @param execution Partial execution data to merge
64
62
  * @returns The step with the updated execution object
65
63
  */
66
64
  updateExecution(
67
65
  step: LiFiStepExtended,
68
- status: ExecutionStatus,
69
- execution?: Partial<Execution>
66
+ execution: Partial<Execution>
70
67
  ): LiFiStep {
71
68
  if (!step.execution) {
72
69
  throw Error("Can't update empty execution.")
73
70
  }
74
- step.execution.status = status
75
- if (execution) {
76
- step.execution = {
77
- ...step.execution,
78
- ...execution,
79
- }
71
+ step.execution = {
72
+ ...step.execution,
73
+ ...execution,
80
74
  }
81
75
  this.updateStepInRoute(step)
82
76
  return step
@@ -86,13 +80,11 @@ export class StatusManager {
86
80
  * Finds an action of the specified type in the step's execution
87
81
  * @param step The step to search in
88
82
  * @param type The action type to find
89
- * @param status Optional status to update the action with if found
90
83
  * @returns The found action or undefined if not found
91
84
  */
92
85
  findAction(
93
86
  step: LiFiStepExtended,
94
- type: ExecutionActionType,
95
- status?: ExecutionActionStatus
87
+ type: ExecutionActionType
96
88
  ): ExecutionAction | undefined {
97
89
  if (!step.execution?.actions) {
98
90
  throw new Error("Execution hasn't been initialized.")
@@ -100,46 +92,66 @@ export class StatusManager {
100
92
 
101
93
  const action = step.execution.actions.find((p) => p.type === type)
102
94
 
103
- if (action && status && action.status !== status) {
104
- action.status = status
105
- this.updateStepInRoute(step)
106
- }
107
-
108
95
  return action
109
96
  }
110
97
 
111
98
  /**
112
99
  * Create and push a new action into the execution.
100
+ * Caller is responsible for ensuring an action of this type does not already exist.
113
101
  * @param step The step that should contain the new action.
114
- * @param type Type of the action. Used to identify already existing actions.
102
+ * @param type Type of the action.
115
103
  * @param chainId Chain Id of the action.
116
- * @param status By default created action is set to the STARTED status. We can override new action with the needed status.
117
- * @returns Returns action.
104
+ * @param status The initial status for the new action.
105
+ * @returns The created action.
118
106
  */
119
- findOrCreateAction = ({
107
+ createAction = ({
120
108
  step,
121
109
  type,
122
110
  chainId,
123
111
  status,
124
- }: FindOrCreateActionProps): ExecutionAction => {
125
- const action = this.findAction(step, type, status)
126
-
127
- if (action) {
128
- return action
112
+ }: ActionProps): ExecutionAction => {
113
+ if (!step.execution) {
114
+ throw new Error("Execution hasn't been initialized.")
129
115
  }
130
116
 
131
117
  const newAction: ExecutionAction = {
132
- type: type,
133
- message: getActionMessage(type, status ?? 'STARTED'),
134
- status: status ?? 'STARTED',
135
- chainId: chainId,
118
+ type,
119
+ message: getActionMessage(type, status),
120
+ status,
121
+ chainId,
136
122
  }
137
123
 
138
- step.execution!.actions.push(newAction)
124
+ step.execution.actions.push(newAction)
125
+ step.execution.lastActionType = type
139
126
  this.updateStepInRoute(step)
140
127
  return newAction
141
128
  }
142
129
 
130
+ /**
131
+ * Find an existing action by type and update it, or create a new one if none exists.
132
+ * @param step The step that should contain the action.
133
+ * @param type Type of the action. Used to identify already existing actions.
134
+ * @param chainId Chain Id of the action (used when creating).
135
+ * @param status The status to set on the found or newly created action.
136
+ * @returns The updated or newly created action.
137
+ */
138
+ initializeAction = ({
139
+ step,
140
+ type,
141
+ chainId,
142
+ status,
143
+ }: ActionProps): ExecutionAction => {
144
+ const action = this.findAction(step, type)
145
+
146
+ if (action) {
147
+ return this.updateAction(step, type, status, {
148
+ error: undefined,
149
+ })
150
+ }
151
+
152
+ return this.createAction({ step, type, chainId, status })
153
+ }
154
+
143
155
  /**
144
156
  * Update an action object.
145
157
  * @param step The step where the action should be updated
@@ -152,7 +164,7 @@ export class StatusManager {
152
164
  step: LiFiStepExtended,
153
165
  type: ExecutionActionType,
154
166
  status: ExecutionActionStatus,
155
- params?: Partial<ExecutionAction>
167
+ params?: Partial<ExecutionAction & { signedAt?: number }>
156
168
  ): ExecutionAction => {
157
169
  if (!step.execution) {
158
170
  throw new Error("Can't update an empty step execution.")
@@ -168,11 +180,17 @@ export class StatusManager {
168
180
  break
169
181
  case 'FAILED':
170
182
  step.execution.status = 'FAILED'
183
+ if (params?.error) {
184
+ step.execution.error = params.error
185
+ }
171
186
  break
172
187
  case 'DONE':
173
188
  break
174
189
  case 'PENDING':
175
190
  step.execution.status = 'PENDING'
191
+ if (params?.signedAt) {
192
+ step.execution.signedAt = params.signedAt
193
+ }
176
194
  break
177
195
  case 'RESET_REQUIRED':
178
196
  case 'MESSAGE_REQUIRED':
@@ -183,13 +201,14 @@ export class StatusManager {
183
201
  break
184
202
  }
185
203
 
204
+ step.execution.lastActionType = type
205
+
186
206
  currentAction.status = status
187
207
  currentAction.message = getActionMessage(type, status)
188
208
  // set extra parameters or overwrite the standard params set in the switch statement
189
209
  if (params) {
190
- for (const [key, value] of Object.entries(params)) {
191
- currentAction[key] = value
192
- }
210
+ const { signedAt: _signedAt, ...rest } = params
211
+ Object.assign(currentAction, rest)
193
212
  }
194
213
  // Sort actions, the ones with DONE status go first
195
214
  step.execution.actions = [
@@ -200,20 +219,6 @@ export class StatusManager {
200
219
  return currentAction
201
220
  }
202
221
 
203
- /**
204
- * Remove an action from the execution
205
- * @param step The step where the action should be removed from
206
- * @param type The action type to remove
207
- */
208
- removeAction = (step: LiFiStepExtended, type: ExecutionActionType): void => {
209
- if (!step.execution) {
210
- throw new Error("Execution hasn't been initialized.")
211
- }
212
- const index = step.execution.actions.findIndex((p) => p.type === type)
213
- step.execution.actions.splice(index, 1)
214
- this.updateStepInRoute(step)
215
- }
216
-
217
222
  updateStepInRoute = (step: LiFiStep): LiFiStep => {
218
223
  if (!this.shouldUpdate) {
219
224
  return step
@@ -0,0 +1,28 @@
1
+ import type { StepExecutorContext, TaskResult } from '../types/execution.js'
2
+ import type { BaseStepExecutionTask } from './BaseStepExecutionTask.js'
3
+
4
+ export class TaskPipeline {
5
+ private readonly tasks: BaseStepExecutionTask[]
6
+
7
+ constructor(tasks: BaseStepExecutionTask[]) {
8
+ this.tasks = tasks
9
+ }
10
+
11
+ async run(context: StepExecutorContext): Promise<TaskResult> {
12
+ for (const task of this.tasks) {
13
+ const shouldRun = await task.shouldRun(context)
14
+ if (!shouldRun) {
15
+ continue
16
+ }
17
+ const result = await task.run(context)
18
+ if (result.status === 'PAUSED') {
19
+ return { status: 'PAUSED' }
20
+ }
21
+ if (result.context && typeof result.context === 'object') {
22
+ Object.assign(context, result.context)
23
+ }
24
+ }
25
+
26
+ return { status: 'COMPLETED' }
27
+ }
28
+ }
@@ -8,11 +8,20 @@ const actionMessages: Record<
8
8
  ExecutionActionType,
9
9
  Partial<Record<ExecutionActionStatus, string>>
10
10
  > = {
11
- TOKEN_ALLOWANCE: {
11
+ CHECK_ALLOWANCE: {
12
+ STARTED: 'Checking token allowance',
13
+ PENDING: 'Waiting for token allowance check',
14
+ DONE: 'Token allowance checked',
15
+ },
16
+ RESET_ALLOWANCE: {
17
+ STARTED: 'Resetting token allowance',
18
+ RESET_REQUIRED: 'Resetting token allowance',
19
+ PENDING: 'Waiting for token allowance reset',
20
+ DONE: 'Token allowance reset',
21
+ },
22
+ SET_ALLOWANCE: {
12
23
  STARTED: 'Setting token allowance',
13
24
  ACTION_REQUIRED: 'Set token allowance',
14
- RESET_REQUIRED: 'Resetting token allowance',
15
- MESSAGE_REQUIRED: 'Sign token allowance message',
16
25
  PENDING: 'Waiting for token allowance',
17
26
  DONE: 'Token allowance set',
18
27
  },
@@ -31,6 +40,7 @@ const actionMessages: Record<
31
40
  DONE: 'Bridge transaction confirmed',
32
41
  },
33
42
  RECEIVING_CHAIN: {
43
+ STARTED: 'Waiting for destination chain',
34
44
  PENDING: 'Waiting for destination chain',
35
45
  DONE: 'Bridge completed',
36
46
  },
@@ -40,7 +50,14 @@ const actionMessages: Record<
40
50
  PENDING: 'Waiting for permit message',
41
51
  DONE: 'Permit message signed',
42
52
  },
53
+ NATIVE_PERMIT: {
54
+ STARTED: 'Preparing transaction',
55
+ ACTION_REQUIRED: 'Sign permit message',
56
+ PENDING: 'Waiting for permit message',
57
+ DONE: 'Permit message signed',
58
+ },
43
59
  }
60
+
44
61
  const substatusMessages: Record<
45
62
  StatusMessage,
46
63
  Partial<Record<Substatus, string>>
@@ -1,8 +1,9 @@
1
1
  import type { Route } from '@lifi/types'
2
2
  import { LiFiErrorCode } from '../errors/constants.js'
3
- import { ProviderError } from '../errors/errors.js'
3
+ import { ExecuteStepRetryError, ProviderError } from '../errors/errors.js'
4
4
  import type {
5
5
  ExecutionOptions,
6
+ LiFiStepExtended,
6
7
  RouteExtended,
7
8
  SDKClient,
8
9
  SDKProvider,
@@ -94,7 +95,6 @@ const executeSteps = async (
94
95
  const step = route.steps[index]
95
96
  const previousStep = route.steps[index - 1]
96
97
  // Check if the step is already done
97
- //
98
98
  if (step.execution?.status === 'DONE') {
99
99
  continue
100
100
  }
@@ -136,7 +136,21 @@ const executeSteps = async (
136
136
  updateRouteExecution(route, execution.executionOptions)
137
137
  }
138
138
 
139
- const executedStep = await stepExecutor.executeStep(client, step)
139
+ let executedStep: LiFiStepExtended
140
+ try {
141
+ executedStep = await stepExecutor.executeStep(client, step)
142
+ } catch (e) {
143
+ if (e instanceof ExecuteStepRetryError) {
144
+ step.execution = undefined
145
+ executedStep = await stepExecutor.executeStep(
146
+ client,
147
+ step,
148
+ e.retryParams
149
+ )
150
+ } else {
151
+ throw e
152
+ }
153
+ }
140
154
 
141
155
  // We may reach this point if user interaction isn't allowed. We want to stop execution until we resume it
142
156
  if (executedStep.execution?.status !== 'DONE') {
@@ -7,9 +7,8 @@ export const prepareRestart = (route: RouteExtended) => {
7
7
  // Find the index of the last action that has tx hash, taskId, or signed messages
8
8
  const lastValidIndex = step.execution.actions.findLastIndex(
9
9
  (action) =>
10
- (!!action.txHash ||
11
- !!action.taskId ||
12
- !!action.signedTypedData?.length) &&
10
+ ['SWAP', 'CROSS_CHAIN', 'RECEIVING_CHAIN'].includes(action.type) &&
11
+ (!!action.txHash || !!action.taskId) &&
13
12
  action.status !== 'FAILED'
14
13
  )
15
14
 
@@ -23,6 +22,8 @@ export const prepareRestart = (route: RouteExtended) => {
23
22
  // If no tx hash exists, reset the actions array
24
23
  step.execution.actions = []
25
24
  }
25
+ // Reset the last action type
26
+ step.execution.lastActionType = undefined
26
27
  }
27
28
  step.transactionRequest = undefined
28
29
  }
@@ -0,0 +1,42 @@
1
+ export interface SDKStorage {
2
+ get(key: string): string | null | Promise<string | null>
3
+ set(key: string, value: string): void | Promise<void>
4
+ remove(key: string): void | Promise<void>
5
+ }
6
+
7
+ export class LocalStorageAdapter implements SDKStorage {
8
+ get(key: string): string | null {
9
+ return window.localStorage.getItem(key)
10
+ }
11
+
12
+ set(key: string, value: string): void {
13
+ window.localStorage.setItem(key, value)
14
+ }
15
+
16
+ remove(key: string): void {
17
+ window.localStorage.removeItem(key)
18
+ }
19
+ }
20
+
21
+ export class InMemoryStorage implements SDKStorage {
22
+ private store = new Map<string, string>()
23
+
24
+ get(key: string): string | null {
25
+ return this.store.get(key) ?? null
26
+ }
27
+
28
+ set(key: string, value: string): void {
29
+ this.store.set(key, value)
30
+ }
31
+
32
+ remove(key: string): void {
33
+ this.store.delete(key)
34
+ }
35
+ }
36
+
37
+ export function createDefaultStorage(): SDKStorage {
38
+ if (typeof window !== 'undefined' && window.localStorage) {
39
+ return new LocalStorageAdapter()
40
+ }
41
+ return new InMemoryStorage()
42
+ }
@@ -0,0 +1,29 @@
1
+ import { LiFiErrorCode } from '../../errors/constants.js'
2
+ import { TransactionError } from '../../errors/errors.js'
3
+ import type { StepExecutorContext, TaskResult } from '../../types/execution.js'
4
+ import { BaseStepExecutionTask } from '../BaseStepExecutionTask.js'
5
+ import { checkBalance } from './helpers/checkBalance.js'
6
+
7
+ export class CheckBalanceTask extends BaseStepExecutionTask {
8
+ async run(context: StepExecutorContext): Promise<TaskResult> {
9
+ const { client, step, statusManager, isBridgeExecution } = context
10
+
11
+ statusManager.initializeAction({
12
+ step,
13
+ type: isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP',
14
+ chainId: step.action.fromChainId,
15
+ status: 'STARTED',
16
+ })
17
+
18
+ const walletAddress = step.action.fromAddress
19
+ if (!walletAddress) {
20
+ throw new TransactionError(
21
+ LiFiErrorCode.InternalError,
22
+ 'The wallet address is undefined.'
23
+ )
24
+ }
25
+
26
+ await checkBalance(client, walletAddress, step)
27
+ return { status: 'COMPLETED' }
28
+ }
29
+ }