11import React , { useCallback , useEffect , useMemo , useRef , useState } from "react" ;
22import styled , { css } from "styled-components" ;
33
4- import { Address } from "viem" ;
4+ import { Address , PublicClient } from "viem" ;
5+ import { usePublicClient } from "wagmi" ;
56
67import { Copiable , DropdownSelect , Field } from "@kleros/ui-components-library" ;
78
@@ -10,6 +11,7 @@ import { shortenAddress } from "utils/shortenAddress";
1011import { klerosCoreAddress } from "hooks/contracts/generated" ;
1112import { DEFAULT_CHAIN } from "consts/chains" ;
1213import { landscapeStyle } from "styles/landscapeStyle" ;
14+ import { validateAddress } from "utils/validateAddressOrEns" ;
1315
1416const Container = styled . div `
1517 width: 100%;
@@ -78,10 +80,19 @@ const StyledDropdown = styled(DropdownSelect)`
7880 }
7981` ;
8082
83+ const ErrorMessage = styled . div `
84+ color: red;
85+ font-size: 14px;
86+ margin-top: 4px;
87+ ` ;
88+
8189const SelectArbitrable : React . FC = ( ) => {
8290 const { arbitrable, setArbitrable, knownArbitrables } = useRulerContext ( ) ;
91+ const publicClient = usePublicClient ( { chainId : 1 } ) as PublicClient ;
8392 const ref = useRef < HTMLDivElement > ( null ) ;
8493 const [ isClient , setIsClient ] = useState ( false ) ;
94+ const [ inputValue , setInputValue ] = useState ( "" ) ;
95+ const [ error , setError ] = useState < string | null > ( null ) ;
8596
8697 // hydration workaround, local storage is inevitably going to be different, so knownArbitrables will be different
8798 // server and client side
@@ -102,6 +113,25 @@ const SelectArbitrable: React.FC = () => {
102113 child . click ( ) ;
103114 } , [ knownArbitrables , ref ] ) ;
104115
116+ const handleInputChange = useCallback (
117+ async ( value : string ) => {
118+ setInputValue ( value ) ;
119+ setError ( null ) ;
120+
121+ if ( value ) {
122+ const isValid = await validateAddress ( value , publicClient ) ;
123+ if ( isValid ) {
124+ setArbitrable ( value as Address ) ;
125+ } else {
126+ setError ( "Invalid address or ENS name" ) ;
127+ }
128+ } else {
129+ setArbitrable ( "" as Address ) ;
130+ }
131+ } ,
132+ [ publicClient , setArbitrable ]
133+ ) ;
134+
105135 return (
106136 < Container >
107137 < AddressContainer >
@@ -113,15 +143,18 @@ const SelectArbitrable: React.FC = () => {
113143 < Arbitrables suppressHydrationWarning = { true } >
114144 < StyledLabel > Arbitrable:</ StyledLabel >
115145 < SelectContainer ref = { ref } >
116- < StyledDropdown defaultValue = { arbitrable } items = { items } callback = { ( val ) => setArbitrable ( val as Address ) } />
146+ < StyledDropdown
147+ defaultValue = { arbitrable }
148+ items = { items }
149+ callback = { ( val ) => handleInputChange ( val . toString ( ) ) }
150+ />
117151 < StyledField
118- value = { arbitrable }
152+ value = { inputValue }
119153 placeholder = "Enter Arbitrable"
120- onChange = { ( e ) => {
121- setArbitrable ( e . target . value as Address ) ;
122- } }
154+ onChange = { ( e ) => handleInputChange ( e . target . value ) }
123155 onClick = { openDropdown }
124156 />
157+ { error && < ErrorMessage > { error } </ ErrorMessage > }
125158 </ SelectContainer >
126159 </ Arbitrables >
127160 </ Container >
0 commit comments