Skip to content

feat: advertise supported networks, tokens and bank rails in landing FAQ#2338

Merged
Hugo0 merged 4 commits into
mainfrom
feat/faq-supported-rails
Jul 2, 2026
Merged

feat: advertise supported networks, tokens and bank rails in landing FAQ#2338
Hugo0 merged 4 commits into
mainfrom
feat/faq-supported-rails

Conversation

@Hugo0

@Hugo0 Hugo0 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Prospective users comparing cards look for supported networks/tokens in the FAQ and bounce when it's missing (X thread 2026-07-02, @0xPumbi/@ddgn — Hugo promised a fix). Adds a rich "Which networks, tokens and banks does Peanut support?" entry to the landing FAQ (/ and /lp):

  • Networks/tokens render from rhino.consts — the same constants the add-money Choose Network drawer uses, so the public claim can't drift from what the app accepts (9 EVM chains one-address, Solana, Tron; USDC/USDT + ETH on EVM, Tron USDT-only).
  • Bank & local rails: US ACH + wire, SEPA EUR, UK Faster Payments, Mexico SPEI, Argentina Mercado Pago, Brazil Pix.
  • Plain-text answer joins the existing FAQPage JSON-LD for SEO; rich chip UI (reusing ChainChip) renders in the panel. Inserted before the "My question is not here" catch-all.

Risks / breaking changes

  • FE-only, landing page only. Global/FAQs gains an optional answerContent prop — all other consumers (quests, merchant LP, card LP, mdx) unchanged.
  • Base is main (marketing timing) → needs main→dev back-merge after merge.

QA

  • npm test 1660 passed · typecheck clean · next build green.
  • Served the production build locally; asserted the question, chain chips (BNB Chain/Katana/…), rails, and FAQPage JSON-LD in the rendered HTML of /.
  • Visual check: Vercel preview → landing → FAQ → open the new entry.

Users comparing cards can't find which chains/stables we support without
signing up (X thread 2026-07-02 — reviewers literally said they look for
this in the FAQ and bounce when it's missing). Renders the answer from the
same rhino.consts the add-money Choose Network drawer uses, so the public
claim can never drift from what the app actually accepts; plain-text
answer feeds the FAQPage JSON-LD for SEO.
@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
peanut-wallet Ready Ready Preview, Comment Jul 2, 2026 10:23pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 35 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 020a48da-eaca-41d3-a7bb-6ed9cd756ec1

📥 Commits

Reviewing files that changed from the base of the PR and between 02da547 and 8d4d799.

📒 Files selected for processing (2)
  • src/components/LandingPage/SupportedRailsFaqAnswer.tsx
  • src/lib/landingContent.ts

Walkthrough

This PR adds support for rich JSX FAQ answers via a new optional answerContent field, introduces a "supported networks/tokens/banks" FAQ item with a dedicated component, backing constants (FIAT_RAILS, FAQ id/question/answer), a chain display-name utility, and wires the new FAQ into landing content and the landing page client with memoization.

Changes

Supported Rails FAQ Feature

Layer / File(s) Summary
Rich JSX FAQ answer support
src/components/Global/FAQs/index.tsx
FAQsProps gains optional answerContent?: ReactNode; rendering prefers answerContent over the plain answer string.
Chain display name utility
src/utils/chain-display.utils.ts
New chainDisplayName function maps chain keys to display names with overrides (e.g., BNB) and title-case fallback.
Supported-rails FAQ constants
src/constants/faq.consts.ts
New constants export FAQ id, FIAT_RAILS data, and question/answer strings derived from supported chains and rails.
Supported-rails FAQ answer component
src/components/LandingPage/SupportedRailsFaqAnswer.tsx
New client component renders sections for supported networks, tokens, and banks/rails using the new constants and utility.
Landing content injection
src/lib/landingContent.ts
Imports new FAQ constants, builds SUPPORTED_RAILS_QUESTION, and splices it into faqData.questions via withSupportedRails inside getLandingContent.
Landing page client wiring
src/components/LandingPage/LandingPageClient.tsx
Memoizes faqQuestions with useMemo, replacing the supported-rails answer with the new JSX component, and passes it to FAQs.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: jjramirezn

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding supported networks, tokens, and bank rails to the landing FAQ.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the new landing FAQ entry and supporting refactor.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Code-analysis diff

Painscore total: 5840.84 → 5854.51 (+13.67)
Findings: +3 net (+17 new, -14 resolved)

🆕 New findings (17)

  • high complexity — src/components/LandingPage/LandingPageClient.tsx — CC 39, MI 55.86, SLOC 145
  • medium high-mdd — src/components/LandingPage/LandingPageClient.tsx:44 — LandingPageClient: MDD 41.4 (uses across many lines from declarations)
  • medium method-complexity — src/components/LandingPage/LandingPageClient.tsx:116 — CC 17 SLOC 39
  • medium complexity — src/lib/landingContent.ts — CC 14, MI 61.2, SLOC 56
  • medium complexity — src/components/Global/FAQs/index.tsx — CC 12, MI 63.28, SLOC 28
  • medium complexity — src/constants/faq.consts.ts — CC 2, MI 54.74, SLOC 39
  • medium react-direct-dom — src/components/LandingPage/LandingPageClient.tsx:118 — direct DOM: document.getElementById
  • low high-dlt — src/components/LandingPage/LandingPageClient.tsx:44 — LandingPageClient: DLT 23 (calls 23 distinct functions — high context load)
  • low high-mdd — src/components/LandingPage/LandingPageClient.tsx:115 — : MDD 18.6 (uses across many lines from declarations)
  • low high-dlt — src/components/LandingPage/LandingPageClient.tsx:115 — : DLT 15 (calls 15 distinct functions — high context load)
  • low high-mdd — src/components/Global/FAQs/index.tsx:52 — : MDD 11.8 (uses across many lines from declarations)
  • low high-mdd — src/lib/landingContent.ts:71 — readLandingContent: MDD 11.0 (uses across many lines from declarations)
  • low high-mdd — src/components/Global/FAQs/index.tsx:19 — linkifyText: MDD 10.2 (uses across many lines from declarations)
  • low missing-return-type — src/components/Global/FAQs/index.tsx:44 — FAQsPanel: exported fn missing return type annotation
  • low missing-return-type — src/components/LandingPage/LandingPageClient.tsx:44 — LandingPageClient: exported fn missing return type annotation
  • low missing-return-type — src/components/LandingPage/SupportedRailsFaqAnswer.tsx:14 — SupportedRailsFaqAnswer: exported fn missing return type annotation
  • low nextjs-use-client-overuse — src/components/LandingPage/SupportedRailsFaqAnswer.tsx:1 — 'use client' but no hooks/handlers/browser API

✅ Resolved (14)

  • src/components/LandingPage/LandingPageClient.tsx — CC 36, MI 54.54, SLOC 137
  • src/components/LandingPage/LandingPageClient.tsx:42 — LandingPageClient: MDD 39.7 (uses across many lines from declarations)
  • src/components/LandingPage/LandingPageClient.tsx:103 — CC 17 SLOC 39
  • src/components/Global/FAQs/index.tsx — CC 12, MI 63.45, SLOC 28
  • src/lib/landingContent.ts — CC 10, MI 60.18, SLOC 35
  • src/components/LandingPage/LandingPageClient.tsx:105 — direct DOM: document.getElementById
  • src/components/LandingPage/LandingPageClient.tsx:42 — LandingPageClient: DLT 21 (calls 21 distinct functions — high context load)
  • src/components/LandingPage/LandingPageClient.tsx:102 — : MDD 18.6 (uses across many lines from declarations)
  • src/components/LandingPage/LandingPageClient.tsx:102 — : DLT 15 (calls 15 distinct functions — high context load)
  • src/components/Global/FAQs/index.tsx:48 — : MDD 12.1 (uses across many lines from declarations)
  • src/lib/landingContent.ts:43 — getLandingContent: MDD 11.0 (uses across many lines from declarations)
  • src/components/Global/FAQs/index.tsx:15 — linkifyText: MDD 10.2 (uses across many lines from declarations)
  • src/components/Global/FAQs/index.tsx:40 — FAQsPanel: exported fn missing return type annotation
  • src/components/LandingPage/LandingPageClient.tsx:42 — LandingPageClient: exported fn missing return type annotation

📈 Painscore deltas (top movers)

File Before After Δ
src/constants/faq.consts.ts 0.0 5.2 +5.2
src/components/LandingPage/SupportedRailsFaqAnswer.tsx 0.0 4.2 +4.2
src/utils/chain-display.utils.ts 0.0 3.8 +3.8

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🧪 UI test report — ✅ all green

Suites

  • unit: 1663 ran, 0 failed, 0 skipped, 24.2s

📊 Coverage (unit)

metric %
statements 54.9%
branches 37.9%
functions 42.7%
lines 54.8%
⏱ 10 slowest test cases
time test
3.3s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › never places two stickers in heavy overlap (broad seed sweep)
0.4s src/components/Card/share-asset/__tests__/shareAssetLayout.test.ts › every sticker stays within canvas at any count
0.3s src/app/actions/__tests__/api-headers.test.ts › should include Content-Type in updateUserById
0.3s src/app/actions/__tests__/api-headers-extended.test.ts › should not include apiKey in updateUserById body
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid 9-digit US account
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid UK IBAN with spaces
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle too long for US account
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid ETH address
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid ENS name
0.1s src/components/Global/GeneralRecipientInput/__tests__/GeneralRecipientInput.test.tsx › should handle valid ETH address in lowercase
📍 Inline annotations are in the **Unit test report** check above. Coverage artifact: `coverage-unit`. Generated by `.github/workflows/tests.yml`.

Fiat rails now live once in FIAT_RAILS (chips + JSON-LD prose both derive
from it), Solana/Tron chips derive from OTHER_SUPPORTED_CHAINS, token chips
reuse getSupportedTokens' logoUrl, chainDisplayName moves to a utils file
per export rules, withSupportedRails wraps in one place, and the FAQ array
is memoized (LandingPageClient re-renders per scroll frame).
@Hugo0

Hugo0 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

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

@coderabbitai coderabbitai Bot added the enhancement New feature or request label Jul 2, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/constants/faq.consts.ts (1)

24-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Grammar edge case if a third "other" chain is added.

OTHER_SUPPORTED_CHAINS.map(chainDisplayName).join(' and ') reads fine for exactly two items ("Solana and Tron") but would read incorrectly for three or more (e.g. "Solana and Tron and X" instead of an Oxford-comma list). Low priority since the array currently has 2 entries, but worth a defensive fix if this list is expected to grow.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/constants/faq.consts.ts` at line 24, The OTHER_CHAIN_LIST formatting in
faq.consts.ts only joins items with "and", which breaks grammar if
OTHER_SUPPORTED_CHAINS grows beyond two entries. Update the constant built from
OTHER_SUPPORTED_CHAINS.map(chainDisplayName) to use a list formatter that
handles 2+ items correctly, with the fix centered on OTHER_CHAIN_LIST so future
additions produce a proper Oxford-comma style string.
src/components/LandingPage/SupportedRailsFaqAnswer.tsx (1)

35-37: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Same drift risk for the token summary line.

USDC & USDT on every network · ETH on EVM networks · Tron is USDT-only is hardcoded prose describing token support, while the chips above are rendered dynamically from getSupportedTokens('EVM'). If token support changes, this summary text won't automatically reflect it. Lower risk than the chain list above since token support changes less frequently, but the same single-source principle applies.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/LandingPage/SupportedRailsFaqAnswer.tsx` around lines 35 - 37,
The token summary line in SupportedRailsFaqAnswer is hardcoded and can drift
from the dynamically rendered chips driven by getSupportedTokens('EVM'). Update
this paragraph to derive its wording from the same token source/config used for
the chips, so changes to token support are reflected automatically. Keep the
summary logic co-located with the existing supported-token rendering in
SupportedRailsFaqAnswer and avoid maintaining a separate manual prose string.
src/lib/landingContent.ts (1)

59-64: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Position-based insertion is fragile; empty-array branch is dead code.

withSupportedRails relies on the last array element always being the "not here" catch-all by convention — if content ordering ever changes, the FAQ lands in the wrong spot silently. Also, the questions.length === 0 special case is redundant: the general-case slice logic already produces the same [SUPPORTED_RAILS_QUESTION] result for an empty array.

♻️ Simplify by removing the dead branch
 function withSupportedRails(questions: LandingContent['faqData']['questions']) {
-    if (questions.length === 0) return [SUPPORTED_RAILS_QUESTION]
     return [...questions.slice(0, -1), SUPPORTED_RAILS_QUESTION, ...questions.slice(-1)]
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/landingContent.ts` around lines 59 - 64, The withSupportedRails
helper in landingContent.ts inserts SUPPORTED_RAILS_QUESTION by assuming the
last FAQ item is always the catch-all, and its empty-array branch is redundant.
Simplify the function by removing the questions.length === 0 special case and
rely on the existing slice-based insertion for all inputs, while keeping the
SUPPORTED_RAILS_QUESTION placement logic in withSupportedRails clear and
maintainable.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/LandingPage/SupportedRailsFaqAnswer.tsx`:
- Around line 18-21: The paragraph copy in SupportedRailsFaqAnswer is hardcoding
“plus Solana and Tron,” which can drift from the supported-chain source of
truth. Update the text to derive the non-EVM chain names from the same
OTHER_SUPPORTED_CHAINS data used by faq.consts.ts, using chainDisplayName (or an
equivalent shared formatter) instead of a fixed string. Keep the wording in sync
with any future additions or removals from OTHER_SUPPORTED_CHAINS so the rich UI
and plain-text answer stay aligned.

In `@src/lib/landingContent.ts`:
- Around line 48-69: The supported-rails FAQ entry is hardcoded in English
because SUPPORTED_RAILS_QUESTION is created once at module load and inserted by
withSupportedRails for every locale. Update getLandingContent and/or
withSupportedRails so the supported-rails question and answer are selected per
locale, using a locale-aware lookup like readLandingContent rather than the
module-level constants. Keep the insertion behavior by SUPPORTED_RAILS_FAQ_ID,
but ensure non-en locales receive localized text instead of the English-only
SUPPORTED_RAILS_FAQ_QUESTION and SUPPORTED_RAILS_FAQ_ANSWER.

---

Nitpick comments:
In `@src/components/LandingPage/SupportedRailsFaqAnswer.tsx`:
- Around line 35-37: The token summary line in SupportedRailsFaqAnswer is
hardcoded and can drift from the dynamically rendered chips driven by
getSupportedTokens('EVM'). Update this paragraph to derive its wording from the
same token source/config used for the chips, so changes to token support are
reflected automatically. Keep the summary logic co-located with the existing
supported-token rendering in SupportedRailsFaqAnswer and avoid maintaining a
separate manual prose string.

In `@src/constants/faq.consts.ts`:
- Line 24: The OTHER_CHAIN_LIST formatting in faq.consts.ts only joins items
with "and", which breaks grammar if OTHER_SUPPORTED_CHAINS grows beyond two
entries. Update the constant built from
OTHER_SUPPORTED_CHAINS.map(chainDisplayName) to use a list formatter that
handles 2+ items correctly, with the fix centered on OTHER_CHAIN_LIST so future
additions produce a proper Oxford-comma style string.

In `@src/lib/landingContent.ts`:
- Around line 59-64: The withSupportedRails helper in landingContent.ts inserts
SUPPORTED_RAILS_QUESTION by assuming the last FAQ item is always the catch-all,
and its empty-array branch is redundant. Simplify the function by removing the
questions.length === 0 special case and rely on the existing slice-based
insertion for all inputs, while keeping the SUPPORTED_RAILS_QUESTION placement
logic in withSupportedRails clear and maintainable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 50618662-1d9d-4289-92d7-6aaa4d9fd35d

📥 Commits

Reviewing files that changed from the base of the PR and between 1b75fbb and 02da547.

📒 Files selected for processing (6)
  • src/components/Global/FAQs/index.tsx
  • src/components/LandingPage/LandingPageClient.tsx
  • src/components/LandingPage/SupportedRailsFaqAnswer.tsx
  • src/constants/faq.consts.ts
  • src/lib/landingContent.ts
  • src/utils/chain-display.utils.ts

Comment thread src/components/LandingPage/SupportedRailsFaqAnswer.tsx
Comment thread src/lib/landingContent.ts
@Hugo0 Hugo0 marked this pull request as ready for review July 2, 2026 22:25
@Hugo0 Hugo0 merged commit 9752628 into main Jul 2, 2026
22 of 24 checks passed
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.

1 participant