@lifi/widget 3.18.3 → 3.18.5
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.
- package/CHANGELOG.md +14 -0
- package/README.md +2 -1
- package/dist/esm/components/ActiveTransactions/ActiveTransactionItem.js +2 -2
- package/dist/esm/components/ActiveTransactions/ActiveTransactionItem.js.map +1 -1
- package/dist/esm/components/Timer/StepTimer.js +69 -31
- package/dist/esm/components/Timer/StepTimer.js.map +1 -1
- package/dist/esm/config/version.d.ts +1 -1
- package/dist/esm/config/version.js +1 -1
- package/dist/esm/hooks/timer/time.d.ts +19 -0
- package/dist/esm/hooks/timer/time.js +25 -0
- package/dist/esm/hooks/timer/time.js.map +1 -0
- package/dist/esm/hooks/timer/useInterval.d.ts +1 -1
- package/dist/esm/hooks/timer/useInterval.js +3 -3
- package/dist/esm/hooks/timer/useInterval.js.map +1 -1
- package/dist/esm/hooks/timer/useTimer.d.ts +10 -10
- package/dist/esm/hooks/timer/useTimer.js +31 -24
- package/dist/esm/hooks/timer/useTimer.js.map +1 -1
- package/dist/esm/hooks/timer/validate.d.ts +2 -0
- package/dist/esm/hooks/timer/validate.js +15 -0
- package/dist/esm/hooks/timer/validate.js.map +1 -0
- package/dist/esm/hooks/useRoutes.js +3 -2
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/i18n/bn.json +35 -17
- package/dist/esm/i18n/de.json +36 -18
- package/dist/esm/i18n/es.json +65 -47
- package/dist/esm/i18n/fr.json +40 -22
- package/dist/esm/i18n/hi.json +27 -9
- package/dist/esm/i18n/id.json +68 -50
- package/dist/esm/i18n/it.json +36 -18
- package/dist/esm/i18n/ja.json +40 -22
- package/dist/esm/i18n/ko.json +38 -20
- package/dist/esm/i18n/pt.json +42 -24
- package/dist/esm/i18n/th.json +40 -22
- package/dist/esm/i18n/tr.json +52 -34
- package/dist/esm/i18n/uk.json +43 -25
- package/dist/esm/i18n/vi.json +40 -22
- package/dist/esm/i18n/zh.json +43 -25
- package/package.json +6 -6
- package/package.json.tmp +5 -5
- package/src/components/ActiveTransactions/ActiveTransactionItem.tsx +2 -2
- package/src/components/Timer/StepTimer.tsx +97 -38
- package/src/config/version.ts +1 -1
- package/src/hooks/timer/time.ts +49 -0
- package/src/hooks/timer/useInterval.ts +4 -4
- package/src/hooks/timer/useTimer.ts +49 -35
- package/src/hooks/timer/validate.ts +15 -0
- package/src/hooks/useRoutes.ts +3 -2
- package/src/i18n/bn.json +35 -17
- package/src/i18n/de.json +36 -18
- package/src/i18n/es.json +65 -47
- package/src/i18n/fr.json +40 -22
- package/src/i18n/hi.json +27 -9
- package/src/i18n/id.json +68 -50
- package/src/i18n/it.json +36 -18
- package/src/i18n/ja.json +40 -22
- package/src/i18n/ko.json +38 -20
- package/src/i18n/pt.json +42 -24
- package/src/i18n/th.json +40 -22
- package/src/i18n/tr.json +52 -34
- package/src/i18n/uk.json +43 -25
- package/src/i18n/vi.json +40 -22
- package/src/i18n/zh.json +43 -25
- package/dist/esm/components/Timer/RouteTimer.d.ts +0 -4
- package/dist/esm/components/Timer/RouteTimer.js +0 -23
- package/dist/esm/components/Timer/RouteTimer.js.map +0 -1
- package/dist/esm/hooks/timer/useStopwatch.d.ts +0 -16
- package/dist/esm/hooks/timer/useStopwatch.js +0 -41
- package/dist/esm/hooks/timer/useStopwatch.js.map +0 -1
- package/dist/esm/hooks/timer/utils.d.ts +0 -12
- package/dist/esm/hooks/timer/utils.js +0 -55
- package/dist/esm/hooks/timer/utils.js.map +0 -1
- package/src/components/Timer/RouteTimer.tsx +0 -33
- package/src/hooks/timer/useStopwatch.ts +0 -65
- 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 {
|
|
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
|
-
<
|
|
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 {
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
13
|
-
|
|
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
|
-
|
|
16
|
-
|
|
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
|
|
24
|
-
|
|
54
|
+
}> = ({ step, hideInProgress }) => {
|
|
55
|
+
const { t, i18n } = useTranslation()
|
|
56
|
+
const [isExpired, setExpired] = useState(false)
|
|
25
57
|
const [isExecutionStarted, setExecutionStarted] = useState(
|
|
26
|
-
() => !!
|
|
58
|
+
() => !!getProgressProcess(step)
|
|
27
59
|
)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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 =
|
|
71
|
+
const executionProcess = getProgressProcess(step)
|
|
37
72
|
if (!executionProcess) {
|
|
38
73
|
return
|
|
39
74
|
}
|
|
40
75
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
76
|
+
if (isExecutionStarted && isExpired) {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const isProcessStarted =
|
|
44
81
|
executionProcess.status === 'STARTED' ||
|
|
45
82
|
executionProcess.status === 'PENDING'
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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 (
|
|
53
|
-
|
|
54
|
-
return
|
|
102
|
+
if (shouldPause) {
|
|
103
|
+
return pause()
|
|
55
104
|
}
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
reset()
|
|
59
|
-
return
|
|
105
|
+
if (shouldResume) {
|
|
106
|
+
return resume()
|
|
60
107
|
}
|
|
61
|
-
|
|
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 (
|
|
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,
|
package/src/config/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = '@lifi/widget'
|
|
2
|
-
export const version = '3.18.
|
|
2
|
+
export const version = '3.18.5'
|
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from './
|
|
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
|
|
10
|
+
const SECOND_INTERVAL = 1000
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
export type useTimerSettingsType = {
|
|
13
13
|
expiryTimestamp: Date
|
|
14
|
-
onExpire
|
|
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
|
-
|
|
19
|
-
|
|
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
|
-
|
|
34
|
+
interval: customInterval = SECOND_INTERVAL,
|
|
35
|
+
}: useTimerSettingsType): useTimerResultType {
|
|
25
36
|
const [expiryTimestamp, setExpiryTimestamp] = useState(expiry)
|
|
26
|
-
const [
|
|
27
|
-
|
|
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 [
|
|
32
|
-
getDelayFromExpiryTimestamp(expiryTimestamp, DEFAULT_DELAY)
|
|
33
|
-
)
|
|
42
|
+
const [interval, setInterval] = useState<number | null>(customInterval)
|
|
34
43
|
|
|
35
44
|
const handleExpire = useCallback(() => {
|
|
36
|
-
validateOnExpire(onExpire)
|
|
45
|
+
if (validateOnExpire(onExpire)) {
|
|
46
|
+
onExpire()
|
|
47
|
+
}
|
|
37
48
|
setIsRunning(false)
|
|
38
|
-
|
|
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
|
-
|
|
58
|
+
setInterval(customInterval)
|
|
48
59
|
setDidStart(newAutoStart)
|
|
49
60
|
setIsRunning(newAutoStart)
|
|
50
61
|
setExpiryTimestamp(newExpiryTimestamp)
|
|
51
|
-
|
|
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() +
|
|
69
|
+
time.setMilliseconds(time.getMilliseconds() + milliseconds)
|
|
59
70
|
restart(time)
|
|
60
|
-
}, [
|
|
71
|
+
}, [milliseconds, restart])
|
|
61
72
|
|
|
62
73
|
const start = useCallback(() => {
|
|
63
74
|
if (didStart) {
|
|
64
|
-
|
|
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
|
-
|
|
74
|
-
|
|
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 ?
|
|
92
|
+
isRunning ? interval : null
|
|
83
93
|
)
|
|
84
94
|
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
validateExpiryTimestamp(expiryTimestamp)
|
|
97
|
+
}, [expiryTimestamp])
|
|
98
|
+
|
|
85
99
|
return {
|
|
86
|
-
...
|
|
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
|
+
}
|
package/src/hooks/useRoutes.ts
CHANGED
|
@@ -422,7 +422,8 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
|
|
|
422
422
|
if (shouldUseRelayerQuote && initialRoutes.length) {
|
|
423
423
|
emitter.emit(WidgetEvent.AvailableRoutes, initialRoutes)
|
|
424
424
|
setIntermediateRoutes(queryKey, initialRoutes)
|
|
425
|
-
|
|
425
|
+
// Return early if we're only using main routes
|
|
426
|
+
} else if (shouldUseMainRoutes) {
|
|
426
427
|
// If we don't need relayer quote, return the initial routes
|
|
427
428
|
return initialRoutes
|
|
428
429
|
}
|
|
@@ -465,7 +466,7 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
|
|
|
465
466
|
queryClient.setQueryData(
|
|
466
467
|
queryDataKey,
|
|
467
468
|
{ routes: [route] },
|
|
468
|
-
{ updatedAt: dataUpdatedAt }
|
|
469
|
+
{ updatedAt: dataUpdatedAt || Date.now() }
|
|
469
470
|
)
|
|
470
471
|
setExecutableRoute(route)
|
|
471
472
|
}
|
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
|
-
"
|
|
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
|
-
"
|
|
252
|
-
"
|
|
253
|
-
"
|
|
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": "
|
|
303
|
+
"tokenOnChainAmount": "",
|
|
286
304
|
"tokenSearch": "আপনার টোকেন অনুসন্ধান করুন",
|
|
287
305
|
"valueLoss": "মান ক্ষতি",
|
|
288
306
|
"searchChains": "",
|