-
Notifications
You must be signed in to change notification settings - Fork 192
App/use whitelisted addresses for points #1408
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…handling - Updated PointHistoryList to include loading of disclosure events on refresh. - Enhanced ProveScreen to set user's points address if not already defined. - Added endpoint field to ProofHistory and database schema for better tracking. - Introduced utility functions for fetching whitelisted disclosure addresses and managing disclosure events.
- Changed navigation action in PointsNavBar from `goBack` to `navigate('Home')` for a more direct user experience.
- Updated GratificationScreen to navigate to 'Points' instead of going back, enhancing the flow after user interactions.
- Replaced the ArrowLeft icon with a new X icon for better visual consistency.
WalkthroughThe PR extends the points system with whitelist-based disclosure events and endpoint tracking. It adds a new Changes
Sequence DiagramsequenceDiagram
participant User
participant ProveScreen
participant ProofRequest as ProofRequestStatusScreen
participant Whitelist as Whitelist Service
participant GratificationScreen
participant HomeScreen
User->>ProveScreen: Select app
ProveScreen->>ProveScreen: Enrich with points address
User->>ProveScreen: Submit proof
ProveScreen->>ProofRequest: Navigate with proof
ProofRequest->>ProofRequest: Complete proof
alt Whitelist Endpoint Check
ProofRequest->>Whitelist: Query whitelisted addresses
Whitelist-->>ProofRequest: Return contracts & points
ProofRequest->>ProofRequest: Set whitelistedPoints state
ProofRequest->>GratificationScreen: Navigate with points
GratificationScreen-->>User: Show gratification
else No Whitelist Data
ProofRequest->>HomeScreen: Navigate
HomeScreen-->>User: Return to home
end
ProofRequest->>ProofRequest: Cleanup (2s delay)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~35–45 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (4)
app/src/stores/database.ts (1)
90-90: Consider adding an index on the endpoint column.The endpoint column is queried by
getDisclosurePointEventsto match against whitelisted addresses. If the proof_history table grows large, an index onendpointwould improve query performance. The existing pattern creates indexes on frequently queried columns (line 103-104).Add an index after table creation:
await db.executeSql(` CREATE INDEX IF NOT EXISTS idx_proof_history_timestamp ON ${TABLE_NAME} (timestamp) `); + + await db.executeSql(` + CREATE INDEX IF NOT EXISTS idx_proof_history_endpoint ON ${TABLE_NAME} (endpoint) + `);Also applies to: 218-221
app/src/utils/points/utils.ts (1)
111-129: Consider adding timeout and caching for whitelist fetch.The
getWhiteListedDisclosureAddressesfunction lacks:
- Fetch timeout - could hang indefinitely on slow/unresponsive network
- Caching - the whitelist is fetched multiple times (in ProofRequestStatusScreen and getDisclosurePointEvents) for each proof
Consider adding a timeout and a simple in-memory cache with TTL to reduce network calls and improve reliability.
Example timeout pattern:
const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 5000); try { const response = await fetch( `${POINTS_API_BASE_URL}/whitelisted-addresses`, { signal: controller.signal } ); // ... rest of logic } finally { clearTimeout(timeoutId); }app/src/screens/verification/ProofRequestStatusScreen.tsx (1)
68-84: Extract duplicate cleanup logic and clarify timing.The
onOkPressfunction contains duplicatesetTimeoutblocks (lines 75-77 and 80-82) that both clean up selfApp state after 2 seconds. This can be simplified. Additionally, the 2-second delay rationale isn't clear—consider documenting why this delay is necessary.Apply this diff:
const onOkPress = useCallback(async () => { buttonTap(); if (whitelistedPoints !== null) { navigation.navigate('Gratification', { points: whitelistedPoints, }); - setTimeout(() => { - selfClient.getSelfAppState().cleanSelfApp(); - }, 2000); } else { goHome(); - setTimeout(() => { - selfClient.getSelfAppState().cleanSelfApp(); - }, 2000); } + + // Clean up after navigation completes + setTimeout(() => { + selfClient.getSelfAppState().cleanSelfApp(); + }, 2000); }, [whitelistedPoints, navigation, goHome, selfClient]);app/src/screens/verification/ProveScreen.tsx (1)
120-141: Remove debug console.log statements from useEffect.The two console.log statements at lines 122 and 132 should be removed. While the blockchain wallet address is not sensitive PII, production code shouldn't retain debug logging. Apply the provided diff to clean this up.
useEffect(() => { - console.log('useEffect selectedApp', selectedApp); if (!selectedApp || selectedApp.selfDefinedData) { return; } const enhanceApp = async () => { const address = await getPointsAddress(); // Only update if still the same session if (selectedAppRef.current?.sessionId === selectedApp.sessionId) { - console.log('enhancing app with points address', address); selfClient.getSelfAppState().setSelfApp({ ...selectedApp, selfDefinedData: address.toLowerCase(), }); } }; enhanceApp(); }, [selectedApp, selfClient]);The effect logic itself is sound—the sessionId guard properly prevents race conditions, and dependencies are correct.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
app/src/components/NavBar/PointsNavBar.tsx(1 hunks)app/src/components/PointHistoryList.tsx(2 hunks)app/src/screens/app/GratificationScreen.tsx(3 hunks)app/src/screens/verification/ProofRequestStatusScreen.tsx(7 hunks)app/src/screens/verification/ProveScreen.tsx(3 hunks)app/src/stores/database.ts(4 hunks)app/src/stores/pointEventStore.ts(2 hunks)app/src/stores/proofHistoryStore.ts(1 hunks)app/src/stores/proofTypes.ts(1 hunks)app/src/utils/points/getEvents.ts(2 hunks)app/src/utils/points/utils.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,ts,tsx,jsx,sol,nr}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{js,ts,tsx,jsx,sol,nr}: NEVER log sensitive data including PII (names, DOB, passport numbers, addresses), credentials, tokens, API keys, private keys, or session identifiers.
ALWAYS redact/mask sensitive fields in logs using consistent patterns (e.g.,***-***-1234for passport numbers,J*** D***for names).
Files:
app/src/stores/proofTypes.tsapp/src/screens/app/GratificationScreen.tsxapp/src/components/PointHistoryList.tsxapp/src/screens/verification/ProveScreen.tsxapp/src/components/NavBar/PointsNavBar.tsxapp/src/stores/proofHistoryStore.tsapp/src/screens/verification/ProofRequestStatusScreen.tsxapp/src/utils/points/utils.tsapp/src/stores/pointEventStore.tsapp/src/stores/database.tsapp/src/utils/points/getEvents.ts
app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (app/AGENTS.md)
Type checking must pass before PRs (yarn types)
Files:
app/src/stores/proofTypes.tsapp/src/screens/app/GratificationScreen.tsxapp/src/components/PointHistoryList.tsxapp/src/screens/verification/ProveScreen.tsxapp/src/components/NavBar/PointsNavBar.tsxapp/src/stores/proofHistoryStore.tsapp/src/screens/verification/ProofRequestStatusScreen.tsxapp/src/utils/points/utils.tsapp/src/stores/pointEventStore.tsapp/src/stores/database.tsapp/src/utils/points/getEvents.ts
app/src/**/*.{ts,tsx,js,jsx}
⚙️ CodeRabbit configuration file
app/src/**/*.{ts,tsx,js,jsx}: Review React Native TypeScript code for:
- Component architecture and reusability
- State management patterns
- Performance optimizations
- TypeScript type safety
- React hooks usage and dependencies
- Navigation patterns
Files:
app/src/stores/proofTypes.tsapp/src/screens/app/GratificationScreen.tsxapp/src/components/PointHistoryList.tsxapp/src/screens/verification/ProveScreen.tsxapp/src/components/NavBar/PointsNavBar.tsxapp/src/stores/proofHistoryStore.tsapp/src/screens/verification/ProofRequestStatusScreen.tsxapp/src/utils/points/utils.tsapp/src/stores/pointEventStore.tsapp/src/stores/database.tsapp/src/utils/points/getEvents.ts
🧠 Learnings (9)
📚 Learning: 2025-09-22T11:10:22.019Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-09-22T11:10:22.019Z
Learning: Applies to src/**/*.{js,ts,tsx,jsx} : Use `react-navigation/native` with `createStaticNavigation` for type-safe navigation in React Native.
Applied to files:
app/src/screens/app/GratificationScreen.tsxapp/src/components/NavBar/PointsNavBar.tsxapp/src/screens/verification/ProofRequestStatusScreen.tsx
📚 Learning: 2025-08-23T02:02:02.556Z
Learnt from: transphorm
Repo: selfxyz/self PR: 942
File: app/vite.config.ts:170-0
Timestamp: 2025-08-23T02:02:02.556Z
Learning: In the selfxyz/self React Native app, devTools from '@/navigation/devTools' are intentionally shipped to production builds for testing purposes, not excluded as is typical in most applications.
Applied to files:
app/src/screens/app/GratificationScreen.tsxapp/src/screens/verification/ProofRequestStatusScreen.tsx
📚 Learning: 2025-08-26T14:41:41.821Z
Learnt from: shazarre
Repo: selfxyz/self PR: 936
File: app/src/screens/aesop/PassportOnboardingScreen.tsx:0-0
Timestamp: 2025-08-26T14:41:41.821Z
Learning: When verifying provider hierarchies in React Native apps, always check the main App.tsx file at the app root, not just navigation/index.tsx and layout files, as providers are often configured at the top-level App component.
Applied to files:
app/src/screens/app/GratificationScreen.tsxapp/src/screens/verification/ProofRequestStatusScreen.tsx
📚 Learning: 2025-09-22T11:10:22.019Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-09-22T11:10:22.019Z
Learning: Applies to src/navigation/**/*.{js,ts,tsx,jsx} : Platform-specific initial routes: web uses 'Home', mobile uses 'Splash'.
Applied to files:
app/src/screens/app/GratificationScreen.tsxapp/src/components/NavBar/PointsNavBar.tsxapp/src/screens/verification/ProofRequestStatusScreen.tsx
📚 Learning: 2025-08-26T14:49:11.190Z
Learnt from: shazarre
Repo: selfxyz/self PR: 936
File: app/src/screens/passport/PassportNFCScanScreen.tsx:28-31
Timestamp: 2025-08-26T14:49:11.190Z
Learning: The main App.tsx file is located at app/App.tsx (not in app/src), and it properly wraps the entire app with SelfClientProvider at the top of the provider hierarchy, enabling useSelfClient() hook usage throughout all navigation screens.
Applied to files:
app/src/screens/app/GratificationScreen.tsxapp/src/screens/verification/ProveScreen.tsxapp/src/screens/verification/ProofRequestStatusScreen.tsx
📚 Learning: 2025-08-26T14:49:11.190Z
Learnt from: shazarre
Repo: selfxyz/self PR: 936
File: app/src/screens/passport/PassportNFCScanScreen.tsx:28-31
Timestamp: 2025-08-26T14:49:11.190Z
Learning: SelfClientProvider is wrapped in app/App.tsx, providing context for useSelfClient() hook usage throughout the React Native app navigation stacks.
Applied to files:
app/src/screens/app/GratificationScreen.tsxapp/src/screens/verification/ProveScreen.tsxapp/src/screens/verification/ProofRequestStatusScreen.tsx
📚 Learning: 2025-09-22T11:10:22.019Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-09-22T11:10:22.019Z
Learning: Applies to src/screens/**/*.{js,ts,tsx,jsx} : Lazy load screens using `React.lazy()`, organize screens by feature modules.
Applied to files:
app/src/screens/verification/ProofRequestStatusScreen.tsx
📚 Learning: 2025-08-26T14:49:15.210Z
Learnt from: shazarre
Repo: selfxyz/self PR: 936
File: app/src/screens/passport/PassportNFCScanScreen.web.tsx:8-11
Timestamp: 2025-08-26T14:49:15.210Z
Learning: The main App.tsx file is located at app/App.tsx (at the app root), not at app/src/App.tsx, and contains the SelfClientProvider wrapping the entire application.
Applied to files:
app/src/screens/verification/ProofRequestStatusScreen.tsx
📚 Learning: 2025-09-11T19:41:16.601Z
Learnt from: aaronmgdr
Repo: selfxyz/self PR: 1055
File: app/src/components/homeScreen/idCard.tsx:6-6
Timestamp: 2025-09-11T19:41:16.601Z
Learning: The React Native app in selfxyz/self does not implement responsive layouts for orientation changes. The codebase consistently uses Dimensions.get('window') rather than useWindowDimensions(), indicating that orientation handling is not a priority or architectural pattern in this project.
Applied to files:
app/src/screens/verification/ProofRequestStatusScreen.tsx
🧬 Code graph analysis (7)
app/src/components/PointHistoryList.tsx (1)
app/src/stores/pointEventStore.ts (1)
usePointEventStore(53-346)
app/src/screens/verification/ProveScreen.tsx (1)
app/src/utils/points/utils.ts (1)
getPointsAddress(90-92)
app/src/screens/verification/ProofRequestStatusScreen.tsx (1)
app/src/navigation/index.tsx (1)
RootStackParamList(59-173)
app/src/utils/points/utils.ts (1)
app/src/utils/points/constants.ts (1)
POINTS_API_BASE_URL(5-5)
app/src/stores/pointEventStore.ts (2)
app/src/stores/proofHistoryStore.ts (1)
useProofHistoryStore(35-217)app/src/utils/points/getEvents.ts (1)
getDisclosurePointEvents(38-82)
app/src/stores/database.ts (1)
app/src/stores/database.web.ts (1)
openDatabase(16-47)
app/src/utils/points/getEvents.ts (2)
app/src/utils/points/utils.ts (1)
getWhiteListedDisclosureAddresses(111-129)app/src/stores/proofHistoryStore.ts (1)
useProofHistoryStore(35-217)
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: test-common
- GitHub Check: type-check
- GitHub Check: analyze-android
- GitHub Check: analyze-ios
- GitHub Check: build-deps
- GitHub Check: android-build-test
- GitHub Check: e2e-ios
🔇 Additional comments (5)
app/src/screens/verification/ProveScreen.tsx (1)
87-87: LGTM - endpoint field added to proof history.The addition of the endpoint field to the proof history payload correctly aligns with the database schema changes.
app/src/stores/pointEventStore.ts (2)
123-123: LGTM - disclosure events loaded after regular events.The placement of
loadDisclosureEvents()after loading stored events ensures proper initialization order.
130-145: No state loss issue exists—disclosure events are always completed.The verification reveals that
getDisclosurePointEvents()always creates disclosure events withstatus: 'completed'(hardcoded at line 73 ofapp/src/utils/points/getEvents.ts). Since no non-completed disclosure event states exist in AsyncStorage, filtering out and replacing disclosure events poses no risk of losing state. The original concern is invalid.Likely an incorrect or invalid review comment.
app/src/stores/database.ts (1)
106-194: LGTM - endpoint column migration handled correctly.The runtime migration pattern for the endpoint column matches the existing documentId migration approach, with proper error handling and retry logic.
app/src/utils/points/utils.ts (1)
13-17: LGTM - WhitelistedContract type added.The type definition properly captures the structure returned by the whitelist API.
| onPress={() => { | ||
| buttonTap(); | ||
| props.navigation.goBack(); | ||
| props.navigation.navigate('Home'); | ||
| }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify navigation change doesn't break existing flows.
Changing from goBack() to navigate('Home') alters the close button behavior—users will always land on Home instead of returning to their previous screen. If the Points screen can be accessed from multiple entry points (e.g., deep links, notifications, or other screens), this could disrupt the expected navigation flow.
Run the following script to verify the Points screen's entry points and confirm the 'Home' route exists:
🏁 Script executed:
#!/bin/bash
# Description: Check Points screen navigation entry points and verify 'Home' route exists
# Find all navigations to Points screen
echo "=== Entry points to Points screen ==="
rg -n "navigate\(['\"]Points['\"]" --type ts --type tsx -A 2 -B 2
# Find navigation configuration and Home route definition
echo -e "\n=== Navigation configuration with Home route ==="
ast-grep --pattern 'createStaticNavigation($_)'
# Check if Home is defined as a screen
echo -e "\n=== Home screen definitions ==="
rg -n "name.*['\"]Home['\"]" --type ts --type tsx -C 3Length of output: 267
---
🏁 Script executed:
```shell
#!/bin/bash
# Fix file type issues and re-verify navigation structure
# View the navigation configuration
echo "=== Navigation configuration (app/src/navigation/index.tsx) ==="
cat app/src/navigation/index.tsx | head -250
# Find all navigations to Points screen with corrected rg syntax
echo -e "\n=== Navigate to Points calls ==="
rg -n "navigate\(['\"]Points['\"]" -A 2 -B 2
# Check PointsNavBar close button behavior
echo -e "\n=== PointsNavBar close button context ==="
cat app/src/components/NavBar/PointsNavBar.tsx | head -50
Length of output: 1365
🏁 Script executed:
#!/bin/bash
# Find correct file paths and verify navigation structure
# Find PointsNavBar file
echo "=== Finding PointsNavBar.tsx ==="
fd -t f "PointsNavBar" -e tsx
# Find navigation configuration files
echo -e "\n=== Finding navigation configuration files ==="
fd -t f "navigation" -e ts -e tsx | head -20
# Find App.tsx at root
echo -e "\n=== Finding App.tsx ==="
fd -t f "App" -e tsx | grep -E "^[^/]*/App\.(tsx|ts)$"
# View PointsNavBar once located
echo -e "\n=== PointsNavBar.tsx content ==="
find . -name "PointsNavBar.tsx" -exec cat {} \;
# Search for Home route definition
echo -e "\n=== Home screen definition ==="
rg -n "Home.*screen|screen.*Home" --type ts --type jsx -i -C 2 | head -40Length of output: 2202
🏁 Script executed:
#!/bin/bash
# Check app root navigation setup and verify Home route
# View App.tsx to understand navigation structure
echo "=== app/App.tsx ==="
cat app/App.tsx | head -100
# Find where Home screen is defined
echo -e "\n=== Search for Home screen definition ==="
rg -n "name.*Home|Home.*screen|screenOptions.*Home" -i -C 2 | head -60
# Check GratificationScreen to understand the Points navigation context
echo -e "\n=== GratificationScreen navigation context ==="
cat app/src/screens/app/GratificationScreen.tsx | head -80Length of output: 10387
🏁 Script executed:
#!/bin/bash
# Find and examine navigation configuration
# List all files in navigation directory
echo "=== Navigation directory contents ==="
find app/src/navigation -type f | head -20
# View main navigation file
echo -e "\n=== Main navigation configuration ==="
cat app/src/navigation/index.ts 2>/dev/null || cat app/src/navigation/index.tsx 2>/dev/null || cat app/src/navigation.ts 2>/dev/null || echo "File not found in common locations"
# Search for RootStackParamList definition to understand navigation structure
echo -e "\n=== RootStackParamList definition ==="
rg -n "RootStackParamList" -C 5 | head -80
# Check if Home is a screen in the navigation
echo -e "\n=== Home in navigation configuration ==="
rg -n "name.*['\"]Home['\"]|Home.*screen" -C 2 | head -40Length of output: 15720
Revert to goBack() or implement conditional routing to preserve navigation stack.
The change from goBack() to navigate('Home') breaks the user experience when Points screen is accessed from non-Home sources. GratificationScreen navigates to Points via handleExploreRewards (line 41) and handleBackPress (line 49), and users expect the close button to return them to Gratification, not jump to Home.
This creates a fragmented experience:
- Entry from Earn Points → Points → Close → Home ✓
- Entry from Gratification → Points → Close → Home ✗ (should return to Gratification)
Use goBack() to preserve the navigation stack, or implement route-aware navigation if a specific behavior is required.
🤖 Prompt for AI Agents
In app/src/components/NavBar/PointsNavBar.tsx around lines 32 to 35, the close
button uses props.navigation.navigate('Home') which breaks expected back
behavior for flows that opened Points from non-Home screens; change this to
props.navigation.goBack() to preserve the navigation stack (or implement
conditional routing: if navigation.canGoBack() then goBack() else
navigate('Home')) so the close action returns users to the originating screen
while still falling back to Home when no back entry exists.
| if (selfApp?.endpoint && whitelistedPoints === null) { | ||
| const checkWhitelist = async () => { | ||
| try { | ||
| const whitelistedContracts = | ||
| await getWhiteListedDisclosureAddresses(); | ||
| const endpoint = selfApp.endpoint.toLowerCase(); | ||
| const whitelistedContract = whitelistedContracts.find( | ||
| c => c.contract_address.toLowerCase() === endpoint, | ||
| ); | ||
|
|
||
| if (whitelistedContract) { | ||
| setWhitelistedPoints(whitelistedContract.points_per_disclosure); | ||
| } | ||
| } catch (error) { | ||
| console.error('Error checking whitelist:', error); | ||
| } | ||
| }; | ||
|
|
||
| checkWhitelist(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Race condition: whitelist check might not complete before navigation.
The whitelist check in the effect (lines 110-129) is asynchronous and may not complete before the user presses "OK". This could result in navigating to Home instead of Gratification even when the endpoint is whitelisted. Consider:
- Adding a loading state that disables the OK button until whitelist check completes
- Or moving the whitelist check earlier in the proof flow
Run this script to check if there are other whitelist check patterns in the codebase:
🏁 Script executed:
#!/bin/bash
# Search for whitelist checking patterns
rg -nP --type=ts -C5 "getWhiteListedDisclosureAddresses" -g '!node_modules'Length of output: 4999
I'll need to examine the broader context of the screen to verify the race condition claim.
---
🏁 Script executed:
```shell
#!/bin/bash
# Get full context around the effect and navigation logic in ProofRequestStatusScreen
cat app/src/screens/verification/ProofRequestStatusScreen.tsx | head -200 | tail -130
Length of output: 3509
🏁 Script executed:
#!/bin/bash
# Search for where whitelistedPoints state is used
rg -nP --type=ts "whitelistedPoints" app/src/screens/verification/ProofRequestStatusScreen.tsx -C3Length of output: 1269
🏁 Script executed:
#!/bin/bash
# Search for OK button handler and navigation logic
rg -nP --type=ts -A10 "OK\|handlePress\|navigate.*Home\|navigate.*Gratification" app/src/screens/verification/ProofRequestStatusScreen.tsxLength of output: 0
🏁 Script executed:
#!/bin/bash
# Get the full useEffect hook structure
ast-grep --pattern $'useEffect(() => {
$$$
}, $_)' app/src/screens/verification/ProofRequestStatusScreen.tsxLength of output: 9820
🏁 Script executed:
#!/bin/bash
# Check getWhiteListedDisclosureAddresses implementation for error handling
sed -n '111,140p' app/src/utils/points/utils.tsLength of output: 817
Address race condition in whitelist check by preventing premature navigation.
The async whitelist fetch (line 114) is fire-and-forget with no guarantee it completes before user presses OK. Since whitelistedPoints starts as null, pressing OK immediately after proof completion navigates to Home instead of Gratification—even if the endpoint is whitelisted.
Recommended fixes:
- Disable the OK button until the whitelist check completes (add loading state tied to the async operation)
- Or await the whitelist check before allowing user interaction on the success screen
Without one of these safeguards, the navigation destination is determined by timing, not actual whitelist status.
🤖 Prompt for AI Agents
In app/src/screens/verification/ProofRequestStatusScreen.tsx around lines
110-129, the whitelist fetch is started fire-and-forget which allows the OK
button to be pressed while whitelistedPoints is still null, producing a race and
incorrect navigation; fix by introducing a loading flag (or reuse an explicit
pending state) that is set true before calling getWhiteListedDisclosureAddresses
and false in finally, and use that flag to disable the OK button (or show a
spinner) until the check completes, or alternatively make the OK handler await
the whitelist check when pending so navigation only occurs after
whitelistedPoints is resolved; ensure error handling still sets loading false in
the catch/finally so the UI is not permanently blocked.
| if (whitelistedContracts.length === 0) { | ||
| return []; | ||
| } | ||
|
|
||
| const whitelistedMap = new Map( | ||
| whitelistedContracts.map(c => [ | ||
| c.contract_address.toLowerCase(), | ||
| c.points_per_disclosure, | ||
| ]), | ||
| ); | ||
|
|
||
| const proofHistory = useProofHistoryStore.getState().proofHistory; | ||
| const disclosureEvents: PointEvent[] = []; | ||
|
|
||
| for (const proof of proofHistory) { | ||
| if (proof.status !== 'success' || !proof.endpoint) continue; | ||
|
|
||
| const endpoint = proof.endpoint.toLowerCase(); | ||
|
|
||
| if (!whitelistedMap.has(endpoint)) continue; | ||
|
|
||
| const points = whitelistedMap.get(endpoint)!; | ||
| disclosureEvents.push({ | ||
| id: proof.sessionId, | ||
| title: `${proof.appName} disclosure`, | ||
| type: 'disclosure', | ||
| timestamp: proof.timestamp, | ||
| points, | ||
| status: 'completed', | ||
| }); | ||
| } | ||
|
|
||
| return disclosureEvents; | ||
| } catch (error) { | ||
| console.error('Error loading disclosure point events:', error); | ||
| return []; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent wiping disclosure history when whitelist fetch fails
If getWhiteListedDisclosureAddresses() fails (offline/API hiccup) it resolves to an empty array, so this function returns []. usePointEventStore.loadDisclosureEvents() then replaces the store with existingNonDisclosureEvents + [], erasing every cached disclosure event we just loaded from AsyncStorage. That means a transient network error permanently hides earned disclosures from the user. Please propagate the failure (throw or return a sentinel) so the caller can skip the state update, or otherwise guard in loadDisclosureEvents() against replacing cached data when no fresh disclosure entries were produced.
Summary by CodeRabbit
Release Notes
New Features
Improvements