@lifi/widget 3.8.0-beta.1 → 3.8.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.
- package/CHANGELOG.md +16 -0
- package/dist/esm/components/GasMessage/GasRefuelMessage.js +2 -2
- package/dist/esm/components/GasMessage/GasRefuelMessage.js.map +1 -1
- package/dist/esm/components/Token/Token.js +7 -3
- package/dist/esm/components/Token/Token.js.map +1 -1
- package/dist/esm/components/TransactionDetails.js +8 -6
- package/dist/esm/components/TransactionDetails.js.map +1 -1
- package/dist/esm/config/version.d.ts +1 -1
- package/dist/esm/config/version.js +1 -1
- package/dist/esm/config/version.js.map +1 -1
- package/dist/esm/hooks/useLanguages.js +2 -2
- package/dist/esm/hooks/useLanguages.js.map +1 -1
- package/dist/esm/hooks/useSettingMonitor.js +3 -2
- package/dist/esm/hooks/useSettingMonitor.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/pages/SelectEnabledToolsPage.js +3 -6
- package/dist/esm/pages/SelectEnabledToolsPage.js.map +1 -1
- package/dist/esm/pages/SettingsPage/GasPriceSettings.js +2 -2
- package/dist/esm/pages/SettingsPage/GasPriceSettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js +2 -2
- package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js.map +1 -1
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js +16 -10
- package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js.map +1 -1
- package/dist/esm/providers/WalletProvider/SDKProviders.js +2 -1
- package/dist/esm/providers/WalletProvider/SDKProviders.js.map +1 -1
- package/dist/esm/providers/WalletProvider/UTXOBaseProvider.js +2 -1
- package/dist/esm/providers/WalletProvider/UTXOBaseProvider.js.map +1 -1
- package/dist/esm/providers/WalletProvider/UTXOProvider.js +1 -1
- package/dist/esm/providers/WalletProvider/UTXOProvider.js.map +1 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js +3 -2
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js.map +1 -1
- package/dist/esm/stores/form/types.d.ts +1 -1
- package/dist/esm/stores/form/useFieldActions.d.ts +10 -2
- package/dist/esm/stores/form/useFieldActions.js +39 -1
- package/dist/esm/stores/form/useFieldActions.js.map +1 -1
- package/dist/esm/stores/settings/types.d.ts +5 -2
- package/dist/esm/stores/settings/types.js.map +1 -1
- package/dist/esm/stores/settings/useAppearance.js +3 -2
- package/dist/esm/stores/settings/useAppearance.js.map +1 -1
- package/dist/esm/stores/settings/useSettingsActions.d.ts +9 -0
- package/dist/esm/stores/settings/useSettingsActions.js +77 -0
- package/dist/esm/stores/settings/useSettingsActions.js.map +1 -0
- package/dist/esm/stores/settings/useSettingsStore.d.ts +0 -2
- package/dist/esm/stores/settings/useSettingsStore.js +4 -26
- package/dist/esm/stores/settings/useSettingsStore.js.map +1 -1
- package/dist/esm/stores/settings/utils/getStateValues.d.ts +2 -0
- package/dist/esm/stores/settings/utils/getStateValues.js +15 -0
- package/dist/esm/stores/settings/utils/getStateValues.js.map +1 -0
- package/dist/esm/types/events.d.ts +21 -4
- package/dist/esm/types/events.js +2 -0
- package/dist/esm/types/events.js.map +1 -1
- package/dist/esm/utils/chainType.js +2 -1
- package/dist/esm/utils/chainType.js.map +1 -1
- package/dist/esm/utils/deepEqual.d.ts +2 -0
- package/dist/esm/utils/deepEqual.js +52 -0
- package/dist/esm/utils/deepEqual.js.map +1 -0
- package/dist/esm/utils/getPriceImpact.d.ts +9 -0
- package/dist/esm/utils/getPriceImpact.js +10 -0
- package/dist/esm/utils/getPriceImpact.js.map +1 -0
- package/package.json +10 -7
- package/src/components/GasMessage/GasRefuelMessage.tsx +3 -2
- package/src/components/Token/Token.tsx +7 -8
- package/src/components/TransactionDetails.tsx +8 -17
- package/src/config/version.ts +1 -1
- package/src/hooks/useLanguages.ts +2 -2
- package/src/hooks/useSettingMonitor.ts +2 -2
- package/src/index.ts +1 -0
- package/src/pages/SelectEnabledToolsPage.tsx +6 -10
- package/src/pages/SettingsPage/GasPriceSettings.tsx +2 -2
- package/src/pages/SettingsPage/RoutePrioritySettings.tsx +2 -2
- package/src/pages/SettingsPage/SlippageSettings/SlippageSettings.tsx +31 -21
- package/src/providers/WalletProvider/SDKProviders.tsx +2 -4
- package/src/providers/WalletProvider/UTXOBaseProvider.tsx +2 -5
- package/src/providers/WalletProvider/UTXOProvider.tsx +1 -1
- package/src/providers/WidgetProvider/WidgetProvider.tsx +5 -3
- package/src/stores/form/types.ts +1 -1
- package/src/stores/form/useFieldActions.ts +73 -2
- package/src/stores/settings/types.ts +7 -2
- package/src/stores/settings/useAppearance.ts +3 -5
- package/src/stores/settings/useSettingsActions.ts +152 -0
- package/src/stores/settings/useSettingsStore.ts +4 -34
- package/src/stores/settings/utils/getStateValues.ts +16 -0
- package/src/types/events.ts +24 -3
- package/src/utils/chainType.ts +2 -1
- package/src/utils/deepEqual.ts +62 -0
- package/src/utils/getPriceImpact.ts +26 -0
|
@@ -12,7 +12,8 @@ import { formatUnits } from 'viem'
|
|
|
12
12
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
13
13
|
import { isRouteDone } from '../stores/routes/utils.js'
|
|
14
14
|
import { getAccumulatedFeeCostsBreakdown } from '../utils/fees.js'
|
|
15
|
-
import { formatTokenAmount
|
|
15
|
+
import { formatTokenAmount } from '../utils/format.js'
|
|
16
|
+
import { getPriceImpact } from '../utils/getPriceImpact.js'
|
|
16
17
|
import { Card } from './Card/Card.js'
|
|
17
18
|
import { CardIconButton } from './Card/CardIconButton.js'
|
|
18
19
|
import { FeeBreakdownTooltip } from './FeeBreakdownTooltip.js'
|
|
@@ -37,22 +38,12 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
|
|
|
37
38
|
const { gasCosts, feeCosts, gasCostUSD, feeCostUSD, combinedFeesUSD } =
|
|
38
39
|
getAccumulatedFeeCostsBreakdown(route)
|
|
39
40
|
|
|
40
|
-
const
|
|
41
|
-
BigInt(route.fromAmount),
|
|
42
|
-
route.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
route.fromToken.priceUSD
|
|
47
|
-
)
|
|
48
|
-
const toTokenAmount = formatTokenAmount(
|
|
49
|
-
BigInt(route.toAmount),
|
|
50
|
-
route.toToken.decimals
|
|
51
|
-
)
|
|
52
|
-
const toTokenPrice =
|
|
53
|
-
formatTokenPrice(toTokenAmount, route.toToken.priceUSD) || 0.01
|
|
54
|
-
|
|
55
|
-
const priceImpact = toTokenPrice / fromTokenPrice - 1
|
|
41
|
+
const priceImpact = getPriceImpact({
|
|
42
|
+
fromAmount: BigInt(route.fromAmount),
|
|
43
|
+
toAmount: BigInt(route.toAmount),
|
|
44
|
+
fromToken: route.fromToken,
|
|
45
|
+
toToken: route.toToken,
|
|
46
|
+
})
|
|
56
47
|
|
|
57
48
|
const feeCollectionStep = route.steps[0].includedSteps.find(
|
|
58
49
|
(includedStep) => includedStep.tool === 'feeCollection'
|
package/src/config/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = '@lifi/widget'
|
|
2
|
-
export const version = '3.8.0
|
|
2
|
+
export const version = '3.8.0'
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { useTranslation } from 'react-i18next'
|
|
2
2
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
3
3
|
import { useSettings } from '../stores/settings/useSettings.js'
|
|
4
|
-
import {
|
|
4
|
+
import { useSettingsActions } from '../stores/settings/useSettingsActions.js'
|
|
5
5
|
|
|
6
6
|
export const useLanguages = () => {
|
|
7
7
|
const { t, i18n } = useTranslation()
|
|
8
8
|
const { languages } = useWidgetConfig()
|
|
9
9
|
const { language } = useSettings(['language'])
|
|
10
|
-
const setValue =
|
|
10
|
+
const { setValue } = useSettingsActions()
|
|
11
11
|
|
|
12
12
|
const sortedLanguages = Object.keys(i18n.store.data).sort()
|
|
13
13
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { shallow } from 'zustand/shallow'
|
|
2
2
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
3
|
+
import { useSettingsActions } from '../stores/settings/useSettingsActions.js'
|
|
3
4
|
import {
|
|
4
5
|
defaultConfigurableSettings,
|
|
5
|
-
setDefaultSettings,
|
|
6
6
|
useSettingsStore,
|
|
7
7
|
} from '../stores/settings/useSettingsStore.js'
|
|
8
8
|
import { useTools } from './useTools.js'
|
|
@@ -25,8 +25,8 @@ export const useSettingMonitor = () => {
|
|
|
25
25
|
shallow
|
|
26
26
|
)
|
|
27
27
|
const { tools } = useTools()
|
|
28
|
-
const resetSettings = useSettingsStore((state) => state.reset)
|
|
29
28
|
const config = useWidgetConfig()
|
|
29
|
+
const { setDefaultSettings, resetSettings } = useSettingsActions()
|
|
30
30
|
|
|
31
31
|
const isSlippageChanged = config.slippage
|
|
32
32
|
? Number(slippage) !== config.slippage * 100
|
package/src/index.ts
CHANGED
|
@@ -27,6 +27,7 @@ import { useDefaultElementId } from '../hooks/useDefaultElementId.js'
|
|
|
27
27
|
import { useHeader } from '../hooks/useHeader.js'
|
|
28
28
|
import { useScrollableContainer } from '../hooks/useScrollableContainer.js'
|
|
29
29
|
import { useTools } from '../hooks/useTools.js'
|
|
30
|
+
import { useSettingsActions } from '../stores/settings/useSettingsActions.js'
|
|
30
31
|
import { useSettingsStore } from '../stores/settings/useSettingsStore.js'
|
|
31
32
|
|
|
32
33
|
interface SelectAllCheckboxProps {
|
|
@@ -76,16 +77,11 @@ export const SelectEnabledToolsPage: React.FC<{
|
|
|
76
77
|
}> = ({ type }) => {
|
|
77
78
|
const typeKey = type.toLowerCase() as 'bridges' | 'exchanges'
|
|
78
79
|
const { tools } = useTools()
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
state.setToolValue,
|
|
85
|
-
state.toggleToolKeys,
|
|
86
|
-
],
|
|
87
|
-
shallow
|
|
88
|
-
)
|
|
80
|
+
const { setToolValue, toggleToolKeys } = useSettingsActions()
|
|
81
|
+
const [enabledTools, disabledTools] = useSettingsStore(
|
|
82
|
+
(state) => [state[`_enabled${type}`], state[`disabled${type}`]],
|
|
83
|
+
shallow
|
|
84
|
+
)
|
|
89
85
|
|
|
90
86
|
const { t } = useTranslation()
|
|
91
87
|
const elementId = useDefaultElementId()
|
|
@@ -3,13 +3,13 @@ import { useTranslation } from 'react-i18next'
|
|
|
3
3
|
import { CardTabs, Tab } from '../../components/Tabs/Tabs.style.js'
|
|
4
4
|
import { useSettingMonitor } from '../../hooks/useSettingMonitor.js'
|
|
5
5
|
import { useSettings } from '../../stores/settings/useSettings.js'
|
|
6
|
-
import {
|
|
6
|
+
import { useSettingsActions } from '../../stores/settings/useSettingsActions.js'
|
|
7
7
|
import { BadgedValue } from './SettingsCard/BadgedValue.js'
|
|
8
8
|
import { SettingCardExpandable } from './SettingsCard/SettingCardExpandable.js'
|
|
9
9
|
|
|
10
10
|
export const GasPriceSettings: React.FC = () => {
|
|
11
11
|
const { t } = useTranslation()
|
|
12
|
-
const setValue =
|
|
12
|
+
const { setValue } = useSettingsActions()
|
|
13
13
|
const { isGasPriceChanged } = useSettingMonitor()
|
|
14
14
|
const { gasPrice } = useSettings(['gasPrice'])
|
|
15
15
|
|
|
@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'
|
|
|
4
4
|
import { CardTabs, Tab } from '../../components/Tabs/Tabs.style.js'
|
|
5
5
|
import { useSettingMonitor } from '../../hooks/useSettingMonitor.js'
|
|
6
6
|
import { useSettings } from '../../stores/settings/useSettings.js'
|
|
7
|
-
import {
|
|
7
|
+
import { useSettingsActions } from '../../stores/settings/useSettingsActions.js'
|
|
8
8
|
import { BadgedValue } from './SettingsCard/BadgedValue.js'
|
|
9
9
|
import { SettingCardExpandable } from './SettingsCard/SettingCardExpandable.js'
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@ const Priorities: Order[] = ['CHEAPEST', 'FASTEST']
|
|
|
12
12
|
|
|
13
13
|
export const RoutePrioritySettings: React.FC = () => {
|
|
14
14
|
const { t } = useTranslation()
|
|
15
|
-
const setValue =
|
|
15
|
+
const { setValue } = useSettingsActions()
|
|
16
16
|
const { isRoutePriorityChanged } = useSettingMonitor()
|
|
17
17
|
const { routePriority } = useSettings(['routePriority'])
|
|
18
18
|
const currentRoutePriority = routePriority ?? ''
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { Percent, WarningRounded } from '@mui/icons-material'
|
|
2
|
-
import { Box, Typography } from '@mui/material'
|
|
2
|
+
import { Box, Typography, debounce } from '@mui/material'
|
|
3
3
|
import type { ChangeEventHandler, FocusEventHandler } from 'react'
|
|
4
|
-
import { useRef, useState } from 'react'
|
|
4
|
+
import { useCallback, useMemo, useRef, useState } from 'react'
|
|
5
5
|
import { useTranslation } from 'react-i18next'
|
|
6
6
|
import { useSettingMonitor } from '../../../hooks/useSettingMonitor.js'
|
|
7
7
|
import { useSettings } from '../../../stores/settings/useSettings.js'
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
useSettingsStore,
|
|
11
|
-
} from '../../../stores/settings/useSettingsStore.js'
|
|
8
|
+
import { useSettingsActions } from '../../../stores/settings/useSettingsActions.js'
|
|
9
|
+
import { defaultSlippage } from '../../../stores/settings/useSettingsStore.js'
|
|
12
10
|
import { formatSlippage } from '../../../utils/format.js'
|
|
13
11
|
import { BadgedValue } from '../SettingsCard/BadgedValue.js'
|
|
14
12
|
import { SettingCardExpandable } from '../SettingsCard/SettingCardExpandable.js'
|
|
@@ -24,36 +22,48 @@ export const SlippageSettings: React.FC = () => {
|
|
|
24
22
|
const { isSlippageOutsideRecommendedLimits, isSlippageChanged } =
|
|
25
23
|
useSettingMonitor()
|
|
26
24
|
const { slippage } = useSettings(['slippage'])
|
|
27
|
-
const setValue =
|
|
25
|
+
const { setValue } = useSettingsActions()
|
|
28
26
|
const defaultValue = useRef(slippage)
|
|
29
27
|
const [focused, setFocused] = useState<'input' | 'button'>()
|
|
30
28
|
|
|
29
|
+
const customInputValue =
|
|
30
|
+
!slippage || slippage === defaultSlippage ? '' : slippage
|
|
31
|
+
|
|
32
|
+
const [inputValue, setInputValue] = useState(customInputValue)
|
|
33
|
+
|
|
31
34
|
const handleDefaultClick = () => {
|
|
32
35
|
setValue('slippage', formatSlippage(defaultSlippage, defaultValue.current))
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
const
|
|
36
|
-
const { value } = event.target
|
|
38
|
+
const debouncedSetValue = useMemo(() => debounce(setValue, 500), [setValue])
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
const handleInputUpdate: ChangeEventHandler<HTMLInputElement> = useCallback(
|
|
41
|
+
(event) => {
|
|
42
|
+
const { value } = event.target
|
|
43
|
+
|
|
44
|
+
setInputValue(formatSlippage(value, defaultValue.current, true))
|
|
45
|
+
|
|
46
|
+
debouncedSetValue(
|
|
47
|
+
'slippage',
|
|
48
|
+
formatSlippage(value || defaultSlippage, defaultValue.current, true)
|
|
49
|
+
)
|
|
50
|
+
},
|
|
51
|
+
[debouncedSetValue]
|
|
52
|
+
)
|
|
43
53
|
|
|
44
54
|
const handleInputBlur: FocusEventHandler<HTMLInputElement> = (event) => {
|
|
45
55
|
setFocused(undefined)
|
|
46
56
|
|
|
47
57
|
const { value } = event.target
|
|
48
58
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
59
|
+
const formattedValue = formatSlippage(
|
|
60
|
+
value || defaultSlippage,
|
|
61
|
+
defaultValue.current
|
|
52
62
|
)
|
|
53
|
-
|
|
63
|
+
setInputValue(formattedValue === defaultSlippage ? '' : formattedValue)
|
|
54
64
|
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
setValue('slippage', formattedValue)
|
|
66
|
+
}
|
|
57
67
|
|
|
58
68
|
const badgeColor = isSlippageOutsideRecommendedLimits
|
|
59
69
|
? 'warning'
|
|
@@ -98,7 +108,7 @@ export const SlippageSettings: React.FC = () => {
|
|
|
98
108
|
setFocused('input')
|
|
99
109
|
}}
|
|
100
110
|
onBlur={handleInputBlur}
|
|
101
|
-
value={
|
|
111
|
+
value={inputValue}
|
|
102
112
|
autoComplete="off"
|
|
103
113
|
/>
|
|
104
114
|
</SettingsFieldSet>
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
+
import { getConnectorClient as getBigmiConnectorClient } from '@bigmi/client'
|
|
2
|
+
import { useConfig as useBigmiConfig } from '@bigmi/react'
|
|
1
3
|
import type { SDKProvider } from '@lifi/sdk'
|
|
2
4
|
import { ChainType, EVM, Solana, UTXO, config } from '@lifi/sdk'
|
|
3
|
-
import {
|
|
4
|
-
getConnectorClient as getBigmiConnectorClient,
|
|
5
|
-
useConfig as useBigmiConfig,
|
|
6
|
-
} from '@lifi/wallet-management'
|
|
7
5
|
import type { SignerWalletAdapter } from '@solana/wallet-adapter-base'
|
|
8
6
|
import { useWallet } from '@solana/wallet-adapter-react'
|
|
9
7
|
import { useEffect } from 'react'
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
+
import { BigmiProvider, useReconnect } from '@bigmi/react'
|
|
1
2
|
import type { DefaultWagmiConfigResult } from '@lifi/wallet-management'
|
|
2
|
-
import {
|
|
3
|
-
BigmiProvider,
|
|
4
|
-
createDefaultBigmiConfig,
|
|
5
|
-
useReconnect,
|
|
6
|
-
} from '@lifi/wallet-management'
|
|
3
|
+
import { createDefaultBigmiConfig } from '@lifi/wallet-management'
|
|
7
4
|
import { type FC, type PropsWithChildren, useRef } from 'react'
|
|
8
5
|
|
|
9
6
|
export const UTXOBaseProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { BigmiContext } from '@bigmi/react'
|
|
1
2
|
import { ChainType } from '@lifi/sdk'
|
|
2
|
-
import { BigmiContext } from '@lifi/wallet-management'
|
|
3
3
|
import { type FC, type PropsWithChildren, useContext } from 'react'
|
|
4
4
|
import { isItemAllowed } from '../../utils/item.js'
|
|
5
5
|
import { useWidgetConfig } from '../WidgetProvider/WidgetProvider.js'
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { SDKConfig } from '@lifi/sdk'
|
|
2
|
+
import { config, createConfig } from '@lifi/sdk'
|
|
2
3
|
import { createContext, useContext, useId, useMemo } from 'react'
|
|
3
4
|
import { version } from '../../config/version.js'
|
|
4
|
-
import {
|
|
5
|
+
import { useSettingsActions } from '../../stores/settings/useSettingsActions.js'
|
|
5
6
|
import type { WidgetContextProps, WidgetProviderProps } from './types.js'
|
|
6
7
|
|
|
7
8
|
const initialContext: WidgetContextProps = {
|
|
@@ -20,6 +21,7 @@ export const WidgetProvider: React.FC<
|
|
|
20
21
|
React.PropsWithChildren<WidgetProviderProps>
|
|
21
22
|
> = ({ children, config: widgetConfig }) => {
|
|
22
23
|
const elementId = useId()
|
|
24
|
+
const { setDefaultSettings } = useSettingsActions()
|
|
23
25
|
|
|
24
26
|
if (!widgetConfig?.integrator) {
|
|
25
27
|
throw new Error('Required property "integrator" is missing.')
|
|
@@ -69,7 +71,7 @@ export const WidgetProvider: React.FC<
|
|
|
69
71
|
integrator: widgetConfig.integrator,
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
|
-
}, [elementId, widgetConfig])
|
|
74
|
+
}, [elementId, widgetConfig, setDefaultSettings])
|
|
73
75
|
return (
|
|
74
76
|
<WidgetContext.Provider value={value}>{children}</WidgetContext.Provider>
|
|
75
77
|
)
|
package/src/stores/form/types.ts
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
|
+
import { useCallback } from 'react'
|
|
1
2
|
import { shallow } from 'zustand/shallow'
|
|
2
|
-
import
|
|
3
|
+
import { useWidgetEvents } from '../../hooks/useWidgetEvents.js'
|
|
4
|
+
import type { FormFieldChanged } from '../../types/events.js'
|
|
5
|
+
import { WidgetEvent } from '../../types/events.js'
|
|
6
|
+
import type {
|
|
7
|
+
DefaultValues,
|
|
8
|
+
FormActions,
|
|
9
|
+
FormFieldNames,
|
|
10
|
+
GenericFormValue,
|
|
11
|
+
SetOptions,
|
|
12
|
+
} from './types.js'
|
|
3
13
|
import { useFormStore } from './useFormStore.js'
|
|
4
14
|
|
|
5
15
|
export const useFieldActions = () => {
|
|
16
|
+
const emitter = useWidgetEvents()
|
|
6
17
|
const actions = useFormStore<FormActions>(
|
|
7
18
|
(store) => ({
|
|
8
19
|
getFieldValues: store.getFieldValues,
|
|
@@ -16,5 +27,65 @@ export const useFieldActions = () => {
|
|
|
16
27
|
shallow
|
|
17
28
|
)
|
|
18
29
|
|
|
19
|
-
|
|
30
|
+
const setFieldValueWithEmittedEvents = useCallback(
|
|
31
|
+
(
|
|
32
|
+
fieldName: FormFieldNames,
|
|
33
|
+
newValue: GenericFormValue,
|
|
34
|
+
options?: SetOptions
|
|
35
|
+
) => {
|
|
36
|
+
const oldValue = actions.getFieldValues(fieldName)[0]
|
|
37
|
+
|
|
38
|
+
actions.setFieldValue(fieldName, newValue, options)
|
|
39
|
+
|
|
40
|
+
if (newValue !== oldValue) {
|
|
41
|
+
emitter.emit(WidgetEvent.FormFieldChanged, {
|
|
42
|
+
fieldName,
|
|
43
|
+
newValue,
|
|
44
|
+
oldValue,
|
|
45
|
+
} as FormFieldChanged)
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
[actions, emitter]
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
const setUserAndDefaultValuesWithEmittedEvents = useCallback(
|
|
52
|
+
(formValues: Partial<DefaultValues>) => {
|
|
53
|
+
const formValuesKeys = Object.keys(formValues) as FormFieldNames[]
|
|
54
|
+
|
|
55
|
+
const changedValues = formValuesKeys.reduce(
|
|
56
|
+
(accum, fieldName) => {
|
|
57
|
+
const oldValue = actions.getFieldValues(fieldName)[0]
|
|
58
|
+
const newValue = formValues[fieldName]
|
|
59
|
+
|
|
60
|
+
if (newValue !== oldValue) {
|
|
61
|
+
accum.push({ fieldName, newValue, oldValue })
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return accum
|
|
65
|
+
},
|
|
66
|
+
[] as {
|
|
67
|
+
fieldName: FormFieldNames
|
|
68
|
+
newValue: GenericFormValue
|
|
69
|
+
oldValue: GenericFormValue
|
|
70
|
+
}[]
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
actions.setUserAndDefaultValues(formValues)
|
|
74
|
+
|
|
75
|
+
changedValues.forEach(({ fieldName, newValue, oldValue }) => {
|
|
76
|
+
emitter.emit(WidgetEvent.FormFieldChanged, {
|
|
77
|
+
fieldName,
|
|
78
|
+
newValue,
|
|
79
|
+
oldValue,
|
|
80
|
+
} as FormFieldChanged)
|
|
81
|
+
})
|
|
82
|
+
},
|
|
83
|
+
[actions, emitter]
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
...actions,
|
|
88
|
+
setFieldValue: setFieldValueWithEmittedEvents,
|
|
89
|
+
setUserAndDefaultValues: setUserAndDefaultValuesWithEmittedEvents,
|
|
90
|
+
}
|
|
20
91
|
}
|
|
@@ -9,6 +9,8 @@ export type ValueSetter<S> = <K extends keyof S>(
|
|
|
9
9
|
value: S[Extract<K, string>]
|
|
10
10
|
) => void
|
|
11
11
|
|
|
12
|
+
export type ValueGetter<S> = <K extends keyof S>(key: K) => S[K]
|
|
13
|
+
|
|
12
14
|
export type ValuesSetter<S> = <K extends keyof S>(
|
|
13
15
|
values: Record<K, S[Extract<K, string>]>
|
|
14
16
|
) => void
|
|
@@ -31,9 +33,10 @@ export interface SettingsProps {
|
|
|
31
33
|
_enabledExchanges: Record<string, boolean>
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
export interface
|
|
36
|
+
export interface SettingsActions {
|
|
35
37
|
setValue: ValueSetter<SettingsProps>
|
|
36
|
-
|
|
38
|
+
getValue: ValueGetter<SettingsProps>
|
|
39
|
+
getSettings: () => SettingsProps
|
|
37
40
|
initializeTools(
|
|
38
41
|
toolType: SettingsToolType,
|
|
39
42
|
tools: string[],
|
|
@@ -44,6 +47,8 @@ export interface SettingsState extends SettingsProps {
|
|
|
44
47
|
reset(bridges: string[], exchanges: string[]): void
|
|
45
48
|
}
|
|
46
49
|
|
|
50
|
+
export type SettingsState = SettingsProps & SettingsActions
|
|
51
|
+
|
|
47
52
|
export interface SendToWalletState {
|
|
48
53
|
showSendToWallet: boolean
|
|
49
54
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useSettingsActions } from '../../stores/settings/useSettingsActions.js'
|
|
2
2
|
import type { Appearance } from '../../types/widget.js'
|
|
3
3
|
import { useSettingsStore } from './useSettingsStore.js'
|
|
4
4
|
|
|
@@ -6,10 +6,8 @@ export const useAppearance = (): [
|
|
|
6
6
|
Appearance,
|
|
7
7
|
(appearance: Appearance) => void,
|
|
8
8
|
] => {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
shallow
|
|
12
|
-
)
|
|
9
|
+
const { setValue } = useSettingsActions()
|
|
10
|
+
const appearance = useSettingsStore((state) => state.appearance)
|
|
13
11
|
const setAppearance = (appearance: Appearance) => {
|
|
14
12
|
setValue('appearance', appearance)
|
|
15
13
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { useCallback } from 'react'
|
|
2
|
+
import { shallow } from 'zustand/shallow'
|
|
3
|
+
import type { widgetEvents } from '../../hooks/useWidgetEvents.js'
|
|
4
|
+
import { useWidgetEvents } from '../../hooks/useWidgetEvents.js'
|
|
5
|
+
import { WidgetEvent } from '../../types/events.js'
|
|
6
|
+
import type { WidgetConfig } from '../../types/widget.js'
|
|
7
|
+
import { deepEqual } from '../../utils/deepEqual.js'
|
|
8
|
+
import type {
|
|
9
|
+
SettingsActions,
|
|
10
|
+
SettingsProps,
|
|
11
|
+
SettingsToolType,
|
|
12
|
+
ValueSetter,
|
|
13
|
+
} from './types.js'
|
|
14
|
+
import {
|
|
15
|
+
defaultConfigurableSettings,
|
|
16
|
+
useSettingsStore,
|
|
17
|
+
} from './useSettingsStore.js'
|
|
18
|
+
|
|
19
|
+
const emitEventOnChange = <T extends (...args: any[]) => any>(
|
|
20
|
+
emitter: typeof widgetEvents,
|
|
21
|
+
actions: Omit<SettingsActions, 'initializeTools'>,
|
|
22
|
+
settingFunction: T,
|
|
23
|
+
...args: Parameters<T>
|
|
24
|
+
) => {
|
|
25
|
+
const oldSettings = actions.getSettings()
|
|
26
|
+
|
|
27
|
+
settingFunction(...args)
|
|
28
|
+
|
|
29
|
+
const newSettings = actions.getSettings()
|
|
30
|
+
|
|
31
|
+
if (!deepEqual(oldSettings, newSettings)) {
|
|
32
|
+
;(Object.keys(oldSettings) as (keyof SettingsProps)[]).forEach(
|
|
33
|
+
(toolKey) => {
|
|
34
|
+
if (!deepEqual(oldSettings[toolKey], newSettings[toolKey])) {
|
|
35
|
+
emitter.emit(WidgetEvent.SettingUpdated, {
|
|
36
|
+
setting: toolKey,
|
|
37
|
+
newValue: newSettings[toolKey],
|
|
38
|
+
oldValue: oldSettings[toolKey],
|
|
39
|
+
newSettings: newSettings,
|
|
40
|
+
oldSettings: oldSettings,
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const useSettingsActions = () => {
|
|
49
|
+
const emitter = useWidgetEvents()
|
|
50
|
+
const actions = useSettingsStore(
|
|
51
|
+
(state) => ({
|
|
52
|
+
setValue: state.setValue,
|
|
53
|
+
getValue: state.getValue,
|
|
54
|
+
getSettings: state.getSettings,
|
|
55
|
+
reset: state.reset,
|
|
56
|
+
setToolValue: state.setToolValue,
|
|
57
|
+
toggleToolKeys: state.toggleToolKeys,
|
|
58
|
+
}),
|
|
59
|
+
shallow
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
const setValueWithEmittedEvent = useCallback<ValueSetter<SettingsProps>>(
|
|
63
|
+
(value, newValue) => {
|
|
64
|
+
const setting = value as keyof SettingsProps
|
|
65
|
+
emitEventOnChange(emitter, actions, actions.setValue, setting, newValue)
|
|
66
|
+
},
|
|
67
|
+
[emitter, actions]
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
const setDefaultSettingsWithEmittedEvents = useCallback(
|
|
71
|
+
(config?: WidgetConfig) => {
|
|
72
|
+
const slippage = actions.getValue('slippage')
|
|
73
|
+
const routePriority = actions.getValue('routePriority')
|
|
74
|
+
const gasPrice = actions.getValue('gasPrice')
|
|
75
|
+
|
|
76
|
+
const defaultSlippage =
|
|
77
|
+
(config?.slippage || config?.sdkConfig?.routeOptions?.slippage || 0) *
|
|
78
|
+
100
|
|
79
|
+
const defaultRoutePriority =
|
|
80
|
+
config?.routePriority || config?.sdkConfig?.routeOptions?.order
|
|
81
|
+
|
|
82
|
+
defaultConfigurableSettings.slippage = (
|
|
83
|
+
defaultSlippage || defaultConfigurableSettings.slippage
|
|
84
|
+
)?.toString()
|
|
85
|
+
|
|
86
|
+
defaultConfigurableSettings.routePriority =
|
|
87
|
+
defaultRoutePriority || defaultConfigurableSettings.routePriority
|
|
88
|
+
|
|
89
|
+
if (!slippage) {
|
|
90
|
+
setValueWithEmittedEvent(
|
|
91
|
+
'slippage',
|
|
92
|
+
defaultConfigurableSettings.slippage
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
if (!routePriority) {
|
|
96
|
+
setValueWithEmittedEvent(
|
|
97
|
+
'routePriority',
|
|
98
|
+
defaultConfigurableSettings.routePriority
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
if (!gasPrice) {
|
|
102
|
+
setValueWithEmittedEvent(
|
|
103
|
+
'gasPrice',
|
|
104
|
+
defaultConfigurableSettings.gasPrice
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
[actions, setValueWithEmittedEvent]
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
const resetWithEmittedEvents = useCallback(
|
|
112
|
+
(bridges: string[], exchanges: string[]) => {
|
|
113
|
+
emitEventOnChange(emitter, actions, actions.reset, bridges, exchanges)
|
|
114
|
+
},
|
|
115
|
+
[emitter, actions]
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
const setToolValueWithEmittedEvents = useCallback(
|
|
119
|
+
(toolType: SettingsToolType, tool: string, value: boolean) => {
|
|
120
|
+
emitEventOnChange(
|
|
121
|
+
emitter,
|
|
122
|
+
actions,
|
|
123
|
+
actions.setToolValue,
|
|
124
|
+
toolType,
|
|
125
|
+
tool,
|
|
126
|
+
value
|
|
127
|
+
)
|
|
128
|
+
},
|
|
129
|
+
[emitter, actions]
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
const toggleToolKeysWithEmittedEvents = useCallback(
|
|
133
|
+
(toolType: SettingsToolType, toolKeys: string[]) => {
|
|
134
|
+
emitEventOnChange(
|
|
135
|
+
emitter,
|
|
136
|
+
actions,
|
|
137
|
+
actions.toggleToolKeys,
|
|
138
|
+
toolType,
|
|
139
|
+
toolKeys
|
|
140
|
+
)
|
|
141
|
+
},
|
|
142
|
+
[emitter, actions]
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
setValue: setValueWithEmittedEvent,
|
|
147
|
+
setDefaultSettings: setDefaultSettingsWithEmittedEvents,
|
|
148
|
+
resetSettings: resetWithEmittedEvents,
|
|
149
|
+
setToolValue: setToolValueWithEmittedEvents,
|
|
150
|
+
toggleToolKeys: toggleToolKeysWithEmittedEvents,
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { StateCreator } from 'zustand'
|
|
2
2
|
import { persist } from 'zustand/middleware'
|
|
3
3
|
import { createWithEqualityFn } from 'zustand/traditional'
|
|
4
|
-
import type { WidgetConfig } from '../../types/widget.js'
|
|
5
4
|
import type { SettingsProps, SettingsState } from './types.js'
|
|
6
5
|
import { SettingsToolTypes } from './types.js'
|
|
6
|
+
import { getStateValues } from './utils/getStateValues.js'
|
|
7
7
|
|
|
8
8
|
export const defaultSlippage = '0.5'
|
|
9
9
|
|
|
@@ -36,16 +36,8 @@ export const useSettingsStore = createWithEqualityFn<SettingsState>(
|
|
|
36
36
|
set(() => ({
|
|
37
37
|
[key]: value,
|
|
38
38
|
})),
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const updatedState: SettingsProps = { ...state }
|
|
42
|
-
for (const key in values) {
|
|
43
|
-
if (Object.hasOwn(state, key)) {
|
|
44
|
-
updatedState[key] = values[key]
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return updatedState
|
|
48
|
-
}),
|
|
39
|
+
getSettings: () => getStateValues(get()),
|
|
40
|
+
getValue: (key) => get()[key],
|
|
49
41
|
initializeTools: (toolType, tools, reset) => {
|
|
50
42
|
if (!tools.length) {
|
|
51
43
|
return
|
|
@@ -141,6 +133,7 @@ export const useSettingsStore = createWithEqualityFn<SettingsState>(
|
|
|
141
133
|
}))
|
|
142
134
|
get().initializeTools('Bridges', bridges, true)
|
|
143
135
|
get().initializeTools('Exchanges', exchanges, true)
|
|
136
|
+
return { ...get() }
|
|
144
137
|
},
|
|
145
138
|
}),
|
|
146
139
|
{
|
|
@@ -187,26 +180,3 @@ export const useSettingsStore = createWithEqualityFn<SettingsState>(
|
|
|
187
180
|
) as StateCreator<SettingsState, [], [], SettingsState>,
|
|
188
181
|
Object.is
|
|
189
182
|
)
|
|
190
|
-
|
|
191
|
-
export const setDefaultSettings = (config?: WidgetConfig) => {
|
|
192
|
-
const { slippage, routePriority, setValue, gasPrice } =
|
|
193
|
-
useSettingsStore.getState()
|
|
194
|
-
const defaultSlippage =
|
|
195
|
-
(config?.slippage || config?.sdkConfig?.routeOptions?.slippage || 0) * 100
|
|
196
|
-
const defaultRoutePriority =
|
|
197
|
-
config?.routePriority || config?.sdkConfig?.routeOptions?.order
|
|
198
|
-
defaultConfigurableSettings.slippage = (
|
|
199
|
-
defaultSlippage || defaultConfigurableSettings.slippage
|
|
200
|
-
)?.toString()
|
|
201
|
-
defaultConfigurableSettings.routePriority =
|
|
202
|
-
defaultRoutePriority || defaultConfigurableSettings.routePriority
|
|
203
|
-
if (!slippage) {
|
|
204
|
-
setValue('slippage', defaultConfigurableSettings.slippage)
|
|
205
|
-
}
|
|
206
|
-
if (!routePriority) {
|
|
207
|
-
setValue('routePriority', defaultConfigurableSettings.routePriority)
|
|
208
|
-
}
|
|
209
|
-
if (!gasPrice) {
|
|
210
|
-
setValue('gasPrice', defaultConfigurableSettings.gasPrice)
|
|
211
|
-
}
|
|
212
|
-
}
|