From 376feecb280c28504788c9677c6cb3cc455f00b6 Mon Sep 17 00:00:00 2001
From: Pawel Zelawski <pawel@pzelawski.com>
Date: Sat, 23 May 2026 10:33:53 +0200
Subject: chore: upgrade digiid-ts to v3 and stabilize dev/build scripts

---
 src/client/App.tsx | 103 +++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 80 insertions(+), 23 deletions(-)

(limited to 'src/client/App.tsx')

diff --git a/src/client/App.tsx b/src/client/App.tsx
index b3f0308..ad1e230 100644
--- a/src/client/App.tsx
+++ b/src/client/App.tsx
@@ -7,7 +7,7 @@ type UiState = 'initial' | 'waiting' | 'success' | 'failed';
 // Define the structure for result data (success or failure)
 interface ResultData {
   address?: string; // Present on success
-  error?: string;   // Present on failure
+  error?: string; // Present on failure
   addressType?: string; // Added later
 }
 
@@ -30,7 +30,7 @@ function App() {
     }
 
     console.log(`Starting status polling for session: ${sessionId}`);
-    let intervalId: any = null; // Use 'any' to avoid browser/node type conflict for setInterval return type
+    let intervalId: ReturnType<typeof setInterval> | null = null;
 
     const checkStatus = async () => {
       if (!sessionId) return; // Should not happen here, but type guard
@@ -41,19 +41,26 @@ function App() {
         if (!response.ok) {
           // Handle specific errors like 404 (session not found/expired)
           if (response.status === 404) {
-            console.warn(`Session ${sessionId} not found or expired during polling.`);
+            console.warn(
+              `Session ${sessionId} not found or expired during polling.`
+            );
             setError('Session expired or could not be found.');
             setUiState('failed'); // Transition to failed state
             setResultData({ error: 'Session expired or could not be found.' });
           } else {
-            const errorData = await response.json().catch(() => ({ message: 'Error fetching status' }));
-            throw new Error(errorData.message || `Server responded with ${response.status}`);
+            const errorData = await response
+              .json()
+              .catch(() => ({ message: 'Error fetching status' }));
+            throw new Error(
+              errorData.message || `Server responded with ${response.status}`
+            );
           }
           if (intervalId) clearInterval(intervalId); // Stop polling on error
           return;
         }
 
-        const data: { status: UiState, address?: string, error?: string } = await response.json();
+        const data: { status: UiState; address?: string; error?: string } =
+          await response.json();
         console.log('Received status data:', data);
 
         // If status changed from pending, update UI and stop polling
@@ -67,10 +74,12 @@ function App() {
           if (intervalId) clearInterval(intervalId);
         }
         // If status is still 'pending', the interval will continue
-
       } catch (err) {
         console.error('Error polling status:', err);
-        const message = err instanceof Error ? err.message : 'An unknown error occurred during status check';
+        const message =
+          err instanceof Error
+            ? err.message
+            : 'An unknown error occurred during status check';
         setError(`Status polling failed: ${message}`);
         // Decide if we should stop polling or transition state on generic fetch error
         // For now, let's stop polling and show error, moving to failed state
@@ -104,7 +113,11 @@ function App() {
     try {
       const response = await fetch('/api/digiid/start');
       if (!response.ok) {
-        const errorData = await response.json().catch(() => ({ message: 'Failed to start session. Server responded with status: ' + response.status }));
+        const errorData = await response.json().catch(() => ({
+          message:
+            'Failed to start session. Server responded with status: ' +
+            response.status,
+        }));
         throw new Error(errorData.message || 'Failed to start session');
       }
       const data = await response.json();
@@ -114,7 +127,8 @@ function App() {
       setUiState('waiting'); // Move to waiting state
     } catch (err) {
       console.error('Error starting Digi-ID session:', err);
-      const message = err instanceof Error ? err.message : 'An unknown error occurred';
+      const message =
+        err instanceof Error ? err.message : 'An unknown error occurred';
       setError(`Failed to initiate Digi-ID: ${message}`);
       setUiState('initial'); // Stay in initial state on error
     } finally {
@@ -140,9 +154,20 @@ function App() {
       {/* --- Views based on uiState --- */}
       {uiState === 'initial' && (
         <div className="initial-view">
-          <button onClick={handleStart} disabled={isLoading} className="signin-button">
-            <img src="/assets/digiid-logo.png" alt="Digi-ID Logo" width="24" height="24" />
-            <span>{isLoading ? 'Generating QR...' : 'Sign in with Digi-ID'}</span>
+          <button
+            onClick={handleStart}
+            disabled={isLoading}
+            className="signin-button"
+          >
+            <img
+              src="/assets/digiid-logo.png"
+              alt="Digi-ID Logo"
+              width="24"
+              height="24"
+            />
+            <span>
+              {isLoading ? 'Generating QR...' : 'Sign in with Digi-ID'}
+            </span>
           </button>
         </div>
       )}
@@ -152,7 +177,10 @@ function App() {
           {uiState === 'waiting' && qrCodeDataUrl && (
             <div className="waiting-view view-box">
               <h2>Scan the QR Code</h2>
-              <p>Scan the QR code below using your Digi-ID compatible mobile wallet.</p>
+              <p>
+                Scan the QR code below using your Digi-ID compatible mobile
+                wallet.
+              </p>
               <img src={qrCodeDataUrl} alt="Digi-ID QR Code" width="250" />
               <p>Waiting for authentication...</p>
               <button onClick={handleReset}>Cancel</button>
@@ -161,14 +189,30 @@ function App() {
 
           {uiState === 'success' && resultData?.address && (
             <div className="success-view view-box">
-              <svg xmlns="http://www.w3.org/2000/svg" className="checkmark-icon" viewBox="0 0 52 52">
-                <circle className="checkmark__circle" cx="26" cy="26" r="25" fill="none"/>
-                <path className="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
+              <svg
+                xmlns="http://www.w3.org/2000/svg"
+                className="checkmark-icon"
+                viewBox="0 0 52 52"
+              >
+                <circle
+                  className="checkmark__circle"
+                  cx="26"
+                  cy="26"
+                  r="25"
+                  fill="none"
+                />
+                <path
+                  className="checkmark__check"
+                  fill="none"
+                  d="M14.1 27.2l7.1 7.2 16.7-16.8"
+                />
               </svg>
               <h2>Authentication Successful!</h2>
               <p>Verified Address:</p>
               <p className="address">{resultData.address}</p>
-              <p>Address Format: {getDigiByteAddressType(resultData.address)}</p>
+              <p>
+                Address Format: {getDigiByteAddressType(resultData.address)}
+              </p>
               <button onClick={handleReset}>Start Over</button>
             </div>
           )}
@@ -177,7 +221,8 @@ function App() {
             <div className="failed-view view-box">
               <h2>Authentication Failed</h2>
               <p className="error-message">
-                Reason: {resultData?.error || error || 'An unknown error occurred.'}
+                Reason:{' '}
+                {resultData?.error || error || 'An unknown error occurred.'}
               </p>
               <button onClick={handleReset}>Try Again</button>
             </div>
@@ -188,14 +233,26 @@ function App() {
       {/* --- Description section (Always visible below the view container) --- */}
       <div className="description">
         <p className="code-link">
-          This application demonstrates integrating Digi-ID authentication using the <a href="https://github.com/pawelzelawski/digiid-ts" target="_blank" rel="noopener noreferrer">digiid-ts</a> library.
+          This application demonstrates integrating Digi-ID authentication using
+          the{' '}
+          <a
+            href="https://github.com/pawelzelawski/digiid-ts"
+            target="_blank"
+            rel="noopener noreferrer"
+          >
+            digiid-ts
+          </a>{' '}
+          library.
         </p>
         <p>
-          Upon successful verification, the system can identify the following DigiByte address formats:
+          Upon successful verification, the system can identify the following
+          DigiByte address formats:
         </p>
         <ul>
           <li>Legacy Addresses (P2PKH) - starting with 'D'</li>
-          <li>Pay-to-Script-Hash Addresses (P2SH) - commonly starting with 'S'</li>
+          <li>
+            Pay-to-Script-Hash Addresses (P2SH) - commonly starting with 'S'
+          </li>
           <li>Segregated Witness (SegWit) Addresses - starting with 'dgb1'</li>
         </ul>
       </div>
@@ -203,4 +260,4 @@ function App() {
   );
 }
 
-export default App; 
\ No newline at end of file
+export default App;
-- 
cgit v1.2.3

