@dodoex/wallet-web3-react 0.0.1-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 (78) hide show
  1. package/babel.config.js +9 -0
  2. package/dist/index.js +72 -0
  3. package/dist/types/ClientProvider.d.ts +2 -0
  4. package/dist/types/LangProvider.d.ts +11 -0
  5. package/dist/types/WalletConnect/AccountPage.d.ts +11 -0
  6. package/dist/types/WalletConnect/ActivityList.d.ts +20 -0
  7. package/dist/types/WalletConnect/ConnectAlchemy/index.d.ts +6 -0
  8. package/dist/types/WalletConnect/ConnectAlchemy/useConnectAlchemy.d.ts +12 -0
  9. package/dist/types/WalletConnect/ConnectLedger/ErrorDialog.d.ts +4 -0
  10. package/dist/types/WalletConnect/ConnectLedger/LoadingDialog.d.ts +3 -0
  11. package/dist/types/WalletConnect/ConnectLedger/LockedDialog.d.ts +4 -0
  12. package/dist/types/WalletConnect/ConnectLedger/ProtocolDialog.d.ts +6 -0
  13. package/dist/types/WalletConnect/ConnectLedger/SelectAddressDialog.d.ts +8 -0
  14. package/dist/types/WalletConnect/ConnectLedger/SelectPathDialog.d.ts +5 -0
  15. package/dist/types/WalletConnect/ConnectLedger/helper.d.ts +2 -0
  16. package/dist/types/WalletConnect/ConnectLedger/index.d.ts +6 -0
  17. package/dist/types/WalletConnect/ConnectPage.d.ts +9 -0
  18. package/dist/types/WalletConnect/HasBalanceTokenList.d.ts +4 -0
  19. package/dist/types/WalletConnect/ReceiveTokenPage.d.ts +4 -0
  20. package/dist/types/WalletConnect/SendTokenPage.d.ts +5 -0
  21. package/dist/types/WalletConnect/WalletDialog.d.ts +6 -0
  22. package/dist/types/WalletConnectProvider.d.ts +72 -0
  23. package/dist/types/components/AddressWithLinkAndCopy.d.ts +28 -0
  24. package/dist/types/components/Dialog.d.ts +15 -0
  25. package/dist/types/components/TokenLogo.d.ts +26 -0
  26. package/dist/types/components/WalletTag.d.ts +7 -0
  27. package/dist/types/constants/localstorage.d.ts +6 -0
  28. package/dist/types/hooks/useConnectWalet.d.ts +30 -0
  29. package/dist/types/hooks/useFetchFiatPrice.d.ts +3 -0
  30. package/dist/types/hooks/useFetchTokensBalance.d.ts +14 -0
  31. package/dist/types/hooks/useHasBalanceTokenList.d.ts +21 -0
  32. package/dist/types/hooks/useTransactionList.d.ts +272 -0
  33. package/dist/types/index.d.ts +4 -0
  34. package/dist/types/utils/formatter.d.ts +20 -0
  35. package/dist/types/utils/time.d.ts +3 -0
  36. package/dist/types/utils/utils.d.ts +2 -0
  37. package/lingui.config.ts +13 -0
  38. package/locales/en.po +251 -0
  39. package/locales/en.ts +1 -0
  40. package/locales/zh.po +249 -0
  41. package/locales/zh.ts +1 -0
  42. package/package.json +68 -0
  43. package/rollup.config.mjs +64 -0
  44. package/src/ClientProvider.tsx +15 -0
  45. package/src/LangProvider.tsx +32 -0
  46. package/src/WalletConnect/AccountPage.tsx +535 -0
  47. package/src/WalletConnect/ActivityList.tsx +597 -0
  48. package/src/WalletConnect/ConnectAlchemy/index.tsx +246 -0
  49. package/src/WalletConnect/ConnectAlchemy/useConnectAlchemy.ts +101 -0
  50. package/src/WalletConnect/ConnectLedger/ErrorDialog.tsx +61 -0
  51. package/src/WalletConnect/ConnectLedger/LoadingDialog.tsx +106 -0
  52. package/src/WalletConnect/ConnectLedger/LockedDialog.tsx +54 -0
  53. package/src/WalletConnect/ConnectLedger/ProtocolDialog.tsx +61 -0
  54. package/src/WalletConnect/ConnectLedger/SelectAddressDialog.tsx +326 -0
  55. package/src/WalletConnect/ConnectLedger/SelectPathDialog.tsx +68 -0
  56. package/src/WalletConnect/ConnectLedger/helper.ts +14 -0
  57. package/src/WalletConnect/ConnectLedger/index.tsx +89 -0
  58. package/src/WalletConnect/ConnectPage.tsx +459 -0
  59. package/src/WalletConnect/HasBalanceTokenList.tsx +201 -0
  60. package/src/WalletConnect/ReceiveTokenPage.tsx +143 -0
  61. package/src/WalletConnect/SendTokenPage.tsx +249 -0
  62. package/src/WalletConnect/WalletDialog.tsx +72 -0
  63. package/src/WalletConnectProvider.tsx +54 -0
  64. package/src/components/AddressWithLinkAndCopy.tsx +200 -0
  65. package/src/components/Dialog.tsx +155 -0
  66. package/src/components/TokenLogo.tsx +165 -0
  67. package/src/components/WalletTag.tsx +113 -0
  68. package/src/constants/localstorage.ts +22 -0
  69. package/src/hooks/useConnectWalet.ts +144 -0
  70. package/src/hooks/useFetchFiatPrice.ts +51 -0
  71. package/src/hooks/useFetchTokensBalance.ts +52 -0
  72. package/src/hooks/useHasBalanceTokenList.ts +157 -0
  73. package/src/hooks/useTransactionList.ts +87 -0
  74. package/src/index.tsx +4 -0
  75. package/src/utils/formatter.ts +102 -0
  76. package/src/utils/time.ts +21 -0
  77. package/src/utils/utils.ts +8 -0
  78. package/tsconfig.json +22 -0
@@ -0,0 +1,200 @@
1
+ import {
2
+ Box,
3
+ BoxProps,
4
+ HoverOpacity,
5
+ HoverAddBackground,
6
+ HoverAddUnderLine,
7
+ useTheme,
8
+ ButtonBase,
9
+ } from '@dodoex/components';
10
+ import { ArrowRight, ArrowTopRightBorder } from '@dodoex/icons';
11
+ import { useWalletStore } from '@dodoex/wallet-web3';
12
+ import { useWalletConnectContext } from '../WalletConnectProvider';
13
+
14
+ export function truncatePoolAddress(address: string): string {
15
+ if (address.length <= 10) {
16
+ return address;
17
+ }
18
+ return `${address.slice(0, 6)}...${address.slice(
19
+ address.length - 4,
20
+ address.length,
21
+ )}`;
22
+ }
23
+
24
+ interface AddressTextProps {
25
+ sx?: BoxProps['sx'];
26
+ truncate?: boolean;
27
+ address: string;
28
+ disabledAddress?: boolean;
29
+ addressHoverColor?: string;
30
+ addressHoverShowIcon?: boolean;
31
+ handleOpen?: (
32
+ event: React.MouseEvent<HTMLDivElement, MouseEvent>,
33
+ type: 'address' | 'icon',
34
+ ) => void;
35
+ }
36
+
37
+ interface Props extends AddressTextProps {
38
+ showCopy?: boolean;
39
+ size?: 'small' | 'medium' | 'big';
40
+ newTab?: boolean;
41
+ iconSize?: number;
42
+ iconSpace?: number;
43
+ iconDarkHover?: boolean;
44
+ customChainId?: number;
45
+ onAddressClick?: (
46
+ event: React.MouseEvent<HTMLDivElement, MouseEvent>,
47
+ ) => void;
48
+ }
49
+
50
+ export function AddressText({
51
+ truncate,
52
+ address,
53
+ disabledAddress,
54
+ sx,
55
+ handleOpen,
56
+ addressHoverColor,
57
+ addressHoverShowIcon,
58
+ }: AddressTextProps & {
59
+ typography?: string;
60
+ domain?: string;
61
+ }) {
62
+ if (disabledAddress) {
63
+ return <Box>{truncate ? truncatePoolAddress(address) : address}</Box>;
64
+ }
65
+ return (
66
+ <HoverAddUnderLine
67
+ lineSx={{
68
+ bottom: -1,
69
+ }}
70
+ // @ts-ignore
71
+ lineColor={addressHoverColor ?? (sx?.color || '')}
72
+ hoverSx={{
73
+ color: 'addressHoverColor',
74
+ '& svg': {
75
+ display: 'inline-block',
76
+ },
77
+ }}
78
+ className="truncate-address-link"
79
+ >
80
+ <Box
81
+ onClick={(evt) => {
82
+ handleOpen?.(evt, 'address');
83
+ }}
84
+ sx={{
85
+ display: 'flex',
86
+ alignItems: 'center',
87
+ cursor: 'pointer',
88
+ }}
89
+ >
90
+ {truncate ? truncatePoolAddress(address) : address}
91
+ {addressHoverShowIcon ? (
92
+ <Box
93
+ component={ArrowRight}
94
+ sx={{
95
+ display: 'none',
96
+ width: 14,
97
+ height: 14,
98
+ }}
99
+ />
100
+ ) : (
101
+ ''
102
+ )}
103
+ </Box>
104
+ </HoverAddUnderLine>
105
+ );
106
+ }
107
+
108
+ export function AddressWithLink({
109
+ address,
110
+ truncate,
111
+ size = 'medium',
112
+ iconSize,
113
+ iconSpace: iconSpaceProps,
114
+ sx,
115
+ iconDarkHover,
116
+ disabledAddress,
117
+ addressHoverColor,
118
+ addressHoverShowIcon,
119
+ customChainId,
120
+ handleOpen,
121
+ onAddressClick,
122
+ }: Props) {
123
+ const theme = useTheme();
124
+
125
+ const isBig = size === 'big';
126
+ const isMedium = size === 'medium';
127
+
128
+ const IconHoverBox = iconDarkHover ? HoverAddBackground : HoverOpacity;
129
+ const getIconSpace = (isMediumRes?: boolean) => {
130
+ let iconSpace = isMediumRes ? 12 : 8;
131
+ if (iconSpaceProps) {
132
+ iconSpace = iconSpaceProps;
133
+ }
134
+ if (iconDarkHover) {
135
+ iconSpace -= 3;
136
+ }
137
+ return iconSpace;
138
+ };
139
+ // eslint-disable-next-line no-nested-ternary
140
+ const typography = isBig ? 'h5' : isMedium ? 'body1' : 'body2';
141
+ const { chainId: currentChainId } = useWalletStore();
142
+ const chainId = customChainId ?? currentChainId;
143
+ const { getChain } = useWalletConnectContext();
144
+
145
+ const handleOpenResult: AddressTextProps['handleOpen'] = (evt, type) => {
146
+ if (handleOpen) {
147
+ handleOpen(evt, type);
148
+ return;
149
+ }
150
+ if (chainId) {
151
+ evt.stopPropagation();
152
+ const scanUrl = getChain(chainId)?.scanUrl;
153
+ if (!scanUrl) return;
154
+ window.open(`https://${scanUrl}${address ? `/address/${address}` : ''}`);
155
+ }
156
+ };
157
+
158
+ return (
159
+ <Box
160
+ sx={{
161
+ display: 'flex',
162
+ alignItems: 'center',
163
+ typography,
164
+ color: theme.palette.text.primary,
165
+ lineHeight: 'normal',
166
+ ...(sx || {}),
167
+ }}
168
+ >
169
+ <AddressText
170
+ truncate={truncate}
171
+ address={address}
172
+ disabledAddress={disabledAddress}
173
+ sx={sx}
174
+ typography={typography}
175
+ handleOpen={onAddressClick ?? handleOpenResult}
176
+ addressHoverColor={addressHoverColor}
177
+ addressHoverShowIcon={addressHoverShowIcon}
178
+ />
179
+
180
+ <IconHoverBox
181
+ sx={{
182
+ display: 'inline-flex',
183
+ ml: getIconSpace(isMedium),
184
+ cursor: 'pointer',
185
+ }}
186
+ onClick={(evt) => {
187
+ handleOpenResult(evt, 'icon');
188
+ }}
189
+ >
190
+ <Box
191
+ component={ArrowTopRightBorder}
192
+ sx={{
193
+ width: iconSize || (isMedium ? 16 : 14),
194
+ height: iconSize || (isMedium ? 16 : 14),
195
+ }}
196
+ />
197
+ </IconHoverBox>
198
+ </Box>
199
+ );
200
+ }
@@ -0,0 +1,155 @@
1
+ import { Modal, ModalProps } from '@mui/base/Modal';
2
+ import { Error } from '@dodoex/icons';
3
+ import clsx from 'clsx';
4
+ import React from 'react';
5
+ import { Box, BoxProps, ButtonBase, useTheme } from '@dodoex/components';
6
+
7
+ export function DialogTitle({
8
+ children,
9
+ center,
10
+ onClose,
11
+ sx,
12
+ }: React.PropsWithChildren<{
13
+ center?: boolean;
14
+ onClose?: () => void;
15
+ sx?: BoxProps['sx'];
16
+ }>) {
17
+ return (
18
+ <Box
19
+ sx={{
20
+ position: 'relative',
21
+ display: 'flex',
22
+ alignItems: 'center',
23
+ p: 20,
24
+ justifyContent: center ? 'center' : 'flex-start',
25
+ ...sx,
26
+ }}
27
+ >
28
+ <Box
29
+ component="h5"
30
+ sx={{
31
+ typography: 'h5',
32
+ margin: 0,
33
+ padding: 0,
34
+ }}
35
+ >
36
+ {children}
37
+ </Box>
38
+ {!!onClose && (
39
+ <Box
40
+ component={ButtonBase}
41
+ onClick={() => onClose()}
42
+ sx={{
43
+ position: 'absolute',
44
+ top: 20,
45
+ right: 20,
46
+ color: 'text.secondary',
47
+ '&:hover': {
48
+ color: 'text.primary',
49
+ },
50
+ }}
51
+ >
52
+ <Box
53
+ component={Error}
54
+ sx={{
55
+ width: 24,
56
+ height: 24,
57
+ }}
58
+ />
59
+ </Box>
60
+ )}
61
+ </Box>
62
+ );
63
+ }
64
+
65
+ const Backdrop = React.forwardRef<
66
+ HTMLDivElement,
67
+ { open?: boolean; className: string }
68
+ >((props, ref) => {
69
+ const { open, className, ...other } = props;
70
+ return (
71
+ <Box
72
+ className={clsx({ 'MuiBackdrop-open': open }, className)}
73
+ sx={{
74
+ position: 'fixed',
75
+ inset: 0,
76
+ zIndex: -1,
77
+ backgroundColor: 'background.backdrop',
78
+ '-webkitTapHighlightColor': 'transparent',
79
+ }}
80
+ ref={ref}
81
+ {...other}
82
+ />
83
+ );
84
+ });
85
+ Backdrop.displayName = 'Backdrop';
86
+
87
+ export function DialogBase({ className, slots, ...props }: ModalProps) {
88
+ return (
89
+ <Modal
90
+ className={clsx('fixed z-modal inset-0 flex', className)}
91
+ slots={{
92
+ backdrop: Backdrop,
93
+ ...slots,
94
+ }}
95
+ {...props}
96
+ />
97
+ );
98
+ }
99
+
100
+ export default function Dialog({
101
+ children,
102
+ sx,
103
+ bodySx,
104
+ slots,
105
+ width,
106
+ ...props
107
+ }: Omit<ModalProps, 'children'> & {
108
+ children: React.ReactNode;
109
+ sx?: BoxProps['sx'];
110
+ bodySx?: BoxProps['sx'];
111
+ width?: number;
112
+ }) {
113
+ const theme = useTheme();
114
+ return (
115
+ <Box
116
+ component={Modal}
117
+ slots={{
118
+ backdrop: Backdrop,
119
+ ...slots,
120
+ }}
121
+ sx={{
122
+ position: 'fixed',
123
+ inset: 0,
124
+ display: 'flex',
125
+ alignItems: 'flex-end',
126
+ [theme.breakpoints.up('tablet')]: {
127
+ alignItems: 'center',
128
+ justifyContent: 'center',
129
+ },
130
+ zIndex: (theme.zIndex as any)?.modal ?? 100,
131
+ ...sx,
132
+ }}
133
+ {...props}
134
+ >
135
+ <Box
136
+ sx={{
137
+ display: 'flex',
138
+ flexDirection: 'column',
139
+ backgroundColor: 'background.paper',
140
+ borderTopWidth: 1,
141
+ maxHeight: '80vh',
142
+ borderRadius: theme.spacing(6, 6, 0, 0),
143
+ [theme.breakpoints.up('tablet')]: {
144
+ minWidth: width ?? 420,
145
+ width,
146
+ borderRadius: 12,
147
+ },
148
+ ...bodySx,
149
+ }}
150
+ >
151
+ {children}
152
+ </Box>
153
+ </Box>
154
+ );
155
+ }
@@ -0,0 +1,165 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import React, { useCallback, useEffect, useState } from 'react';
3
+ import Identicon from 'identicon.js';
4
+ import { Box, BoxProps } from '@dodoex/components';
5
+ import { useWalletConnectContext } from '../WalletConnectProvider';
6
+
7
+ export interface TokenInfo {
8
+ readonly chainId: number;
9
+ readonly address: string;
10
+ readonly symbol?: string;
11
+ readonly name?: string;
12
+ readonly decimals?: number;
13
+ readonly logoURI?: string;
14
+ }
15
+
16
+ export interface TokenLogoProps {
17
+ address?: string;
18
+ logoURI?: string;
19
+ width?: number;
20
+ height?: number;
21
+ marginRight?: number;
22
+ url?: string;
23
+ zIndex?: number;
24
+ sx?: BoxProps['sx'];
25
+ chainId?: number;
26
+ noShowChain?: boolean;
27
+ noBorder?: boolean;
28
+ chainSize?: number;
29
+ logoOffset?: number;
30
+ }
31
+
32
+ export default function TokenLogo({
33
+ width = 24,
34
+ height = 24,
35
+ marginRight = 8,
36
+ zIndex,
37
+ address,
38
+ logoURI,
39
+ sx,
40
+ chainId,
41
+ noBorder,
42
+ chainSize = 12,
43
+ logoOffset: logoOffsetProps,
44
+ }: TokenLogoProps): React.ReactElement {
45
+ const [loaded, setLoaded] = useState(false);
46
+ const [defaultUrl, setDefaultUrl] = useState('');
47
+ const [error, setError] = useState(false);
48
+ const onLoad = useCallback(() => setLoaded(true), []);
49
+ const symbol = '';
50
+ const initial = symbol?.charAt(0).toUpperCase();
51
+
52
+ const { getTokenLogoUrl } = useWalletConnectContext();
53
+ const logoUrl =
54
+ getTokenLogoUrl?.({
55
+ chainId,
56
+ address,
57
+ width,
58
+ height,
59
+ }) || logoURI;
60
+
61
+ let logoOffset = logoOffsetProps;
62
+ if (!logoOffset) {
63
+ logoOffset = chainSize / 2 < 8 ? chainSize / 2 : chainSize - 8;
64
+ }
65
+
66
+ useEffect(() => {
67
+ setError(false);
68
+ }, [address, logoUrl]);
69
+
70
+ useEffect(() => {
71
+ try {
72
+ let addr = address;
73
+ if (addr && addr.length < 15) {
74
+ addr = addr.padEnd(15, '0');
75
+ }
76
+ if (addr) {
77
+ const data = new Identicon(addr, {
78
+ size: width,
79
+ format: 'svg',
80
+ margin: 0.2,
81
+ background: [255, 234, 4, 255],
82
+ }).toString();
83
+ setDefaultUrl(`data:image/svg+xml;base64,${data}`);
84
+ }
85
+ } catch (err) {
86
+ // address is empty
87
+ console.error('generate Identicon error: ', err);
88
+ }
89
+ }, [address, width]);
90
+
91
+ const showChain = false;
92
+
93
+ const logo = (
94
+ <Box
95
+ sx={{
96
+ position: 'relative',
97
+ display: 'inline-flex',
98
+ alignItems: 'center',
99
+ justifyContent: 'center',
100
+ width,
101
+ height,
102
+ borderRadius: '50%',
103
+ ...(noBorder
104
+ ? {}
105
+ : {
106
+ border: 'solid 1px',
107
+ borderColor: 'border.main',
108
+ }),
109
+ flexShrink: 0,
110
+ ...(showChain
111
+ ? {}
112
+ : {
113
+ marginRight,
114
+ zIndex,
115
+ ...sx,
116
+ }),
117
+ }}
118
+ >
119
+ {!loaded && (
120
+ <Box
121
+ sx={{
122
+ typography: 'ht',
123
+ height: '100%',
124
+ width: '100%',
125
+ borderRadius: '50%',
126
+ border: 'transparent 2px solid',
127
+ borderColor: 'text.primary',
128
+ color: 'text.primary',
129
+
130
+ display: 'flex',
131
+ alignItems: 'center',
132
+ justifyContent: 'center',
133
+ }}
134
+ >
135
+ {initial}
136
+ </Box>
137
+ )}
138
+ <Box
139
+ component="img"
140
+ src={!logoUrl || error ? defaultUrl : logoUrl}
141
+ onLoad={onLoad}
142
+ onError={(e: any) => {
143
+ const target = e.target as HTMLImageElement;
144
+ if (address && defaultUrl) {
145
+ setError(true);
146
+ }
147
+ target.onerror = null;
148
+ }}
149
+ sx={{
150
+ position: 'absolute',
151
+ top: '0',
152
+ bottom: '0',
153
+ left: '0',
154
+ right: '0',
155
+ borderRadius: '50%',
156
+ overflow: 'hidden',
157
+ width: '100%',
158
+ height: '100%',
159
+ }}
160
+ />
161
+ </Box>
162
+ );
163
+
164
+ return logo;
165
+ }
@@ -0,0 +1,113 @@
1
+ import { alpha, Box, RotatingIcon, useTheme } from '@dodoex/components';
2
+ import { WalletType } from '@dodoex/wallet-web3';
3
+ import { Trans } from '@lingui/macro';
4
+ import { WalletItem } from '../hooks/useConnectWalet';
5
+
6
+ export default function WalletTag({
7
+ loading,
8
+ wallet,
9
+ isChecked,
10
+ installed,
11
+ }: {
12
+ loading: boolean;
13
+ wallet: WalletItem;
14
+ isChecked: boolean;
15
+ installed: boolean;
16
+ }) {
17
+ const theme = useTheme();
18
+ const greenColor = theme.palette.success.main;
19
+ const connectedColor = theme.palette.mode === 'light' ? '#EB8D27' : '#FFE804';
20
+ const connectedColorBg = alpha('#FFE804', 0.1);
21
+ if (loading) {
22
+ return (
23
+ <Box
24
+ sx={{
25
+ display: 'flex',
26
+ alignItems: 'center',
27
+ gap: 4,
28
+ p: theme.spacing(4, 8),
29
+ borderRadius: 6,
30
+ typography: 'body2',
31
+ backgroundColor: alpha(theme.palette.text.primary, 0.1),
32
+ color: 'text.secondary',
33
+ }}
34
+ >
35
+ <RotatingIcon
36
+ sx={{
37
+ width: 18,
38
+ height: 18,
39
+ color: 'text.secondary',
40
+ }}
41
+ />
42
+ <Trans>Connecting</Trans>··
43
+ </Box>
44
+ );
45
+ }
46
+
47
+ if (isChecked) {
48
+ return (
49
+ <Box
50
+ sx={{
51
+ p: theme.spacing(4, 8),
52
+ borderRadius: 6,
53
+ typography: 'body2',
54
+ backgroundColor: connectedColorBg,
55
+ color: connectedColor,
56
+ }}
57
+ >
58
+ <Trans>Connected</Trans>
59
+ </Box>
60
+ );
61
+ }
62
+
63
+ if (wallet.isLastConnection) {
64
+ return (
65
+ <Box
66
+ sx={{
67
+ p: theme.spacing(4, 8),
68
+ borderRadius: 6,
69
+ typography: 'body2',
70
+ backgroundColor: alpha(theme.palette.text.primary, 0.1),
71
+ color: 'text.secondary',
72
+ }}
73
+ >
74
+ <Trans>Last connection</Trans>
75
+ </Box>
76
+ );
77
+ }
78
+
79
+ if (wallet.currentType === WalletType.SocialLogin) {
80
+ return (
81
+ <Box
82
+ sx={{
83
+ mt: 4,
84
+ padding: theme.spacing(4, 8),
85
+ borderRadius: 6,
86
+ typography: 'body2',
87
+ backgroundColor: alpha(greenColor, 0.1),
88
+ color: greenColor,
89
+ }}
90
+ >
91
+ New
92
+ </Box>
93
+ );
94
+ }
95
+
96
+ if (installed) {
97
+ return (
98
+ <Box
99
+ sx={{
100
+ p: theme.spacing(4, 8),
101
+ borderRadius: 6,
102
+ typography: 'body2',
103
+ backgroundColor: alpha(theme.palette.text.primary, 0.1),
104
+ color: 'text.secondary',
105
+ }}
106
+ >
107
+ <Trans>Installed Wallet</Trans>
108
+ </Box>
109
+ );
110
+ }
111
+
112
+ return null;
113
+ }
@@ -0,0 +1,22 @@
1
+ const TOKEN_FIAT_PRICE_LIST = 'DODO_WIDGET_TOKEN_FIAT_PRICE_LIST';
2
+ interface FiatPriceCacheList {
3
+ [k: string]: number;
4
+ }
5
+ export function setTokenFiatPriceList(value: FiatPriceCacheList) {
6
+ const oldList = getTokenFiatPriceList();
7
+ const newList = {
8
+ ...oldList,
9
+ ...value,
10
+ };
11
+ localStorage.setItem(TOKEN_FIAT_PRICE_LIST, JSON.stringify(newList));
12
+ }
13
+ export function getTokenFiatPriceList(): FiatPriceCacheList {
14
+ const storage = localStorage.getItem(TOKEN_FIAT_PRICE_LIST);
15
+ try {
16
+ if (!storage) return {};
17
+ return JSON.parse(storage);
18
+ } catch (e) {
19
+ console.error(e);
20
+ return {};
21
+ }
22
+ }