Skip to content

Commit 201276e

Browse files
committed
Merge branch 'main' into pr-194
2 parents 70f21cd + ce81319 commit 201276e

File tree

10 files changed

+1899
-60
lines changed

10 files changed

+1899
-60
lines changed

frontend/WALLET_AUTH_BACKEND_INTEGRATION.md

Lines changed: 489 additions & 0 deletions
Large diffs are not rendered by default.

frontend/WALLET_AUTH_GUIDE.md

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
# Wallet Authentication System
2+
3+
## Overview
4+
5+
The Wallet Authentication System provides automatic sign-in verification after wallet connection, ensuring users verify wallet ownership before accessing sensitive information.
6+
7+
## Features
8+
9+
-**Automatic Popup**: Appears automatically after wallet connection
10+
-**Wallet Signature Verification**: Uses typed data signing for secure verification
11+
-**Session Persistence**: Authentication persists for the current session
12+
-**Auto Reset on Disconnect**: Clears authentication when wallet disconnects
13+
-**Theme Support**: Fully integrated with dark/light mode
14+
-**Mobile Responsive**: Works seamlessly across all devices
15+
16+
## How It Works
17+
18+
### 1. User Flow
19+
20+
1. User connects wallet via Starknetkit modal
21+
2. **Automatic popup appears** prompting user to sign in
22+
3. User clicks "Sign Message" to verify wallet ownership
23+
4. Wallet prompts user to sign a message (no gas fees)
24+
5. Upon successful signature, user is authenticated
25+
6. Authentication persists for the session
26+
7. When wallet disconnects, authentication resets
27+
28+
### 2. Architecture
29+
30+
#### Components
31+
32+
- **`WalletAuthProvider`**: Context provider managing authentication state
33+
- **`WalletSignInModal`**: The popup modal for signature verification
34+
- **`ProtectedContent`**: Wrapper component for sensitive content
35+
- **`useWalletAuth`**: Hook to access authentication state and functions
36+
- **`useRequireAuth`**: Hook to require authentication in components
37+
38+
#### File Structure
39+
40+
```
41+
frontend/
42+
├── app/
43+
│ ├── context/
44+
│ │ └── wallet-auth-context.tsx # Authentication context
45+
│ ├── components/
46+
│ │ └── modals/
47+
│ │ └── WalletSignInModal.tsx # Sign-in modal component
48+
│ └── layout.tsx # Provider integration
49+
└── components/
50+
└── shared/
51+
├── ProtectedContent.tsx # Protected content wrapper
52+
└── WalletConnected.tsx # Updated with auth clearing
53+
```
54+
55+
## Usage Examples
56+
57+
### 1. Protecting Sensitive Content
58+
59+
Use the `ProtectedContent` component to wrap any sensitive information:
60+
61+
```tsx
62+
import ProtectedContent from '@/components/shared/ProtectedContent'
63+
64+
function UserSettings() {
65+
return (
66+
<ProtectedContent fallbackMessage="Sign in to view your settings">
67+
<div>
68+
<h2>Private Settings</h2>
69+
<p>Your sensitive data here...</p>
70+
</div>
71+
</ProtectedContent>
72+
)
73+
}
74+
```
75+
76+
### 2. Checking Authentication Status
77+
78+
Use the `useWalletAuth` hook to check authentication status:
79+
80+
```tsx
81+
import { useWalletAuth } from '@/app/context/wallet-auth-context'
82+
83+
function MyComponent() {
84+
const { isAuthenticated } = useWalletAuth()
85+
86+
return (
87+
<div>
88+
{isAuthenticated ? (
89+
<div>Welcome! You are authenticated.</div>
90+
) : (
91+
<div>Please authenticate to continue.</div>
92+
)}
93+
</div>
94+
)
95+
}
96+
```
97+
98+
### 3. Requiring Authentication Before Action
99+
100+
Use the `useRequireAuth` hook to require authentication before performing actions:
101+
102+
```tsx
103+
import { useRequireAuth } from '@/components/shared/ProtectedContent'
104+
105+
function TransactionComponent() {
106+
const { requireAuth } = useRequireAuth()
107+
108+
const handleTransaction = () => {
109+
// Check if user is authenticated before proceeding
110+
if (!requireAuth()) {
111+
return // Will show auth modal
112+
}
113+
114+
// Proceed with transaction
115+
executeSensitiveOperation()
116+
}
117+
118+
return <button onClick={handleTransaction}>Execute Transaction</button>
119+
}
120+
```
121+
122+
### 4. Manually Triggering Auth Modal
123+
124+
```tsx
125+
import { useWalletAuth } from '@/app/context/wallet-auth-context'
126+
127+
function CustomComponent() {
128+
const { setIsAuthModalOpen } = useWalletAuth()
129+
130+
return <button onClick={() => setIsAuthModalOpen(true)}>Verify Wallet</button>
131+
}
132+
```
133+
134+
## API Reference
135+
136+
### `useWalletAuth()` Hook
137+
138+
Returns an object with:
139+
140+
- **`isAuthenticated`** (boolean): Whether the user is authenticated
141+
- **`isAuthModalOpen`** (boolean): Whether the auth modal is open
142+
- **`setIsAuthModalOpen`** (function): Function to open/close the modal
143+
- **`authenticate`** (function): Function to mark user as authenticated
144+
- **`logout`** (function): Function to disconnect wallet and clear auth
145+
- **`needsAuthentication`** (boolean): Whether user needs to authenticate
146+
147+
### `useRequireAuth()` Hook
148+
149+
Returns an object with:
150+
151+
- **`isAuthenticated`** (boolean): Whether the user is authenticated
152+
- **`requireAuth`** (function): Function that returns true if authenticated, opens modal if not
153+
154+
### `ProtectedContent` Component
155+
156+
Props:
157+
158+
- **`children`** (ReactNode): The sensitive content to protect
159+
- **`fallbackMessage`** (string, optional): Custom message when not authenticated
160+
161+
## Technical Details
162+
163+
### Signature Process
164+
165+
The system uses Starknet typed data signing:
166+
167+
1. Creates a typed data structure with:
168+
169+
- Domain: Spherre app identification
170+
- Message: Sign-in text with wallet address and timestamp
171+
- Types: StarkNet domain and message types
172+
173+
2. Requests signature from user's wallet
174+
3. Validates signature exists (signature verification is done client-side)
175+
4. Marks user as authenticated in session storage
176+
177+
### Session Storage
178+
179+
Authentication state is stored per wallet address:
180+
181+
- Key format: `wallet_auth_{address}`
182+
- Storage: `sessionStorage` (cleared when browser tab closes)
183+
- Automatic cleanup on disconnect
184+
185+
### Auto-Trigger Logic
186+
187+
The modal automatically appears when:
188+
189+
1. Wallet address is detected (connected)
190+
2. User is not already authenticated for that address
191+
3. Small 500ms delay after wallet connection for smooth UX
192+
193+
## Security Considerations
194+
195+
**Secure**: Uses cryptographic signature verification
196+
**Gas-free**: No blockchain transactions involved
197+
**Session-only**: Auth clears when session ends
198+
**Per-wallet**: Each wallet requires separate authentication
199+
**No private keys**: Never exposes or stores private keys
200+
201+
## Testing Checklist
202+
203+
- [ ] Connect wallet → Modal appears automatically
204+
- [ ] Sign message → Authentication succeeds
205+
- [ ] Reject signature → Error message shown with retry option
206+
- [ ] Authenticated → ProtectedContent renders children
207+
- [ ] Not authenticated → ProtectedContent shows fallback
208+
- [ ] Disconnect wallet → Authentication resets
209+
- [ ] Reconnect same wallet → Modal appears again (new session)
210+
- [ ] Dark/light mode → Modal theme updates correctly
211+
- [ ] Mobile view → Modal is responsive and usable
212+
213+
## Troubleshooting
214+
215+
### Modal doesn't appear after connection
216+
217+
- Check that `WalletAuthProvider` is in the provider tree
218+
- Check browser console for errors
219+
- Ensure `StarknetProvider` is above `WalletAuthProvider`
220+
221+
### Authentication doesn't persist
222+
223+
- Check that sessionStorage is enabled in browser
224+
- Verify wallet address is being captured correctly
225+
- Check for console errors in `wallet-auth-context.tsx`
226+
227+
### Modal appears too quickly after connection
228+
229+
- Adjust the 500ms delay in `wallet-auth-context.tsx` line 48
230+
- Increase timeout for slower wallet connection modals
231+
232+
## Future Enhancements
233+
234+
Potential improvements:
235+
236+
- [ ] Backend signature verification
237+
- [ ] JWT token generation for API authentication
238+
- [ ] Remember device option (localStorage with expiry)
239+
- [ ] Biometric authentication fallback
240+
- [ ] Multi-signature support for shared accounts
241+
- [ ] Rate limiting for signature requests
242+
243+
## Support
244+
245+
For issues or questions:
246+
247+
- Check the troubleshooting section above
248+
- Review the code comments in context files
249+
- Test with a fresh browser session (incognito mode)

0 commit comments

Comments
 (0)