@lifi/widget 3.18.4 → 3.18.6

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 (74) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +2 -1
  3. package/dist/esm/components/ActiveTransactions/ActiveTransactionItem.js +2 -2
  4. package/dist/esm/components/ActiveTransactions/ActiveTransactionItem.js.map +1 -1
  5. package/dist/esm/components/Timer/StepTimer.js +69 -31
  6. package/dist/esm/components/Timer/StepTimer.js.map +1 -1
  7. package/dist/esm/config/version.d.ts +1 -1
  8. package/dist/esm/config/version.js +1 -1
  9. package/dist/esm/hooks/timer/time.d.ts +19 -0
  10. package/dist/esm/hooks/timer/time.js +25 -0
  11. package/dist/esm/hooks/timer/time.js.map +1 -0
  12. package/dist/esm/hooks/timer/useInterval.d.ts +1 -1
  13. package/dist/esm/hooks/timer/useInterval.js +3 -3
  14. package/dist/esm/hooks/timer/useInterval.js.map +1 -1
  15. package/dist/esm/hooks/timer/useTimer.d.ts +10 -10
  16. package/dist/esm/hooks/timer/useTimer.js +31 -24
  17. package/dist/esm/hooks/timer/useTimer.js.map +1 -1
  18. package/dist/esm/hooks/timer/validate.d.ts +2 -0
  19. package/dist/esm/hooks/timer/validate.js +15 -0
  20. package/dist/esm/hooks/timer/validate.js.map +1 -0
  21. package/dist/esm/hooks/useRoutes.js +2 -1
  22. package/dist/esm/hooks/useRoutes.js.map +1 -1
  23. package/dist/esm/i18n/bn.json +35 -17
  24. package/dist/esm/i18n/de.json +36 -18
  25. package/dist/esm/i18n/es.json +65 -47
  26. package/dist/esm/i18n/fr.json +40 -22
  27. package/dist/esm/i18n/hi.json +27 -9
  28. package/dist/esm/i18n/id.json +68 -50
  29. package/dist/esm/i18n/it.json +36 -18
  30. package/dist/esm/i18n/ja.json +40 -22
  31. package/dist/esm/i18n/ko.json +38 -20
  32. package/dist/esm/i18n/pt.json +42 -24
  33. package/dist/esm/i18n/th.json +40 -22
  34. package/dist/esm/i18n/tr.json +52 -34
  35. package/dist/esm/i18n/uk.json +43 -25
  36. package/dist/esm/i18n/vi.json +40 -22
  37. package/dist/esm/i18n/zh.json +43 -25
  38. package/package.json +6 -6
  39. package/package.json.tmp +5 -5
  40. package/src/components/ActiveTransactions/ActiveTransactionItem.tsx +2 -2
  41. package/src/components/Timer/StepTimer.tsx +97 -38
  42. package/src/config/version.ts +1 -1
  43. package/src/hooks/timer/time.ts +49 -0
  44. package/src/hooks/timer/useInterval.ts +4 -4
  45. package/src/hooks/timer/useTimer.ts +49 -35
  46. package/src/hooks/timer/validate.ts +15 -0
  47. package/src/hooks/useRoutes.ts +2 -1
  48. package/src/i18n/bn.json +35 -17
  49. package/src/i18n/de.json +36 -18
  50. package/src/i18n/es.json +65 -47
  51. package/src/i18n/fr.json +40 -22
  52. package/src/i18n/hi.json +27 -9
  53. package/src/i18n/id.json +68 -50
  54. package/src/i18n/it.json +36 -18
  55. package/src/i18n/ja.json +40 -22
  56. package/src/i18n/ko.json +38 -20
  57. package/src/i18n/pt.json +42 -24
  58. package/src/i18n/th.json +40 -22
  59. package/src/i18n/tr.json +52 -34
  60. package/src/i18n/uk.json +43 -25
  61. package/src/i18n/vi.json +40 -22
  62. package/src/i18n/zh.json +43 -25
  63. package/dist/esm/components/Timer/RouteTimer.d.ts +0 -4
  64. package/dist/esm/components/Timer/RouteTimer.js +0 -23
  65. package/dist/esm/components/Timer/RouteTimer.js.map +0 -1
  66. package/dist/esm/hooks/timer/useStopwatch.d.ts +0 -16
  67. package/dist/esm/hooks/timer/useStopwatch.js +0 -41
  68. package/dist/esm/hooks/timer/useStopwatch.js.map +0 -1
  69. package/dist/esm/hooks/timer/utils.d.ts +0 -12
  70. package/dist/esm/hooks/timer/utils.js +0 -55
  71. package/dist/esm/hooks/timer/utils.js.map +0 -1
  72. package/src/components/Timer/RouteTimer.tsx +0 -33
  73. package/src/hooks/timer/useStopwatch.ts +0 -65
  74. package/src/hooks/timer/utils.ts +0 -64
@@ -7,7 +7,7 @@ import { RouteExecutionStatus } from '../../stores/routes/types.js'
7
7
  import { navigationRoutes } from '../../utils/navigationRoutes.js'
8
8
  import { TokenAvatarGroup } from '../Avatar/Avatar.style.js'
9
9
  import { TokenAvatar } from '../Avatar/TokenAvatar.js'
10
- import { RouteTimer } from '../Timer/RouteTimer.js'
10
+ import { StepTimer } from '../Timer/StepTimer.js'
11
11
  import { ListItem, ListItemButton } from './ActiveTransactions.style.js'
12
12
 
13
13
  export const ActiveTransactionItem: React.FC<{
@@ -47,7 +47,7 @@ export const ActiveTransactionItem: React.FC<{
47
47
  fontWeight: 600,
48
48
  }}
49
49
  >
50
- <RouteTimer route={route} />
50
+ <StepTimer step={lastActiveStep} hideInProgress />
51
51
  </Typography>
52
52
  )
53
53
  }
@@ -1,66 +1,123 @@
1
1
  import type { LiFiStepExtended } from '@lifi/sdk'
2
2
  import { useEffect, useState } from 'react'
3
3
  import { useTranslation } from 'react-i18next'
4
- import { useStopwatch } from '../../hooks/timer/useStopwatch.js'
5
- import { useSettings } from '../../stores/settings/useSettings.js'
4
+ import { useTimer } from '../../hooks/timer/useTimer.js'
6
5
  import { formatTimer } from '../../utils/timer.js'
7
6
  import { TimerContent } from './TimerContent.js'
8
7
 
9
- const getFirstExecutionProcess = (step: LiFiStepExtended) =>
10
- step.execution?.process.at(0)
8
+ /**
9
+ * Finds the most recent process that is either a SWAP, CROSS_CHAIN, or RECEIVING_CHAIN.
10
+ * Includes RECEIVING_CHAIN to track the complete transaction lifecycle for UI updates.
11
+ */
12
+ const getProgressProcess = (step: LiFiStepExtended) =>
13
+ step.execution?.process.findLast(
14
+ (process) =>
15
+ process.type === 'SWAP' ||
16
+ process.type === 'CROSS_CHAIN' ||
17
+ process.type === 'RECEIVING_CHAIN'
18
+ )
11
19
 
12
- const getExecutionProcess = (step: LiFiStepExtended) =>
13
- step.execution?.process.at(-1)
20
+ /**
21
+ * Finds the most recent SWAP or CROSS_CHAIN process, excluding RECEIVING_CHAIN.
22
+ * Expiry time is based on when the active transaction started, not the receiving phase.
23
+ */
24
+ const getExpiryProcess = (step: LiFiStepExtended) =>
25
+ step.execution?.process.findLast(
26
+ (process) => process.type === 'SWAP' || process.type === 'CROSS_CHAIN'
27
+ )
14
28
 
15
- const getStartTimestamp = (step: LiFiStepExtended) =>
16
- new Date(getFirstExecutionProcess(step)?.startedAt ?? Date.now())
29
+ /**
30
+ * Calculates expiry timestamp based on process start time, estimated duration, and pause time.
31
+ * Pause time is added when action is required (usually for signature requests).
32
+ */
33
+ const getExpiryTimestamp = (step: LiFiStepExtended) => {
34
+ const lastProcess = getExpiryProcess(step)
35
+ let timeInPause = 0
36
+ if (lastProcess?.actionRequiredAt) {
37
+ const actionDoneAt =
38
+ lastProcess.pendingAt ?? lastProcess.doneAt ?? Date.now()
39
+ timeInPause = new Date(
40
+ actionDoneAt - lastProcess.actionRequiredAt
41
+ ).getTime()
42
+ }
43
+ const expiry = new Date(
44
+ (lastProcess?.startedAt ?? Date.now()) +
45
+ step.estimate.executionDuration * 1000 +
46
+ timeInPause
47
+ )
48
+ return expiry
49
+ }
17
50
 
18
51
  export const StepTimer: React.FC<{
19
52
  step: LiFiStepExtended
20
53
  hideInProgress?: boolean
21
- }> = ({ step }) => {
22
- const { i18n } = useTranslation()
23
- const { language } = useSettings(['language'])
24
-
54
+ }> = ({ step, hideInProgress }) => {
55
+ const { t, i18n } = useTranslation()
56
+ const [isExpired, setExpired] = useState(false)
25
57
  const [isExecutionStarted, setExecutionStarted] = useState(
26
- () => !!getExecutionProcess(step)
58
+ () => !!getProgressProcess(step)
27
59
  )
28
-
29
- const { seconds, minutes, days, hours, isRunning, pause, reset, start } =
30
- useStopwatch({
31
- autoStart: true,
32
- offsetTimestamp: getStartTimestamp(step),
60
+ const [expiryTimestamp, setExpiryTimestamp] = useState(() =>
61
+ getExpiryTimestamp(step)
62
+ )
63
+ const { days, hours, minutes, seconds, isRunning, pause, resume, restart } =
64
+ useTimer({
65
+ autoStart: false,
66
+ expiryTimestamp,
67
+ onExpire: () => setExpired(true),
33
68
  })
34
69
 
35
70
  useEffect(() => {
36
- const executionProcess = getExecutionProcess(step)
71
+ const executionProcess = getProgressProcess(step)
37
72
  if (!executionProcess) {
38
73
  return
39
74
  }
40
75
 
41
- const shouldRestart =
42
- executionProcess.status === 'FAILED' || executionProcess.status === 'DONE'
43
- const shouldStart =
76
+ if (isExecutionStarted && isExpired) {
77
+ return
78
+ }
79
+
80
+ const isProcessStarted =
44
81
  executionProcess.status === 'STARTED' ||
45
82
  executionProcess.status === 'PENDING'
46
- const shouldResume = executionProcess.status === 'PENDING'
47
- if (isExecutionStarted && shouldRestart) {
48
- setExecutionStarted(false)
49
- pause()
50
- return
83
+
84
+ const shouldRestart = !isExecutionStarted && isProcessStarted && !isRunning
85
+
86
+ const shouldPause =
87
+ isExecutionStarted &&
88
+ executionProcess.status === 'ACTION_REQUIRED' &&
89
+ isRunning
90
+
91
+ const shouldStop =
92
+ isExecutionStarted && executionProcess.status === 'FAILED'
93
+
94
+ const shouldResume = isExecutionStarted && isProcessStarted && !isRunning
95
+
96
+ if (shouldRestart) {
97
+ const newExpiryTimestamp = getExpiryTimestamp(step)
98
+ setExecutionStarted(true)
99
+ setExpiryTimestamp(newExpiryTimestamp)
100
+ return restart(newExpiryTimestamp, true)
51
101
  }
52
- if (isExecutionStarted && !isRunning && shouldResume) {
53
- start()
54
- return
102
+ if (shouldPause) {
103
+ return pause()
55
104
  }
56
- if (!isExecutionStarted && shouldStart) {
57
- setExecutionStarted(true)
58
- reset()
59
- return
105
+ if (shouldResume) {
106
+ return resume()
60
107
  }
61
- }, [isExecutionStarted, isRunning, pause, reset, start, step])
108
+ if (shouldStop) {
109
+ setExecutionStarted(false)
110
+ setExpired(false)
111
+ }
112
+ }, [isExecutionStarted, isExpired, isRunning, pause, restart, resume, step])
113
+
114
+ const isTimerExpired = isExpired || (!minutes && !seconds)
62
115
 
63
- if (step.execution?.status === 'DONE') {
116
+ if (
117
+ step.execution?.status === 'DONE' ||
118
+ step.execution?.status === 'FAILED' ||
119
+ (isTimerExpired && hideInProgress)
120
+ ) {
64
121
  return null
65
122
  }
66
123
 
@@ -80,10 +137,12 @@ export const StepTimer: React.FC<{
80
137
  )
81
138
  }
82
139
 
83
- return (
140
+ return isTimerExpired ? (
141
+ t('main.inProgress')
142
+ ) : (
84
143
  <TimerContent>
85
144
  {formatTimer({
86
- locale: language,
145
+ locale: i18n.language,
87
146
  days,
88
147
  hours,
89
148
  minutes,
@@ -1,2 +1,2 @@
1
1
  export const name = '@lifi/widget'
2
- export const version = '3.18.4'
2
+ export const version = '3.18.6'
@@ -0,0 +1,49 @@
1
+ export type TimeFromMillisecondsType = {
2
+ totalMilliseconds: number
3
+ totalSeconds: number
4
+ milliseconds: number
5
+ seconds: number
6
+ minutes: number
7
+ hours: number
8
+ days: number
9
+ }
10
+
11
+ export type AMPMType = '' | 'pm' | 'am'
12
+
13
+ export type FormattedTimeFromMillisecondsType = {
14
+ milliseconds: number
15
+ seconds: number
16
+ minutes: number
17
+ hours: number
18
+ ampm?: AMPMType
19
+ }
20
+
21
+ export function getTimeFromMilliseconds(
22
+ millisecs: number,
23
+ isCountDown = true
24
+ ): TimeFromMillisecondsType {
25
+ const totalSeconds = isCountDown
26
+ ? Math.ceil(millisecs / 1000)
27
+ : Math.floor(millisecs / 1000)
28
+ const days = Math.floor(totalSeconds / (60 * 60 * 24))
29
+ const hours = Math.floor((totalSeconds % (60 * 60 * 24)) / (60 * 60))
30
+ const minutes = Math.floor((totalSeconds % (60 * 60)) / 60)
31
+ const seconds = Math.floor(totalSeconds % 60)
32
+ const milliseconds = Math.floor(millisecs % 1000)
33
+
34
+ return {
35
+ totalMilliseconds: millisecs,
36
+ totalSeconds,
37
+ milliseconds,
38
+ seconds,
39
+ minutes,
40
+ hours,
41
+ days,
42
+ }
43
+ }
44
+
45
+ export function getMillisecondsFromExpiry(expiry: Date): number {
46
+ const now = new Date().getTime()
47
+ const milliSecondsDistance = expiry?.getTime() - now
48
+ return milliSecondsDistance > 0 ? milliSecondsDistance : 0
49
+ }
@@ -1,11 +1,11 @@
1
1
  import { useEffect, useRef } from 'react'
2
2
 
3
- export function useInterval(callback: () => void, delay: number) {
4
- const callbacRef = useRef<() => void>(null)
3
+ export function useInterval(callback: () => void, delay: number | null) {
4
+ const callbackRef = useRef(callback)
5
5
 
6
6
  // update callback function with current render callback that has access to latest props and state
7
7
  useEffect(() => {
8
- callbacRef.current = callback
8
+ callbackRef.current = callback
9
9
  })
10
10
 
11
11
  useEffect(() => {
@@ -14,7 +14,7 @@ export function useInterval(callback: () => void, delay: number) {
14
14
  }
15
15
 
16
16
  const interval = setInterval(() => {
17
- callbacRef.current?.()
17
+ callbackRef?.current?.()
18
18
  }, delay)
19
19
  return () => clearInterval(interval)
20
20
  }, [delay])
@@ -1,41 +1,52 @@
1
- import { useCallback, useState } from 'react'
2
- import { useInterval } from './useInterval.js'
1
+ import { useCallback, useEffect, useState } from 'react'
3
2
  import {
4
- getDelayFromExpiryTimestamp,
5
- getSecondsFromExpiry,
6
- getTimeFromSeconds,
7
- validateOnExpire,
8
- } from './utils.js'
3
+ type TimeFromMillisecondsType,
4
+ getMillisecondsFromExpiry,
5
+ getTimeFromMilliseconds,
6
+ } from './time.js'
7
+ import { useInterval } from './useInterval.js'
8
+ import { validateExpiryTimestamp, validateOnExpire } from './validate.js'
9
9
 
10
- const DEFAULT_DELAY = 1000
10
+ const SECOND_INTERVAL = 1000
11
11
 
12
- interface UseTimerProps {
12
+ export type useTimerSettingsType = {
13
13
  expiryTimestamp: Date
14
- onExpire: () => void
14
+ onExpire?: () => void
15
15
  autoStart?: boolean
16
+ interval?: number
17
+ }
18
+
19
+ export type useTimerResultType = TimeFromMillisecondsType & {
20
+ start: () => void
21
+ pause: () => void
22
+ resume: () => void
23
+ restart: (newExpiryTimestamp: Date, newAutoStart?: boolean) => void
24
+ isRunning: boolean
16
25
  }
17
26
 
18
- // This implementation was taken from the common js project - https://www.npmjs.com/package/react-timer-hook
19
- // modified to work in the Widget codebase with Typescript
27
+ /**
28
+ * `useTimer` from https://github.com/amrlabib/react-timer-hook
29
+ */
20
30
  export function useTimer({
21
31
  expiryTimestamp: expiry,
22
- onExpire,
32
+ onExpire = () => {},
23
33
  autoStart = true,
24
- }: UseTimerProps) {
34
+ interval: customInterval = SECOND_INTERVAL,
35
+ }: useTimerSettingsType): useTimerResultType {
25
36
  const [expiryTimestamp, setExpiryTimestamp] = useState(expiry)
26
- const [seconds, setSeconds] = useState(() =>
27
- getSecondsFromExpiry(expiryTimestamp)
37
+ const [milliseconds, setMilliseconds] = useState(
38
+ getMillisecondsFromExpiry(expiryTimestamp)
28
39
  )
29
40
  const [isRunning, setIsRunning] = useState(autoStart)
30
41
  const [didStart, setDidStart] = useState(autoStart)
31
- const [delay, setDelay] = useState(() =>
32
- getDelayFromExpiryTimestamp(expiryTimestamp, DEFAULT_DELAY)
33
- )
42
+ const [interval, setInterval] = useState<number | null>(customInterval)
34
43
 
35
44
  const handleExpire = useCallback(() => {
36
- validateOnExpire(onExpire) && onExpire()
45
+ if (validateOnExpire(onExpire)) {
46
+ onExpire()
47
+ }
37
48
  setIsRunning(false)
38
- setDelay(0)
49
+ setInterval(null)
39
50
  }, [onExpire])
40
51
 
41
52
  const pause = useCallback(() => {
@@ -44,24 +55,24 @@ export function useTimer({
44
55
 
45
56
  const restart = useCallback(
46
57
  (newExpiryTimestamp: Date, newAutoStart = true) => {
47
- setDelay(getDelayFromExpiryTimestamp(newExpiryTimestamp, DEFAULT_DELAY))
58
+ setInterval(customInterval)
48
59
  setDidStart(newAutoStart)
49
60
  setIsRunning(newAutoStart)
50
61
  setExpiryTimestamp(newExpiryTimestamp)
51
- setSeconds(getSecondsFromExpiry(newExpiryTimestamp))
62
+ setMilliseconds(getMillisecondsFromExpiry(newExpiryTimestamp))
52
63
  },
53
- []
64
+ [customInterval]
54
65
  )
55
66
 
56
67
  const resume = useCallback(() => {
57
68
  const time = new Date()
58
- time.setMilliseconds(time.getMilliseconds() + seconds * 1000)
69
+ time.setMilliseconds(time.getMilliseconds() + milliseconds)
59
70
  restart(time)
60
- }, [seconds, restart])
71
+ }, [milliseconds, restart])
61
72
 
62
73
  const start = useCallback(() => {
63
74
  if (didStart) {
64
- setSeconds(getSecondsFromExpiry(expiryTimestamp))
75
+ setMilliseconds(getMillisecondsFromExpiry(expiryTimestamp))
65
76
  setIsRunning(true)
66
77
  } else {
67
78
  resume()
@@ -70,20 +81,23 @@ export function useTimer({
70
81
 
71
82
  useInterval(
72
83
  () => {
73
- if (delay !== DEFAULT_DELAY) {
74
- setDelay(DEFAULT_DELAY)
75
- }
76
- const secondsValue = getSecondsFromExpiry(expiryTimestamp)
77
- setSeconds(secondsValue)
78
- if (secondsValue <= 0) {
84
+ const millisecondsValue = getMillisecondsFromExpiry(expiryTimestamp)
85
+ setMilliseconds(millisecondsValue)
86
+ if (millisecondsValue <= 0) {
79
87
  handleExpire()
88
+ } else if (interval && millisecondsValue < interval) {
89
+ setInterval(millisecondsValue)
80
90
  }
81
91
  },
82
- isRunning ? delay : 0
92
+ isRunning ? interval : null
83
93
  )
84
94
 
95
+ useEffect(() => {
96
+ validateExpiryTimestamp(expiryTimestamp)
97
+ }, [expiryTimestamp])
98
+
85
99
  return {
86
- ...getTimeFromSeconds(seconds),
100
+ ...getTimeFromMilliseconds(milliseconds),
87
101
  start,
88
102
  pause,
89
103
  resume,
@@ -0,0 +1,15 @@
1
+ export function validateExpiryTimestamp(expiryTimestamp: Date) {
2
+ const isValid = new Date(expiryTimestamp).getTime() > 0
3
+ if (!isValid) {
4
+ console.warn('useTimer Invalid expiryTimestamp settings', expiryTimestamp)
5
+ }
6
+ return isValid
7
+ }
8
+
9
+ export function validateOnExpire(onExpire: () => void) {
10
+ const isValid = onExpire && typeof onExpire === 'function'
11
+ if (onExpire && !isValid) {
12
+ console.warn('useTimer Invalid onExpire settings function', onExpire)
13
+ }
14
+ return isValid
15
+ }
@@ -420,11 +420,12 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
420
420
  const initialRoutes = routesResult?.routes ?? []
421
421
 
422
422
  if (shouldUseRelayerQuote && initialRoutes.length) {
423
- emitter.emit(WidgetEvent.AvailableRoutes, initialRoutes)
424
423
  setIntermediateRoutes(queryKey, initialRoutes)
424
+ emitter.emit(WidgetEvent.AvailableRoutes, initialRoutes)
425
425
  // Return early if we're only using main routes
426
426
  } else if (shouldUseMainRoutes) {
427
427
  // If we don't need relayer quote, return the initial routes
428
+ emitter.emit(WidgetEvent.AvailableRoutes, initialRoutes)
428
429
  return initialRoutes
429
430
  }
430
431
 
package/src/i18n/bn.json CHANGED
@@ -6,7 +6,8 @@
6
6
  "format": {
7
7
  "currency": "",
8
8
  "number": "{{value, number(maximumFractionDigits: 9)}}",
9
- "percent": ""
9
+ "percent": "",
10
+ "tokenAmount": ""
10
11
  },
11
12
  "button": {
12
13
  "auto": "স্বয়ংক্রিয়",
@@ -83,14 +84,13 @@
83
84
  "message": {
84
85
  "autoRefuel": "আপনার {{chainName}} গ্যাস কম। চালিয়ে যাওয়ার মাধ্যমে, আপনি সোওয়াপ সম্পূর্ণ করার জন্য পর্যাপ্ত গ্যাস পাবেন।",
85
86
  "emptyActiveTransactions": "",
86
- "emptyTokenList": "",
87
- "emptyChainList": "",
88
87
  "emptyBridgesList": "",
88
+ "emptyChainList": "",
89
89
  "emptyExchangesList": "",
90
+ "emptyTokenList": "",
90
91
  "emptyTransactionHistory": "",
91
- "fundsToExchange": "",
92
- "toAddressIsRequired": "",
93
- "routeNotFound": ""
92
+ "routeNotFound": "",
93
+ "toAddressIsRequired": ""
94
94
  },
95
95
  "title": {
96
96
  "autoRefuel": "",
@@ -117,14 +117,18 @@
117
117
  },
118
118
  "warning": {
119
119
  "message": {
120
+ "accountNotDeployedMessage": "",
121
+ "lowAddressActivity": "",
120
122
  "deleteActiveTransactions": "",
121
123
  "deleteTransactionHistory": "",
124
+ "fundsLossPrevention": "",
122
125
  "highValueLoss": "প্রাপ্ত টোকেনগুলির মান সোওয়াপ করা টোকেন এবং লেনদেনের খরচের তুলনায় উল্লেখযোগ্যভাবে কম।",
123
126
  "insufficientFunds": "সোওয়াপ সম্পূর্ণ করার জন্য আপনার কাছে পর্যাপ্ত তহবিল নেই।",
124
127
  "insufficientGas": "সোওয়াপ সম্পূর্ণ করার জন্য আপনার কাছে পর্যাপ্ত গ্যাস নেই। আপনাকে অন্তত যোগ করতে হবে:",
125
128
  "rateChanged": "বিনিময় হার পরিবর্তিত হয়েছে। সোওয়াপ চালিয়ে যাওয়ার মাধ্যমে, আপনি নতুন হার গ্রহণ করবেন।",
126
129
  "resetSettings": "এটি আপনার রুটের অগ্রাধিকার, স্লিপেজ, গ্যাসের দাম, সক্ষম ব্রিজ এবং এক্সচেঞ্জ রিসেট করবে।",
127
- "slippageOutsideRecommendedLimits": ""
130
+ "slippageOutsideRecommendedLimits": "",
131
+ "slippageUnderRecommendedLimits": ""
128
132
  },
129
133
  "title": {
130
134
  "deleteActiveTransactions": "",
@@ -133,7 +137,8 @@
133
137
  "highValueLoss": "উচ্চ মূল্য ক্ষতি",
134
138
  "insufficientGas": "অপর্যাপ্ত গ্যাস",
135
139
  "rateChanged": "হার পরিবর্তিত হয়েছে",
136
- "resetSettings": "রিসেট সেটিংস?"
140
+ "resetSettings": "রিসেট সেটিংস?",
141
+ "lowAddressActivity": ""
137
142
  }
138
143
  },
139
144
  "error": {
@@ -146,6 +151,7 @@
146
151
  "transactionCanceled": "",
147
152
  "transactionConflict": "",
148
153
  "transactionExpired": "",
154
+ "transactionRejected": "",
149
155
  "transactionFailed": "আরও তথ্যের জন্য ব্লক এক্সপ্লোরার চেক করুন।",
150
156
  "transactionNotSent": "",
151
157
  "transactionSimulationFailed": "",
@@ -167,6 +173,7 @@
167
173
  "transactionConflict": "",
168
174
  "transactionExpired": "",
169
175
  "transactionFailed": "লেনদেন ব্যর্থ হয়েছে",
176
+ "transactionRejected": "",
170
177
  "transactionSimulationFailed": "",
171
178
  "transactionUnderpriced": "লেনদেনের দাম কম",
172
179
  "transactionUnprepared": "লেনদেন প্রস্তুত করতে অক্ষম",
@@ -187,6 +194,7 @@
187
194
  "text": "আমরা এই পৃষ্ঠাটি খুঁজে পাইনি।",
188
195
  "title": "৪০৪"
189
196
  },
197
+ "relayerService": "",
190
198
  "numberOfSteps": "",
191
199
  "priceImpact": "",
192
200
  "progressToNextUpdate": "প্রদর্শিত ডেটা {{value}} সেকেন্ড পরে স্বয়ংক্রিয়ভাবে রিফ্রেশ হবে। ম্যানুয়ালি আপডেট করতে এখানে ক্লিক করুন।",
@@ -203,7 +211,9 @@
203
211
  "featuredTokens": "বৈশিষ্ট্যযুক্ত টোকেন",
204
212
  "fees": {
205
213
  "defaultIntegrator": "",
214
+ "relayerService": "",
206
215
  "estimated": "",
216
+ "free": "",
207
217
  "integrator": "",
208
218
  "network": "",
209
219
  "paid": "",
@@ -238,19 +248,26 @@
238
248
  "refunded": "ব্রিজ লেনদেন ফেরত করা হয়েছে"
239
249
  },
240
250
  "swap": {
241
- "actionRequired": "দয়াকরে লেনদেন স্বাক্ষর করুন",
251
+ "actionRequired": "",
242
252
  "done": "সোওয়াপ সম্পন্ন হয়েছে",
243
- "pending": "সোওয়াপ লেনদেনের জন্য অপেক্ষা করা হচ্ছে",
253
+ "pending": "",
244
254
  "started": "সোয়াপ লেনদেন প্রস্তুত করা হচ্ছে"
245
255
  },
246
256
  "switchChain": {
247
- "actionRequired": "চেইন সুইচ প্রয়োজন",
248
- "done": "চেইন সফলভাবে সুইচ করা হয়েছে"
257
+ "actionRequired": "",
258
+ "done": ""
259
+ },
260
+ "permit": {
261
+ "actionRequired": "",
262
+ "done": "",
263
+ "pending": "",
264
+ "started": ""
249
265
  },
250
266
  "tokenAllowance": {
251
- "done": "টোকেন অনুমতি অনুমোদিত",
252
- "pending": "টোকেন অনুমতির অপেক্ষায়",
253
- "started": "টোকেন অনুমতির অপেক্ষায়"
267
+ "actionRequired": "",
268
+ "done": "",
269
+ "pending": "",
270
+ "started": ""
254
271
  }
255
272
  },
256
273
  "quotedAmount": "উদ্ধৃত পরিমাণ",
@@ -278,11 +295,12 @@
278
295
  "transferId": "",
279
296
  "tags": {
280
297
  "cheapest": "",
281
- "fastest": ""
298
+ "fastest": "",
299
+ "gasless": ""
282
300
  },
283
301
  "to": "প্রতি",
284
302
  "tokenOnChain": "{{chainName}} -এ {{tokenSymbol}}",
285
- "tokenOnChainAmount": "{{amount, number(maximumFractionDigits: 9)}} {{tokenSymbol}} {{chainName}} -এ",
303
+ "tokenOnChainAmount": "",
286
304
  "tokenSearch": "আপনার টোকেন অনুসন্ধান করুন",
287
305
  "valueLoss": "মান ক্ষতি",
288
306
  "searchChains": "",