@@ -37,6 +37,7 @@ export function App() {
3737 const [ providers , setProviders ] = useState < { info : EIP6963ProviderInfo ; provider : EIP1193 } [ ] > (
3838 [ ] ,
3939 ) ;
40+
4041 const [ confirmed , setConfirmed ] = useState < boolean > ( false ) ;
4142 const [ pending , setPending ] = useState < PendingAny | null > ( null ) ;
4243 const [ selectedUuid , setSelectedUuid ] = useState < string | null > ( null ) ;
@@ -48,6 +49,7 @@ export function App() {
4849 const [ lastTxReceipt , setLastTxReceipt ] = useState < TransactionReceipt | null > ( null ) ;
4950 const [ lastTxHash , setLastTxHash ] = useState < string | null > ( null ) ;
5051
52+ const pollIntervalRef = useRef < number | null > ( null ) ;
5153 const prevSelectedUuidRef = useRef < string | null > ( null ) ;
5254
5355 const connect = async ( ) => {
@@ -67,6 +69,8 @@ export function App() {
6769 }
6870 } ;
6971
72+ // Confirm the current connection.
73+ // This is required for Foundry to fill out the `from` field and `chain` in transactions.
7074 const confirm = async ( ) => {
7175 if ( ! account || chainId == null ) {
7276 return ;
@@ -81,6 +85,7 @@ export function App() {
8185 setConfirmed ( true ) ;
8286 } ;
8387
88+ // Sign and send the current pending transaction.
8489 const signAndSendCurrent = async ( ) => {
8590 if ( ! selected || ! pending ?. request ) return ;
8691
@@ -96,12 +101,14 @@ export function App() {
96101 } ) ) as `0x${string } `;
97102 setLastTxHash ( hash ) ;
98103
104+ await api ( "/api/transaction/response" , "POST" , { id : pending . id , hash, error : null } ) ;
105+
106+ console . log ( "sent tx:" , hash ) ;
107+
99108 const receipt = await waitForTransactionReceipt ( walletClient , { hash } ) ;
100109 setLastTxReceipt ( receipt ) ;
101110
102- await api ( "/api/transaction/response" , "POST" , { id : pending . id , hash, error : null } ) ;
103-
104- setPending ( null ) ;
111+ console . log ( "tx receipt:" , receipt ) ;
105112 } catch ( e : unknown ) {
106113 const msg =
107114 typeof e === "object" &&
@@ -111,7 +118,7 @@ export function App() {
111118 ? ( e as { message : string } ) . message
112119 : String ( e ) ;
113120
114- console . log ( "send failed:" , msg ) ;
121+ console . error ( "send failed:" , msg ) ;
115122
116123 try {
117124 await api ( "/api/transaction/response" , "POST" , {
@@ -120,12 +127,16 @@ export function App() {
120127 error : msg ,
121128 } ) ;
122129 } catch { }
123-
124- setPending ( null ) ;
125130 }
126131 } ;
127132
128- const resetClientState = useCallback ( async ( ) => {
133+ // Reset all client state.
134+ const resetClientState = useCallback ( ( ) => {
135+ if ( pollIntervalRef . current ) {
136+ window . clearInterval ( pollIntervalRef . current ) ;
137+ pollIntervalRef . current = null ;
138+ }
139+
129140 setPending ( null ) ;
130141 setLastTxHash ( null ) ;
131142 setLastTxReceipt ( null ) ;
@@ -135,9 +146,7 @@ export function App() {
135146 setChain ( undefined ) ;
136147 setConfirmed ( false ) ;
137148
138- try {
139- await api ( "/api/connection" , "POST" , null ) ;
140- } catch { }
149+ void api ( "/api/connection" , "POST" , null ) ;
141150 } , [ ] ) ;
142151
143152 // Upon switching wallets, reset state.
@@ -201,20 +210,34 @@ export function App() {
201210 } ;
202211 } , [ selected , confirmed ] ) ;
203212
213+ // Poll for pending transaction requests.
214+ // Stops when one is found.
204215 useEffect ( ( ) => {
205216 if ( ! confirmed || pending ) return ;
206217
218+ let active = true ;
219+
207220 const id = window . setInterval ( async ( ) => {
221+ if ( ! active ) return ;
208222 try {
209223 const resp = await api < ApiOk < PendingAny > | ApiErr > ( "/api/transaction/request" ) ;
210224 if ( isOk ( resp ) ) {
211- setPending ( resp . data ) ;
225+ window . clearInterval ( id ) ;
226+ if ( active ) {
227+ setPending ( resp . data ) ;
228+ }
212229 }
213230 } catch { }
214231 } , 1000 ) ;
215232
233+ pollIntervalRef . current = id ;
234+
216235 return ( ) => {
236+ active = false ;
217237 window . clearInterval ( id ) ;
238+ if ( pollIntervalRef . current === id ) {
239+ pollIntervalRef . current = null ;
240+ }
218241 } ;
219242 } , [ confirmed , pending ] ) ;
220243
@@ -298,7 +321,7 @@ rpc: ${chain?.rpcUrls?.default?.http?.[0] ?? chain?.rpcUrls?.public?.http?.[
298321 </ >
299322 ) }
300323
301- { selected && account && pending && confirmed && (
324+ { selected && account && pending && confirmed && ! lastTxHash && (
302325 < button type = "button" className = "wallet-send" onClick = { signAndSendCurrent } >
303326 Sign & Send
304327 </ button >
0 commit comments