@lifi/sdk 3.14.0 → 3.15.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 (59) hide show
  1. package/package.json +1 -1
  2. package/src/_cjs/constants.js +2 -1
  3. package/src/_cjs/constants.js.map +1 -1
  4. package/src/_cjs/core/EVM/EVMStepExecutor.js +86 -17
  5. package/src/_cjs/core/EVM/EVMStepExecutor.js.map +1 -1
  6. package/src/_cjs/core/EVM/typeguards.js +4 -0
  7. package/src/_cjs/core/EVM/typeguards.js.map +1 -1
  8. package/src/_cjs/core/utils.js +0 -5
  9. package/src/_cjs/core/utils.js.map +1 -1
  10. package/src/_cjs/index.js +11 -8
  11. package/src/_cjs/index.js.map +1 -1
  12. package/src/_cjs/services/api.js +12 -1
  13. package/src/_cjs/services/api.js.map +1 -1
  14. package/src/_cjs/utils/convertQuoteToRoute.js +73 -5
  15. package/src/_cjs/utils/convertQuoteToRoute.js.map +1 -1
  16. package/src/_cjs/version.js +1 -1
  17. package/src/_cjs/version.js.map +1 -1
  18. package/src/_esm/constants.js +1 -0
  19. package/src/_esm/constants.js.map +1 -1
  20. package/src/_esm/core/EVM/EVMStepExecutor.js +86 -10
  21. package/src/_esm/core/EVM/EVMStepExecutor.js.map +1 -1
  22. package/src/_esm/core/EVM/typeguards.js +3 -0
  23. package/src/_esm/core/EVM/typeguards.js.map +1 -1
  24. package/src/_esm/core/utils.js +0 -11
  25. package/src/_esm/core/utils.js.map +1 -1
  26. package/src/_esm/index.js +3 -2
  27. package/src/_esm/index.js.map +1 -1
  28. package/src/_esm/services/api.js +10 -0
  29. package/src/_esm/services/api.js.map +1 -1
  30. package/src/_esm/utils/convertQuoteToRoute.js +76 -7
  31. package/src/_esm/utils/convertQuoteToRoute.js.map +1 -1
  32. package/src/_esm/version.js +1 -1
  33. package/src/_esm/version.js.map +1 -1
  34. package/src/_types/constants.d.ts +1 -0
  35. package/src/_types/constants.d.ts.map +1 -1
  36. package/src/_types/core/EVM/EVMStepExecutor.d.ts.map +1 -1
  37. package/src/_types/core/EVM/typeguards.d.ts +1 -0
  38. package/src/_types/core/EVM/typeguards.d.ts.map +1 -1
  39. package/src/_types/core/types.d.ts +24 -1
  40. package/src/_types/core/types.d.ts.map +1 -1
  41. package/src/_types/core/utils.d.ts +1 -10
  42. package/src/_types/core/utils.d.ts.map +1 -1
  43. package/src/_types/index.d.ts +4 -3
  44. package/src/_types/index.d.ts.map +1 -1
  45. package/src/_types/services/api.d.ts +19 -0
  46. package/src/_types/services/api.d.ts.map +1 -1
  47. package/src/_types/utils/convertQuoteToRoute.d.ts +11 -3
  48. package/src/_types/utils/convertQuoteToRoute.d.ts.map +1 -1
  49. package/src/_types/version.d.ts +1 -1
  50. package/src/_types/version.d.ts.map +1 -1
  51. package/src/constants.ts +2 -0
  52. package/src/core/EVM/EVMStepExecutor.ts +111 -10
  53. package/src/core/EVM/typeguards.ts +4 -0
  54. package/src/core/types.ts +30 -0
  55. package/src/core/utils.ts +1 -13
  56. package/src/index.ts +7 -1
  57. package/src/services/api.ts +37 -0
  58. package/src/utils/convertQuoteToRoute.ts +117 -8
  59. package/src/version.ts +1 -1
@@ -1,23 +1,132 @@
1
- import type { LiFiStep, Route } from '@lifi/types'
1
+ import type { LiFiStep, Route, Step } from '@lifi/types'
2
+ import { formatUnits } from 'viem'
2
3
  import { ValidationError } from '../errors/errors.js'
3
4
  import { SDKError } from '../errors/SDKError.js'
4
5
 
6
+ interface ConvertQuoteToRouteOptions {
7
+ /**
8
+ * When true, if the quote has zero output values (toAmount, toAmountMin, toAmountUSD),
9
+ * use the values from the previous included step that has non-zero output.
10
+ */
11
+ adjustZeroOutputFromPreviousStep?: boolean
12
+ }
13
+
14
+ const parseBigInt = (value: string | undefined): bigint => {
15
+ if (!value) {
16
+ return 0n
17
+ }
18
+ try {
19
+ return BigInt(value)
20
+ } catch {
21
+ return 0n
22
+ }
23
+ }
24
+
25
+ const parseNumber = (value: string | undefined): number => {
26
+ if (!value) {
27
+ return 0
28
+ }
29
+ const parsed = Number(value)
30
+ return Number.isNaN(parsed) ? 0 : parsed
31
+ }
32
+
33
+ const isZeroOutput = (
34
+ toAmount: string,
35
+ toAmountMin: string,
36
+ toAmountUSD?: string
37
+ ): boolean => {
38
+ return (
39
+ !parseBigInt(toAmount) &&
40
+ !parseBigInt(toAmountMin) &&
41
+ !parseNumber(toAmountUSD)
42
+ )
43
+ }
44
+
45
+ const hasNonZeroOutput = (step: Step): boolean => {
46
+ return (
47
+ !!parseBigInt(step.estimate.toAmount) ||
48
+ !!parseBigInt(step.estimate.toAmountMin)
49
+ )
50
+ }
51
+
52
+ const findPreviousNonZeroStep = (steps: Step[]): Step | undefined => {
53
+ // Find the last step that has non-zero output (the step before the zero output step)
54
+ for (let i = steps.length - 1; i >= 0; i--) {
55
+ const step = steps[i]
56
+ if (hasNonZeroOutput(step)) {
57
+ return step
58
+ }
59
+ }
60
+ return undefined
61
+ }
62
+
63
+ export function formatTokenPrice(
64
+ amount?: string | bigint,
65
+ price?: string,
66
+ decimals?: number
67
+ ) {
68
+ if (!amount || !price) {
69
+ return 0
70
+ }
71
+
72
+ const formattedAmount =
73
+ typeof amount === 'bigint' && decimals !== undefined
74
+ ? formatUnits(amount, decimals)
75
+ : amount.toString()
76
+
77
+ if (Number.isNaN(Number(formattedAmount)) || Number.isNaN(Number(price))) {
78
+ return 0
79
+ }
80
+ return Number.parseFloat(formattedAmount) * Number.parseFloat(price)
81
+ }
82
+
5
83
  /**
6
84
  * Converts a quote to Route
7
85
  * @param quote - Step returned from the quote endpoint.
8
- * @param txHash
9
- * @param chainId
86
+ * @param options - Optional configuration for handling edge cases.
10
87
  * @returns - The route to be executed.
11
88
  * @throws {BaseError} Throws a ValidationError if the step has missing values.
12
89
  */
13
- export const convertQuoteToRoute = (quote: LiFiStep): Route => {
90
+ export const convertQuoteToRoute = (
91
+ quote: LiFiStep,
92
+ options?: ConvertQuoteToRouteOptions
93
+ ): Route => {
94
+ let toAmount = quote.estimate.toAmount
95
+ let toAmountMin = quote.estimate.toAmountMin
96
+ let toAmountUSD = quote.estimate.toAmountUSD
97
+
98
+ // Handle zero output values by looking at previous included step
99
+ if (
100
+ options?.adjustZeroOutputFromPreviousStep &&
101
+ quote.includedSteps?.length &&
102
+ isZeroOutput(toAmount, toAmountMin, toAmountUSD)
103
+ ) {
104
+ const previousStep = findPreviousNonZeroStep(quote.includedSteps)
105
+ if (previousStep) {
106
+ toAmount = previousStep.estimate.toAmount
107
+ toAmountMin = previousStep.estimate.toAmountMin
108
+ toAmountUSD = formatTokenPrice(
109
+ parseBigInt(toAmount),
110
+ previousStep.action.toToken.priceUSD,
111
+ previousStep.action.toToken.decimals
112
+ ).toFixed(2)
113
+
114
+ // Update the last included step's estimate with the adjusted values
115
+ const lastStep = quote.includedSteps[quote.includedSteps.length - 1]
116
+ if (lastStep && !hasNonZeroOutput(lastStep)) {
117
+ lastStep.estimate.toAmount = toAmount
118
+ lastStep.estimate.toAmountMin = toAmountMin
119
+ }
120
+ }
121
+ }
122
+
14
123
  if (!quote.estimate.fromAmountUSD) {
15
124
  throw new SDKError(
16
125
  new ValidationError("Missing 'fromAmountUSD' in step estimate.")
17
126
  )
18
127
  }
19
128
 
20
- if (!quote.estimate.toAmountUSD) {
129
+ if (!toAmountUSD) {
21
130
  throw new SDKError(
22
131
  new ValidationError("Missing 'toAmountUSD' in step estimate.")
23
132
  )
@@ -32,9 +141,9 @@ export const convertQuoteToRoute = (quote: LiFiStep): Route => {
32
141
  fromAddress: quote.action.fromAddress,
33
142
  toChainId: quote.action.toToken.chainId,
34
143
  toToken: quote.action.toToken,
35
- toAmount: quote.estimate.toAmount,
36
- toAmountMin: quote.estimate.toAmountMin,
37
- toAmountUSD: quote.estimate.toAmountUSD,
144
+ toAmount,
145
+ toAmountMin,
146
+ toAmountUSD,
38
147
  toAddress: quote.action.toAddress || quote.action.fromAddress,
39
148
  gasCostUSD: quote.estimate.gasCosts?.[0]?.amountUSD || '0',
40
149
  steps: [quote],
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export const name = '@lifi/sdk'
2
- export const version = '3.14.0'
2
+ export const version = '3.15.0-beta.0'