@dodoex/wallet-web3-react 0.2.0 → 0.3.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 (40) hide show
  1. package/babel.config.js +9 -9
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.js +1 -1
  4. package/lingui.config.ts +13 -13
  5. package/package.json +91 -76
  6. package/rollup.config.mjs +100 -100
  7. package/src/ClientProvider.tsx +17 -15
  8. package/src/LangProvider.tsx +36 -34
  9. package/src/WalletConnect/AccountPage.tsx +496 -494
  10. package/src/WalletConnect/ActivityList.tsx +606 -604
  11. package/src/WalletConnect/ConnectAlchemy/index.tsx +248 -246
  12. package/src/WalletConnect/ConnectAlchemy/useConnectAlchemy.ts +105 -105
  13. package/src/WalletConnect/ConnectDialog.tsx +35 -33
  14. package/src/WalletConnect/ConnectLedger/ErrorDialog.tsx +61 -61
  15. package/src/WalletConnect/ConnectLedger/LockedDialog.tsx +54 -54
  16. package/src/WalletConnect/ConnectLedger/helper.ts +14 -14
  17. package/src/WalletConnect/ConnectLedger/index.tsx +2 -0
  18. package/src/WalletConnect/ConnectPage.tsx +508 -506
  19. package/src/WalletConnect/HasBalanceTokenList.tsx +202 -200
  20. package/src/WalletConnect/ReceiveTokenPage.tsx +145 -143
  21. package/src/WalletConnect/SendTokenPage.tsx +251 -249
  22. package/src/WalletConnect/WalletDialog.tsx +80 -78
  23. package/src/WalletConnectProvider.tsx +57 -55
  24. package/src/components/AddressWithLinkAndCopy.tsx +202 -200
  25. package/src/components/Dialog.tsx +158 -156
  26. package/src/components/TokenLogo.tsx +167 -165
  27. package/src/components/WalletTag.tsx +117 -115
  28. package/src/constants/localstorage.ts +24 -22
  29. package/src/hooks/useConnectWallet.ts +150 -146
  30. package/src/hooks/useFetchFiatPrice.ts +53 -51
  31. package/src/hooks/useFetchTokensBalance.ts +53 -51
  32. package/src/hooks/useHasBalanceTokenList.ts +95 -93
  33. package/src/hooks/useTransactionList.ts +89 -87
  34. package/src/index.tsx +7 -7
  35. package/src/locales/en.po +51 -51
  36. package/src/locales/zh.po +51 -51
  37. package/src/utils/formatter.ts +102 -102
  38. package/src/utils/time.ts +21 -21
  39. package/src/utils/utils.ts +8 -8
  40. package/tsconfig.json +23 -23
@@ -1,156 +1,158 @@
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
- width: '100%',
144
- [theme.breakpoints.up('tablet')]: {
145
- minWidth: width ?? 420,
146
- width,
147
- borderRadius: 12,
148
- },
149
- ...bodySx,
150
- }}
151
- >
152
- {children}
153
- </Box>
154
- </Box>
155
- );
156
- }
1
+ 'use client';
2
+
3
+ import { Modal, ModalProps } from '@mui/base/Modal';
4
+ import { Error } from '@dodoex/icons';
5
+ import clsx from 'clsx';
6
+ import React from 'react';
7
+ import { Box, BoxProps, ButtonBase, useTheme } from '@dodoex/components';
8
+
9
+ export function DialogTitle({
10
+ children,
11
+ center,
12
+ onClose,
13
+ sx,
14
+ }: React.PropsWithChildren<{
15
+ center?: boolean;
16
+ onClose?: () => void;
17
+ sx?: BoxProps['sx'];
18
+ }>) {
19
+ return (
20
+ <Box
21
+ sx={{
22
+ position: 'relative',
23
+ display: 'flex',
24
+ alignItems: 'center',
25
+ p: 20,
26
+ justifyContent: center ? 'center' : 'flex-start',
27
+ ...sx,
28
+ }}
29
+ >
30
+ <Box
31
+ component="h5"
32
+ sx={{
33
+ typography: 'h5',
34
+ margin: 0,
35
+ padding: 0,
36
+ }}
37
+ >
38
+ {children}
39
+ </Box>
40
+ {!!onClose && (
41
+ <Box
42
+ component={ButtonBase}
43
+ onClick={() => onClose()}
44
+ sx={{
45
+ position: 'absolute',
46
+ top: 20,
47
+ right: 20,
48
+ color: 'text.secondary',
49
+ '&:hover': {
50
+ color: 'text.primary',
51
+ },
52
+ }}
53
+ >
54
+ <Box
55
+ component={Error}
56
+ sx={{
57
+ width: 24,
58
+ height: 24,
59
+ }}
60
+ />
61
+ </Box>
62
+ )}
63
+ </Box>
64
+ );
65
+ }
66
+
67
+ const Backdrop = React.forwardRef<
68
+ HTMLDivElement,
69
+ { open?: boolean; className: string }
70
+ >((props, ref) => {
71
+ const { open, className, ...other } = props;
72
+ return (
73
+ <Box
74
+ className={clsx({ 'MuiBackdrop-open': open }, className)}
75
+ sx={{
76
+ position: 'fixed',
77
+ inset: 0,
78
+ zIndex: -1,
79
+ backgroundColor: 'background.backdrop',
80
+ '-webkitTapHighlightColor': 'transparent',
81
+ }}
82
+ ref={ref}
83
+ {...other}
84
+ />
85
+ );
86
+ });
87
+ Backdrop.displayName = 'Backdrop';
88
+
89
+ export function DialogBase({ className, slots, ...props }: ModalProps) {
90
+ return (
91
+ <Modal
92
+ className={clsx('fixed z-modal inset-0 flex', className)}
93
+ slots={{
94
+ backdrop: Backdrop,
95
+ ...slots,
96
+ }}
97
+ {...props}
98
+ />
99
+ );
100
+ }
101
+
102
+ export default function Dialog({
103
+ children,
104
+ sx,
105
+ bodySx,
106
+ slots,
107
+ width,
108
+ ...props
109
+ }: Omit<ModalProps, 'children'> & {
110
+ children: React.ReactNode;
111
+ sx?: BoxProps['sx'];
112
+ bodySx?: BoxProps['sx'];
113
+ width?: number;
114
+ }) {
115
+ const theme = useTheme();
116
+ return (
117
+ <Box
118
+ component={Modal}
119
+ slots={{
120
+ backdrop: Backdrop,
121
+ ...slots,
122
+ }}
123
+ sx={{
124
+ position: 'fixed',
125
+ inset: 0,
126
+ display: 'flex',
127
+ alignItems: 'flex-end',
128
+ [theme.breakpoints.up('tablet')]: {
129
+ alignItems: 'center',
130
+ justifyContent: 'center',
131
+ },
132
+ zIndex: (theme.zIndex as any)?.modal ?? 100,
133
+ ...sx,
134
+ }}
135
+ {...props}
136
+ >
137
+ <Box
138
+ sx={{
139
+ display: 'flex',
140
+ flexDirection: 'column',
141
+ backgroundColor: 'background.paper',
142
+ borderTopWidth: 1,
143
+ maxHeight: '80vh',
144
+ borderRadius: theme.spacing(6, 6, 0, 0),
145
+ width: '100%',
146
+ [theme.breakpoints.up('tablet')]: {
147
+ minWidth: width ?? 420,
148
+ width,
149
+ borderRadius: 12,
150
+ },
151
+ ...bodySx,
152
+ }}
153
+ >
154
+ {children}
155
+ </Box>
156
+ </Box>
157
+ );
158
+ }
@@ -1,165 +1,167 @@
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
- }
1
+ 'use client';
2
+
3
+ /* eslint-disable @typescript-eslint/no-explicit-any */
4
+ import React, { useCallback, useEffect, useState } from 'react';
5
+ import Identicon from 'identicon.js';
6
+ import { Box, BoxProps } from '@dodoex/components';
7
+ import { useWalletConnectContext } from '../WalletConnectProvider';
8
+
9
+ export interface TokenInfo {
10
+ readonly chainId: number;
11
+ readonly address: string;
12
+ readonly symbol?: string;
13
+ readonly name?: string;
14
+ readonly decimals?: number;
15
+ readonly logoURI?: string;
16
+ }
17
+
18
+ export interface TokenLogoProps {
19
+ address?: string;
20
+ logoURI?: string;
21
+ width?: number;
22
+ height?: number;
23
+ marginRight?: number;
24
+ url?: string;
25
+ zIndex?: number;
26
+ sx?: BoxProps['sx'];
27
+ chainId?: number;
28
+ noShowChain?: boolean;
29
+ noBorder?: boolean;
30
+ chainSize?: number;
31
+ logoOffset?: number;
32
+ }
33
+
34
+ export default function TokenLogo({
35
+ width = 24,
36
+ height = 24,
37
+ marginRight = 8,
38
+ zIndex,
39
+ address,
40
+ logoURI,
41
+ sx,
42
+ chainId,
43
+ noBorder,
44
+ chainSize = 12,
45
+ logoOffset: logoOffsetProps,
46
+ }: TokenLogoProps): React.ReactElement {
47
+ const [loaded, setLoaded] = useState(false);
48
+ const [defaultUrl, setDefaultUrl] = useState('');
49
+ const [error, setError] = useState(false);
50
+ const onLoad = useCallback(() => setLoaded(true), []);
51
+ const symbol = '';
52
+ const initial = symbol?.charAt(0).toUpperCase();
53
+
54
+ const { getTokenLogoUrl } = useWalletConnectContext();
55
+ const logoUrl =
56
+ getTokenLogoUrl?.({
57
+ chainId,
58
+ address,
59
+ width,
60
+ height,
61
+ }) || logoURI;
62
+
63
+ let logoOffset = logoOffsetProps;
64
+ if (!logoOffset) {
65
+ logoOffset = chainSize / 2 < 8 ? chainSize / 2 : chainSize - 8;
66
+ }
67
+
68
+ useEffect(() => {
69
+ setError(false);
70
+ }, [address, logoUrl]);
71
+
72
+ useEffect(() => {
73
+ try {
74
+ let addr = address;
75
+ if (addr && addr.length < 15) {
76
+ addr = addr.padEnd(15, '0');
77
+ }
78
+ if (addr) {
79
+ const data = new Identicon(addr, {
80
+ size: width,
81
+ format: 'svg',
82
+ margin: 0.2,
83
+ background: [255, 234, 4, 255],
84
+ }).toString();
85
+ setDefaultUrl(`data:image/svg+xml;base64,${data}`);
86
+ }
87
+ } catch (err) {
88
+ // address is empty
89
+ console.error('generate Identicon error: ', err);
90
+ }
91
+ }, [address, width]);
92
+
93
+ const showChain = false;
94
+
95
+ const logo = (
96
+ <Box
97
+ sx={{
98
+ position: 'relative',
99
+ display: 'inline-flex',
100
+ alignItems: 'center',
101
+ justifyContent: 'center',
102
+ width,
103
+ height,
104
+ borderRadius: '50%',
105
+ ...(noBorder
106
+ ? {}
107
+ : {
108
+ border: 'solid 1px',
109
+ borderColor: 'border.main',
110
+ }),
111
+ flexShrink: 0,
112
+ ...(showChain
113
+ ? {}
114
+ : {
115
+ marginRight,
116
+ zIndex,
117
+ ...sx,
118
+ }),
119
+ }}
120
+ >
121
+ {!loaded && (
122
+ <Box
123
+ sx={{
124
+ typography: 'ht',
125
+ height: '100%',
126
+ width: '100%',
127
+ borderRadius: '50%',
128
+ border: 'transparent 2px solid',
129
+ borderColor: 'text.primary',
130
+ color: 'text.primary',
131
+
132
+ display: 'flex',
133
+ alignItems: 'center',
134
+ justifyContent: 'center',
135
+ }}
136
+ >
137
+ {initial}
138
+ </Box>
139
+ )}
140
+ <Box
141
+ component="img"
142
+ src={!logoUrl || error ? defaultUrl : logoUrl}
143
+ onLoad={onLoad}
144
+ onError={(e: any) => {
145
+ const target = e.target as HTMLImageElement;
146
+ if (address && defaultUrl) {
147
+ setError(true);
148
+ }
149
+ target.onerror = null;
150
+ }}
151
+ sx={{
152
+ position: 'absolute',
153
+ top: '0',
154
+ bottom: '0',
155
+ left: '0',
156
+ right: '0',
157
+ borderRadius: '50%',
158
+ overflow: 'hidden',
159
+ width: '100%',
160
+ height: '100%',
161
+ }}
162
+ />
163
+ </Box>
164
+ );
165
+
166
+ return logo;
167
+ }