Skip to content

Conversation

kushagrasarathe
Copy link
Contributor

@kushagrasarathe kushagrasarathe commented Aug 19, 2025

  • contributes to TASK-13784 : handles history changes for request fulfillments using bank accounts and send link claims to bank accounts

ui changes

  • on requestor sides looks the way it used to
    Screenshot 2025-08-19 at 4 28 26 PM

  • on payers side, if it's being fulfilled using bank:
    image
    Screenshot 2025-08-19 at 4 29 31 PM

Copy link

Copy link
Contributor

coderabbitai bot commented Aug 19, 2025

Walkthrough

Refactors TransactionDetails: extracts a new TransactionDetailsReceipt component and updates Drawer integration, mapping, and enums. Introduces user verification/interaction labeling (VerifiedUserLabel), tooltip system, and interaction hooks. Threads haveSentMoneyToUser, KYC fields, and external wallet/bridge semantics across UI and types. Adds chargeId to onramp flows. Removes AchievementsBadge and related AvatarWithBadge props.

Changes

Cohort / File(s) Summary
Transaction details refactor & mapping
src/components/TransactionDetails/TransactionDetailsDrawer.tsx, src/components/TransactionDetails/TransactionDetailsReceipt.tsx, src/components/TransactionDetails/transactionTransformer.ts, src/hooks/useTransactionHistory.ts, src/components/TransactionDetails/TransactionCard.tsx, src/components/TransactionDetails/TransactionDetailsHeaderCard.tsx, src/components/TransactionDetails/TransactionAvatarBadge.tsx
Extracts receipt to new module and makes Drawer a thin wrapper. Expands transformer with fulfillmentType/bridgeTransferId, haveSentMoneyToUser, status type changes, and BANK_SEND_LINK_CLAIM. Updates card/header/avatar to support bank_request_fulfillment and verified labeling.
App payment/receipt flow updates
src/app/[...recipient]/client.tsx, src/components/Claim/Claim.tsx
Switches to new Receipt import, adds external_wallet flow handling, resolves counterparty, fetches interactions, and passes isVerified/haveSentMoneyToUser into details/receipt.
Onramp payloads (chargeId)
src/app/actions/onramp.ts, src/hooks/useCreateOnramp.ts, src/components/Request/views/ReqFulfillBankFlowManager.tsx
Adds optional chargeId to onramp guest/standard creation APIs and propagates in payloads.
User verification, interactions, and headers
src/components/UserHeader/index.tsx, src/components/Profile/components/ProfileHeader.tsx, src/components/Profile/components/PublicProfile.tsx, src/components/User/UserCard.tsx, src/components/Profile/AvatarWithBadge.tsx
Introduces VerifiedUserLabel with tooltips/badges; removes isVerified/achievementsBadge from AvatarWithBadge. Threads haveSentMoneyToUser and KYC-driven isVerified across headers and user cards.
Search and recent users with interactions
src/components/SearchUsers/index.tsx, src/components/SearchUsers/SearchResults.tsx, src/components/RouterViewWrapper/index.tsx, src/hooks/useRecentUsers.ts
Updates recent/search user types to RecentUser with kycStatus; adds interactions prop; renders names via VerifiedUserLabel; computes and fetches interactions.
Interaction and user lookup hooks
src/hooks/useUserInteractions.ts, src/hooks/useUserByUsername.ts
Adds hooks to fetch per-user interaction status and to resolve user by username.
Direct request recipient resolution
src/components/Request/direct-request/views/Initial.direct.request.view.tsx
Switches to useUserByUsername and useUserInteractions; updates validation and API usage; passes verification/interaction props to UserCard.
Home history interaction flags
src/components/Home/HomeHistory.tsx
Computes related userIds, fetches interactions, and passes haveSentMoneyToUser to TransactionCard.
Tooltip system
src/components/Tooltip/TooltipContent.tsx, src/components/Tooltip/index.tsx
Adds tooltip content and wrapper components with dynamic positioning and portal rendering.
Icons and display adjustments
src/components/Global/Icons/Icon.tsx, src/components/Global/Icons/double-check.tsx, src/components/Global/DisplayIcon.tsx, src/components/Global/TokenSelector/Components/NetworkButton.tsx
Adds double-check icon; removes achievementsBadgeSize usage from AvatarWithBadge call sites.
Services/types updates
src/services/services.types.ts, src/services/users.ts, src/services/sendLinks.ts
Replaces PaymentResponse with PaymentCreationResponse; adds CASHOUT enum member; extends KYC fields; renames ApiUser totals, adds RecentUser type; adds usersApi.getInteractionStatus; extends SendLink types with KYC/account fields.
Removed badge component
src/components/Global/Badges/AchievementsBadge.tsx
Deletes AchievementsBadge and its exported type.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested reviewers

  • kushagrasarathe

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/links-v2.1-history

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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)
src/components/TransactionDetails/transactionTransformer.ts (1)

387-392: Guard against missing recipientAccount in bankAccountDetails to avoid runtime crashes

If recipientAccount is unexpectedly absent for these types, this will throw during transform. Guard with optional chaining/fallback.

Apply this diff:

-        bankAccountDetails:
-            entry.type === EHistoryEntryType.BRIDGE_OFFRAMP || entry.type === EHistoryEntryType.BANK_SEND_LINK_CLAIM
-                ? {
-                      identifier: entry.recipientAccount.identifier,
-                      type: entry.recipientAccount.type,
-                  }
-                : undefined,
+        bankAccountDetails:
+            entry.type === EHistoryEntryType.BRIDGE_OFFRAMP || entry.type === EHistoryEntryType.BANK_SEND_LINK_CLAIM
+                ? (entry.recipientAccount?.identifier && entry.recipientAccount?.type
+                      ? {
+                            identifier: entry.recipientAccount.identifier,
+                            type: entry.recipientAccount.type,
+                        }
+                      : undefined)
+                : undefined,
♻️ Duplicate comments (1)
src/components/TransactionDetails/TransactionDetailsReceipt.tsx (1)

852-865: Cancel on-ramp uses transaction.id; must use bridgeTransferId (avoids cancelling wrong entity)

cancelOnramp expects the bridge transferId. transaction.id is mapped from entry.uuid. Use extraDataForDrawer.bridgeTransferId with a guard.

Apply this diff:

-                            try {
-                                const result = await cancelOnramp(transaction.id)
+                            try {
+                                const transferId = transaction.extraDataForDrawer?.bridgeTransferId
+                                if (!transferId) {
+                                    console.error('Missing bridgeTransferId for on-ramp cancellation')
+                                    setIsLoading(false)
+                                    return
+                                }
+                                const result = await cancelOnramp(transferId)
🧹 Nitpick comments (3)
src/components/TransactionDetails/transactionTransformer.ts (1)

178-183: Request → bank fulfillment path is correctly introduced; verify isPeerActuallyUser semantics

The new mapping for REQUEST + fulfillmentType === 'bridge' (payer view) looks consistent with the new UI flows. One nuance: setting isPeerActuallyUser to include senderAccount.isUser may suppress isLinkTransaction for bank-fulfilled requests. If UI treats “bank” as non-link regardless, this is fine; otherwise, consider narrowing isPeerActuallyUser to recipientAccount (the peer).

Would you like me to generate a quick patch to compute isPeerActuallyUser solely from recipientAccount?.isUser for this path?

src/components/TransactionDetails/TransactionDetailsReceipt.tsx (2)

29-38: Guard getBankAccountLabel against undefined or unexpected types

Callers may pass an undefined or unknown type. Avoid toLowerCase on undefined and default to “Account Number”.

Apply this diff:

-const getBankAccountLabel = (type: string) => {
-    switch (type.toLowerCase()) {
+const getBankAccountLabel = (type?: string) => {
+    switch ((type ?? '').toLowerCase()) {
         case 'iban':
             return 'IBAN'
         case 'clabe':
             return 'CLABE'
         default:
             return 'Account Number'
     }
 }

949-980: Guard username/link before claiming to self in Cancel Link Modal

Avoid non-null assertions on user and link to prevent runtime errors in edge cases.

Apply this diff:

-                    onClick={() => {
+                    onClick={() => {
                         setIsLoading(true)
                         setShowCancelLinkModal(false)
-                        sendLinksApi
-                            .claim(user!.user.username!, transaction.extraDataForDrawer!.link!)
+                        const username = user?.user?.username
+                        const link = transaction.extraDataForDrawer?.link
+                        if (!username || !link) {
+                            console.error('Missing username or link for self-claim cancellation path')
+                            setIsLoading(false)
+                            return
+                        }
+                        sendLinksApi
+                            .claim(username, link)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1a51de9 and 4e9a258.

📒 Files selected for processing (7)
  • src/app/[...recipient]/client.tsx (1 hunks)
  • src/components/Request/views/ReqFulfillBankFlowManager.tsx (1 hunks)
  • src/components/TransactionDetails/TransactionAvatarBadge.tsx (1 hunks)
  • src/components/TransactionDetails/TransactionCard.tsx (4 hunks)
  • src/components/TransactionDetails/TransactionDetailsReceipt.tsx (1 hunks)
  • src/components/TransactionDetails/transactionTransformer.ts (5 hunks)
  • src/hooks/useCreateOnramp.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/app/[...recipient]/client.tsx
  • src/hooks/useCreateOnramp.ts
  • src/components/Request/views/ReqFulfillBankFlowManager.tsx
  • src/components/TransactionDetails/TransactionCard.tsx
  • src/components/TransactionDetails/TransactionAvatarBadge.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/components/TransactionDetails/TransactionDetailsReceipt.tsx (10)
src/components/TransactionDetails/transactionTransformer.ts (1)
  • TransactionDetails (32-110)
src/redux/hooks.ts (1)
  • useUserStore (13-13)
src/hooks/wallet/useWallet.ts (1)
  • useWallet (21-124)
src/utils/general.utils.ts (5)
  • formatAmount (325-365)
  • getInitialsFromName (1179-1186)
  • formatDate (862-874)
  • formatIban (890-897)
  • shortenAddress (43-49)
src/utils/currency.ts (1)
  • getDisplayCurrencySymbol (4-28)
src/components/Payment/PaymentInfoRow.tsx (1)
  • PaymentInfoRow (7-81)
src/services/charges.ts (1)
  • chargesApi (6-94)
src/constants/query.consts.ts (1)
  • TRANSACTIONS (2-2)
src/app/actions/onramp.ts (1)
  • cancelOnramp (26-64)
src/services/sendLinks.ts (1)
  • sendLinksApi (83-202)
🔇 Additional comments (6)
src/components/TransactionDetails/transactionTransformer.ts (5)

60-61: New bridge-related fields are well-scoped

Adding fulfillmentType and bridgeTransferId to extraDataForDrawer is the right call and keeps bridge-specific concerns out of the top-level shape.


229-234: BANK_SEND_LINK_CLAIM case mapping looks correct

Renaming and mapping this type to direction 'bank_claim' and card 'bank_withdraw' aligns with the new enum member and downstream UI usage.


377-383: Deposit instructions forwarding for bridge-fulfilled requests is correct

Threading depositInstructions when original type is BRIDGE_ONRAMP or when REQUEST is bank-fulfilled ensures the receipt can render instructions in both paths.


129-133: TransactionDirection includes ‘bank_request_fulfillment’ and is fully supported
Confirmed that the TransactionDirection union (in src/components/TransactionDetails/TransactionDetailsHeaderCard.tsx:13–24) lists 'bank_request_fulfillment', and all downstream UI components handle it correctly:

  • TransactionDetailsHeaderCard.tsx (switch case at line 117)
  • TransactionCard.tsx (type union at line 26; switch/icon/text at lines 72, 233–252)
  • TransactionAvatarBadge.tsx (switch case at line 57)

No further changes needed.


265-267: Validate Bridge Flow Status Strings

Before merging, please confirm that entries with entry.extraData?.fulfillmentType === 'bridge' (on REQUEST) emit the expected status values (e.g. AWAITING_FUNDS, PAYMENT_SUBMITTED, etc.) so they map correctly to the intended pill states in the UI. I wasn’t able to surface any example statuses for the bridge flow in our local fixtures or mocks—please manually verify against your sample data or API responses.

• Check your bridge-related fixtures or mock responses for actual status strings.
• Ensure those status values line up with the cases in transactionTransformer.ts so the UI pills render as intended.

src/components/TransactionDetails/TransactionDetailsReceipt.tsx (1)

171-201: Amount display rules for bank flows look solid

The USD vs original-currency handling for bank_deposit/bank_request_fulfillment and the reward token branchings are consistent with the transformer’s currency shaping.

@kushagrasarathe kushagrasarathe changed the base branch from feat/links-v2.1-req to peanut-wallet-dev August 22, 2025 06:54
@kushagrasarathe kushagrasarathe changed the base branch from peanut-wallet-dev to feat/links-v2.1-req August 22, 2025 06:57
@kushagrasarathe kushagrasarathe changed the base branch from feat/links-v2.1-req to peanut-wallet-dev August 22, 2025 07:09
* feat: badges updates and hook to check for interactions

* feat: handle badges for receipts and drawer header

* feat: handle badges on request and send flow

* feat: tooltip for badges

* fix: tooltip positioning
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: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
src/components/Global/DisplayIcon.tsx (1)

24-35: Update AvatarWithBadge “extra-small” size to 24×24

To match the DisplayIcon branch (which always renders a 24×24 px image within an h-6 w-6 container), adjust the extra-small mapping in AvatarWithBadge:

• In src/components/Profile/AvatarWithBadge.tsx, change the sizeClasses for 'extra-small' from h-8 w-8 text-xs (32 px) to h-6 w-6 text-xs (24 px).
• Likewise, update the iconSizeMap entry for 'extra-small' from 16 to 24 so non-image icons align with the container.

--- a/src/components/Profile/AvatarWithBadge.tsx
+++ b/src/components/Profile/AvatarWithBadge.tsx
@@ -40,8 +40,8 @@ const sizeClasses: Record<AvatarSize, string> = {
-    'extra-small': 'h-8 w-8 text-xs',
+    'extra-small': 'h-6 w-6 text-xs',
     small:        'h-12 w-12 text-sm',
     medium:       'h-16 w-16 text-2xl',
     large:        'h-24 w-24 text-3xl',
@@ -47,7 +47,7 @@ const iconSizeMap: Record<AvatarSize, number> = {
-    'extra-small': 16,
+    'extra-small': 24,
     small:        18,
     medium:       32,
     large:        48,

• Verified that neither achievementsBadgeSize nor isVerified (the removed props) remain on AvatarWithBadge. – no usages found in its file or tests.

src/hooks/useRecentUsers.ts (1)

17-27: Potential runtime crash: username/fullName/userId are optional but used with non-null assertions.
HistoryEntry accounts mark username/fullName/userId as optional. Using account.username.toLowerCase() and pushing !-asserted fields can crash if the API omits them.

Proposed safer implementation:

import { useMemo } from 'react'
import { useTransactionHistory, HistoryEntry } from '@/hooks/useTransactionHistory'
import { RecentUser } from '@/services/users'

export function useRecentUsers() {
  const { data } = useTransactionHistory({ mode: 'latest', limit: 20 })

  return useMemo<RecentUser[]>(() => {
    if (!data) return []

    const seen = new Set<string>()
    const out: RecentUser[] = []

    for (const entry of data.entries) {
      const account =
        entry.userRole === 'SENDER' ? entry.recipientAccount :
        entry.userRole === 'RECIPIENT' ? entry.senderAccount : undefined

      if (!account?.isUser) continue

      const idKey = account.userId ? `id:${account.userId}` : null
      const unameLower = account.username?.toLowerCase()
      const unameKey = unameLower ? `u:${unameLower}` : null

      if (!idKey && !unameKey) continue // skip incomplete user records

      const key = idKey ?? unameKey!
      if (seen.has(key)) continue
      seen.add(key)

      out.push({
        userId: account.userId ?? `unknown:${unameLower}`, // or skip if you must require userId
        username: account.username ?? 'unknown',
        fullName: account.fullName ?? account.username ?? 'Unknown',
        kycStatus: entry.isVerified ? 'approved' : 'not_started',
      })
    }
    return out
  }, [data])
}

If userId is required elsewhere, replace the fallback with continue to skip such entries.

src/components/Payment/PaymentForm/index.tsx (1)

356-377: Avoid logging PII-rich payloads; gate debug logs in non-production

Both logs dump the full payment payload (includes recipient, attachment refs, etc.). Gate behind NODE_ENV !== 'production' and avoid logging full objects.

-                console.log('Initiating PINTA payment with payload:', payload)
+                if (process.env.NODE_ENV !== 'production') {
+                    console.debug('Initiating PINTA payment', { type: 'PINTA', keys: Object.keys(payload) })
+                }
@@
-        console.log('Initiating payment with payload:', payload)
+        if (process.env.NODE_ENV !== 'production') {
+            console.debug('Initiating payment', { keys: Object.keys(payload) })
+        }

Also applies to: 439-441

src/components/TransactionDetails/TransactionDetailsHeaderCard.tsx (1)

39-45: Set getTitle return type to string; remove unsafe cast at callsite

getTitle only returns strings. Advertising React.ReactNode and then casting back to string is unnecessary and could mask future type slips.

-const getTitle = (
+const getTitle = (
   direction: TransactionDirection,
   userName: string,
   isLinkTransaction?: boolean,
   status?: StatusType
-): React.ReactNode => {
+): string => {
@@
-    return titleText
+    return titleText
@@
-                        <VerifiedUserLabel
-                            name={getTitle(direction, userName, isLinkTransaction, status) as string}
+                        <VerifiedUserLabel
+                            name={getTitle(direction, userName, isLinkTransaction, status)}
                             isVerified={isVerified}
                             className="flex items-center gap-1"
                             haveSentMoneyToUser={haveSentMoneyToUser}
                             iconSize={18}
                         />

Also applies to: 109-110, 171-179

src/components/SearchUsers/index.tsx (1)

84-96: Fix input focus: effect is targeting a different ref than the input in the portal

SearchUsers defines inputRef and focuses it on expand, but the actual input lives inside SearchContent with a different inputRef. Result: focus never happens. Move the focus logic into SearchContent (where the real input ref is) and remove the unused ref/effect from SearchUsers.

Apply this diff:

@@
-    const inputRef = useRef<HTMLInputElement>(null)
@@
-    // focus input when expanded
-    useEffect(() => {
-        if (isExpanded && inputRef.current) {
-            // small delay to ensure the portal is mounted
-            setTimeout(() => {
-                inputRef.current?.focus()
-            }, 100)
-        }
-    }, [isExpanded])

And inside SearchContent, add the focus-on-mount effect:

@@
 const SearchContent = ({ closePortal, recentTransactions }: SearchContentProps) => {
     const inputRef = useRef<HTMLInputElement>(null)
@@
     const router = useRouter()
 
+    // focus input when the portal content mounts
+    useEffect(() => {
+        const t = setTimeout(() => inputRef.current?.focus(), 0)
+        return () => clearTimeout(t)
+    }, [])
♻️ Duplicate comments (3)
src/components/TransactionDetails/TransactionDetailsReceipt.tsx (3)

401-419: Use bridgeTransferId for transfer ID display when available


862-870: Use bridgeTransferId for onramp cancellation


900-914: Add defensive check for bridgeTransferId

🧹 Nitpick comments (37)
src/components/Global/DisplayIcon.tsx (1)

39-41: A11y: Add alt semantics to the fallback avatar.

When the image fails, screen readers lose the altText. Mirror the img semantics on the fallback container so assistive tech still announces the label.

Apply this diff:

-    <div className={`${sizeClass} flex items-center justify-center rounded-full bg-gray-200 ${className}`.trim()}>
+    <div
+      className={`${sizeClass} flex items-center justify-center rounded-full bg-gray-200 ${className}`.trim()}
+      role="img"
+      aria-label={altText}
+    >
       <AvatarWithBadge name={fallbackName} size={badgeSize} />
     </div>
src/components/Global/TokenSelector/Components/NetworkButton.tsx (2)

51-53: A11y: Hide decorative fallback avatar to avoid duplicate announcements.

The button already exposes the chain name via the adjacent text. Mark the fallback avatar as aria-hidden to prevent screen readers from announcing the label twice.

Apply this diff:

-                ) : (
-                    <AvatarWithBadge size="extra-small" name={chainName} />
-                )}
+                ) : (
+                    <div aria-hidden="true">
+                      <AvatarWithBadge size="extra-small" name={chainName} />
+                    </div>
+                )}

23-24: Resilience: Reset error flag when the icon URI changes.

If chainIconURI changes after an error (e.g., user switches networks), the stale error flag forces the fallback even when the new image would load. Reset it on URI changes.

Apply this diff:

-import React, { useState } from 'react'
+import React, { useEffect, useState } from 'react'
@@
-    const [chainImageError, setChainImageError] = useState(false)
+    const [chainImageError, setChainImageError] = useState(false)
+    useEffect(() => {
+        setChainImageError(false)
+    }, [chainIconURI])

Also applies to: 43-50, 52-53

src/components/Global/Icons/double-check.tsx (2)

3-10: Add accessible title support and default aria-hidden/focusable for better a11y.
Most icons are decorative, but some need an accessible name. Recommend optional title prop + aria-hidden default.

Apply this diff to make the icon optionally accessible:

-import { FC, SVGProps } from 'react'
-
-export const DoubleCheckIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
-    <svg width="15" height="9" viewBox="0 0 15 9" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
-        <path
+import { FC, SVGProps } from 'react'
+
+export const DoubleCheckIcon: FC<SVGProps<SVGSVGElement> & { title?: string }> = ({ title, ...props }) => (
+    <svg
+        width="15"
+        height="9"
+        viewBox="0 0 15 9"
+        fill="none"
+        xmlns="http://www.w3.org/2000/svg"
+        role="img"
+        aria-hidden={title ? undefined : true}
+        focusable="false"
+        {...props}
+    >
+        {title ? <title>{title}</title> : null}
+        <path
             d="M10.3514 1.12054C10.1078 0.876949 9.71434 0.876949 9.47075 1.12054L5.94811 4.64318L6.82877 5.52384L10.3514 1.99495C10.5888 1.75761 10.5888 1.35788 10.3514 1.12054ZM12.9996 1.11429L6.82877 7.28516L4.65523 5.11786C4.41164 4.87427 4.01815 4.87427 3.77457 5.11786C3.53098 5.36145 3.53098 5.75493 3.77457 5.99852L6.38532 8.60927C6.6289 8.85286 7.02239 8.85286 7.26598 8.60927L13.8803 2.0012C14.1239 1.75761 14.1239 1.36412 13.8803 1.12054H13.8741C13.6367 0.870703 13.2432 0.870703 12.9996 1.11429ZM0.245678 6.00477L2.85643 8.61552C3.10002 8.8591 3.4935 8.8591 3.73709 8.61552L4.1743 8.17831L1.12634 5.11786C0.882752 4.87427 0.489265 4.87427 0.245678 5.11786C0.00209156 5.36145 0.00209156 5.76118 0.245678 6.00477Z"
             fill="currentColor"
         />
     </svg>
 )

4-4: Nit: consider dropping fixed width/height or switch to 1em for font-size scaling.
Icon.tsx already overrides width/height; removing defaults (or using 1em) avoids double-specification.

src/components/Global/Icons/Icon.tsx (1)

61-121: Avoid drift: derive IconName from the map keys to remove duplication.
Today you must update both the union and the map for each new icon. Deriving IconName from iconComponents prevents mistakes.

You can restructure like this (illustrative):

// 1) Define the map first and mark it const
const iconComponents = {
  /* existing entries... */
  'double-check': DoubleCheckIcon,
} as const satisfies Record<string, ComponentType<SVGProps<SVGSVGElement>>>

// 2) Derive the union
export type IconName = keyof typeof iconComponents

// 3) IconProps stays the same
export interface IconProps extends SVGProps<SVGSVGElement> {
  name: IconName
  size?: number | string
}

If reordering is undesirable, consider a lint rule/test that validates the union equals the map keys.

Also applies to: 127-187

src/services/sendLinks.ts (1)

34-39: Type consistency: use AccountType for account.type and centralize KYC status.

  • accounts[].type is a string here but elsewhere uses AccountType. Unify to prevent typos and narrow types.
  • kycStatus is a plain string; consider a shared KycStatus union/enum across the app to avoid mismatches.

Apply this diff for account.type:

 export type SendLink = {
   /* ... */
   sender: {
     userId: string
     username: string
     fullName: string
-    kycStatus: string
+    kycStatus: string
     accounts: {
       identifier: string
-      type: string
+      type: AccountType
     }[]
   }
   claim?: {
     /* ... */
     recipient?: {
-      userId: string
+      userId: string
       username: string
       fullName: string
-      kycStatus: string
+      kycStatus: string
       accounts: {
         identifier: string
-        type: string
+        type: AccountType
       }[]
     }
   }

And add the import at the top of this file:

import { AccountType } from '@/interfaces'

For kycStatus, consider introducing a shared KycStatus type in src/services/users.ts and reuse it here.

Also applies to: 46-54

src/services/users.ts (2)

33-34: RecentUser pick is appropriate; consider exporting a shared KycStatus type.
Multiple files assign string literals like 'approved'/'not_started'. A central union (e.g., 'approved' | 'pending' | 'not_started' | 'rejected') avoids drift.


50-61: Add response.ok check to align with stricter error handling used elsewhere.
Currently this will attempt to parse JSON even on 4xx/5xx which might not match the declared return type.

Apply this diff:

   getInteractionStatus: async (userIds: string[]): Promise<Record<string, boolean>> => {
     // returns a map of userIds to booleans indicating if the current user has sent money to them
     const response = await fetchWithSentry(`${PEANUT_API_URL}/users/interaction-status`, {
       method: 'POST',
       headers: {
         'Content-Type': 'application/json',
         Authorization: `Bearer ${Cookies.get('jwt-token')}`,
       },
       body: JSON.stringify({ userIds }),
     })
-    return await response.json()
+    if (!response.ok) {
+      throw new Error(`HTTP error! status: ${response.status}`)
+    }
+    return await response.json()
   },
src/hooks/useRecentUsers.ts (1)

26-26: Optional: extract KYC mapping into a helper to keep consistency.
Centralize mapping from isVerified to kycStatus to avoid diverging strings across files.

-                kycStatus: entry.isVerified ? 'approved' : 'not_started',
+                kycStatus: entry.isVerified ? 'approved' : 'not_started', // consider mapVerificationToKycStatus(entry.isVerified)
src/hooks/useTransactionHistory.ts (2)

74-75: isVerified on HistoryEntry: clarify semantics (peer vs self) and keep consistent across UI

Good addition. Please document whether isVerified refers to the counterparty (peer) or the authenticated user. The transformer passes isVerified straight through to the drawer and labels. Any ambiguity will surface as incorrect badges in VerifiedUserLabel.


246-253: Guard ‘public’ mode against missing username to avoid 404s (/users/undefined/history)

When mode === 'public', fetchHistory closes over username but does not guard against it being undefined. Add an enable guard to the query.

Apply:

   if (mode === 'public') {
     return useQuery({
       queryKey: [TRANSACTIONS, 'public', username, { limit }],
-      queryFn: () => fetchHistory({ limit, isPublic: true }),
-      enabled,
+      queryFn: () => fetchHistory({ limit, isPublic: true }),
+      enabled: enabled && !!username,
       staleTime: 15 * 1000, // 15 seconds
     })
   }

Optionally also assert in fetchHistory when isPublic && !username to fail fast.

src/services/services.types.ts (2)

147-149: kycStatus typed as string — prefer a discriminated union for safety

Adding kycStatus is aligned with VerifiedUserLabel. Consider tightening the type to known states to prevent accidental string drift (e.g., 'APPROVED' | 'PENDING' | 'REJECTED' | 'FAILED'), ideally sourced from a shared server contract.

If you have the canonical list server-side, I can generate a shared KycStatus type and replace all string usages repo-wide.


202-209: Duplicated username and kycStatus at multiple nesting levels — define source of truth

recipientAccount.username and recipientAccount.user.username (and the same for kycStatus) can diverge. Decide which field is canonical for UI consumption and either:

  • Deprecate one in the API/types, or
  • Add a doc comment and normalize in mappers to a single field.
src/components/TransactionDetails/transactionTransformer.ts (1)

271-277: Status mapping: bridge flows now include BANK_SEND_LINK_CLAIM and fulfillmentType === 'bridge'

Nice consolidation. This ensures consistent pill states across onramp/offramp/bridge-fulfilled requests. Consider adding a brief comment noting these statuses are from the provider to aid future maintenance.

Also applies to: 278-303

src/components/RouterViewWrapper/index.tsx (2)

27-33: Build userIds defensively (filter undefined) to avoid accidental “undefined” entries

If any source item lacks userId, Set would get an "undefined" value. Filter falsy ids.

Apply:

 const userIds = useMemo(() => {
-    const ids = new Set<string>()
-    searchResults.forEach((user) => ids.add(user.userId))
-    recentTransactions.forEach((user) => ids.add(user.userId))
-    return Array.from(ids)
+    const ids = new Set<string>()
+    searchResults.forEach((u) => u.userId && ids.add(u.userId))
+    recentTransactions.forEach((u) => u.userId && ids.add(u.userId))
+    return Array.from(ids)
 }, [searchResults, recentTransactions])

35-36: Interactions fetched but loading state unused — consider passing through to SearchResults

If SearchResults can reflect loading/error for badges, pass isLoading/isError to prevent “badge pop-in.”

-const { interactions } = useUserInteractions(userIds)
+const { interactions, isLoading: isInteractionsLoading, isError: isInteractionsError } = useUserInteractions(userIds)
 ...
 <SearchResults
   ...
-  interactions={interactions}
+  interactions={interactions}
+  interactionsLoading={isInteractionsLoading}
+  interactionsError={isInteractionsError}
 />

Check that SearchResults supports these optional props, or add them.

Also applies to: 67-68

src/components/User/UserCard.tsx (1)

9-10: Adopt VerifiedUserLabel for username recipients — LGTM

Clean swap and props align with the label’s API. Tooltip behavior will now scale with haveSentMoneyToUser.

If available in context, consider passing isAuthenticatedUserVerified to improve the tooltip message for verified viewers.

Also applies to: 19-21, 31-33, 74-80

src/hooks/useUserByUsername.ts (1)

24-29: Surface 404/Not Found semantics distinctly (optional)

If the API returns 404 for nonexistent usernames, consider mapping that case to user === null with error === null so UI can render "user not found" vs. generic error. Requires usersApi.getByUsername to throw or expose status. If desired, I can add a small wrapper that checks response.ok and throws domain-specific errors.

src/hooks/useUserInteractions.ts (1)

7-14: Doc comment drift: include error object in return

The JSDoc mentions “error state.” Returning error (not just isError) helps callers log/diagnose. The diff above adds it. Update the comment accordingly.

src/components/Payment/PaymentForm/index.tsx (1)

559-561: String-matching on error messages is brittle

isInsufficientBalanceError depends on a specific string fragment. Elsewhere we set errors like “Insufficient balance”. Prefer structured error codes from the store (e.g., errorCode === 'INSUFFICIENT_BALANCE') or centralize message mapping.

I can add a small error util and wire it through paymentActions.setError({ code, message }) if you want.

src/components/Home/HomeHistory.tsx (1)

65-81: Good dedupe; consider stabilizing order for cache friendliness (optional)

You already de-duplicate IDs and skip KYC items—nice. If you notice frequent refetches due to changing order, either:

  • Sort userIds here, or
  • Rely on the hook-level stabilization (recommended; see my change suggestion in useUserInteractions).

No action required if you adopt the hook change.

Also applies to: 83-84

src/components/SearchUsers/index.tsx (3)

25-31: Stabilize the interactions query key by sorting userIds

useUserInteractions uses userIds in the React Query key. Without stable ordering, the query can refetch unnecessarily as list order fluctuates. Sort the IDs to stabilize.

-    const userIds = useMemo(() => {
+    const userIds = useMemo(() => {
         const ids = new Set<string>()
         searchResults.forEach((user) => ids.add(user.userId))
         recentTransactions.forEach((user) => ids.add(user.userId))
-        return Array.from(ids)
+        return Array.from(ids).sort()
     }, [searchResults, recentTransactions])

32-33: Consider surfacing loading/error state from useUserInteractions

Right now, interactions default to {}. That can momentarily under-represent “have sent money” until the query resolves. Optionally pass isLoading/isError down to SearchResults to gate the double-check badge or show a subtle placeholder.

Also applies to: 73-74


4-4: Unify React imports (minor)

Import useMemo with the rest of the React hooks and remove the extra import line.

-import { useCallback, useEffect, useRef, useState } from 'react'
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
@@
-import { useMemo } from 'react'

Also applies to: 12-12

src/components/SearchUsers/SearchResults.tsx (1)

49-57: DRY up repeated card position logic

The “first/middle/last/single” logic is duplicated. Extract a helper for readability and to prevent future drift.

-                                    position={
-                                        results.length === 1
-                                            ? 'single'
-                                            : index === 0
-                                              ? 'first'
-                                              : index === results.length - 1
-                                                ? 'last'
-                                                : 'middle'
-                                    }
+                                    position={getCardPosition(index, results.length)}
@@
-                                        position={
-                                            recentTransactions.length === 1
-                                                ? 'single'
-                                                : index === 0
-                                                  ? 'first'
-                                                  : index === recentTransactions.length - 1
-                                                    ? 'last'
-                                                    : 'middle'
-                                        }
+                                        position={getCardPosition(index, recentTransactions.length)}

Add this helper (outside the component or above the return):

const getCardPosition = (index: number, length: number): 'single' | 'first' | 'middle' | 'last' => {
    if (length === 1) return 'single'
    if (index === 0) return 'first'
    if (index === length - 1) return 'last'
    return 'middle'
}

Also applies to: 121-129

src/components/Tooltip/index.tsx (1)

3-3: Improve accessibility: wire aria-describedby and stable IDs; support touch

Link the trigger to the tooltip via aria-describedby and ensure a stable id exists. Consider basic touch support for mobile.

-import React, { useState, useRef, useEffect } from 'react'
+import React, { useState, useRef, useEffect, useMemo } from 'react'
@@
 export const Tooltip = ({
@@
 }: TooltipProps) => {
     const [visible, setVisible] = useState(false)
     const [coords, setCoords] = useState({ top: 0, left: 0, width: 0, height: 0 })
     const triggerRef = useRef<HTMLDivElement>(null)
     const [isMounted, setIsMounted] = useState(false)
     const [dynamicPosition, setDynamicPosition] = useState(position)
+    const tooltipId = useMemo(() => id ?? `tooltip-${Math.random().toString(36).slice(2)}`, [id])
@@
             <div
                 ref={triggerRef}
                 className={twMerge('inline-block cursor-pointer', className)}
                 onMouseEnter={showTooltip}
                 onMouseLeave={hideTooltip}
                 onFocus={showTooltip}
                 onBlur={hideTooltip}
+                onTouchStart={showTooltip}
+                onTouchEnd={hideTooltip}
+                aria-describedby={visible ? tooltipId : undefined}
             >
                 {children}
             </div>
@@
                     <TooltipContent
-                        id={id}
+                        id={tooltipId}
                         content={content}
                         position={dynamicPosition}
                         coords={coords}
                         contentClassName={contentClassName}
                         updatePosition={setDynamicPosition}
                         initialPosition={position}
                     />,

Also applies to: 18-26, 76-85, 90-97

src/components/Tooltip/TooltipContent.tsx (2)

100-101: Avoid extra layout-effect churn

finalPosition in the dependency array causes an extra effect run after you set it. You already compute best position inside the effect; removing finalPosition from deps keeps a single pass per coords/initial change.

-    }, [coords, initialPosition, updatePosition, finalPosition])
+    }, [coords, initialPosition, updatePosition])

171-175: Expose id on the tooltip element for a11y linkage

Set the id on the role="tooltip" node so triggers can reference it via aria-describedby.

-            <div role="tooltip" className={tooltipClasses}>
+            <div role="tooltip" id={id} className={tooltipClasses}>
src/components/Profile/components/ProfileHeader.tsx (2)

37-38: Remove stray console.log

console.log('isVerified', isVerified) will leak to production logs.

-    console.log('isVerified', isVerified)

61-64: Avoid floating promise on clipboard write

Mark the promise as intentionally unawaited to satisfy linters and keep the UX unchanged.

-                        onClick={() => {
-                            navigator.clipboard.writeText(profileUrl)
-                            setIsDrawerOpen(true)
-                        }}
+                        onClick={() => {
+                            void navigator.clipboard.writeText(profileUrl)
+                            setIsDrawerOpen(true)
+                        }}
src/components/Profile/components/PublicProfile.tsx (2)

28-30: Consider better variable naming for clarity

The variable name totalSentByLoggedInUser could be more precise since it actually represents the total USD amount the profile user has received from the current user, not what the current user has sent.

Apply this diff for clearer naming:

-    const [totalSentByLoggedInUser, setTotalSentByLoggedInUser] = useState<string>('0')
+    const [totalReceivedFromCurrentUser, setTotalReceivedFromCurrentUser] = useState<string>('0')

And update the corresponding setter calls:

-                setTotalSentByLoggedInUser(user.totalUsdReceivedFromCurrentUser)
+                setTotalReceivedFromCurrentUser(user.totalUsdReceivedFromCurrentUser)

54-55: Optimize haveSentMoneyToUser computation

The conversion to Number in the useMemo is unnecessary since a simple string comparison would be more efficient.

-    const haveSentMoneyToUser = useMemo(() => Number(totalSentByLoggedInUser) > 0, [totalSentByLoggedInUser])
+    const haveSentMoneyToUser = useMemo(() => totalSentByLoggedInUser !== '0' && totalSentByLoggedInUser !== '', [totalSentByLoggedInUser])
src/components/UserHeader/index.tsx (1)

46-60: Consider extracting badge logic to a helper function

The badge determination logic could be extracted to improve readability and testability.

+const getVerificationBadge = (isVerified: boolean | undefined, haveSentMoneyToUser: boolean, iconSize: number) => {
+    if (!isVerified) return null;
+    
+    const iconName = haveSentMoneyToUser ? 'double-check' : 'check';
+    return <Icon name={iconName} size={iconSize} className="text-success-1" />
+}

 export const VerifiedUserLabel = ({
     name,
     isVerified,
     className,
     iconSize = 14,
     haveSentMoneyToUser = false,
     isAuthenticatedUserVerified = false,
 }: {
     // ... props
 }) => {
-    // determine badge and tooltip content based on verification status
-    let badge = null
-    let tooltipContent = ''
-
-    // A kyc-verified user always gets at least a single badge.
-    if (isVerified) {
-        badge = <Icon name="check" size={iconSize} className="text-success-1" />
-        tooltipContent = isAuthenticatedUserVerified ? "You're a verified user." : 'This is a verified user.'
-    }
-
-    // if they are also verified and the viewer has sent them money, it's upgraded to a double badge.
-    if (isVerified && haveSentMoneyToUser) {
-        badge = <Icon name="double-check" size={iconSize} className="text-success-1" />
-        tooltipContent = "This is a verified user and you've sent them money before."
-    }
+    const badge = getVerificationBadge(isVerified, haveSentMoneyToUser, iconSize)
+    
+    let tooltipContent = ''
+    if (isVerified) {
+        if (haveSentMoneyToUser) {
+            tooltipContent = "This is a verified user and you've sent them money before."
+        } else {
+            tooltipContent = isAuthenticatedUserVerified ? "You're a verified user." : 'This is a verified user.'
+        }
+    }
src/components/Request/direct-request/views/Initial.direct.request.view.tsx (1)

207-214: Consider simplifying the haveSentMoneyToUser logic

The nested ternary for haveSentMoneyToUser is complex and could be simplified.

-                    haveSentMoneyToUser={recipientUser?.userId ? interactions[recipientUser.userId] || false : false}
+                    haveSentMoneyToUser={recipientUser?.userId && interactions[recipientUser.userId] || false}
src/app/[...recipient]/client.tsx (1)

309-314: Consider extracting username resolution to a helper function

The username determination logic is complex and could benefit from extraction.

+const resolveCounterpartyUsername = (
+    counterparty: any,
+    isCurrentUser: boolean,
+    chargeDetails: any
+) => {
+    if (counterparty?.user?.username) return counterparty.user.username;
+    if (counterparty?.identifier) return counterparty.identifier;
+    
+    if (isCurrentUser && chargeDetails.payments.length > 0) {
+        return chargeDetails.payments[0].payerAddress;
+    }
+    return chargeDetails.requestLink.recipientAddress;
+}

-        const username =
-            counterparty?.user?.username ||
-            counterparty?.identifier ||
-            (isCurrentUser && chargeDetails.payments.length > 0
-                ? chargeDetails.payments[0].payerAddress
-                : chargeDetails.requestLink.recipientAddress)
+        const username = resolveCounterpartyUsername(counterparty, isCurrentUser, chargeDetails)
src/components/TransactionDetails/TransactionDetailsReceipt.tsx (1)

81-134: Consider extracting complex border visibility logic

The shouldHideCreatedRowBorder logic is very complex and would benefit from being broken down into smaller, more testable functions.

+const hasDetailRows = (transaction: TransactionDetails, isPendingBankRequest: boolean) => {
+    const conditions = {
+        tokenDetails: transaction.tokenDisplayDetails && transaction.sourceView === 'history',
+        cancellationDate: transaction.status === 'cancelled' && transaction.cancelledDate,
+        claimDate: transaction.status === 'completed' && transaction.claimedAt,
+        completionDate: transaction.status === 'completed' && transaction.completedAt && 
+            transaction.extraDataForDrawer?.originalType !== EHistoryEntryType.DIRECT_SEND,
+        fee: transaction.fee !== undefined,
+        exchangeRate: transaction.direction === 'bank_deposit' && 
+            transaction.status === 'completed' && 
+            transaction.currency?.code && 
+            transaction.currency.code.toUpperCase() !== 'USD',
+        bankAccount: transaction.bankAccountDetails?.identifier,
+        transferId: transaction.id && 
+            (transaction.direction === 'bank_withdraw' || transaction.direction === 'bank_claim'),
+        depositInstructions: (
+            transaction.extraDataForDrawer?.originalType === EHistoryEntryType.BRIDGE_ONRAMP ||
+            (isPendingBankRequest && 
+                transaction.extraDataForDrawer?.originalUserRole === EHistoryUserRole.SENDER)
+        ) && 
+        transaction.status === 'pending' && 
+        transaction.extraDataForDrawer?.depositInstructions?.bank_name,
+        memo: !!transaction.memo?.trim(),
+        networkFee: transaction.networkFeeDetails && transaction.sourceView === 'status',
+        attachment: !!transaction.attachmentUrl,
+        nonPending: transaction.status !== 'pending'
+    };
+    
+    return Object.values(conditions).some(Boolean);
+}

 const shouldHideCreatedRowBorder = useMemo(() => {
     if (!transaction) return true;
-    // ... existing long logic
-    return !hasFollowingRows
+    return !hasDetailRows(transaction, isPendingBankRequest);
 }, [transaction, isPendingBankRequest])
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ad4b549 and b724647.

📒 Files selected for processing (32)
  • src/app/[...recipient]/client.tsx (6 hunks)
  • src/components/Claim/Claim.tsx (3 hunks)
  • src/components/Global/Badges/AchievementsBadge.tsx (0 hunks)
  • src/components/Global/DisplayIcon.tsx (1 hunks)
  • src/components/Global/Icons/Icon.tsx (3 hunks)
  • src/components/Global/Icons/double-check.tsx (1 hunks)
  • src/components/Global/TokenSelector/Components/NetworkButton.tsx (1 hunks)
  • src/components/Home/HomeHistory.tsx (6 hunks)
  • src/components/Payment/PaymentForm/index.tsx (3 hunks)
  • src/components/Profile/AvatarWithBadge.tsx (0 hunks)
  • src/components/Profile/components/ProfileHeader.tsx (2 hunks)
  • src/components/Profile/components/PublicProfile.tsx (4 hunks)
  • src/components/Request/direct-request/views/Initial.direct.request.view.tsx (10 hunks)
  • src/components/RouterViewWrapper/index.tsx (3 hunks)
  • src/components/SearchUsers/SearchResults.tsx (5 hunks)
  • src/components/SearchUsers/index.tsx (3 hunks)
  • src/components/Tooltip/TooltipContent.tsx (1 hunks)
  • src/components/Tooltip/index.tsx (1 hunks)
  • src/components/TransactionDetails/TransactionAvatarBadge.tsx (1 hunks)
  • src/components/TransactionDetails/TransactionCard.tsx (8 hunks)
  • src/components/TransactionDetails/TransactionDetailsHeaderCard.tsx (8 hunks)
  • src/components/TransactionDetails/TransactionDetailsReceipt.tsx (1 hunks)
  • src/components/TransactionDetails/transactionTransformer.ts (8 hunks)
  • src/components/User/UserCard.tsx (4 hunks)
  • src/components/UserHeader/index.tsx (2 hunks)
  • src/hooks/useRecentUsers.ts (2 hunks)
  • src/hooks/useTransactionHistory.ts (3 hunks)
  • src/hooks/useUserByUsername.ts (1 hunks)
  • src/hooks/useUserInteractions.ts (1 hunks)
  • src/services/sendLinks.ts (2 hunks)
  • src/services/services.types.ts (2 hunks)
  • src/services/users.ts (2 hunks)
💤 Files with no reviewable changes (2)
  • src/components/Global/Badges/AchievementsBadge.tsx
  • src/components/Profile/AvatarWithBadge.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/components/Claim/Claim.tsx
  • src/components/TransactionDetails/TransactionCard.tsx
  • src/components/TransactionDetails/TransactionAvatarBadge.tsx
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2025-05-23T19:26:58.220Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#873
File: src/components/Withdraw/views/Initial.withdraw.view.tsx:95-95
Timestamp: 2025-05-23T19:26:58.220Z
Learning: The GeneralRecipientInput component supports username validation and resolution through the validateAndResolveRecipient function in src/lib/validation/recipient.ts. The function automatically detects usernames (inputs that don't contain '.' for ENS and don't start with '0x' for addresses), validates them via API HEAD request, fetches user data, and resolves them to Ethereum addresses from the user's PEANUT_WALLET account.

Applied to files:

  • src/services/sendLinks.ts
  • src/components/Request/direct-request/views/Initial.direct.request.view.tsx
📚 Learning: 2025-04-11T11:33:53.245Z
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#798
File: src/components/Home/HomeHistory.tsx:138-192
Timestamp: 2025-04-11T11:33:53.245Z
Learning: In the HomeHistory component, infinite scrolling is intentionally not implemented despite the presence of useInfiniteQuery and IntersectionObserver code. The component is designed to only display the first 5 entries with a "View all transactions" link for viewing the complete history.

Applied to files:

  • src/components/RouterViewWrapper/index.tsx
  • src/components/Home/HomeHistory.tsx
  • src/components/SearchUsers/SearchResults.tsx
📚 Learning: 2025-08-22T07:28:32.260Z
Learnt from: Zishan-7
PR: peanutprotocol/peanut-ui#1104
File: src/components/Payment/PaymentForm/index.tsx:522-545
Timestamp: 2025-08-22T07:28:32.260Z
Learning: In `src/components/Payment/PaymentForm/index.tsx`, the `handleCompleteDaimoPayment` function is only for updating payment status in the backend after a successful Daimo payment. Payment success/failure is handled by Daimo itself, so try/catch error handling and error display are not needed for backend sync failures - users shouldn't see errors if payment succeeded but database update failed.

Applied to files:

  • src/components/Payment/PaymentForm/index.tsx
📚 Learning: 2025-05-15T14:47:26.891Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#857
File: src/hooks/useWebSocket.ts:77-82
Timestamp: 2025-05-15T14:47:26.891Z
Learning: The useWebSocket hook in src/hooks/useWebSocket.ts is designed to provide raw history entries, while the components using it (such as HomeHistory.tsx) are responsible for implementing deduplication logic based on UUID to prevent duplicate entries when combining WebSocket data with other data sources.

Applied to files:

  • src/components/Home/HomeHistory.tsx
  • src/hooks/useRecentUsers.ts
📚 Learning: 2025-08-20T09:08:19.266Z
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#1112
File: src/components/Claim/Link/views/BankFlowManager.view.tsx:336-343
Timestamp: 2025-08-20T09:08:19.266Z
Learning: In the KYC flow implementation, `setJustCompletedKyc` must be called after `await fetchUser()` in the `handleKycSuccess` callback. Setting `justCompletedKyc` before fetching the user would cause a re-fetching loop because `handleKycSuccess` is set in a useEffect inside the KYC hook, which would cause the UI flow to get stuck in one view.

Applied to files:

  • src/components/Home/HomeHistory.tsx
  • src/components/Profile/components/PublicProfile.tsx
📚 Learning: 2025-05-13T10:05:24.057Z
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#845
File: src/components/Request/link/views/Create.request.link.view.tsx:81-81
Timestamp: 2025-05-13T10:05:24.057Z
Learning: In the peanut-ui project, pages that handle request flows (like Create.request.link.view.tsx) are only accessible to logged-in users who will always have a username, making null checks for user?.user.username unnecessary in these contexts.

Applied to files:

  • src/components/Request/direct-request/views/Initial.direct.request.view.tsx
📚 Learning: 2024-12-02T17:19:18.532Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#551
File: src/components/Request/Create/Views/Initial.view.tsx:151-156
Timestamp: 2024-12-02T17:19:18.532Z
Learning: In the `InitialView` component at `src/components/Request/Create/Views/Initial.view.tsx`, when setting the default chain and token in the `useEffect` triggered by `isPeanutWallet`, it's acceptable to omit the setters from the dependency array and not include additional error handling for invalid defaults.

Applied to files:

  • src/components/Request/direct-request/views/Initial.direct.request.view.tsx
🧬 Code graph analysis (19)
src/components/Tooltip/index.tsx (1)
src/components/Tooltip/TooltipContent.tsx (2)
  • TooltipPosition (4-4)
  • TooltipContent (16-178)
src/hooks/useUserByUsername.ts (1)
src/services/users.ts (2)
  • ApiUser (21-31)
  • usersApi (39-100)
src/components/User/UserCard.tsx (1)
src/components/UserHeader/index.tsx (1)
  • VerifiedUserLabel (31-72)
src/services/users.ts (2)
src/utils/sentry.utils.ts (1)
  • fetchWithSentry (11-89)
src/constants/general.consts.ts (1)
  • PEANUT_API_URL (45-49)
src/hooks/useUserInteractions.ts (1)
src/services/users.ts (1)
  • usersApi (39-100)
src/components/RouterViewWrapper/index.tsx (1)
src/hooks/useUserInteractions.ts (1)
  • useUserInteractions (15-35)
src/components/Payment/PaymentForm/index.tsx (2)
src/hooks/useUserByUsername.ts (1)
  • useUserByUsername (9-39)
src/hooks/useUserInteractions.ts (1)
  • useUserInteractions (15-35)
src/components/UserHeader/index.tsx (2)
src/components/Global/Icons/Icon.tsx (1)
  • Icon (189-198)
src/components/Tooltip/index.tsx (1)
  • Tooltip (18-102)
src/components/Home/HomeHistory.tsx (2)
src/hooks/useKycFlow.ts (1)
  • isKycStatusItem (34-36)
src/hooks/useUserInteractions.ts (1)
  • useUserInteractions (15-35)
src/components/TransactionDetails/TransactionDetailsReceipt.tsx (11)
src/components/TransactionDetails/transactionTransformer.ts (1)
  • TransactionDetails (40-120)
src/redux/hooks.ts (1)
  • useUserStore (13-13)
src/hooks/wallet/useWallet.ts (1)
  • useWallet (21-124)
src/utils/general.utils.ts (5)
  • formatAmount (400-440)
  • getInitialsFromName (1254-1261)
  • formatDate (937-949)
  • formatIban (965-972)
  • shortenAddress (43-49)
src/utils/currency.ts (1)
  • getDisplayCurrencySymbol (4-28)
src/components/TransactionDetails/TransactionDetailsHeaderCard.tsx (1)
  • TransactionDetailsHeaderCard (136-191)
src/components/Payment/PaymentInfoRow.tsx (1)
  • PaymentInfoRow (7-81)
src/components/0_Bruddle/Button.tsx (1)
  • Button (76-267)
src/services/charges.ts (1)
  • chargesApi (6-94)
src/constants/query.consts.ts (1)
  • TRANSACTIONS (2-2)
src/app/actions/onramp.ts (1)
  • cancelOnramp (26-64)
src/components/SearchUsers/index.tsx (2)
src/services/users.ts (1)
  • RecentUser (33-33)
src/hooks/useUserInteractions.ts (1)
  • useUserInteractions (15-35)
src/components/Profile/components/PublicProfile.tsx (1)
src/redux/hooks.ts (1)
  • useAppDispatch (5-5)
src/components/Request/direct-request/views/Initial.direct.request.view.tsx (2)
src/hooks/useUserByUsername.ts (1)
  • useUserByUsername (9-39)
src/hooks/useUserInteractions.ts (1)
  • useUserInteractions (15-35)
src/components/TransactionDetails/TransactionDetailsHeaderCard.tsx (1)
src/components/UserHeader/index.tsx (1)
  • VerifiedUserLabel (31-72)
src/hooks/useRecentUsers.ts (2)
src/hooks/useTransactionHistory.ts (2)
  • useTransactionHistory (111-264)
  • HistoryEntry (34-75)
src/services/users.ts (1)
  • RecentUser (33-33)
src/components/Profile/components/ProfileHeader.tsx (2)
src/context/authContext.tsx (1)
  • useAuth (177-183)
src/components/UserHeader/index.tsx (1)
  • VerifiedUserLabel (31-72)
src/components/Global/Icons/Icon.tsx (1)
src/components/Global/Icons/double-check.tsx (1)
  • DoubleCheckIcon (3-10)
src/app/[...recipient]/client.tsx (1)
src/hooks/useUserInteractions.ts (1)
  • useUserInteractions (15-35)
src/components/SearchUsers/SearchResults.tsx (3)
src/services/users.ts (1)
  • RecentUser (33-33)
src/components/SearchUsers/SearchResultCard.tsx (1)
  • SearchResultCard (19-70)
src/components/UserHeader/index.tsx (1)
  • VerifiedUserLabel (31-72)
⏰ 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: Deploy-Preview
🔇 Additional comments (27)
src/components/Global/DisplayIcon.tsx (1)

39-41: LGTM: Correctly updated AvatarWithBadge usage to new API.

Passing only name and size aligns with the AvatarWithBadge prop changes and removes the obsolete achievements badge prop.

src/components/Global/TokenSelector/Components/NetworkButton.tsx (1)

52-53: LGTM: Fallback updated to new AvatarWithBadge API.

The removal of achievements badge props is consistent with the refactor.

src/components/Global/Icons/double-check.tsx (1)

3-10: New icon looks correct and matches the icon system (currentColor + prop spread).
The SVG is minimal, prop-spread comes last (overrides width/height), and the path is self-contained. Good addition.

src/components/Global/Icons/Icon.tsx (1)

59-59: Icon wired correctly (import, union type, map entry).
Name literal 'double-check' is consistent with file/component naming; mapping is correct.

Also applies to: 76-76, 140-140

src/services/sendLinks.ts (1)

95-151: Robust error surfacing for create(): good handling of FormData vs JSON and backend error payload.
FormData path avoids setting Content-Type manually and you stringify non-file attachments; jsonStringify will handle bigint. Looks solid.

src/services/users.ts (1)

28-31: No stale references to renamed fields found
I searched for both the old (totalUsdSent / totalUsdReceived) and new field names across all .ts and .tsx files. The only occurrences are the updated declarations and their intended usage:

  • src/services/users.ts (lines 28–29):
    totalUsdSentToCurrentUser
    totalUsdReceivedFromCurrentUser
  • src/components/Profile/components/PublicProfile.tsx (lines 48–49):
    • usage of user.totalUsdReceivedFromCurrentUser

There are no remaining references to the old names, so no further changes are needed.

src/hooks/useRecentUsers.ts (1)

3-3: Type alignment looks good.
Switching to RecentUser and updating the accumulator type matches upstream ApiUser shape changes.

Also applies to: 9-9

src/hooks/useTransactionHistory.ts (2)

207-211: BANK_SEND_LINK_CLAIM handling mirrors withdraw/offramp — confirm amount units

Logic mirrors WITHDRAW/BRIDGE_* and is consistent. Please confirm the amount unit for BANK_SEND_LINK_CLAIM is already a fiat string (like other withdraw/offramp) to avoid inconsistent $ formatting downstream. If it can arrive in token units, we should convert using token decimals.


21-22: UI enums and mapping updated for BANK_SEND_LINK_CLAIM

All references to the old BRIDGE_GUEST_OFFRAMP have been removed, and the new enum is fully wired through the UI:

  • No remaining occurrences of BRIDGE_GUEST_OFFRAMP in the codebase.
  • In transactionTransformer.ts, EHistoryEntryType.BANK_SEND_LINK_CLAIM is mapped to
    • direction = 'bank_claim'
    • transactionCardType = 'bank_withdraw'
  • The TransactionDirection union (used by TransactionDetailsHeaderCard) includes 'bank_claim' alongside the other bank actions.
  • The TransactionType union (used by TransactionCard) includes 'bank_withdraw', which matches the mapped type for link claims.

Please confirm that the backend is now emitting BANK_SEND_LINK_CLAIM so that this new path will actually be used at runtime.

src/services/services.types.ts (1)

152-170: Verified removal of PaymentResponse and correct usage of PaymentCreationResponse

  • Ripgrep found zero occurrences of the old PaymentResponse type, confirming it has been removed.
  • All existing call sites reference the new PaymentCreationResponse and align with its shape, including:
    • Definition in src/services/services.types.ts
    • chargesApi.createPayment in src/services/charges.ts
    • setPaymentDetails in src/redux/slices/payment-slice.ts
    • State typing in src/redux/types/payment.types.ts
    • Consumption and dispatch in src/hooks/usePaymentInitiator.ts
  • No further updates are needed; callers have been successfully migrated.
src/components/TransactionDetails/transactionTransformer.ts (5)

54-55: Threaded haveSentMoneyToUser — LGTM

Plumbing looks correct and optionality matches VerifiedUserLabel defaults. No concerns.

Also applies to: 428-429


70-72: Bridge fields (fulfillmentType, bridgeTransferId, depositInstructions) — consistent propagation

Good addition. Including fulfillmentType === 'bridge' in the depositInstructions gate fixes previous gaps for request-based bank fulfillments.

Also applies to: 410-416


239-245: BANK_SEND_LINK_CLAIM mapped to bank_withdraw UI — LGTM

Direction/card/name choices are coherent with “claimed to bank” semantics. No issues.


392-393: isVerified is now sourced directly from HistoryEntry — confirm it’s peer-oriented

Same note as in the hook: confirm this boolean refers to the counterparty shown in userName to prevent badge mislabeling.


419-424: Bank account details: now include BANK_SEND_LINK_CLAIM — LGTM

This unifies bank destination rendering across offramps and link-claim → bank. Good catch.

src/components/Payment/PaymentForm/index.tsx (1)

684-694: LGTM: UserCard now enriched with verification and interaction state

The props derivation is correct and safely defaults when IDs are missing. This should make the card rendering consistent across flows.

src/components/Home/HomeHistory.tsx (1)

219-224: LGTM: Interaction lookup logic for both sender/recipient roles

The ternary accounts for both roles and defaults safely. Mirrors the pending and general lists consistently.

Also applies to: 274-280

src/components/TransactionDetails/TransactionDetailsHeaderCard.tsx (3)

14-25: Extend TransactionDirection for bank flows

Adding bank_request_fulfillment to the union is consistent with the rest of the bank-* directions.


118-130: Icon mapping parity for new bank directions

Treating bank_request_fulfillment like send (arrow-up-right) and bank_deposit like add (arrow-down) aligns well with transaction semantics.


36-37: Prop threading for haveSentMoneyToUser looks good

Defaulting to false maintains backward compatibility. VerifiedUserLabel centralizes the badge logic—nice decoupling.

Also applies to: 146-147

src/components/SearchUsers/SearchResults.tsx (1)

44-74: Verified/interaction-aware titles: LGTM

Good integration of VerifiedUserLabel with kycStatus and per-user interaction flags. Keys are stable (userId), and SearchResultCard now takes a ReactNode title cleanly.

Also applies to: 103-132

src/components/Tooltip/index.tsx (1)

1-16: Solid portal-based tooltip with visibility/position lifecycle

Mount-guarding with isMounted, listener management tied to visible, and delegating layout to TooltipContent are all clean. Nice.

Also applies to: 74-101

src/components/Profile/components/ProfileHeader.tsx (1)

46-53: VerifiedUserLabel integration: LGTM

Clean replacement of name/verification rendering. Using useAuth to compute viewer verification for tooltip copy is a nice touch.

src/components/Profile/components/PublicProfile.tsx (1)

43-52: LGTM! Good use of optional chaining and state management

The user data fetching logic properly handles KYC verification status and tracks money sent between users with appropriate null checks.

src/components/UserHeader/index.tsx (1)

31-72: Well-structured verification label component

The VerifiedUserLabel component has a clean implementation with clear logic for badge and tooltip content determination. The progressive enhancement from single check to double check based on interaction history is intuitive.

src/components/Request/direct-request/views/Initial.direct.request.view.tsx (1)

50-56: Good use of custom hooks for user data fetching

The refactor to use useUserByUsername and useUserInteractions hooks improves code organization and reusability.

src/app/[...recipient]/client.tsx (1)

64-74: LGTM! Clean counterparty determination logic

The logic for determining the counterparty based on whether the current user is the recipient is well-structured and clear.

@kushagrasarathe kushagrasarathe merged commit 8093280 into peanut-wallet-dev Aug 22, 2025
6 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Aug 25, 2025
jjramirezn pushed a commit that referenced this pull request Aug 25, 2025
* reafactor: create reusable country list component and use it for all the flows

* feat: reusable user accounts components

* feat: handle different cases based on kyc status for bank claim

* fix: account creation

* chore: add docstring to hooks

* chore: better comments for bank flow manager

* fix: kyc modal closing after tos acceptance issue

* fix: remove bank acc caching from withdraw flow

* fix: update confirm claim modal copy

* fix: remove bank acc caching from claim flow

* fix: navheader title

* feat: req fulfillment exchange flow

* fix: header title

* feat: req fulfillment using connected external wallet

* fix: navigation and ui

* fix: file name

* feat: abstract reusbale components from onramp flow for bank fulfilment

* feat: handle onramp creation for request fulfilment

* feat: reusable verification component

* feat: handle bank req fulfilment for peanut users

* fix: show all supported countries in req/claim bank flow

* feat: show google-pay/apple-pay based on users device

* feat: handle bank send link claim hisotry for peanut users

* feat: handle history ui changes for request fulfillment using bank accounts

* fix: resolve pr review comments

* fix: exhange rate hook fallback value

* fix: resolve pr comments

* fix: review comments

* feat: badges updates (#1119)

* feat: badges updates and hook to check for interactions

* feat: handle badges for receipts and drawer header

* feat: handle badges on request and send flow

* feat: tooltip for badges

* fix: tooltip positioning
jjramirezn added a commit that referenced this pull request Sep 4, 2025
* feat: handle send link claims to bank account for peanut users (#1078)

* reafactor: create reusable country list component and use it for all the flows

* feat: reusable user accounts components

* feat: handle different cases based on kyc status for bank claim

* fix: account creation

* chore: add docstring to hooks

* chore: better comments for bank flow manager

* fix: kyc modal closing after tos acceptance issue

* fix: remove bank acc caching from withdraw flow

* fix: update confirm claim modal copy

* fix: remove bank acc caching from claim flow

* fix: navheader title

* remove duplicate debounce code and use `useDebounce` hook instead (#1079)

* Landing page v2.1 (#1089)

* lpv2.1 part 1

* Add exchange widget

* add and integrate exchange API

* add yourMoney component bg

* update landing countries svg

* integrate frankfurter API

* fixes and improvements

* decrease hero section height

* allow max 2 decimal places

* Add `/exchange` route

* fix: overlay

* make destination amount editable and bugg fixes

* some fixes & currency improvements

* crucial commit

* fix checkmark, font size and weight

---------

Co-authored-by: Hugo Montenegro <[email protected]>

* [TASK-13186] refactor: use networkName instead of axelarChainName (#1095)

* refactor: use networkName instead of axelarChainName

* fix: types

* fix: onramp currency (#1096)

* fix: stretched favicon (#1099)

* [TASK-13971] fix: scientific notation in eip681 parsing (#1097)

* fix: scientific notation in eip681 parsing

* fix: qr handling tests

* fix: peanut sdk mock

* pull iban hotfix (#1100)

* fix: claim flow bugs (#1102)

* fix: cross chain claim

* fix: full name issue on confirm bank claim view

* fix: back navigation on desktop views

* Fix back button not working on /profile (#1101)

* Fix back button not working

* fix public profile page

* extract internal navigation logic to utility function

* fix: send link claims to us bank accounts (#1108)

* fix: usa bank account claims

* fix: show bank account details in confirm claim view

* Sync Landing page changes (#1111)

* reduce clouds size and update font

* fix: hero section responsiveness issue

* fix: formatting errors

* add currency animation

* fix: us bank claims after kyc for logged in users (#1112)

* fix: trim account form inputs for spaces (#1114)

* [TASK-14107] fix: don't allow claiming on xChain if route is not found (#1115)

* fix: don't allow claiming on xChain if route is not found

* fix(claim): use correct decimals for min receive amount

* feat: handle redirect uri when on unsupported browsers (#1117)

* feat: handle redirect uri when on unsupported browsers

* fix: confirm bank claim ui rows for iban guest claim

* remove animation (#1118)

* Prod to staging (#1124)

* HOTFIX - IBAN country detection and incorrect bank acc details (#1094)

* Fix: Iban country detection and incorrect bank acc details

* Fix: update IBAN country validation to use correct locale string comparison

* add validations for US and mexican bank accounts

* fix typo

* fix claim flow and create a reusable function for getting 3 letter code

* fix country code mismatch

* fix: show error below input field

* remove unnecessary checks

* remove unnecessary CLABE check

* Prod LP v2.1 (#1098)

* feat: lpv2.1

* fix: gigaclouds, font and exchange widget

* fixes and improvements

* remove duplicate export

* remove unused component

* Fix: Landing page hero section responsiveness issue (#1107)

* fix: hero section responsiveness issue

* fix: stars position

* fix height on desktop

* remove unused code

* fix margins (#1113)

* [TASK-14052] Prod release 105 (#1122)

* feat: handle send link claims to bank account for peanut users (#1078)

* reafactor: create reusable country list component and use it for all the flows

* feat: reusable user accounts components

* feat: handle different cases based on kyc status for bank claim

* fix: account creation

* chore: add docstring to hooks

* chore: better comments for bank flow manager

* fix: kyc modal closing after tos acceptance issue

* fix: remove bank acc caching from withdraw flow

* fix: update confirm claim modal copy

* fix: remove bank acc caching from claim flow

* fix: navheader title

* remove duplicate debounce code and use `useDebounce` hook instead (#1079)

* Landing page v2.1 (#1089)

* lpv2.1 part 1

* Add exchange widget

* add and integrate exchange API

* add yourMoney component bg

* update landing countries svg

* integrate frankfurter API

* fixes and improvements

* decrease hero section height

* allow max 2 decimal places

* Add `/exchange` route

* fix: overlay

* make destination amount editable and bugg fixes

* some fixes & currency improvements

* crucial commit

* fix checkmark, font size and weight

---------

Co-authored-by: Hugo Montenegro <[email protected]>

* [TASK-13186] refactor: use networkName instead of axelarChainName (#1095)

* refactor: use networkName instead of axelarChainName

* fix: types

* fix: onramp currency (#1096)

* fix: stretched favicon (#1099)

* [TASK-13971] fix: scientific notation in eip681 parsing (#1097)

* fix: scientific notation in eip681 parsing

* fix: qr handling tests

* fix: peanut sdk mock

* pull iban hotfix (#1100)

* fix: claim flow bugs (#1102)

* fix: cross chain claim

* fix: full name issue on confirm bank claim view

* fix: back navigation on desktop views

* Fix back button not working on /profile (#1101)

* Fix back button not working

* fix public profile page

* extract internal navigation logic to utility function

* fix: send link claims to us bank accounts (#1108)

* fix: usa bank account claims

* fix: show bank account details in confirm claim view

* Sync Landing page changes (#1111)

* reduce clouds size and update font

* fix: hero section responsiveness issue

* fix: formatting errors

* add currency animation

* fix: us bank claims after kyc for logged in users (#1112)

* fix: trim account form inputs for spaces (#1114)

* [TASK-14107] fix: don't allow claiming on xChain if route is not found (#1115)

* fix: don't allow claiming on xChain if route is not found

* fix(claim): use correct decimals for min receive amount

* feat: handle redirect uri when on unsupported browsers (#1117)

* feat: handle redirect uri when on unsupported browsers

* fix: confirm bank claim ui rows for iban guest claim

* remove animation (#1118)

* fix: formatting

---------

Co-authored-by: Kushagra Sarathe <[email protected]>
Co-authored-by: Mohd Zishan <[email protected]>
Co-authored-by: Hugo Montenegro <[email protected]>

---------

Co-authored-by: Mohd Zishan <[email protected]>
Co-authored-by: Kushagra Sarathe <[email protected]>
Co-authored-by: Hugo Montenegro <[email protected]>

* fix: dates in receipts (#1105)

* [TASK-13865] fix: add tx info on receipt (#1109)

* fix: add tx info on receipt

* feat: use address explorer url for depositor address

* fix(history): check befroe creating address explorer url

* Fix: logged in users have to re-login after installing PWA (#1103)

* store `LOCAL_STORAGE_WEB_AUTHN_KEY` in cookies

* ensure backward compatibility

* refactor: move syncLocalStorageToCookie call into useEffect for better lifecycle management

* feat: links v2.1 req fulfilment flows (#1085)

* reafactor: create reusable country list component and use it for all the flows

* feat: reusable user accounts components

* feat: handle different cases based on kyc status for bank claim

* fix: account creation

* chore: add docstring to hooks

* chore: better comments for bank flow manager

* fix: kyc modal closing after tos acceptance issue

* fix: remove bank acc caching from withdraw flow

* fix: update confirm claim modal copy

* fix: remove bank acc caching from claim flow

* fix: navheader title

* feat: req fulfillment exchange flow

* fix: header title

* feat: req fulfillment using connected external wallet

* fix: navigation and ui

* fix: file name

* feat: abstract reusbale components from onramp flow for bank fulfilment

* feat: handle onramp creation for request fulfilment

* feat: reusable verification component

* feat: handle bank req fulfilment for peanut users

* fix: show all supported countries in req/claim bank flow

* feat: show google-pay/apple-pay based on users device

* fix: resolve pr review comments

* fix: exhange rate hook fallback value

* fix: resolve pr comments

* Feat: Collect tg username (#1110)

* feat: collect tg username

* update animations

* fix api route

* add thinking peanut gif

* fix typescript errors

* fix typo and reset telegramHandle field on logout

* fix: spacing and describe regex rules

* add missing export

* feat: add sound in success views (#1127)

* feat: handle history ui changes for links v2.1 (#1106)

* reafactor: create reusable country list component and use it for all the flows

* feat: reusable user accounts components

* feat: handle different cases based on kyc status for bank claim

* fix: account creation

* chore: add docstring to hooks

* chore: better comments for bank flow manager

* fix: kyc modal closing after tos acceptance issue

* fix: remove bank acc caching from withdraw flow

* fix: update confirm claim modal copy

* fix: remove bank acc caching from claim flow

* fix: navheader title

* feat: req fulfillment exchange flow

* fix: header title

* feat: req fulfillment using connected external wallet

* fix: navigation and ui

* fix: file name

* feat: abstract reusbale components from onramp flow for bank fulfilment

* feat: handle onramp creation for request fulfilment

* feat: reusable verification component

* feat: handle bank req fulfilment for peanut users

* fix: show all supported countries in req/claim bank flow

* feat: show google-pay/apple-pay based on users device

* feat: handle bank send link claim hisotry for peanut users

* feat: handle history ui changes for request fulfillment using bank accounts

* fix: resolve pr review comments

* fix: exhange rate hook fallback value

* fix: resolve pr comments

* fix: review comments

* feat: badges updates (#1119)

* feat: badges updates and hook to check for interactions

* feat: handle badges for receipts and drawer header

* feat: handle badges on request and send flow

* feat: tooltip for badges

* fix: tooltip positioning

* fix: associate a external wallet claim to user if logged in (#1126)

* fix: associate a external wallet claim to user if logged in

* chore: fix comments

* [TASK-14113] fix: handle rpc outage when creating sendlinks (#1120)

* HOTFIX - IBAN country detection and incorrect bank acc details (#1094)

* Fix: Iban country detection and incorrect bank acc details

* Fix: update IBAN country validation to use correct locale string comparison

* add validations for US and mexican bank accounts

* fix typo

* fix claim flow and create a reusable function for getting 3 letter code

* fix country code mismatch

* fix: show error below input field

* remove unnecessary checks

* remove unnecessary CLABE check

* Prod LP v2.1 (#1098)

* feat: lpv2.1

* fix: gigaclouds, font and exchange widget

* fixes and improvements

* remove duplicate export

* remove unused component

* Fix: Landing page hero section responsiveness issue (#1107)

* fix: hero section responsiveness issue

* fix: stars position

* fix height on desktop

* remove unused code

* fix margins (#1113)

* fix: handle rpc outage when creating sendlinks

* fix: formatting

* fix: parallelize geting deposit index

---------

Co-authored-by: Mohd Zishan <[email protected]>

* Integrate Daimo Pay (#1104)

* add daimo pay

* minor improvements

* cleanup and add success state

* resolve dependency issues

* fix: formatting

* fix: recent methods redirection

* add functions for daimo payment in request fulfilment flow

* Integrate daimo in request fulfilment flow

* remove hardcoded address

* add separate arbitrum usdc flow for deposits

* Add risk modal

* fix overlay blur

* Enhance loading state indication in payment process

* Add payer's address in deposit history entry

* Add validation

* add error handling

* remove action and move logic to API route

* fix errors

* fix: request flow

* fix: validation

* fixes

* add daimo flow in country specific method

* fix: slider not working on first attempt

* filter supported networks

* create reusable daimo button

* remove space

* remove route.ts file and move logic to server actions

* fix: infinite loading edge case

* update api and remove delay

* fix: layout shift

* fix: shadow

* update function name

* fix: success receipt (#1129)

* fix: roboto font not working (#1130)

* fix: allow cancel link from the claim page

* fix: allow canceling links from the shared receipt (#1134)

* fix: send flow cta (#1133)

* fix: send flow ctas

* fix: success sound on send flow

* fix: disabled btn on req pay flow

* Fix Daimo bugs (#1132)

* fix: bugs

* fix cross chain deposit details not correct

* fix: request screen UI

* add loading state

* remove old daimo button

* fix: missing dependencies and dead code

* add try catch finally block

* remove clear Daimo errors inside the balance-check effect

* fix copy

* minor fixes

* move ACTION_METHODS to constants file to remove circular dependency

* fix: circular dependency

* fix ts error

* update daimo version

* [TASK-14095] feat: add fallback transport to viem clients (#1131)

* feat: add fallback transport to viem clients

Use viem fallback transport to handle RPC errors and fallback to other
providers.

* style: Apply prettier formatting

* test: add fallback to viem mock

* fix: external claim links history ui + badges fix (#1136)

* fix: external claim links history ui + badges fix

* fix: resolve codderrabbit suggestions

* fix: coderrabbit comment on state stale

* Fix: disable add money button on default state + disable sound on IOS (#1145)

* fix: add money success screen shows usernmae

* disable add money button in default state

* disable sound on IOS

* Fix: daimo bugs part2 (#1149)

* fix: black screen on IOS

* fix: sucess screen showed without paying - add money flow

* fix currency and double $ in  txn history

* fix: x-chan token size and add API to get missing token icons

* fix: req fulfilment

* add default value to tokenData

* fix: move useeffect above transaction null check

* format amount

* fix: space between currency and amount (#1135)

* Lock token to USDC arb for peanut ens username (#1128)

* Lock token to USDC arb for peanut ens username

* add comment

* revert variable declaration for sanitizedValue in GeneralRecipientInput component

* fix add regex to strip only from the end

* [TASK-13900] Feat/kyc modal changes (#1137)

* fix: pointer events

* fix: modal btns not working on mobile

* add missing dependency

* remove close button

* Chore/prod to dev 106 (#1152)

* HOTFIX - IBAN country detection and incorrect bank acc details (#1094)

* Fix: Iban country detection and incorrect bank acc details

* Fix: update IBAN country validation to use correct locale string comparison

* add validations for US and mexican bank accounts

* fix typo

* fix claim flow and create a reusable function for getting 3 letter code

* fix country code mismatch

* fix: show error below input field

* remove unnecessary checks

* remove unnecessary CLABE check

* Prod LP v2.1 (#1098)

* feat: lpv2.1

* fix: gigaclouds, font and exchange widget

* fixes and improvements

* remove duplicate export

* remove unused component

* Fix: Landing page hero section responsiveness issue (#1107)

* fix: hero section responsiveness issue

* fix: stars position

* fix height on desktop

* remove unused code

* fix margins (#1113)

* [TASK-14052] Prod release 105 (#1122)

* feat: handle send link claims to bank account for peanut users (#1078)

* reafactor: create reusable country list component and use it for all the flows

* feat: reusable user accounts components

* feat: handle different cases based on kyc status for bank claim

* fix: account creation

* chore: add docstring to hooks

* chore: better comments for bank flow manager

* fix: kyc modal closing after tos acceptance issue

* fix: remove bank acc caching from withdraw flow

* fix: update confirm claim modal copy

* fix: remove bank acc caching from claim flow

* fix: navheader title

* remove duplicate debounce code and use `useDebounce` hook instead (#1079)

* Landing page v2.1 (#1089)

* lpv2.1 part 1

* Add exchange widget

* add and integrate exchange API

* add yourMoney component bg

* update landing countries svg

* integrate frankfurter API

* fixes and improvements

* decrease hero section height

* allow max 2 decimal places

* Add `/exchange` route

* fix: overlay

* make destination amount editable and bugg fixes

* some fixes & currency improvements

* crucial commit

* fix checkmark, font size and weight

---------

Co-authored-by: Hugo Montenegro <[email protected]>

* [TASK-13186] refactor: use networkName instead of axelarChainName (#1095)

* refactor: use networkName instead of axelarChainName

* fix: types

* fix: onramp currency (#1096)

* fix: stretched favicon (#1099)

* [TASK-13971] fix: scientific notation in eip681 parsing (#1097)

* fix: scientific notation in eip681 parsing

* fix: qr handling tests

* fix: peanut sdk mock

* pull iban hotfix (#1100)

* fix: claim flow bugs (#1102)

* fix: cross chain claim

* fix: full name issue on confirm bank claim view

* fix: back navigation on desktop views

* Fix back button not working on /profile (#1101)

* Fix back button not working

* fix public profile page

* extract internal navigation logic to utility function

* fix: send link claims to us bank accounts (#1108)

* fix: usa bank account claims

* fix: show bank account details in confirm claim view

* Sync Landing page changes (#1111)

* reduce clouds size and update font

* fix: hero section responsiveness issue

* fix: formatting errors

* add currency animation

* fix: us bank claims after kyc for logged in users (#1112)

* fix: trim account form inputs for spaces (#1114)

* [TASK-14107] fix: don't allow claiming on xChain if route is not found (#1115)

* fix: don't allow claiming on xChain if route is not found

* fix(claim): use correct decimals for min receive amount

* feat: handle redirect uri when on unsupported browsers (#1117)

* feat: handle redirect uri when on unsupported browsers

* fix: confirm bank claim ui rows for iban guest claim

* remove animation (#1118)

* fix: formatting

---------

Co-authored-by: Kushagra Sarathe <[email protected]>
Co-authored-by: Mohd Zishan <[email protected]>
Co-authored-by: Hugo Montenegro <[email protected]>

* fix: bank claim flow runtime error (#1138)

* hotfix: make iban non optional (#1139)

* fix: bank claim flow runtime error

* fix: dont have iban as optional

* fix: merge conflicts

* fix: merge external account with bank details (#1140)

* fix: add id to external account (#1142)

* added tg footer (#1144)

* Hotfix : add missing countries - claim as guest flow (#1146)

* fix: add missing countries

* remove duplicate comment

* fix: show error on dynamic bank account form (#1147)

* fix: Invalid IBAN for UK (#1151)

---------

Co-authored-by: Mohd Zishan <[email protected]>
Co-authored-by: Kushagra Sarathe <[email protected]>
Co-authored-by: Hugo Montenegro <[email protected]>
Co-authored-by: Hugo Montenegro <[email protected]>

* [TASK-13950] Fix: incorrect token amount on second withdraw (#1150)

* fix: incorrect token amount on second withdraw

* move `resetTokenContextProvider()` to unmount callback

* fix: transaction explorer url for deposits

* fix: history skeleton copy

* save token and chain details for cross chain req-fulfilments (#1154)

* fix: send links history ui for senders pov when claimed to bank accounts (#1156)

* fix: sort action list methods

* fix: send links claimed to bank accounts history ui for senders pov

* fix: issues for request link paying with bank (#1158)

- Specify recipient when creating onramp for request fulfillment
- Use correct amount depending on currency

* fix: stop cleaning error by bic field (#1159)

We now always clear before starting submission and also bic field will
always show, so that logic is not needed anymore.

* fix: claim country currency and amount, fallback to $  (#1164)

* feat: show local bank currency incase of bank claims

* fix: activity rows for sender's send link history

* fix: verification modal when claiming

* fix: state issue when new user tries to claim to bank

* fix: request pay copy (#1165)

* fix: close kyc modal btn (#1166)

* Fix testing github action (#1167)

* chore: remove prettier action

When commiting it clashes with signature verification rules

* chore: update test action setup version

* fix: install first

* fix: actually make sure that cancelledDate is a Date (#1170)

* fix: icon and margin (#1171)

* Hide pay with wallet button in Daimo component (#1172)

* hide pay with wallet button

* improve targeted css approach

* Fix: Daimo bug and activity receipt bug (#1175)

* sligify chain name

* fix: stale state issue

* hide row if tokenData is not present

* Fix/conflicts (#1177)

* HOTFIX - IBAN country detection and incorrect bank acc details (#1094)

* Fix: Iban country detection and incorrect bank acc details

* Fix: update IBAN country validation to use correct locale string comparison

* add validations for US and mexican bank accounts

* fix typo

* fix claim flow and create a reusable function for getting 3 letter code

* fix country code mismatch

* fix: show error below input field

* remove unnecessary checks

* remove unnecessary CLABE check

* Prod LP v2.1 (#1098)

* feat: lpv2.1

* fix: gigaclouds, font and exchange widget

* fixes and improvements

* remove duplicate export

* remove unused component

* Fix: Landing page hero section responsiveness issue (#1107)

* fix: hero section responsiveness issue

* fix: stars position

* fix height on desktop

* remove unused code

* fix margins (#1113)

* [TASK-14052] Prod release 105 (#1122)

* feat: handle send link claims to bank account for peanut users (#1078)

* reafactor: create reusable country list component and use it for all the flows

* feat: reusable user accounts components

* feat: handle different cases based on kyc status for bank claim

* fix: account creation

* chore: add docstring to hooks

* chore: better comments for bank flow manager

* fix: kyc modal closing after tos acceptance issue

* fix: remove bank acc caching from withdraw flow

* fix: update confirm claim modal copy

* fix: remove bank acc caching from claim flow

* fix: navheader title

* remove duplicate debounce code and use `useDebounce` hook instead (#1079)

* Landing page v2.1 (#1089)

* lpv2.1 part 1

* Add exchange widget

* add and integrate exchange API

* add yourMoney component bg

* update landing countries svg

* integrate frankfurter API

* fixes and improvements

* decrease hero section height

* allow max 2 decimal places

* Add `/exchange` route

* fix: overlay

* make destination amount editable and bugg fixes

* some fixes & currency improvements

* crucial commit

* fix checkmark, font size and weight

---------

Co-authored-by: Hugo Montenegro <[email protected]>

* [TASK-13186] refactor: use networkName instead of axelarChainName (#1095)

* refactor: use networkName instead of axelarChainName

* fix: types

* fix: onramp currency (#1096)

* fix: stretched favicon (#1099)

* [TASK-13971] fix: scientific notation in eip681 parsing (#1097)

* fix: scientific notation in eip681 parsing

* fix: qr handling tests

* fix: peanut sdk mock

* pull iban hotfix (#1100)

* fix: claim flow bugs (#1102)

* fix: cross chain claim

* fix: full name issue on confirm bank claim view

* fix: back navigation on desktop views

* Fix back button not working on /profile (#1101)

* Fix back button not working

* fix public profile page

* extract internal navigation logic to utility function

* fix: send link claims to us bank accounts (#1108)

* fix: usa bank account claims

* fix: show bank account details in confirm claim view

* Sync Landing page changes (#1111)

* reduce clouds size and update font

* fix: hero section responsiveness issue

* fix: formatting errors

* add currency animation

* fix: us bank claims after kyc for logged in users (#1112)

* fix: trim account form inputs for spaces (#1114)

* [TASK-14107] fix: don't allow claiming on xChain if route is not found (#1115)

* fix: don't allow claiming on xChain if route is not found

* fix(claim): use correct decimals for min receive amount

* feat: handle redirect uri when on unsupported browsers (#1117)

* feat: handle redirect uri when on unsupported browsers

* fix: confirm bank claim ui rows for iban guest claim

* remove animation (#1118)

* fix: formatting

---------

Co-authored-by: Kushagra Sarathe <[email protected]>
Co-authored-by: Mohd Zishan <[email protected]>
Co-authored-by: Hugo Montenegro <[email protected]>

* fix: bank claim flow runtime error (#1138)

* hotfix: make iban non optional (#1139)

* fix: bank claim flow runtime error

* fix: dont have iban as optional

* fix: merge conflicts

* fix: merge external account with bank details (#1140)

* fix: add id to external account (#1142)

* added tg footer (#1144)

* Hotfix : add missing countries - claim as guest flow (#1146)

* fix: add missing countries

* remove duplicate comment

* fix: show error on dynamic bank account form (#1147)

* fix: Invalid IBAN for UK (#1151)

---------

Co-authored-by: Mohd Zishan <[email protected]>
Co-authored-by: Juan José Ramírez <[email protected]>
Co-authored-by: Hugo Montenegro <[email protected]>
Co-authored-by: Hugo Montenegro <[email protected]>

---------

Co-authored-by: Mohd Zishan <[email protected]>
Co-authored-by: Hugo Montenegro <[email protected]>
Co-authored-by: Juan José Ramírez <[email protected]>
Co-authored-by: Juan José Ramírez <[email protected]>
Co-authored-by: Hugo Montenegro <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants