Skip to content

Conversation

@gregfromstl
Copy link
Contributor

@gregfromstl gregfromstl commented Jun 3, 2025

Summary

  • move the onramp country support page to /onramp/countries
  • update import paths after moving

Testing

  • pnpm biome check --apply apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/page.tsx apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/components/server/countries-table.tsx apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/components/client/provider.tsx apps/dashboard/src/app/(app)/(dashboard)/(bridge)/types/onramp-country.ts apps/dashboard/src/app/(app)/(dashboard)/(bridge)/utils.ts
  • pnpm test -r (fails: spawn anvil ENOENT)

https://chatgpt.com/codex/tasks/task_b_683f13becfd483268bf07f6d964ccaf2


PR-Codex overview

This PR introduces types and components for managing onramp country support in a dashboard application. It adds functionality to fetch and display supported countries and currencies based on selected providers.

Detailed summary

  • Added types: OnrampCountryToken, OnrampCountryDetails, OnrampCountrySupport.
  • Implemented getOnrampCountrySupport function to fetch country data.
  • Created ProviderSelector component for selecting onramp providers.
  • Developed CountriesTable component to display countries and currencies.
  • Updated OnrampCountriesPage to integrate new components and display data.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features
    • Introduced a page displaying supported countries and currencies for onramp providers.
    • Added a provider selector to switch between "coinbase", "stripe", and "transak".
    • Implemented a table listing countries and their supported currencies for the selected provider.
  • Enhancements
    • Improved navigation and provider selection experience with responsive design and updated metadata for better SEO.

@gregfromstl gregfromstl requested review from a team as code owners June 3, 2025 16:05
@changeset-bot
Copy link

changeset-bot bot commented Jun 3, 2025

⚠️ No Changeset found

Latest commit: 59934b3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Jun 3, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
thirdweb-www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 3, 2025 4:12pm
4 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Skipped (Inspect) Jun 3, 2025 4:12pm
login ⬜️ Skipped (Inspect) Jun 3, 2025 4:12pm
thirdweb_playground ⬜️ Skipped (Inspect) Jun 3, 2025 4:12pm
wallet-ui ⬜️ Skipped (Inspect) Jun 3, 2025 4:12pm

@vercel vercel bot temporarily deployed to Preview – thirdweb_playground June 3, 2025 16:05 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui June 3, 2025 16:05 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 June 3, 2025 16:05 Inactive
@vercel vercel bot temporarily deployed to Preview – login June 3, 2025 16:05 Inactive
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 3, 2025

Walkthrough

This update introduces a new Onramp Countries dashboard page, enabling users to select an onramp provider and view supported countries and currencies. It adds new React components for provider selection and country display, TypeScript types for country data structures, and a utility for fetching provider-specific country support data.

Changes

Files / Folders Change Summary
.../onramp/countries/components/client/provider.tsx Added ProviderSelector component and OnrampProvider type for provider selection UI.
.../onramp/countries/components/server/countries-table.tsx Added CountriesTable server component to display country and currency data for a provider.
.../onramp/countries/page.tsx Added new page component with metadata; renders provider selector and countries table based on selected provider.
.../onramp/countries/types/onramp-country.ts Introduced types: OnrampCountryToken, OnrampCountryDetails, OnrampCountrySupport for modeling country data.
.../onramp/countries/utils.ts Added getOnrampCountrySupport async function to fetch supported countries per provider from API.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant OnrampCountriesPage
    participant ProviderSelector
    participant CountriesTable
    participant getOnrampCountrySupport

    User->>OnrampCountriesPage: Accesses page with optional provider param
    OnrampCountriesPage->>ProviderSelector: Renders with activeProvider
    OnrampCountriesPage->>CountriesTable: Renders with provider
    CountriesTable->>getOnrampCountrySupport: Fetch supported countries for provider
    getOnrampCountrySupport-->>CountriesTable: Return country/currency data
    CountriesTable-->>OnrampCountriesPage: Rendered table
    ProviderSelector->>OnrampCountriesPage: (On provider change) triggers navigation/update
Loading

Suggested labels

Dashboard

Suggested reviewers

  • joaquim-verges
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
    • Explain this complex logic.
    • 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. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

  • 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.

@github-actions github-actions bot added the Dashboard Involves changes to the Dashboard. label Jun 3, 2025
@graphite-app
Copy link
Contributor

graphite-app bot commented Jun 3, 2025

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge-queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

@codecov
Copy link

codecov bot commented Jun 3, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 55.57%. Comparing base (6cce31d) to head (59934b3).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7262   +/-   ##
=======================================
  Coverage   55.57%   55.57%           
=======================================
  Files         909      909           
  Lines       58680    58680           
  Branches     4157     4157           
=======================================
  Hits        32610    32610           
  Misses      25963    25963           
  Partials      107      107           
Flag Coverage Δ
packages 55.57% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/components/server/countries-table.tsx (2)

10-10: Consider using absolute imports for better maintainability.

The relative import path ../../../../utils is quite long and prone to breaking when files are moved. Consider using an absolute import path.

-import { getOnrampCountrySupport } from "../../../../utils";
+import { getOnrampCountrySupport } from "@/app/(app)/(dashboard)/(bridge)/utils";

31-38: Add fallback for empty countries list.

Consider handling the case where no countries are returned for a provider.

        <TableBody>
+         {countries.length === 0 ? (
+           <TableRow>
+             <TableCell colSpan={2} className="text-center text-muted-foreground py-8">
+               No countries found for {props.provider}
+             </TableCell>
+           </TableRow>
+         ) : (
          {countries.map((country) => (
            <TableRow key={country.code} className="hover:bg-accent/50">
              <TableCell className="font-medium">{country.name}</TableCell>
              <TableCell className="text-muted-foreground">
                {country.currencies.join(", ")}
              </TableCell>
            </TableRow>
          ))}
+         )}
        </TableBody>
apps/dashboard/src/app/(app)/(dashboard)/(bridge)/types/onramp-country.ts (1)

14-17: Strongly-typed OnrampCountrySupport union
Using a string-literal union for provider enforces valid values at compile time. If these provider identifiers are used elsewhere, you might consider extracting them into a shared enum or constant map to avoid duplication.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6cce31d and 59934b3.

📒 Files selected for processing (5)
  • apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/components/client/provider.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/components/server/countries-table.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/page.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(bridge)/types/onramp-country.ts (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(bridge)/utils.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/components/server/countries-table.tsx (3)
apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/components/client/provider.tsx (1)
  • OnrampProvider (8-8)
apps/dashboard/src/app/(app)/(dashboard)/(bridge)/utils.ts (1)
  • getOnrampCountrySupport (72-92)
apps/portal/src/components/ui/table.tsx (7)
  • TableContainer (151-151)
  • Table (143-143)
  • TableHeader (144-144)
  • TableRow (148-148)
  • TableHead (147-147)
  • TableBody (145-145)
  • TableCell (149-149)
apps/dashboard/src/app/(app)/(dashboard)/(bridge)/utils.ts (2)
apps/dashboard/src/@/constants/public-envs.ts (1)
  • NEXT_PUBLIC_THIRDWEB_BRIDGE_HOST (24-25)
apps/dashboard/src/@/constants/server-envs.ts (1)
  • DASHBOARD_THIRDWEB_SECRET_KEY (8-9)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Size
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (8)
apps/dashboard/src/app/(app)/(dashboard)/(bridge)/utils.ts (1)

72-92: LGTM! Well-implemented utility function.

The implementation follows excellent patterns:

  • Proper error handling with descriptive error messages
  • Appropriate caching strategy (1 hour revalidation)
  • Type safety with imported type assertion
  • Consistent with existing getRoutes function patterns
  • Secure authentication with secret key headers

The function correctly constructs the URL, handles the provider parameter, and returns properly typed data.

apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/page.tsx (2)

11-18: LGTM! Excellent metadata setup.

The metadata configuration is comprehensive with proper title, description, and Open Graph tags for social sharing. This will improve SEO and user experience when the page is shared.


27-46: Well-structured responsive layout.

The component layout is well-organized with:

  • Responsive flexbox design that adapts to different screen sizes
  • Proper spacing and typography hierarchy
  • Clean separation between header controls and data display
  • Good accessibility with semantic header structure
apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/components/client/provider.tsx (3)

17-24: Excellent URL manipulation with proper optimization.

The createPageURL function is well-implemented with:

  • Proper handling of existing search parameters
  • Correct use of useCallback for performance optimization
  • Type-safe provider parameter handling
  • Clean URLSearchParams manipulation

28-42: Clean provider selection UI implementation.

The provider selection UI is well-crafted with:

  • Dynamic styling based on active state (default vs outline variants)
  • Proper key assignment for React list rendering
  • Accessible button interactions with router navigation
  • Consistent capitalization styling
  • Good responsive flex layout

8-8:

✅ Verification successful

Verify type consistency across the codebase.

The OnrampProvider type definition should be consistent with the provider parameter types used in the utility function.

Let me verify that this type matches the usage in the utils function:


🏁 Script executed:

#!/bin/bash
# Description: Verify OnrampProvider type consistency across files
echo "Checking OnrampProvider type definitions and usage..."

# Find all OnrampProvider type definitions
rg "OnrampProvider.*=" -A 1

# Find all provider parameter type definitions in functions
rg "provider.*stripe.*coinbase.*transak" -A 1

Length of output: 2227


OnrampProvider type consistency verified

The OnrampProvider union ("stripe" | "coinbase" | "transak") is used identically in:

  • apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/components/client/provider.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(bridge)/utils.ts
  • apps/dashboard/src/app/(app)/(dashboard)/(bridge)/types/onramp-country.ts

No discrepancies found—no changes required.

apps/dashboard/src/app/(app)/(dashboard)/(bridge)/types/onramp-country.ts (2)

1-5: Well-defined OnrampCountryToken type
The OnrampCountryToken interface correctly captures chainId, address, and symbol. This will ensure downstream code can safely rely on these fields.


7-12: Clear OnrampCountryDetails structure
This type cleanly models a country’s code, name, supported currencies, and associated tokens. It aligns well with the shape of the API responses and will make the table rendering straightforward.

Comment on lines +13 to +15
export async function CountriesTable(props: { provider: OnrampProvider }) {
const data = await getOnrampCountrySupport(props.provider);
const countries = data.supportedCountries;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for the async data fetching.

The component directly awaits getOnrampCountrySupport without error handling. If the API call fails, this will cause the entire page to error.

Consider wrapping the data fetching in a try-catch block or creating an error boundary:

export async function CountriesTable(props: { provider: OnrampProvider }) {
+  try {
    const data = await getOnrampCountrySupport(props.provider);
    const countries = data.supportedCountries;
+  } catch (error) {
+    return (
+      <div className="flex items-center justify-center p-8">
+        <p className="text-muted-foreground">
+          Failed to load country data for {props.provider}
+        </p>
+      </div>
+    );
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export async function CountriesTable(props: { provider: OnrampProvider }) {
const data = await getOnrampCountrySupport(props.provider);
const countries = data.supportedCountries;
export async function CountriesTable(props: { provider: OnrampProvider }) {
try {
const data = await getOnrampCountrySupport(props.provider);
const countries = data.supportedCountries;
} catch (error) {
return (
<div className="flex items-center justify-center p-8">
<p className="text-muted-foreground">
Failed to load country data for {props.provider}
</p>
</div>
);
}
// ...rest of the component using `countries`
}
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/components/server/countries-table.tsx
around lines 13 to 15, the async call to getOnrampCountrySupport lacks error
handling, which can cause the entire page to crash if the API call fails. Wrap
the await call in a try-catch block to catch any errors during data fetching,
and handle the error gracefully, such as by logging the error and returning
fallback UI or empty data to prevent the page from breaking.


export async function CountriesTable(props: { provider: OnrampProvider }) {
const data = await getOnrampCountrySupport(props.provider);
const countries = data.supportedCountries;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Validate data structure before accessing properties.

The code assumes data.supportedCountries exists without validation. This could cause runtime errors if the API response structure changes.

Add validation for the data structure:

  const data = await getOnrampCountrySupport(props.provider);
- const countries = data.supportedCountries;
+ const countries = data.supportedCountries || [];
+ 
+ if (!Array.isArray(countries)) {
+   console.warn('Invalid country data structure received:', data);
+   return (
+     <div className="flex items-center justify-center p-8">
+       <p className="text-muted-foreground">Invalid country data format</p>
+     </div>
+   );
+ }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const countries = data.supportedCountries;
const data = await getOnrampCountrySupport(props.provider);
const countries = data.supportedCountries || [];
if (!Array.isArray(countries)) {
console.warn('Invalid country data structure received:', data);
return (
<div className="flex items-center justify-center p-8">
<p className="text-muted-foreground">Invalid country data format</p>
</div>
);
}
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/components/server/countries-table.tsx
at line 15, the code accesses data.supportedCountries without checking if data
is defined or if supportedCountries exists. To fix this, add validation to
ensure data is not null or undefined and that supportedCountries is a valid
array before accessing it. Use conditional checks or optional chaining to safely
access supportedCountries and handle cases where the data structure might differ
or be missing.

Comment on lines +23 to +25
const searchParams = await props.searchParams;
const activeProvider: OnrampProvider =
(searchParams.provider as OnrampProvider) || "coinbase";
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add type safety for search params provider validation.

The type assertion (searchParams.provider as OnrampProvider) doesn't validate if the provider is actually a valid OnrampProvider value. Invalid values could cause issues downstream.

Add validation for the provider parameter:

  const searchParams = await props.searchParams;
- const activeProvider: OnrampProvider =
-   (searchParams.provider as OnrampProvider) || "coinbase";
+ const validProviders: OnrampProvider[] = ["stripe", "coinbase", "transak"];
+ const activeProvider: OnrampProvider = 
+   validProviders.includes(searchParams.provider as OnrampProvider) 
+     ? (searchParams.provider as OnrampProvider)
+     : "coinbase";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const searchParams = await props.searchParams;
const activeProvider: OnrampProvider =
(searchParams.provider as OnrampProvider) || "coinbase";
const searchParams = await props.searchParams;
const validProviders: OnrampProvider[] = ["stripe", "coinbase", "transak"];
const activeProvider: OnrampProvider =
validProviders.includes(searchParams.provider as OnrampProvider)
? (searchParams.provider as OnrampProvider)
: "coinbase";
🤖 Prompt for AI Agents
In apps/dashboard/src/app/(app)/(dashboard)/(bridge)/onramp/countries/page.tsx
around lines 23 to 25, the code uses a type assertion for searchParams.provider
without validating if it is a valid OnrampProvider, which risks invalid values
causing issues. To fix this, implement a validation step that checks if
searchParams.provider is one of the allowed OnrampProvider values before
assigning it to activeProvider. If it is invalid or missing, default to
"coinbase". This ensures type safety and prevents invalid provider values from
propagating.

@github-actions
Copy link
Contributor

github-actions bot commented Jun 3, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 62.57 KB (0%) 1.3 s (0%) 294 ms (+147.48% 🔺) 1.6 s
thirdweb (cjs) 345.62 KB (0%) 7 s (0%) 888 ms (-3.45% 🔽) 7.9 s
thirdweb (minimal + tree-shaking) 5.7 KB (0%) 114 ms (0%) 107 ms (+1353.27% 🔺) 221 ms
thirdweb/chains (tree-shaking) 531 B (0%) 11 ms (0%) 55 ms (+1128.87% 🔺) 65 ms
thirdweb/react (minimal + tree-shaking) 19.56 KB (0%) 392 ms (0%) 127 ms (+504.34% 🔺) 519 ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex Dashboard Involves changes to the Dashboard.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants