Skip to content

Conversation

@Dprof-in-tech
Copy link
Collaborator

@Dprof-in-tech Dprof-in-tech commented Oct 3, 2025

Description

This pull request enhances the recipient details form to better handle cases where recipient account verification fails, allowing users to manually enter the recipient name and providing clearer feedback. The main changes include introducing an editable recipient name input, updating error handling, and displaying a warning message when verification is unsuccessful.

Recipient Name Verification & Manual Entry

  • Added a new state variable isRecipientNameEditable to control whether the recipient name field is editable by the user.
  • Updated the recipient verification logic: if the backend responds with "Ok" (indicating verification failure but not an error), the form now enables manual entry of the recipient name and clears any previous value or error.
  • Ensured that the editable state resets appropriately when the recipient or account identifier changes, when a recipient is selected from the modal, or when manual entry is triggered. [1] [2] [3]

User Interface & Feedback

  • Modified the form UI to show an input field for recipient name when manual entry is enabled, including validation and error display.
  • Added a warning message with an icon to inform users when recipient details could not be verified, prompting them to ensure the account number is correct before proceeding.

Icon Usage

  • Imported and used InformationSquareIcon for the warning message to visually highlight verification issues.

References

closes #229
closes #275

Testing

  • This change adds test coverage for new/changed/fixed functionality
Screenshot 2025-10-03 at 14 32 00 Screenshot 2025-11-06 at 07 40 25 Screenshot 2025-11-06 at 07 41 34 Screenshot 2025-11-06 at 07 43 06 Screenshot 2025-11-06 at 07 43 34

Checklist

  • I have added documentation and tests for new/changed functionality in this PR
  • All active GitHub checks for tests, formatting, and security are passing
  • The correct base branch is being used, if not main

By submitting a PR, I agree to Paycrest's Contributor Code of Conduct and Contribution Guide.

Summary by CodeRabbit

  • New Features

    • Inline editable recipient name with validation, info icon and "Learn more" link.
    • Contextual alert beneath recipient details that adapts to name/edit state and records view and "Learn more" interactions.
  • Improvements

    • Selection, verification and currency flows auto-toggle editable vs verified modes and update form controls accordingly.
    • Alerts integrated into the UI flow beneath recipient details.
  • Bug Fixes

    • Reset and error flows refined to keep editable state consistent and improve user feedback.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

Walkthrough

Adds an editable recipient-name flow and an inline recipient safety alert to RecipientDetailsForm. Provider response "Ok" (case-insensitive) enables manual account-name entry (clears name/errors) and shows a learn-more alert; verified responses populate a read-only name. TransactionForm only has whitespace changes.

Changes

Cohort / File(s) Summary
Recipient verification & editable account-name flow
app/components/recipient/RecipientDetailsForm.tsx
Adds InformationSquareIcon, isRecipientNameEditable and alertViewed state, an internal RecipientAlert component, and trackEvent usage. Treats provider response "Ok" (case-insensitive) as requiring manual entry (clears recipientName and errors), renders editable input with validation, shows conditional RecipientAlert, tracks alert view and Learn more clicks, and resets editable state in select/clear/save/change flows.
Whitespace-only formatting
app/pages/TransactionForm.tsx
Minor whitespace/line-break adjustment; no behavioral change.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Form as RecipientDetailsForm
    participant API as Verification API
    participant Analytics

    User->>Form: Enter account number / select institution
    Form->>API: verifyAccount(accountNumber, institution)
    API-->>Form: response (verified name / "Ok" / error)

    alt API returns "Ok" (manual entry required)
        Form->>Form: set isRecipientNameEditable = true and clear recipientName/errors
        Form-->>User: Render editable Account Name input + RecipientAlert
        Form->>Analytics: trackEvent recipient_alert_viewed
        User->>Form: Click "Learn more"
        Form->>Analytics: trackEvent recipient_alert_learn_more_clicked
        User->>Form: Type account name
        Form->>Form: validate recipientName
    else API returns verified name
        Form->>Form: set recipientName, isRecipientNameEditable = false
        Form-->>User: Show verified (read-only) name + RecipientAlert
        Form->>Analytics: trackEvent recipient_alert_viewed
    else API error
        Form->>Form: set recipientNameError, isRecipientNameEditable = false
        Form-->>User: Show verification error (no alert)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review focus:
    • Branching for provider response "Ok" vs verified name vs error.
    • State transitions for isRecipientNameEditable and alertViewed.
    • Form validation, accessibility, and wiring of the editable account-name input.
    • Analytics event placement and payloads for view and Learn more interactions.

Suggested reviewers

  • chibie
  • jeremy0x

Poem

🐇 I saw a name that said “Ok” and cleared the row,
nibbling letters softly so a true name could grow.
Type it in kindly, check each single part,
the little alert keeps watch as you start.
Hop, click "Learn more", then send with a happy heart.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main feature additions: updating warning styles and adding a recipient accuracy reminder alert in the form.
Description check ✅ Passed The PR description covers key changes including editable recipient name state, verification logic updates, UI modifications, and icon usage. References to linked issues (#229, #275) are included with relevant context and screenshots.
Linked Issues check ✅ Passed The implementation addresses all major coding requirements: editable recipient name input when verification fails, conditional alert display with analytics tracking, and proper state management across form interactions.
Out of Scope Changes check ✅ Passed Changes are limited to RecipientDetailsForm.tsx for the alert/editable name feature and minor whitespace adjustments in TransactionForm.tsx. All changes directly support the linked issue objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-add-reciepient-alert-manual-name-verification

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.

@Dprof-in-tech Dprof-in-tech marked this pull request as ready for review November 6, 2025 06:47
@Dprof-in-tech Dprof-in-tech requested a review from chibie as a code owner November 6, 2025 06:47
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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2abf105 and 3cda2d4.

📒 Files selected for processing (2)
  • app/components/recipient/RecipientDetailsForm.tsx (9 hunks)
  • app/pages/TransactionForm.tsx (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app/components/recipient/RecipientDetailsForm.tsx (3)
app/components/AnimatedComponents.tsx (1)
  • AnimatedFeedbackItem (275-288)
app/utils.ts (1)
  • classNames (22-24)
app/components/InputError.tsx (1)
  • InputError (5-20)

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: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 203188b and 44ee74e.

📒 Files selected for processing (1)
  • app/components/recipient/RecipientDetailsForm.tsx (9 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-10T16:44:32.125Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 244
File: app/components/CopyAddressWarningModal.tsx:48-52
Timestamp: 2025-10-10T16:44:32.125Z
Learning: In the CopyAddressWarningModal component (app/components/CopyAddressWarningModal.tsx), selectedNetwork from useNetwork() is always defined and does not require null safety checks when accessing its properties like selectedNetwork.chain.name.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
🧬 Code graph analysis (1)
app/components/recipient/RecipientDetailsForm.tsx (3)
app/components/AnimatedComponents.tsx (1)
  • AnimatedFeedbackItem (275-288)
app/utils.ts (1)
  • classNames (22-24)
app/components/InputError.tsx (1)
  • InputError (5-20)
🔇 Additional comments (7)
app/components/recipient/RecipientDetailsForm.tsx (7)

5-5: LGTM!

The InformationSquareIcon import is correctly added and used in the warning banners below.


61-61: LGTM!

The state declaration for tracking editable recipient name is correct and properly initialized.


128-128: LGTM!

Correctly disables manual entry mode when selecting a saved recipient with a pre-verified name.


243-243: LGTM!

Correctly resets the editable state when the institution changes, ensuring clean state for new verification.


283-284: LGTM!

Correctly disables manual entry and displays an error message when account name verification fails.


332-332: LGTM!

Correctly resets the editable state when clearing all recipient details.


434-459: LGTM!

The conditional rendering for editable vs verified recipient name is well-implemented with proper validation and error handling.

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: 1

♻️ Duplicate comments (1)
app/components/recipient/RecipientDetailsForm.tsx (1)

494-511: Alert condition is incomplete and misses validation error state.

The alert conditions on lines 495 and 503 don't check for form validation errors (errors.recipientName) or the fetching state. Per the PR objectives: "Alert is shown only when recipientName is present and there is no recipientNameError; validation/error state takes precedence."

When a user enters an invalid name (e.g., 1 character), recipientName will contain that value AND errors.recipientName will be set, yet the alert will still render. The previous review comment identified this exact issue.

Apply this diff to fix the conditions:

-      <AnimatedFeedbackItem>
-        {isRecipientNameEditable && recipientName && !recipientNameError && (
+      {recipientName && !recipientNameError && !errors.recipientName && !isFetchingRecipientName && (
+        <AnimatedFeedbackItem>
+          {isRecipientNameEditable ? (
         <div className="min-h-[48px] h-fit w-full dark:bg-warning-background/10 bg-warning-background/35 px-3 py-2 rounded-xl flex items-start gap-2">
           <InformationSquareIcon className="dark:text-warning-text text-warning-foreground w-[36px] h-[36px] md:w-[24px] md:h-[24px]" />
           <p className="text-xs font-light dark:text-warning-text text-warning-foreground leading-tight">
               Unable to verify details. Ensure the recipient&apos;s account number is accurate before proceeding with swap. <a href="#" className="text-lavender-500 text-semibold">Learn more.</a>
           </p>
         </div>
-        )}
-        {!isRecipientNameEditable && recipientName && !recipientNameError && (
+          ) : (
           <div className="min-h-[48px] h-fit w-full dark:bg-warning-background/10 bg-warning-background/35 px-3 py-2 rounded-xl flex items-start gap-2">
           <InformationSquareIcon className="dark:text-warning-text text-warning-foreground w-[36px] h-[36px] md:w-[24px] md:h-[24px]" />
           <p className="text-xs font-light dark:text-warning-text text-warning-foreground leading-tight">
             Make sure the recipient&apos;s account number is accurate before proceeding with swap. <a href="#" className="text-lavender-500 text-semibold">Learn more.</a>
           </p>
         </div>
-        )}
-      </AnimatedFeedbackItem>
+          )}
+        </AnimatedFeedbackItem>
+      )}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 44ee74e and d64cfc0.

📒 Files selected for processing (1)
  • app/components/recipient/RecipientDetailsForm.tsx (9 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:271-280
Timestamp: 2025-11-06T07:08:54.567Z
Learning: In the RecipientDetailsForm component (app/components/recipient/RecipientDetailsForm.tsx), Mobile Money institutions always return "Ok" from the fetchAccountName verification endpoint. Therefore, checking for accountName.toLowerCase() === "ok" is sufficient to handle both verification failures and Mobile Money institutions without needing explicit institution type checks in the frontend.
📚 Learning: 2025-11-06T07:08:54.567Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:271-280
Timestamp: 2025-11-06T07:08:54.567Z
Learning: In the RecipientDetailsForm component (app/components/recipient/RecipientDetailsForm.tsx), Mobile Money institutions always return "Ok" from the fetchAccountName verification endpoint. Therefore, checking for accountName.toLowerCase() === "ok" is sufficient to handle both verification failures and Mobile Money institutions without needing explicit institution type checks in the frontend.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
🧬 Code graph analysis (1)
app/components/recipient/RecipientDetailsForm.tsx (3)
app/components/AnimatedComponents.tsx (1)
  • AnimatedFeedbackItem (275-288)
app/utils.ts (1)
  • classNames (22-24)
app/components/InputError.tsx (1)
  • InputError (5-20)
🔇 Additional comments (9)
app/components/recipient/RecipientDetailsForm.tsx (9)

5-5: LGTM!

Import addition is appropriate for the new warning alerts below.


61-61: LGTM!

State declaration is appropriate for managing the editable/non-editable recipient name flow.


128-128: LGTM!

Correctly resets editable state when selecting a saved recipient, ensuring the verified name is displayed read-only.


243-243: LGTM!

Appropriately resets editable state when institution changes during manual entry flow.


284-284: LGTM!

Correctly disables editable mode when verification encounters an error.


332-332: LGTM!

Properly resets editable state when clearing recipient details.


271-280: LGTM!

The verification logic correctly handles the "Ok" response for manual entry fallback. Based on learnings, Mobile Money institutions always return "Ok" from verification, so this check is sufficient without additional institution type checks.


434-459: LGTM!

The editable input implementation correctly renders when manual entry is required, includes appropriate validation rules, and displays errors properly.


499-507: Fix text accuracy and styling issues.

Multiple small issues with the alert text and styling:

  1. Line 507: Missing "your" before "swap" — requirements specify "your swap"
  2. Lines 499, 507: Missing period before "Learn more"
  3. Lines 499, 507: text-semibold should be font-semibold (correct Tailwind class)

Apply this diff:

-              Unable to verify details. Ensure the recipient&apos;s account number is accurate before proceeding with swap. <a href="#" className="text-lavender-500 text-semibold">Learn more.</a>
+              Unable to verify details. Ensure the recipient&apos;s account number is accurate before proceeding with your swap. <a href="#" className="text-lavender-500 font-semibold">Learn more.</a>
-            Make sure the recipient&apos;s account number is accurate before proceeding with swap. <a href="#" className="text-lavender-500 text-semibold">Learn more.</a>
+            Make sure the recipient&apos;s account number is accurate before proceeding with your swap. <a href="#" className="text-lavender-500 font-semibold">Learn more.</a>
⛔ Skipped due to learnings
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:271-280
Timestamp: 2025-11-06T07:08:54.567Z
Learning: In the RecipientDetailsForm component (app/components/recipient/RecipientDetailsForm.tsx), Mobile Money institutions always return "Ok" from the fetchAccountName verification endpoint. Therefore, checking for accountName.toLowerCase() === "ok" is sufficient to handle both verification failures and Mobile Money institutions without needing explicit institution type checks in the frontend.

…recipient name to include form validation errors
…rification feedback and track alert visibility
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: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d64cfc0 and 4f7330a.

📒 Files selected for processing (1)
  • app/components/recipient/RecipientDetailsForm.tsx (13 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:494-511
Timestamp: 2025-11-06T07:25:06.205Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), the recipient safety alert should only display when all of the following conditions are met: recipientName is present, !recipientNameError (no API error), !errors.recipientName (no form validation errors), and !isFetchingRecipientName. This ensures validation errors take precedence over the alert as per PR #231 requirements.
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:271-280
Timestamp: 2025-11-06T07:08:54.567Z
Learning: In the RecipientDetailsForm component (app/components/recipient/RecipientDetailsForm.tsx), Mobile Money institutions always return "Ok" from the fetchAccountName verification endpoint. Therefore, checking for accountName.toLowerCase() === "ok" is sufficient to handle both verification failures and Mobile Money institutions without needing explicit institution type checks in the frontend.
📚 Learning: 2025-11-06T07:25:06.205Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:494-511
Timestamp: 2025-11-06T07:25:06.205Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), the recipient safety alert should only display when all of the following conditions are met: recipientName is present, !recipientNameError (no API error), !errors.recipientName (no form validation errors), and !isFetchingRecipientName. This ensures validation errors take precedence over the alert as per PR #231 requirements.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
📚 Learning: 2025-11-06T07:08:54.567Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:271-280
Timestamp: 2025-11-06T07:08:54.567Z
Learning: In the RecipientDetailsForm component (app/components/recipient/RecipientDetailsForm.tsx), Mobile Money institutions always return "Ok" from the fetchAccountName verification endpoint. Therefore, checking for accountName.toLowerCase() === "ok" is sufficient to handle both verification failures and Mobile Money institutions without needing explicit institution type checks in the frontend.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
🧬 Code graph analysis (1)
app/components/recipient/RecipientDetailsForm.tsx (3)
app/components/AnimatedComponents.tsx (1)
  • AnimatedFeedbackItem (275-288)
app/utils.ts (1)
  • classNames (22-24)
app/components/InputError.tsx (1)
  • InputError (5-20)

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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22dc0a6 and 919e34e.

📒 Files selected for processing (1)
  • app/components/recipient/RecipientDetailsForm.tsx (13 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.019Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is true (verification failed/returned "Ok"), the recipient safety alert should display when: isRecipientNameEditable && recipientName && !errors.recipientName && !recipientNameError. The !isFetchingRecipientName check is redundant because recipientName is cleared at fetch start and only populated after fetching completes or when the user manually enters it.
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.019Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is false (verification succeeded), the recipient safety alert should display when: !isRecipientNameEditable && recipientName && !recipientNameError. The !errors.recipientName check is unnecessary because in non-editable mode the recipient name is displayed as read-only text (not an input field), so form validation errors cannot occur.
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:271-280
Timestamp: 2025-11-06T07:08:54.567Z
Learning: In the RecipientDetailsForm component (app/components/recipient/RecipientDetailsForm.tsx), Mobile Money institutions always return "Ok" from the fetchAccountName verification endpoint. Therefore, checking for accountName.toLowerCase() === "ok" is sufficient to handle both verification failures and Mobile Money institutions without needing explicit institution type checks in the frontend.
📚 Learning: 2025-11-06T07:37:39.019Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.019Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is true (verification failed/returned "Ok"), the recipient safety alert should display when: isRecipientNameEditable && recipientName && !errors.recipientName && !recipientNameError. The !isFetchingRecipientName check is redundant because recipientName is cleared at fetch start and only populated after fetching completes or when the user manually enters it.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
📚 Learning: 2025-11-06T07:37:39.019Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.019Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is false (verification succeeded), the recipient safety alert should display when: !isRecipientNameEditable && recipientName && !recipientNameError. The !errors.recipientName check is unnecessary because in non-editable mode the recipient name is displayed as read-only text (not an input field), so form validation errors cannot occur.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
📚 Learning: 2025-11-06T07:08:54.567Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:271-280
Timestamp: 2025-11-06T07:08:54.567Z
Learning: In the RecipientDetailsForm component (app/components/recipient/RecipientDetailsForm.tsx), Mobile Money institutions always return "Ok" from the fetchAccountName verification endpoint. Therefore, checking for accountName.toLowerCase() === "ok" is sufficient to handle both verification failures and Mobile Money institutions without needing explicit institution type checks in the frontend.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
🧬 Code graph analysis (1)
app/components/recipient/RecipientDetailsForm.tsx (3)
app/components/AnimatedComponents.tsx (1)
  • AnimatedFeedbackItem (275-288)
app/utils.ts (1)
  • classNames (22-24)
app/components/InputError.tsx (1)
  • InputError (5-20)

Dprof-in-tech and others added 8 commits November 6, 2025 08:54
* feat: complete glitchtip integration with sentry wizard

* fix: add glitchtip url to env

* fix: resolve CodeRabbit review – harden PII handling,  env example & beforeSend parsing

* fix: harden beforeSend fallback

* fix: add base64url-safe JWT decoding in beforeSend for reliable Privy session extraction

* fix: update glitchtip public-url

* fix: add release to withSentryConfig

* refactor: migrate from GlitchTip to Sentry for error tracking

- Updated environment variables in .env.example to reflect Sentry configuration.
- Refactored Sentry initialization in instrumentation-client.ts, sentry.edge.config.ts, and sentry.server.config.ts to use Sentry DSN and environment variables.
- Adjusted config types and values in app/lib/config.ts to support Sentry integration.
- Updated package dependencies to use the latest version of @sentry/nextjs and related packages.
- Ensured proper handling of PII and traces sample rate based on the environment.
* feat: enhance user tracking with server-side event logging

- Added server-side user identification and event tracking in various components including Navbar, TransactionPreview, and TransactionStatus.
- Implemented `identifyServerUser` and `trackServerEvent` functions to log user actions such as login, logout, funding, and transaction events.
- Updated `trackUserEvent` helper function to streamline user identification and event tracking.
- Ensured backward compatibility with existing client-side tracking methods.

* feat: enhance analytics tracking with IP and User-Agent logging

- Updated the analytics identify and track routes to include IP address and User-Agent in tracking requests.
- Refactored event tracking functions to utilize common properties for improved consistency and clarity.
- Ensured that sensitive data is sanitized before being sent to analytics services for geo-inference and device detection.

* refactor: streamline server event tracking and IP inclusion logic

- Removed redundant trackServerEvent call in analytics tracking.
- Updated trackServerEvent invocation to standardize the event name format.
- Enhanced IP address inclusion logic to respect privacy settings, ensuring compliance with user privacy preferences.

* refactor: remove trackUserEvent function

* refactor: improve wallet address handling and event tracking logic

- Updated wallet address retrieval to use undefined instead of null for better type handling.
- Streamlined event tracking by ensuring wallet address is only included when present, allowing for generic event tracking when absent.
- Enhanced the handling of transaction, funding, and authentication events to ensure they are tracked appropriately based on wallet address availability.
- Removed redundant server-side tracking calls in favor of a more consistent client-side approach.

* refactor: remove wallet address retrieval for server-side tracking

* refactor: standardize properties handling in event tracking functions

- Updated event tracking functions to use default empty object for properties parameter, improving consistency and reducing the need for undefined checks.
- This change applies to multiple tracking functions including trackPageView, trackBlogCardClick, and trackSearch.

* Update app/hooks/analytics/useMixpanel.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: Chibuotu Amadi <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
- Removed unused import of config and replaced it with environment variables for Sentry URL and auth token.
- Standardized formatting in serverExternalPackages and webpack configuration for consistency.
- Ensured proper structure in the rules section of the webpack configuration.
- Minor adjustments to maintain code clarity and organization.
…fig.mjs

- Introduced a new configuration option to disable source map uploads in low-memory environments.
- Added a script in package.json for building in low-memory mode, setting appropriate Node options.
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: 0

🧹 Nitpick comments (1)
app/components/recipient/RecipientDetailsForm.tsx (1)

87-107: Consider extracting RecipientAlert for reusability.

The component is well-implemented and correctly handles analytics. Defining it inside the parent function means it's recreated on every render, though React handles this efficiently.

If you prefer, you could extract it outside and pass currency and selectedInstitution?.name as props, but the current approach is acceptable given the tight coupling with parent state.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 919e34e and 7fe4350.

📒 Files selected for processing (2)
  • app/components/recipient/RecipientDetailsForm.tsx (13 hunks)
  • app/pages/TransactionForm.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/pages/TransactionForm.tsx
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is true (verification failed/returned "Ok"), the recipient safety alert should display when: isRecipientNameEditable && recipientName && !errors.recipientName && !recipientNameError. The !isFetchingRecipientName check is redundant because recipientName is cleared at fetch start and only populated after fetching completes or when the user manually enters it.
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is false (verification succeeded), the recipient safety alert should display when: !isRecipientNameEditable && recipientName && !recipientNameError. The !errors.recipientName check is unnecessary because in non-editable mode the recipient name is displayed as read-only text (not an input field), so form validation errors cannot occur.
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:271-280
Timestamp: 2025-11-06T07:08:54.593Z
Learning: In the RecipientDetailsForm component (app/components/recipient/RecipientDetailsForm.tsx), Mobile Money institutions always return "Ok" from the fetchAccountName verification endpoint. Therefore, checking for accountName.toLowerCase() === "ok" is sufficient to handle both verification failures and Mobile Money institutions without needing explicit institution type checks in the frontend.
📚 Learning: 2025-11-06T07:37:39.036Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is true (verification failed/returned "Ok"), the recipient safety alert should display when: isRecipientNameEditable && recipientName && !errors.recipientName && !recipientNameError. The !isFetchingRecipientName check is redundant because recipientName is cleared at fetch start and only populated after fetching completes or when the user manually enters it.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
📚 Learning: 2025-11-06T07:37:39.036Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is false (verification succeeded), the recipient safety alert should display when: !isRecipientNameEditable && recipientName && !recipientNameError. The !errors.recipientName check is unnecessary because in non-editable mode the recipient name is displayed as read-only text (not an input field), so form validation errors cannot occur.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
📚 Learning: 2025-11-06T07:08:54.593Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:271-280
Timestamp: 2025-11-06T07:08:54.593Z
Learning: In the RecipientDetailsForm component (app/components/recipient/RecipientDetailsForm.tsx), Mobile Money institutions always return "Ok" from the fetchAccountName verification endpoint. Therefore, checking for accountName.toLowerCase() === "ok" is sufficient to handle both verification failures and Mobile Money institutions without needing explicit institution type checks in the frontend.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
🧬 Code graph analysis (1)
app/components/recipient/RecipientDetailsForm.tsx (3)
app/components/AnimatedComponents.tsx (1)
  • AnimatedFeedbackItem (275-288)
app/utils.ts (1)
  • classNames (23-25)
app/components/InputError.tsx (1)
  • InputError (5-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build (20.x)
🔇 Additional comments (6)
app/components/recipient/RecipientDetailsForm.tsx (6)

5-5: LGTM!

The new imports (InformationSquareIcon and trackEvent) are correctly used for rendering the alert UI and tracking analytics events.

Also applies to: 14-14


62-62: LGTM!

The new state variables correctly manage the editable name flow and per-instance analytics tracking.

Also applies to: 73-73


216-235: LGTM!

The analytics tracking correctly matches the actual alert visibility conditions per the learnings. The shouldShowAlert logic properly handles both editable and non-editable cases, and the dependency array is complete.

Based on learnings.


318-331: LGTM!

The verification logic correctly handles the "Ok" response by enabling manual entry mode. Per the learnings, Mobile Money institutions always return "Ok", so this check appropriately covers both verification failures and Mobile Money without needing explicit institution type checks.

Based on learnings.


481-506: LGTM!

The editable recipient name input is correctly implemented with appropriate validation (required, minimum 2 characters) and error handling. The integration with react-hook-form and conditional styling work well.


541-554: LGTM!

The alert rendering conditions correctly match the learnings:

  • Editable case (line 542): Checks all four conditions including form validation errors
  • Non-editable case (line 548): Omits errors.recipientName check since the name is read-only

The conditions ensure alerts display only when appropriate, with validation errors taking precedence.

Based on learnings.

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: 0

🧹 Nitpick comments (1)
app/components/recipient/RecipientDetailsForm.tsx (1)

90-127: Update anchor href to use the actual URL for better accessibility.

The "Learn more" link has a real URL defined at line 108 and opens it via JavaScript, but the href attribute still uses "#" as a placeholder. This creates accessibility and UX issues:

  • Screen readers won't announce the correct destination
  • Users can't right-click to copy/open the link
  • Keyboard navigation shows "#" in the status bar
  • Link won't work if JavaScript is disabled
🔎 Suggested improvement

Update the anchor tag to use the actual URL and add security attributes:

         <a
-          href="#"
+          href="https://noblocks.xyz/blog/understanding-account-name-verification-on-noblocks"
+          target="_blank"
+          rel="noopener noreferrer"
           onClick={handleLearnMoreClick}
           className="font-semibold text-lavender-500"
         >
           Learn more.
         </a>

Then update the click handler to prevent default navigation since you're tracking analytics:

     const handleLearnMoreClick = (e: React.MouseEvent) => {
-      e.preventDefault();
       trackEvent("recipient_alert_learn_more_clicked", {
         alert_type: isEditable ? "verification_failed" : "verification_success",
         message: message.substring(0, 100),
         currency: currency,
         institution: selectedInstitution?.name || "",
       });
-      // Open relevant help article in new tab
-      const helpUrl =
-        "https://noblocks.xyz/blog/understanding-account-name-verification-on-noblocks";
-      window.open(helpUrl, "_blank");
     };

This approach:

  • Maintains the analytics tracking
  • Provides proper accessibility
  • Works without JavaScript
  • Follows security best practices with rel="noopener noreferrer"
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7fe4350 and f87d107.

📒 Files selected for processing (1)
  • app/components/recipient/RecipientDetailsForm.tsx (12 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is true (verification failed/returned "Ok"), the recipient safety alert should display when: isRecipientNameEditable && recipientName && !errors.recipientName && !recipientNameError. The !isFetchingRecipientName check is redundant because recipientName is cleared at fetch start and only populated after fetching completes or when the user manually enters it.
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is false (verification succeeded), the recipient safety alert should display when: !isRecipientNameEditable && recipientName && !recipientNameError. The !errors.recipientName check is unnecessary because in non-editable mode the recipient name is displayed as read-only text (not an input field), so form validation errors cannot occur.
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:271-280
Timestamp: 2025-11-06T07:08:54.593Z
Learning: In the RecipientDetailsForm component (app/components/recipient/RecipientDetailsForm.tsx), Mobile Money institutions always return "Ok" from the fetchAccountName verification endpoint. Therefore, checking for accountName.toLowerCase() === "ok" is sufficient to handle both verification failures and Mobile Money institutions without needing explicit institution type checks in the frontend.
📚 Learning: 2025-11-06T07:37:39.036Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is true (verification failed/returned "Ok"), the recipient safety alert should display when: isRecipientNameEditable && recipientName && !errors.recipientName && !recipientNameError. The !isFetchingRecipientName check is redundant because recipientName is cleared at fetch start and only populated after fetching completes or when the user manually enters it.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
📚 Learning: 2025-11-06T07:37:39.036Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:539-552
Timestamp: 2025-11-06T07:37:39.036Z
Learning: In RecipientDetailsForm (app/components/recipient/RecipientDetailsForm.tsx), when isRecipientNameEditable is false (verification succeeded), the recipient safety alert should display when: !isRecipientNameEditable && recipientName && !recipientNameError. The !errors.recipientName check is unnecessary because in non-editable mode the recipient name is displayed as read-only text (not an input field), so form validation errors cannot occur.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
📚 Learning: 2025-11-06T07:08:54.593Z
Learnt from: Dprof-in-tech
Repo: paycrest/noblocks PR: 231
File: app/components/recipient/RecipientDetailsForm.tsx:271-280
Timestamp: 2025-11-06T07:08:54.593Z
Learning: In the RecipientDetailsForm component (app/components/recipient/RecipientDetailsForm.tsx), Mobile Money institutions always return "Ok" from the fetchAccountName verification endpoint. Therefore, checking for accountName.toLowerCase() === "ok" is sufficient to handle both verification failures and Mobile Money institutions without needing explicit institution type checks in the frontend.

Applied to files:

  • app/components/recipient/RecipientDetailsForm.tsx
🧬 Code graph analysis (1)
app/components/recipient/RecipientDetailsForm.tsx (3)
app/components/AnimatedComponents.tsx (1)
  • AnimatedFeedbackItem (275-288)
app/utils.ts (1)
  • classNames (23-25)
app/components/InputError.tsx (1)
  • InputError (5-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build (20.x)
🔇 Additional comments (6)
app/components/recipient/RecipientDetailsForm.tsx (6)

5-9: LGTM!

The new imports for InformationSquareIcon and trackEvent are properly integrated and used throughout the component.

Also applies to: 18-18


236-268: LGTM!

The analytics tracking logic correctly aligns with alert visibility conditions and includes all necessary dependencies. The implementation properly handles both editable and non-editable cases per the established requirements.

Based on learnings.


352-366: LGTM!

The verification logic correctly handles the "Ok" response by enabling manual name entry. The implementation aligns with the backend behavior where Mobile Money institutions and failed verifications return "Ok", making explicit institution type checks unnecessary.

Based on learnings.


514-544: LGTM!

The editable recipient name input is properly implemented with appropriate validation rules, error handling, and styling. The form integration follows React Hook Form best practices.


578-594: LGTM!

The conditional alert rendering correctly implements the visibility logic per the established requirements. The conditions properly distinguish between editable (verification failed) and non-editable (verification succeeded) cases, ensuring alerts display only when appropriate.

Based on learnings.


174-174: LGTM!

The isRecipientNameEditable state is properly reset in all relevant flows (selecting saved recipient, changing institution, clearing details), ensuring correct behavior throughout the component lifecycle.

Also applies to: 323-323, 412-412

@5ran6 5ran6 force-pushed the main branch 2 times, most recently from 06dafbf to 5b287b7 Compare December 19, 2025 23:29
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.

Account Name reconciliation Add recipient alert; require manual account name for Mobile Money/unverified verify

4 participants