1414 * - selectedAddress: Currently selected address for transactions
1515 * - isSearching: Loading state indicator
1616 */
17- ' use client' ;
17+ " use client" ;
1818
19- import { createClientUPProvider } from "@lukso/up-provider" ;
19+ import {
20+ createClientUPProvider ,
21+ type UPClientProvider ,
22+ } from "@lukso/up-provider" ;
2023import { createWalletClient , custom } from "viem" ;
2124import { lukso , luksoTestnet } from "viem/chains" ;
22- import { createContext , useContext , useEffect , useState , ReactNode } from "react" ;
25+ import {
26+ createContext ,
27+ useContext ,
28+ useEffect ,
29+ useState ,
30+ type ReactNode ,
31+ useMemo ,
32+ } from "react" ;
2333
2434interface UpProviderContext {
25- provider : any ;
26- client : any ;
35+ provider : UPClientProvider | null ;
36+ client : ReturnType < typeof createWalletClient > | null ;
2737 chainId : number ;
2838 accounts : Array < `0x${string } `> ;
2939 contextAccounts : Array < `0x${string } `> ;
@@ -36,7 +46,8 @@ interface UpProviderContext {
3646
3747const UpContext = createContext < UpProviderContext | undefined > ( undefined ) ;
3848
39- const provider = typeof window !== "undefined" ? createClientUPProvider ( ) : null ;
49+ const provider =
50+ typeof window !== "undefined" ? createClientUPProvider ( ) : null ;
4051
4152export function useUpProvider ( ) {
4253 const context = useContext ( UpContext ) ;
@@ -53,20 +64,26 @@ interface UpProviderProps {
5364export function UpProvider ( { children } : UpProviderProps ) {
5465 const [ chainId , setChainId ] = useState < number > ( 0 ) ;
5566 const [ accounts , setAccounts ] = useState < Array < `0x${string } `> > ( [ ] ) ;
56- const [ contextAccounts , setContextAccounts ] = useState < Array < `0x${string } `> > ( [ ] ) ;
67+ const [ contextAccounts , setContextAccounts ] = useState < Array < `0x${string } `> > (
68+ [ ]
69+ ) ;
5770 const [ walletConnected , setWalletConnected ] = useState ( false ) ;
58- const [ selectedAddress , setSelectedAddress ] = useState < `0x${string } ` | null > ( null ) ;
71+ const [ selectedAddress , setSelectedAddress ] = useState < `0x${string } ` | null > (
72+ null
73+ ) ;
5974 const [ isSearching , setIsSearching ] = useState ( false ) ;
75+ const [ account ] = accounts ?? [ ] ;
76+ const [ contextAccount ] = contextAccounts ?? [ ] ;
6077
61- const client = ( ( ) => {
78+ const client = useMemo ( ( ) => {
6279 if ( provider && chainId ) {
6380 return createWalletClient ( {
6481 chain : chainId === 42 ? lukso : luksoTestnet ,
6582 transport : custom ( provider ) ,
6683 } ) ;
6784 }
6885 return null ;
69- } ) ( ) ;
86+ } , [ chainId ] ) ;
7087
7188 useEffect ( ( ) => {
7289 let mounted = true ;
@@ -75,18 +92,21 @@ export function UpProvider({ children }: UpProviderProps) {
7592 try {
7693 if ( ! client || ! provider ) return ;
7794
78- const _chainId = ( await client . getChainId ( ) ) as number ;
95+ const _accounts = ( await provider . request (
96+ "eth_accounts" ,
97+ [ ]
98+ ) ) as Array < `0x${string } `> ;
7999 if ( ! mounted ) return ;
80- setChainId ( _chainId ) ;
100+ setAccounts ( _accounts ) ;
81101
82- const _accounts = ( await client . getAddresses ( ) ) as Array < `0x${ string } ` > ;
102+ const _chainId = ( await provider . request ( "eth_chainId" ) ) as number ;
83103 if ( ! mounted ) return ;
84- setAccounts ( _accounts ) ;
104+ setChainId ( _chainId ) ;
85105
86106 const _contextAccounts = provider . contextAccounts ;
87107 if ( ! mounted ) return ;
88108 setContextAccounts ( _contextAccounts ) ;
89- setWalletConnected ( _accounts . length > 0 && _contextAccounts . length > 0 ) ;
109+ setWalletConnected ( _accounts [ 0 ] != null && _contextAccounts [ 0 ] != null ) ;
90110 } catch ( error ) {
91111 console . error ( error ) ;
92112 }
@@ -97,12 +117,12 @@ export function UpProvider({ children }: UpProviderProps) {
97117 if ( provider ) {
98118 const accountsChanged = ( _accounts : Array < `0x${string } `> ) => {
99119 setAccounts ( _accounts ) ;
100- setWalletConnected ( _accounts . length > 0 && contextAccounts . length > 0 ) ;
120+ setWalletConnected ( _accounts [ 0 ] != null && contextAccount != null ) ;
101121 } ;
102122
103123 const contextAccountsChanged = ( _accounts : Array < `0x${string } `> ) => {
104124 setContextAccounts ( _accounts ) ;
105- setWalletConnected ( accounts . length > 0 && _accounts . length > 0 ) ;
125+ setWalletConnected ( account != null && _accounts [ 0 ] != null ) ;
106126 } ;
107127
108128 const chainChanged = ( _chainId : number ) => {
@@ -116,30 +136,48 @@ export function UpProvider({ children }: UpProviderProps) {
116136 return ( ) => {
117137 mounted = false ;
118138 provider . removeListener ( "accountsChanged" , accountsChanged ) ;
119- provider . removeListener ( "contextAccountsChanged" , contextAccountsChanged ) ;
139+ provider . removeListener (
140+ "contextAccountsChanged" ,
141+ contextAccountsChanged
142+ ) ;
120143 provider . removeListener ( "chainChanged" , chainChanged ) ;
121144 } ;
122145 }
123- } , [ client , accounts . length , contextAccounts . length ] ) ;
124-
146+ // If you want to be responsive to account changes
147+ // you also need to look at the first account rather
148+ // then the length or the whole array. Unfortunately react doesn't properly
149+ // look at array values like vue or knockout.
150+ } , [ client , account , contextAccount ] ) ;
151+
152+ // There has to be a useMemo to make sure the context object doesn't change on every
153+ // render.
154+ const data = useMemo ( ( ) => {
155+ return {
156+ provider,
157+ client,
158+ chainId,
159+ accounts,
160+ contextAccounts,
161+ walletConnected,
162+ selectedAddress,
163+ setSelectedAddress,
164+ isSearching,
165+ setIsSearching,
166+ } ;
167+ } , [
168+ client ,
169+ chainId ,
170+ accounts ,
171+ contextAccounts ,
172+ walletConnected ,
173+ selectedAddress ,
174+ isSearching ,
175+ ] ) ;
125176 return (
126- < UpContext . Provider
127- value = { {
128- provider,
129- client,
130- chainId,
131- accounts,
132- contextAccounts,
133- walletConnected,
134- selectedAddress,
135- setSelectedAddress,
136- isSearching,
137- setIsSearching,
138- } }
139- >
177+ < UpContext . Provider value = { data } >
140178 < div className = "min-h-screen flex items-center justify-center" >
141179 { children }
142180 </ div >
143181 </ UpContext . Provider >
144182 ) ;
145- }
183+ }
0 commit comments