-
Notifications
You must be signed in to change notification settings - Fork 187
Move Points and IncomingPoints to the Point Events Store #1363
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
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (3)
Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis PR refactors the points system from component-level state management to a centralized event store with asynchronous job polling. It introduces background event status tracking, updates hook return signatures to provide both values and refetch methods, and integrates remote job status checks to manage event lifecycle (pending → completed/failed). Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI as PointHistoryList
participant Store as pointEventStore
participant API as Backend
participant Poller as eventPolling
User->>UI: Pull to refresh
UI->>Store: refreshPoints()
UI->>Store: refreshIncomingPoints()
UI->>Store: loadPointEvents()
par Concurrent execution
Store->>API: Fetch total points
Store->>API: Fetch incoming points
Store->>API: Load events from storage
end
Note over Store: Clear refreshing state
UI->>User: Update display
rect rgb(230, 240, 250)
Note over Poller,Store: Background Job Polling
Store->>API: registerBackupPoints()
API-->>Store: { jobId: "abc123" }
Store->>Poller: pollEventProcessingStatus("abc123")
loop Poll up to 10 times (exponential backoff)
Poller->>API: checkEventProcessingStatus("abc123")
API-->>Poller: HTTP 102/200/404
Note over Poller: Map status: 102→pending, 200→completed, 404→failed
end
Poller-->>Store: 'completed' | 'failed' | null
Store->>Store: markEventAsProcessed() or markEventAsFailed()
Store->>Store: Update optimistic totals
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Areas requiring extra attention:
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
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 |
atomically update store state
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
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: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/src/components/PointHistoryList.tsx (1)
69-91: Architectural inconsistency: Point events should be sourced from the store.The inline comment at line 69 raises a valid concern. This component maintains local
pointEventsstate and loads events viagetAllPointEvents(), while other parts of the refresh flow now use the centralized store. This creates two sources of truth and could lead to synchronization issues.Since the PR's objective is to centralize points management in the Point Events Store, consider refactoring to use
usePointEventStore(state => state.events)instead of local state.- const [pointEvents, setPointEvents] = useState<PointEvent[]>([]); - const [isLoading, setIsLoading] = useState(true); + const pointEvents = usePointEventStore(state => state.events); + const isLoading = usePointEventStore(state => state.isLoading); const refreshPoints = usePointEventStore(state => state.refreshPoints); const refreshIncomingPoints = usePointEventStore( state => state.refreshIncomingPoints, ); + const loadPointEvents = usePointEventStore(state => state.loadEvents); - const loadPointEvents = useCallback(async () => { - try { - setIsLoading(true); - const events = await getAllPointEvents(); - setPointEvents(events); - } catch (error) { - console.error('Error loading point events:', error); - } finally { - setIsLoading(false); - } - }, []);
🧹 Nitpick comments (4)
app/src/utils/points/recordEvents.ts (1)
29-36: Consider adding error handling for store update failures.The background polling is fire-and-forget, which is appropriate, but if
markEventAsProcessedormarkEventAsFailedthrow an error, it will result in an unhandled promise rejection.Apply this diff to add error handling:
// Start polling in background - don't await - pollEventProcessingStatus(jobId).then(result => { - if (result === 'completed') { - usePointEventStore.getState().markEventAsProcessed(jobId); - } else if (result === 'failed') { - usePointEventStore.getState().markEventAsFailed(jobId); - } - }); + pollEventProcessingStatus(jobId) + .then(result => { + if (result === 'completed') { + usePointEventStore.getState().markEventAsProcessed(jobId); + } else if (result === 'failed') { + usePointEventStore.getState().markEventAsFailed(jobId); + } + }) + .catch(error => { + console.error(`Error updating event ${jobId} status:`, error); + });app/src/utils/points/jobStatus.ts (1)
12-17: Consider adding a timeout to the fetch call.The fetch request has no timeout, which could result in indefinite hangs if the server doesn't respond. This is especially important for a polling function that will be called repeatedly.
Apply this diff to add a timeout:
- const response = await fetch(`${POINTS_API_BASE_URL}/job/${jobId}/status`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - }); + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout + + const response = await fetch(`${POINTS_API_BASE_URL}/job/${jobId}/status`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + signal: controller.signal, + }); + + clearTimeout(timeoutId);app/src/components/PointHistoryList.tsx (1)
293-302: Clarify or include store method dependencies.The
eslint-disableforexhaustive-depssuppresses warnings aboutrefreshPointsandrefreshIncomingPointsmissing from the dependency array. While Zustand store methods have stable references and the disable is technically safe, it reduces code clarity.Consider including all dependencies for clarity:
const onRefresh = useCallback(() => { setRefreshing(true); Promise.all([ refreshPoints(), refreshIncomingPoints(), loadPointEvents(), ]).finally(() => setRefreshing(false)); - - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [loadPointEvents]); + }, [refreshPoints, refreshIncomingPoints, loadPointEvents]);app/src/stores/pointEventStore.ts (1)
224-281: Complex race condition handling would benefit from inline documentation.The
markEventAsProcessedmethod handles multiple concurrent update scenarios with sophisticated logic:
- Initial status validation (lines 226-237)
- Parallel async operations (lines 245-248)
- Post-async re-validation (lines 251-258)
- Atomic state updates (lines 261-271)
While the implementation appears correct, the complexity could make future maintenance challenging. Consider adding inline comments explaining the race condition scenarios being handled.
Example documentation:
markEventAsProcessed: async (id: string) => { try { // Step 1: Validate event exists and is still pending // (Another concurrent call might have already processed it) const currentEvents = get().events; const event = currentEvents.find(e => e.id === id); if (!event || event.status !== 'pending') { return; // Already handled } // Step 2: Prepare update and fetch fresh data in parallel const updatedEvents = currentEvents.map(e => e.id === id ? { ...e, status: 'completed' as const } : e, ); // Step 3: Persist and fetch concurrently for performance const [points] = await Promise.all([ get().fetchIncomingPoints(), AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(updatedEvents)), ]); // Step 4: Re-validate before final state update // (Events may have changed during async operations) const latestEvents = get().events; const latestEvent = latestEvents.find(e => e.id === id); // ... rest of logic
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
app/src/components/NavBar/Points.tsx(1 hunks)app/src/components/PointHistoryList.tsx(3 hunks)app/src/hooks/usePoints.ts(1 hunks)app/src/screens/home/HomeScreen.tsx(1 hunks)app/src/stores/pointEventStore.ts(3 hunks)app/src/utils/points/api.ts(1 hunks)app/src/utils/points/eventPolling.ts(1 hunks)app/src/utils/points/jobStatus.ts(1 hunks)app/src/utils/points/recordEvents.ts(5 hunks)app/src/utils/points/registerEvents.ts(6 hunks)app/src/utils/points/types.ts(1 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/screens/home/HomeScreen.tsxapp/src/utils/points/types.tsapp/src/utils/points/eventPolling.tsapp/src/utils/points/api.tsapp/src/utils/points/recordEvents.tsapp/src/utils/points/jobStatus.tsapp/src/components/NavBar/Points.tsxapp/src/components/PointHistoryList.tsxapp/src/utils/points/registerEvents.tsapp/src/hooks/usePoints.tsapp/src/stores/pointEventStore.ts
app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (app/AGENTS.md)
Type checking must pass before PRs (yarn types)
Files:
app/src/screens/home/HomeScreen.tsxapp/src/utils/points/types.tsapp/src/utils/points/eventPolling.tsapp/src/utils/points/api.tsapp/src/utils/points/recordEvents.tsapp/src/utils/points/jobStatus.tsapp/src/components/NavBar/Points.tsxapp/src/components/PointHistoryList.tsxapp/src/utils/points/registerEvents.tsapp/src/hooks/usePoints.tsapp/src/stores/pointEventStore.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/screens/home/HomeScreen.tsxapp/src/utils/points/types.tsapp/src/utils/points/eventPolling.tsapp/src/utils/points/api.tsapp/src/utils/points/recordEvents.tsapp/src/utils/points/jobStatus.tsapp/src/components/NavBar/Points.tsxapp/src/components/PointHistoryList.tsxapp/src/utils/points/registerEvents.tsapp/src/hooks/usePoints.tsapp/src/stores/pointEventStore.ts
🧠 Learnings (2)
📚 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/home/HomeScreen.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/state/**/*.{js,ts,tsx,jsx} : Zustand should be used for global state management; custom hooks for complex state.
Applied to files:
app/src/stores/pointEventStore.ts
⏰ 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). (2)
- GitHub Check: analyze-android
- GitHub Check: analyze-ios
🔇 Additional comments (10)
app/src/utils/points/eventPolling.ts (1)
42-44: LGTM!Standard promise-based sleep implementation.
app/src/utils/points/api.ts (1)
94-98: LGTM!Adding generics to
makeApiRequestimproves type safety while maintaining backward compatibility with the defaultunknowntype parameter.app/src/utils/points/recordEvents.ts (1)
52-62: LGTM!All three record functions consistently check for
response.jobIdbefore proceeding with event registration and polling. The pattern is uniform and correctly integrates with the new job-based workflow.Also applies to: 88-98, 127-137
app/src/utils/points/jobStatus.ts (1)
3-6: LGTM!Type definition correctly represents the API response format.
app/src/utils/points/registerEvents.ts (2)
8-10: LGTM!Type definition correctly represents the verify action API response.
34-55: LGTM!All three register functions consistently updated to:
- Use generic
makeApiRequest<VerifyActionResponse>- Return optional
jobIdin the response type- Extract and propagate
job_idfrom successful API responses- Handle error cases without
jobIdThe pattern is uniform across backup, notification, and referral registration.
Also applies to: 81-102, 144-167
app/src/components/NavBar/Points.tsx (1)
57-57: LGTM!Correctly updated to destructure
amountfrom the newusePoints()return signature, maintaining backward compatibility by aliasing it aspoints.app/src/screens/home/HomeScreen.tsx (1)
60-60: LGTM!Correctly updated to destructure
amountfrom the newusePoints()return signature. Consistent with the pattern used in Points.tsx.app/src/utils/points/types.ts (2)
19-19: LGTM!The
PointEventStatustype provides clear lifecycle states for event processing and integrates well with the polling workflow.
10-19: Migration strategy is already in place and working correctly.The
loadEvents()method inpointEventStore.ts(lines 89-95) explicitly validates that each stored event has the requiredstatusfield. Events lacking this field are filtered out with a warning log, so the app gracefully handles existing corrupted or legacy data without crashes. New events are always created withstatus: 'pending'via theaddEvent()method (line 180), ensuring forward compatibility.
| // Resume polling for any pending events that were interrupted by app restart | ||
| // (New events are polled immediately in recordEvents.ts when created) | ||
| get() | ||
| .getUnprocessedEvents() | ||
| .forEach(event => { | ||
| // Use event.id as job_id (id is the job_id) | ||
| pollEventProcessingStatus(event.id).then(result => { | ||
| if (result === 'completed') { | ||
| get().markEventAsProcessed(event.id); | ||
| } else if (result === 'failed') { | ||
| get().markEventAsFailed(event.id); | ||
| } | ||
| }); | ||
| }); |
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.
Consider limiting concurrent polling on startup.
When the app restarts with multiple pending events, the forEach loop initiates polling for all of them simultaneously. With many pending events (e.g., 50+), this could create excessive concurrent backend requests and mobile resource consumption.
Consider implementing a concurrency limit:
// Resume polling for pending events with concurrency limit
const pendingEvents = get().getUnprocessedEvents();
const CONCURRENCY_LIMIT = 5;
for (let i = 0; i < pendingEvents.length; i += CONCURRENCY_LIMIT) {
const batch = pendingEvents.slice(i, i + CONCURRENCY_LIMIT);
await Promise.all(
batch.map(event =>
pollEventProcessingStatus(event.id).then(result => {
if (result === 'completed') {
get().markEventAsProcessed(event.id);
} else if (result === 'failed') {
get().markEventAsFailed(event.id);
}
})
)
);
}🤖 Prompt for AI Agents
In app/src/stores/pointEventStore.ts around lines 98-111, the current forEach
starts a poll for every pending event concurrently which can overwhelm the
backend and device when many events exist; change this to process pending events
in bounded-concurrency batches (e.g., CONCURRENCY_LIMIT = 5) by iterating over
pendingEvents in slices and awaiting Promise.all on each batch (or use a
lightweight semaphore/queue) so only N polls run at once, ensure the surrounding
startup function is async so you can await each batch, and handle/log errors and
still call markEventAsProcessed/markEventAsFailed based on the poll result.
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.
very hard to have more than a few event pending at a time. so i think ok to ignore
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.
@aaronmgdr, understood! Given that pending events are typically limited to just a few at a time, the concurrent polling approach is reasonable for your use case. Thanks for the context.
| /** | ||
| * Polls the server to check if an event has been processed. | ||
| * Checks at: 2s, 4s, 8s, 16s, 32s, 32s, 32s, 32s | ||
| * Returns 'completed' if completed, 'failed' if failed, or null if max attempts reached | ||
| */ | ||
| export async function pollEventProcessingStatus( | ||
| id: string, | ||
| ): Promise<'completed' | 'failed' | null> { | ||
| let delay = 2000; // Start at 2 seconds | ||
| const maxAttempts = 10; |
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.
Update comment to reflect actual polling behavior.
The comment states "Checks at: 2s, 4s, 8s, 16s, 32s, 32s, 32s, 32s" (8 checks), but maxAttempts = 10 results in 10 checks totaling ~222 seconds (~3.7 minutes).
Apply this diff:
/**
* Polls the server to check if an event has been processed.
- * Checks at: 2s, 4s, 8s, 16s, 32s, 32s, 32s, 32s
+ * Checks at: 2s, 4s, 8s, 16s, 32s, 32s, 32s, 32s, 32s, 32s (max ~3.7 minutes total)
* Returns 'completed' if completed, 'failed' if failed, or null if max attempts reached
*/📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /** | |
| * Polls the server to check if an event has been processed. | |
| * Checks at: 2s, 4s, 8s, 16s, 32s, 32s, 32s, 32s | |
| * Returns 'completed' if completed, 'failed' if failed, or null if max attempts reached | |
| */ | |
| export async function pollEventProcessingStatus( | |
| id: string, | |
| ): Promise<'completed' | 'failed' | null> { | |
| let delay = 2000; // Start at 2 seconds | |
| const maxAttempts = 10; | |
| /** | |
| * Polls the server to check if an event has been processed. | |
| * Checks at: 2s, 4s, 8s, 16s, 32s, 32s, 32s, 32s, 32s, 32s (max ~3.7 minutes total) | |
| * Returns 'completed' if completed, 'failed' if failed, or null if max attempts reached | |
| */ | |
| export async function pollEventProcessingStatus( | |
| id: string, | |
| ): Promise<'completed' | 'failed' | null> { | |
| let delay = 2000; // Start at 2 seconds | |
| const maxAttempts = 10; |
🤖 Prompt for AI Agents
In app/src/utils/points/eventPolling.ts around lines 7 to 16, the function
comment incorrectly lists eight checks while the code sets maxAttempts = 10;
update the comment to reflect the actual polling schedule (2s, 4s, 8s, 16s, 32s,
32s, 32s, 32s, 32s, 32s) and include the total approximate duration (~222
seconds / ~3.7 minutes), and keep the return description unchanged.
| if (listRefreshRef.current) { | ||
| await listRefreshRef.current(); | ||
| } |
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.
this looked like a no op
* 2.9 release * 2.9 release * Remove debug console logs from generateTEEInputsRegister function in registerInputs.ts * parse only the passport data during the dsc step * Add ReferralScreen and integrate referral functionality - Introduced ReferralScreen for sharing referral links via messages, WhatsApp, and clipboard. - Updated navigation to include ReferralScreen in the home stack. - Added new icons for sharing and messaging. - Enhanced points utility functions to check user identity document registration and points disclosure status. - Minor adjustments to existing components for better integration with the new referral feature. * fix types * fix font * fix vertical spacing * save current abstraction * clean up linking * clean up spurious ai slop comments * add dinot bold font * minify animations * update fonts and add placeholder animation * fix pipelines * fix order * Update dependencies and enhance Points component functionality - Added `@react-native-masked-view/masked-view` and `react-native-linear-gradient` to dependencies for improved UI components. - Refactored `PointHistoryList` to accept `ListHeaderComponent` and `onRefreshRef` props for better integration with parent components. - Enhanced `Points` component to manage notification and backup point events, including user feedback through modals. - Updated navigation to use `PointsNavBar` for a more cohesive user experience. - Introduced new utility functions for managing incoming points and point event records. * update lock * update lock and project settings * fix line height for android * save wip referral message fix and deeplink setup * Fix whatsapp link (#1352) * add 2 new lines * use path based param instead of query string * use staging url for now * SELF-1089: Fix black screen on Points (#1351) * Fix black screen on Points * Fix: black screen on Referral Page * fix: prevent BlurView from displaying when IdDetailsScreen loses focus * Fix Android message share (#1355) * Referral flow (#1354) * SELF-1139: update getUserAddress() (#1353) * update getUserAddress() * rename getUserAddress to getPointsAddress * [SELF-1098, SELF-1099] polish gratification screen post referrer update history (#1356) * fix: mark document as registered after restoring secret (#1350) * update lock * create useRegisterReferral hook and test * add referral message test * save wip register referral flow request * use register referral from the home screen * fix typing and sort screens * fix linting issues * register poitns and update tests * use package * fix tests * simplify HomeScreen with hooks * fix tests * address tests * abstract points logic, fix types and linting * add test referral flow hook * coderabbit feedback: fix refereral logic issues, remove sensitive logs * move test referral flow button to dev settings screen * close modal after referring and viewing gratification screen * fix tests, remove alert, format --------- Co-authored-by: Seshanth.S <[email protected]> * add gratification bg; use safe bottom padding hook on home screen * prep 2.7.4 as 2.9.0 * manually bump version for custom deploy * match version code * fix types * formatting * fix tests * SELF-1144 - use real points on home screen and improve points screen (#1361) * fix whitespace * move effects for fetching points and incoming points to hooks, add items to deps array so that they refresh when we expect points to change. * cleanup * Add events for new Points Flow (#1362) * remove deeplinkCallback from pointsSelfApp. (#1365) * fix pipelines * SELF-978: wire cloudbackup with points (#1360) * wire cloudbackup with points * wire cloudbackup with points * Remove redundant setSelfPoints() * add signature and simplify POST api requests (#1367) * add signature and simplify POST api requests * better gitleaks ignore * update toml * have gitguardian ignore gitleaks * add buffer lib * update api with 202 success code * update scope and contract-address (#1366) * fix navigation test * SELF-915: Setup and add turnkey utils (#1314) * Setup and add turnkey utils * update CloudBackupScreen * fix: turnkey * add yarn.lock * lint * add podfile.lock * fix deeplink * fix tests: mock turnkey * yarn nice * update .gitleaksignore * patch react-native-svg * fix patch-package * fix lineHeight * points.tsx: fix lineHeight * fix: recover with turnkey disabled state * fix turnkey flow * fix: address generation * minify animations (#1368) * fix pipelines * fix false positives * fix gitguardian --------- Co-authored-by: Justin Hernandez <[email protected]> * enable turnkey only on success * use prod url * fix tests and update mocks * update version and fastlane readme * pointsSelfApp: update scope * bump android version to 117 * incremenet timestamp * abstract points css, hide explore button for now, add points guardrail * better logic * simplify point event list data acquisition (#1375) * simplify point event list data acquisition * explain * Remove BlurView in Points.tsx * Move Points and IncomingPoints to the Point Events Store (#1363) * add polling for event processing. atomically update store state * handle failed states and use real backend api * improve concurrency reliability of pointevents * move points to the store * refresh all points on pull * add points tracking events * fix imports * fix headers * fix import * fix misspelling * enable apps link * remove __DEV__ logging * remove additional referall dev mode features * Add turnkey env * don't allow users to refer themselves * prettier * trim both addresses * fix close webview button * fix tests and format * lint and format * Update point rewards in NavBar component: change earned points from 20 to 44 and from 100 to 32. * Refactor point rewards in NavBar component: replace hardcoded values with constants for backup and notification points, and update subscription state variable names for clarity. * Update POINT_VALUES in types.ts: adjust point rewards for disclosure, notification, and backup events to 8, 44, and 32 respectively. * App/fix backup points (#1381) * Enhance backup completion tracking in Points component: Introduce a ref to manage backup check flag, ensuring points are recorded only when explicitly set, preventing false triggers from other navigation flows. * Update API endpoint in getTotalPoints function: change URL from /distribution to /points for accurate points retrieval. * formatting * update points url * Clear referrer on modal dismiss in useEarnPointsFlow hook to prevent retry loop * use points private key to sign api requests * formatting * save working version of referral confirmation * fix circular dependency * don't fetch private key if unable to fetch points key * add url * add debug info * Refactor optimistic points calculation in usePointEventStore: update return value to only include incomingPoints.amount, marking the optimistic approach for future improvement. * save clean up * clean useReferralConfirmation logic * fix tests * tests pass * standardize android compile sdk version * fix package version * don't log errors * Update app/src/hooks/useReferralConfirmation.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * better test * add turnkey entitlements * fix linting * remove entitlements * prettier and fix lint * update gradle version * update lock file * fix tests * fix build failure * bump android version to 118 * update date * bump version for next build * address failing pipelines due to cache issues * Hide turnkey button (#1387) * prep for 2.9.0 release * fix mobile e2e test * fix tests * bump android version --------- Co-authored-by: Justin Hernandez <[email protected]> Co-authored-by: Seshanth.S <[email protected]> Co-authored-by: Leszek Stachowski <[email protected]> Co-authored-by: Aaron DeRuvo <[email protected]> Co-authored-by: seshanthS <[email protected]> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* 2.9 release * 2.9 release * Remove debug console logs from generateTEEInputsRegister function in registerInputs.ts * parse only the passport data during the dsc step * Add ReferralScreen and integrate referral functionality - Introduced ReferralScreen for sharing referral links via messages, WhatsApp, and clipboard. - Updated navigation to include ReferralScreen in the home stack. - Added new icons for sharing and messaging. - Enhanced points utility functions to check user identity document registration and points disclosure status. - Minor adjustments to existing components for better integration with the new referral feature. * fix types * fix font * fix vertical spacing * save current abstraction * clean up linking * clean up spurious ai slop comments * add dinot bold font * minify animations * update fonts and add placeholder animation * fix pipelines * fix order * Update dependencies and enhance Points component functionality - Added `@react-native-masked-view/masked-view` and `react-native-linear-gradient` to dependencies for improved UI components. - Refactored `PointHistoryList` to accept `ListHeaderComponent` and `onRefreshRef` props for better integration with parent components. - Enhanced `Points` component to manage notification and backup point events, including user feedback through modals. - Updated navigation to use `PointsNavBar` for a more cohesive user experience. - Introduced new utility functions for managing incoming points and point event records. * update lock * update lock and project settings * fix line height for android * save wip referral message fix and deeplink setup * Fix whatsapp link (#1352) * add 2 new lines * use path based param instead of query string * use staging url for now * SELF-1089: Fix black screen on Points (#1351) * Fix black screen on Points * Fix: black screen on Referral Page * fix: prevent BlurView from displaying when IdDetailsScreen loses focus * Fix Android message share (#1355) * Referral flow (#1354) * SELF-1139: update getUserAddress() (#1353) * update getUserAddress() * rename getUserAddress to getPointsAddress * [SELF-1098, SELF-1099] polish gratification screen post referrer update history (#1356) * fix: mark document as registered after restoring secret (#1350) * update lock * create useRegisterReferral hook and test * add referral message test * save wip register referral flow request * use register referral from the home screen * fix typing and sort screens * fix linting issues * register poitns and update tests * use package * fix tests * simplify HomeScreen with hooks * fix tests * address tests * abstract points logic, fix types and linting * add test referral flow hook * coderabbit feedback: fix refereral logic issues, remove sensitive logs * move test referral flow button to dev settings screen * close modal after referring and viewing gratification screen * fix tests, remove alert, format --------- Co-authored-by: Seshanth.S <[email protected]> * add gratification bg; use safe bottom padding hook on home screen * prep 2.7.4 as 2.9.0 * manually bump version for custom deploy * match version code * fix types * formatting * fix tests * SELF-1144 - use real points on home screen and improve points screen (#1361) * fix whitespace * move effects for fetching points and incoming points to hooks, add items to deps array so that they refresh when we expect points to change. * cleanup * Add events for new Points Flow (#1362) * remove deeplinkCallback from pointsSelfApp. (#1365) * fix pipelines * SELF-978: wire cloudbackup with points (#1360) * wire cloudbackup with points * wire cloudbackup with points * Remove redundant setSelfPoints() * add signature and simplify POST api requests (#1367) * add signature and simplify POST api requests * better gitleaks ignore * update toml * have gitguardian ignore gitleaks * add buffer lib * update api with 202 success code * update scope and contract-address (#1366) * fix navigation test * SELF-915: Setup and add turnkey utils (#1314) * Setup and add turnkey utils * update CloudBackupScreen * fix: turnkey * add yarn.lock * lint * add podfile.lock * fix deeplink * fix tests: mock turnkey * yarn nice * update .gitleaksignore * patch react-native-svg * fix patch-package * fix lineHeight * points.tsx: fix lineHeight * fix: recover with turnkey disabled state * fix turnkey flow * fix: address generation * minify animations (#1368) * fix pipelines * fix false positives * fix gitguardian --------- Co-authored-by: Justin Hernandez <[email protected]> * enable turnkey only on success * use prod url * fix tests and update mocks * update version and fastlane readme * pointsSelfApp: update scope * bump android version to 117 * incremenet timestamp * abstract points css, hide explore button for now, add points guardrail * better logic * simplify point event list data acquisition (#1375) * simplify point event list data acquisition * explain * Remove BlurView in Points.tsx * Move Points and IncomingPoints to the Point Events Store (#1363) * add polling for event processing. atomically update store state * handle failed states and use real backend api * improve concurrency reliability of pointevents * move points to the store * refresh all points on pull * add points tracking events * fix imports * fix headers * fix import * fix misspelling * enable apps link * remove __DEV__ logging * remove additional referall dev mode features * Add turnkey env * don't allow users to refer themselves * prettier * trim both addresses * fix close webview button * fix tests and format * lint and format * Update point rewards in NavBar component: change earned points from 20 to 44 and from 100 to 32. * Refactor point rewards in NavBar component: replace hardcoded values with constants for backup and notification points, and update subscription state variable names for clarity. * Update POINT_VALUES in types.ts: adjust point rewards for disclosure, notification, and backup events to 8, 44, and 32 respectively. * App/fix backup points (#1381) * Enhance backup completion tracking in Points component: Introduce a ref to manage backup check flag, ensuring points are recorded only when explicitly set, preventing false triggers from other navigation flows. * Update API endpoint in getTotalPoints function: change URL from /distribution to /points for accurate points retrieval. * formatting * update points url * Clear referrer on modal dismiss in useEarnPointsFlow hook to prevent retry loop * use points private key to sign api requests * formatting * save working version of referral confirmation * fix circular dependency * don't fetch private key if unable to fetch points key * add url * add debug info * Refactor optimistic points calculation in usePointEventStore: update return value to only include incomingPoints.amount, marking the optimistic approach for future improvement. * save clean up * clean useReferralConfirmation logic * fix tests * tests pass * standardize android compile sdk version * fix package version * don't log errors * Update app/src/hooks/useReferralConfirmation.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * better test * add turnkey entitlements * fix linting * remove entitlements * prettier and fix lint * update gradle version * update lock file * fix tests * fix build failure * bump android version to 118 * update date * bump version for next build * address failing pipelines due to cache issues * Hide turnkey button (#1387) * prep for 2.9.0 release * patch turnkey to prevent keychain deletes * add yarn.lock * update yarn.lock * enable buttons * remove console logging from patch * fix test * skip tests * fix test * allow users to advance if they backup via turnkey * Recognize Turnkey backups in onboarding (#1394) * rename var * update var name * remove transform * simplify tests to avoid oom issues * fix check * fix tests --------- Co-authored-by: turnoffthiscomputer <[email protected]> Co-authored-by: Justin Hernandez <[email protected]> Co-authored-by: Leszek Stachowski <[email protected]> Co-authored-by: Aaron DeRuvo <[email protected]> Co-authored-by: turnoffthiscomputer <[email protected]> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
when we add an point event to our store we include
statusaspendingand anidthe id come from the server and is the id if the event in the queue.
this id can be use later to check the status of the event. once we are told it is processed we then mark our event in our point events store as processed
in the mean time any unprocessed events are filtered and reduced and their points are optimistically added with incoming points to give user fast feedback
Summary by CodeRabbit
New Features
Improvements