Skip to content

Conversation

@aaronmgdr
Copy link
Contributor

@aaronmgdr aaronmgdr commented Nov 7, 2025

when we add an point event to our store we include status as pending and an id
the 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

    • Added event status tracking (pending, completed, failed) for point events
    • Implemented background polling to monitor event processing status in real-time
    • Enhanced incoming points display with real-time updates
  • Improvements

    • Improved point event state management and data persistence
    • Added error handling and validation for stored events
    • Enhanced API integration with typed responses for better reliability

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 7, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (3)
  • main
  • dev
  • staging

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This 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

Cohort / File(s) Summary
Hook API Refactor
app/src/hooks/usePoints.ts, app/src/components/NavBar/Points.tsx, app/src/screens/home/HomeScreen.tsx
Updated usePoints() and useIncomingPoints() to return objects with amount and refetch/expectedDate fields instead of primitives. Components updated to destructure amount property and use new hook shapes.
Store Enhancement
app/src/stores/pointEventStore.ts
Expanded PointEventStore with incoming points state tracking, event processing lifecycle methods (markEventAsProcessed, markEventAsFailed), optimistic point calculation, persistent event storage, and startup recovery via pollEventProcessingStatus. Added points, incomingPoints, refreshPoints, fetchIncomingPoints, refreshIncomingPoints, getUnprocessedEvents, totalOptimisticIncomingPoints APIs.
Event Polling Infrastructure
app/src/utils/points/eventPolling.ts, app/src/utils/points/jobStatus.ts
Introduces pollEventProcessingStatus utility with exponential backoff (up to 10 attempts, 32s cap) and checkEventProcessingStatus for querying job status via HTTP 102/200/404 mapping to pending/completed/failed states.
API Integration & Instrumentation
app/src/utils/points/recordEvents.ts, app/src/utils/points/registerEvents.ts, app/src/utils/points/api.ts
Added jobId tracking through event registration and recording APIs; integrated background polling after event creation. makeApiRequest now supports generic type parameter <T>. Registration functions return jobId when available; internally use addEventToStoreAndPoll to coordinate with polling results.
Type System
app/src/utils/points/types.ts
Added PointEventStatus type ('pending' | 'completed' | 'failed') and extended PointEvent with status field.
UI Integration
app/src/components/PointHistoryList.tsx
Updated refresh flow to call refreshPoints and refreshIncomingPoints concurrently via store, executing all three refresh actions with Promise.all before clearing refreshing state.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Areas requiring extra attention:

  • Hook signature breaking changes (usePoints.ts) — Verify all consumers properly destructure new return shapes and handle the new refetch method; audit existing code for places still expecting primitive returns.
  • Polling race conditions (eventPolling.ts, pointEventStore.ts) — Review exponential backoff logic, edge cases when polling exhausts retries (returns null), and concurrent markEventAsProcessed/markEventAsFailed calls while polling is in flight.
  • Storage persistence & recovery (pointEventStore.ts startup) — Validate event deserialization, error handling for corrupted stored data, and correctness of pollEventProcessingStatus integration during app cold start.
  • jobId flow wiring (recordEvents.ts, registerEvents.ts) — Ensure jobId extraction from API responses is consistent across all three registration functions and that addEventToStoreAndPoll correctly correlates events with polling.
  • Type consistency (types.ts, api.ts) — Verify generic type parameter in makeApiRequest<T> is properly threaded through callers and that new PointEventStatus enum aligns with polling status mappings.

Possibly related PRs

  • SELF-915: Setup and add turnkey utils #1314 — Main PR introducing points system refactor that directly depends on the hook signature changes, store expansions, and component updates in this diff; shared ownership of the centralized points architecture.

Suggested labels

codex

Suggested reviewers

  • remicolin

Poem

📊 Points now flow through the store,
Jobs poll in the background of lore,
Status tracked from start to end,
Async patterns seamlessly blend,
Optimistic totals, race-safe and sure! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main refactoring objective: consolidating Points and IncomingPoints state management into the PointEventStore.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@aaronmgdr aaronmgdr marked this pull request as ready for review November 8, 2025 07:57
@aaronmgdr aaronmgdr marked this pull request as draft November 8, 2025 07:57
@aaronmgdr aaronmgdr changed the title WIP optimistic incoming points Move Points and IncomingPoints to the Point Events Store Nov 10, 2025
@aaronmgdr aaronmgdr marked this pull request as ready for review November 10, 2025 11:53
@aaronmgdr
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 10, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 pointEvents state and loads events via getAllPointEvents(), 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 markEventAsProcessed or markEventAsFailed throw 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-disable for exhaustive-deps suppresses warnings about refreshPoints and refreshIncomingPoints missing 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 markEventAsProcessed method 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

📥 Commits

Reviewing files that changed from the base of the PR and between 7f8ad66 and 447ad85.

📒 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., ***-***-1234 for passport numbers, J*** D*** for names).

Files:

  • app/src/screens/home/HomeScreen.tsx
  • app/src/utils/points/types.ts
  • app/src/utils/points/eventPolling.ts
  • app/src/utils/points/api.ts
  • app/src/utils/points/recordEvents.ts
  • app/src/utils/points/jobStatus.ts
  • app/src/components/NavBar/Points.tsx
  • app/src/components/PointHistoryList.tsx
  • app/src/utils/points/registerEvents.ts
  • app/src/hooks/usePoints.ts
  • app/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.tsx
  • app/src/utils/points/types.ts
  • app/src/utils/points/eventPolling.ts
  • app/src/utils/points/api.ts
  • app/src/utils/points/recordEvents.ts
  • app/src/utils/points/jobStatus.ts
  • app/src/components/NavBar/Points.tsx
  • app/src/components/PointHistoryList.tsx
  • app/src/utils/points/registerEvents.ts
  • app/src/hooks/usePoints.ts
  • app/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.tsx
  • app/src/utils/points/types.ts
  • app/src/utils/points/eventPolling.ts
  • app/src/utils/points/api.ts
  • app/src/utils/points/recordEvents.ts
  • app/src/utils/points/jobStatus.ts
  • app/src/components/NavBar/Points.tsx
  • app/src/components/PointHistoryList.tsx
  • app/src/utils/points/registerEvents.ts
  • app/src/hooks/usePoints.ts
  • app/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 makeApiRequest improves type safety while maintaining backward compatibility with the default unknown type parameter.

app/src/utils/points/recordEvents.ts (1)

52-62: LGTM!

All three record functions consistently check for response.jobId before 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 jobId in the response type
  • Extract and propagate job_id from successful API responses
  • Handle error cases without jobId

The 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 amount from the new usePoints() return signature, maintaining backward compatibility by aliasing it as points.

app/src/screens/home/HomeScreen.tsx (1)

60-60: LGTM!

Correctly updated to destructure amount from the new usePoints() return signature. Consistent with the pattern used in Points.tsx.

app/src/utils/points/types.ts (2)

19-19: LGTM!

The PointEventStatus type 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 in pointEventStore.ts (lines 89-95) explicitly validates that each stored event has the required status field. 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 with status: 'pending' via the addEvent() method (line 180), ensuring forward compatibility.

Comment on lines +98 to +111
// 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);
}
});
});
Copy link
Contributor

@coderabbitai coderabbitai bot Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Copy link
Contributor Author

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

Copy link
Contributor

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.

Comment on lines +7 to +16
/**
* 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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

Suggested change
/**
* 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.

Comment on lines -297 to -299
if (listRefreshRef.current) {
await listRefreshRef.current();
}
Copy link
Contributor Author

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

@aaronmgdr aaronmgdr merged commit 1a5ecaf into app/two-point-nine Nov 10, 2025
10 of 13 checks passed
@aaronmgdr aaronmgdr deleted the aaronmgdr/repoints branch November 10, 2025 16:23
transphorm added a commit that referenced this pull request Nov 11, 2025
* 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>
transphorm added a commit that referenced this pull request Nov 12, 2025
* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants