1
- import React from "react" ;
1
+ import React , { useEffect , useRef } from "react" ;
2
2
import { ThirdwebSDK } from "@3rdweb/sdk" ;
3
- import { Text , Button , Flex , Icon , Tooltip , useClipboard , useToast } from "@chakra-ui/react" ;
4
- import { IoWalletOutline } from "react-icons/io5" ;
5
- import { useAccount } from "wagmi" ;
3
+ import {
4
+ Text ,
5
+ Button ,
6
+ Flex ,
7
+ Icon ,
8
+ Tooltip ,
9
+ useClipboard ,
10
+ useToast ,
11
+ Modal ,
12
+ ModalCloseButton ,
13
+ ModalContent ,
14
+ ModalOverlay ,
15
+ useDisclosure ,
16
+ ModalBody ,
17
+ ButtonGroup ,
18
+ IconButton ,
19
+ ModalHeader ,
20
+ Heading ,
21
+ Stack ,
22
+ } from "@chakra-ui/react" ;
23
+ import { IoCopy , IoWalletOutline } from "react-icons/io5" ;
24
+ import { useAccount , useBalance , useNetwork , useProvider } from "wagmi" ;
6
25
import { RiMoneyDollarCircleLine } from "react-icons/ri" ;
7
26
import { isAddressZero , useTokenModule } from "./tokenHooks" ;
8
- import { useEffect } from "react" ;
9
27
import { useQuery } from "react-query" ;
28
+ import { ethers } from "ethers" ;
29
+ import { ChainIDToNativeSymbol } from "./commonRPCUrls" ;
10
30
11
31
interface IConnectedWallet {
12
32
sdk ? : ThirdwebSDK ;
13
33
tokenAddress ?: string ;
14
- showBalance ?: boolean ;
15
34
}
16
35
17
- export const ConnectedWallet : React . FC < IConnectedWallet > = ( { sdk, tokenAddress, showBalance } ) => {
36
+ function shortenAddress ( str : string ) {
37
+ return `${ str . substring ( 0 , 6 ) } ...${ str . substring ( str . length - 4 ) } ` ;
38
+ }
39
+
40
+ export const ConnectedWallet : React . FC < IConnectedWallet > = ( { sdk, tokenAddress } ) => {
18
41
const toast = useToast ( ) ;
42
+ const baseProvider = useProvider ( ) ;
43
+ const { isOpen, onOpen, onClose } = useDisclosure ( { defaultIsOpen : false } ) ;
19
44
const [ { data } , disconnect ] = useAccount ( ) ;
45
+ const [ { data : network } ] = useNetwork ( ) ;
20
46
const { onCopy } = useClipboard ( data ?. address || "" ) ;
21
47
const tokenModule = useTokenModule ( sdk , tokenAddress ) ;
22
48
@@ -30,6 +56,16 @@ export const ConnectedWallet: React.FC<IConnectedWallet> = ({ sdk, tokenAddress,
30
56
isAddressZero ( tokenAddress ) ||
31
57
tokenAddress . toLowerCase ( ) === otherAddressZero . toLowerCase ( )
32
58
) {
59
+ /*
60
+ const balance = await baseProvider.getBalance(data?.address);
61
+
62
+ return {
63
+ value: balance,
64
+ displayValue: ethers.utils.formatEther(balance).slice(0, 6),
65
+ symbol: ChainIDToNativeSymbol[network?.chain?.id || 0],
66
+ };
67
+ */
68
+
33
69
return null ;
34
70
}
35
71
@@ -38,7 +74,25 @@ export const ConnectedWallet: React.FC<IConnectedWallet> = ({ sdk, tokenAddress,
38
74
{
39
75
enabled : ! ! data ?. address && ! ! tokenModule ,
40
76
}
41
- )
77
+ ) ;
78
+
79
+ const switchWallet = async ( ) => {
80
+ const provider = data ?. connector ?. getProvider ( ) ;
81
+ if ( ! provider ?. isMetaMask || ! provider . request ) return ;
82
+
83
+ await provider . request ( {
84
+ method : "wallet_requestPermissions" ,
85
+ params : [ { eth_accounts : { } } ] ,
86
+ } ) ;
87
+
88
+ onClose ( ) ;
89
+ }
90
+
91
+
92
+ const disconnectWallet = ( ) => {
93
+ disconnect ( ) ;
94
+ onClose ( ) ;
95
+ }
42
96
43
97
const copyAddress = ( ) => {
44
98
onCopy ( ) ;
@@ -50,42 +104,106 @@ export const ConnectedWallet: React.FC<IConnectedWallet> = ({ sdk, tokenAddress,
50
104
} )
51
105
}
52
106
53
- if ( ! data ?. address ) {
54
- return null ;
55
- }
56
-
57
107
return (
58
108
< Flex align = "center" gap = { 2 } >
59
- < Tooltip label = "Copy address" hasArrow >
60
- < Button
61
- variant = "outline"
62
- size = "sm"
63
- color = "gray.800"
64
- leftIcon = { < Icon as = { IoWalletOutline } color = "gray.500" boxSize = { 4 } /> }
65
- onClick = { copyAddress }
66
- >
67
- { data ?. address ?. slice ( 0 , 6 ) } ...{ data ?. address ?. slice ( - 4 ) }
68
- </ Button >
69
- </ Tooltip >
70
- { balance && showBalance && (
71
- < Flex
72
- height = "32px"
73
- px = "10px"
74
- borderRadius = "md"
75
- borderColor = "gray.200"
76
- borderWidth = "1px"
77
- align = "center"
78
- gap = { 1 }
79
- >
80
- < Icon as = { RiMoneyDollarCircleLine } boxSize = { 4 } color = "gray.500" />
81
- < Text fontSize = "sm" fontWeight = "semibold" >
82
- { balance ?. displayValue } { balance ?. symbol }
83
- </ Text >
84
- </ Flex >
109
+ { data ?. address && (
110
+ < >
111
+ < Button
112
+ variant = "outline"
113
+ size = "sm"
114
+ color = "gray.800"
115
+ leftIcon = { < Icon as = { IoWalletOutline } color = "gray.500" boxSize = { 4 } /> }
116
+ onClick = { onOpen }
117
+ >
118
+ { shortenAddress ( data . address ) }
119
+ </ Button >
120
+ { balance && (
121
+ < Stack
122
+ direction = "row"
123
+ display = { { base : "none" , md : "flex" } }
124
+ height = "32px"
125
+ px = "10px"
126
+ borderRadius = "md"
127
+ borderColor = "gray.200"
128
+ borderWidth = "1px"
129
+ align = "center"
130
+ >
131
+ < Icon as = { RiMoneyDollarCircleLine } boxSize = { 4 } color = "gray.500" />
132
+ < Text fontSize = "sm" fontWeight = "semibold" whiteSpace = "nowrap" >
133
+ { balance ?. displayValue } { balance ?. symbol }
134
+ </ Text >
135
+ </ Stack >
136
+ ) }
137
+ </ >
85
138
) }
86
- < Button colorScheme = "red" size = "sm" onClick = { disconnect } >
87
- Disconnect
88
- </ Button >
139
+
140
+ < Modal isOpen = { isOpen } onClose = { onClose } isCentered >
141
+ < ModalOverlay />
142
+ < ModalContent pb = { 4 } bg = "gray.50" >
143
+ < ModalCloseButton />
144
+
145
+ < ModalHeader >
146
+ < Heading size = "label.lg" > Account Details</ Heading >
147
+ </ ModalHeader >
148
+
149
+ < ModalBody >
150
+ < Flex direction = "column" gap = { 5 } >
151
+ < Stack >
152
+ < Text size = "label.md" display = { { base : "flex" , md : "none" } } > Connected Wallet</ Text >
153
+ < ButtonGroup isAttached >
154
+ < IconButton
155
+ onClick = { copyAddress }
156
+ mr = "-px"
157
+ borderRight = "none"
158
+ aria-label = "Add to friends"
159
+ variant = "outline"
160
+ size = "sm"
161
+ icon = { < Icon as = { IoCopy } /> }
162
+ />
163
+ < Button size = "sm" variant = "outline" width = "120px" onClick = { copyAddress } >
164
+ { shortenAddress ( data ?. address || "" ) }
165
+ </ Button >
166
+ { data ?. connector ?. getProvider ( ) ?. isMetaMask && (
167
+ < Button size = "sm" onClick = { switchWallet } >
168
+ Switch
169
+ </ Button >
170
+ ) }
171
+ < Button
172
+ onClick = { disconnectWallet }
173
+ colorScheme = "red"
174
+ size = "sm"
175
+ >
176
+ Disconnect
177
+ </ Button >
178
+ </ ButtonGroup >
179
+ </ Stack >
180
+
181
+ { balance && (
182
+ < Stack display = { { base : "flex" , md : "none" } } >
183
+ < Text size = "label.md" > Balance</ Text >
184
+ < Flex >
185
+ < Flex
186
+ direction = "row"
187
+ height = "32px"
188
+ px = "10px"
189
+ borderRadius = "md"
190
+ borderColor = "gray.200"
191
+ borderWidth = "1px"
192
+ align = "center"
193
+ gap = { 1 }
194
+ >
195
+ < Icon as = { RiMoneyDollarCircleLine } boxSize = { 4 } color = "gray.500" />
196
+ < Text fontSize = "sm" fontWeight = "semibold" >
197
+ { balance ?. displayValue } { balance ?. symbol }
198
+ </ Text >
199
+ </ Flex >
200
+ </ Flex >
201
+ </ Stack >
202
+ ) }
203
+ </ Flex >
204
+ </ ModalBody >
205
+ </ ModalContent >
206
+ </ Modal >
89
207
</ Flex >
90
208
)
91
209
}
0 commit comments