Skip to content

feat: Limit the number of tokens to display to significantly reduce the number of instant requests#839

Merged
Woody4618 merged 8 commits intosolana-foundation:masterfrom
hoodieshq:development-fix-tokens-page
Feb 13, 2026
Merged

feat: Limit the number of tokens to display to significantly reduce the number of instant requests#839
Woody4618 merged 8 commits intosolana-foundation:masterfrom
hoodieshq:development-fix-tokens-page

Conversation

@rogaldh
Copy link
Copy Markdown
Contributor

@rogaldh rogaldh commented Feb 4, 2026

Description

Improve the token history and owned tokens components to prevent excessive RPC requests. Previously, loading the tokens page would trigger simultaneous fetches for all token accounts and their transaction details. This change implements progressive loading with manual triggers.

Type of change

  • New feature

Screenshots

image image

Testing

Visit http://localhost:3000/address/TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb/tokens. Tokens for the Token Program should be loaded with no 429s.

Related Issues

HOO-187

Checklist

  • My code follows the project's style guidelines
  • I have added tests that prove my fix/feature works
  • All tests pass locally and in CI
  • I have run build:info script to update build information
  • CI/CD checks pass
  • I have included screenshots for protocol screens (if applicable)

Additional Notes

Key changes:

  • OwnedTokensCard: Added pagination (4 tokens initially, "Load More" for additional)
  • TokenHistoryCard:
    • Initial state shows prompt to load history (no auto-fetch)
    • Progressive token account loading (4 at a time)
    • LazyInstructionDetails component uses IntersectionObserver for viewport-based loading
    • Transaction list pagination (4 visible initially)

@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 4, 2026

@rogaldh is attempting to deploy a commit to the Solana Foundation Team on Vercel.

A member of the Team first needs to authorize it.

@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 4, 2026

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

Project Deployment Actions Updated (UTC)
explorer Ready Ready Preview, Comment Feb 12, 2026 3:06pm

Request Review

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Feb 4, 2026

Greptile Overview

Greptile Summary

This PR introduces progressive/lazy loading to the tokens UI to reduce bursty RPC traffic, and adds a new Token Info subsystem (chain-id + token-info fetchers + API route) to resolve token labels using chainId derived from cluster/genesisHash.

Key UI changes:

  • OwnedTokensCard paginates displayed holdings (initial 4, “Load More”).
  • TokenHistoryCard moves token-history fetching behind a manual “Load Token History” button, adds token-account pagination, and adds a LazyInstructionDetails cell intended to defer transaction detail fetching.

Key infra changes:

  • Adds /api/token-info and new app/entities/{chain-id,token-info} modules.
  • Adds genesisHash into ClusterInfo and threads it into token-info SWR keys.

Fixes needed before merge:

  • app/utils/token-info.ts now fetches '/api/token-info' with a relative URL; this utility is used from server-side contexts (e.g. metadata/title generation), where relative fetches can fail and will silently regress token-name resolution.
  • OwnedTokensCard removed useMetadata when rendering Address, which disables Metaplex metadata lookup for those rows (behavior regression).
  • LazyInstructionDetails currently does not auto-fetch on intersection (still requires a click), which contradicts the stated behavior and reduces the effectiveness of the change.

Confidence Score: 2/5

  • This PR has a few concrete behavior regressions and a likely server-side runtime failure path that should be addressed before merge.
  • While the progressive loading changes are mostly self-contained, token-info fetching was refactored to call a relative '/api/token-info' endpoint from utilities that are used in server contexts (metadata/title generation), which can break token name resolution. There’s also a clear functional regression where Metaplex metadata fetching is disabled in OwnedTokens rows, and the IntersectionObserver-based lazy details currently does not auto-fetch as described.
  • app/utils/token-info.ts, app/utils/get-readable-title-from-address.ts, app/components/account/OwnedTokensCard.tsx, app/components/account/TokenHistoryCard.tsx

Important Files Changed

Filename Overview
.env.example Adds public env vars for Token Info API base URL and timeout.
app/address/[address]/layout.tsx Switches SWR key/fetcher for full token info to include genesisHash via clusterInfo; risk of mismatched fetcher signature depending on new utils.
app/api/token-info/route.ts Adds POST /api/token-info endpoint calling getTokenInfos; request.json is untyped and cluster cast to Cluster after validation.
app/components/account/OwnedTokensCard.tsx Adds pagination/Load More and removes useMetadata prop from Address calls; potential regression in address label/metadata fetching.
app/components/account/TokenHistoryCard.tsx Implements progressive token history loading and lazy transaction detail fetch via IntersectionObserver; changes initial fetch behavior to manual trigger.
app/components/common/Address.tsx Replaces local async token-info fetcher with useTokenInfo hook from entities; now depends on clusterInfo.genesisHash and SWR. Potential mismatch with removed useMetadata behavior in callers.
app/entities/chain-id/lib/get-chain-id.ts Implements getChainId with genesisHash fallback for Custom/SIMD clusters.
app/entities/token-info/lib/fetch-token-mints.ts Server-side fetcher for UTL API, using getChainId and optional Next fetch config; returns [] on errors.
app/entities/token-info/model/use-token-info.ts Adds client SWR hook that calls utils getTokenInfo with deduping; depends on getTokenInfoSwrKey signature update.
app/providers/cluster.tsx Adds genesisHash to ClusterInfo and fetches it during cluster update (extra RPC call).
app/utils/get-readable-title-from-address.ts Removes customUrl usage and switches to entities getTokenInfo(address, cluster); could break custom RPC cluster title resolution.
app/utils/token-info.ts Refactors token info utilities to route through /api/token-info and genesisHash-based chainId; likely introduces client/server fetch mismatch risk.

Sequence Diagram

sequenceDiagram
  actor User
  participant UI as OwnedTokens/TokenHistory UI
  participant SWR as SWR Cache
  participant TokenInfoHook as useTokenInfo()
  participant Utils as app/utils/token-info.ts
  participant API as POST /api/token-info
  participant Entity as app/entities/token-info (UTL fetch)
  participant UTL as UTL Token List API
  participant RPC as Solana RPC

  User->>UI: Open /address/:addr/tokens
  UI->>RPC: Fetch owned token accounts (existing flow)
  UI-->>UI: Render first 4 tokens
  User->>UI: Click "Load More" (holdings)
  UI-->>UI: Increase visibleCount

  UI->>UI: Token history initial state
  User->>UI: Click "Load Token History"
  UI->>RPC: Fetch history for next 4 token accounts
  UI-->>UI: Render tx rows (first 4)
  User->>UI: Scroll tx table
  UI-->>UI: IntersectionObserver marks details cell visible
  User->>UI: Click "Load" on details
  UI->>SWR: Request token label info (optional)
  SWR->>TokenInfoHook: fetcher
  TokenInfoHook->>Utils: getTokenInfo(pubkey, cluster, genesisHash)
  Utils->>API: fetch('/api/token-info', {address, cluster, genesisHash})
  API->>Entity: getTokenInfos([address], cluster, genesisHash)
  Entity->>UTL: POST /v1/mints?chainId=...
  UTL-->>Entity: {content: tokenInfo}
  Entity-->>API: tokenInfo
  API-->>Utils: {content: tokenInfo}
  Utils-->>TokenInfoHook: tokenInfo
  TokenInfoHook-->>SWR: cache tokenInfo
  SWR-->>UI: token label rendered
Loading

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

12 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

Comment thread app/components/account/OwnedTokensCard.tsx
Comment thread app/utils/token-info.ts
Comment thread app/utils/get-readable-title-from-address.ts
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Feb 4, 2026

Additional Comments (1)

app/components/account/TokenHistoryCard.tsx
Lazy details never auto-fetch

LazyInstructionDetails sets isVisible via IntersectionObserver, but visibility alone doesn’t trigger fetchDetails(signature); the fetch only happens on click via handleLoadClick (TokenHistoryCard.tsx:688-691). The component comment/PR description says it “uses IntersectionObserver for viewport-based loading”, but as written it stays in the “Load” state after becoming visible until a user clicks. If you intended auto-fetch on intersection, you need to trigger fetchDetails when isVisible flips true (and details is empty).

Prompt To Fix With AI
This is a comment left during a code review.
Path: app/components/account/TokenHistoryCard.tsx
Line: 670:686

Comment:
**Lazy details never auto-fetch**

`LazyInstructionDetails` sets `isVisible` via IntersectionObserver, but visibility alone doesn’t trigger `fetchDetails(signature)`; the fetch only happens on click via `handleLoadClick` (`TokenHistoryCard.tsx:688-691`). The component comment/PR description says it “uses IntersectionObserver for viewport-based loading”, but as written it stays in the “Load” state after becoming visible until a user clicks. If you intended auto-fetch on intersection, you need to trigger `fetchDetails` when `isVisible` flips true (and `details` is empty).

How can I resolve this? If you propose a fix, please make it concise.

@rogaldh
Copy link
Copy Markdown
Contributor Author

rogaldh commented Feb 4, 2026

Additional Comments (1)

Removed

@C0mberry
Copy link
Copy Markdown
Contributor

image
  • server-side issue: This pr doesn't modify token-info.ts or get-readable-title-from-address.ts. The server-side metadata generation uses @/app/entities/token-info. This was fixed in PR fix: Use utl-api to fetch token-info #838.
  • useMetadata removal: Token names are already provided via tokenLabelInfo from the utl token list. Metaplex lookups add extra rpc calls that are redundant for tokens
  • Auto-fetch on intersection: removed to prevent request spam. Users now explicitly click "load" to fetch details which was the goal of this pr

@Woody4618 Woody4618 merged commit 6cbdbae into solana-foundation:master Feb 13, 2026
7 checks passed
@rogaldh rogaldh deleted the development-fix-tokens-page branch February 27, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants