Skip to content

fix: added image fetching from das#1068

Open
C0mberry wants to merge 11 commits into
solana-foundation:masterfrom
hoodieshq:fix/hoo-571-token-image-missing-on-token-page
Open

fix: added image fetching from das#1068
C0mberry wants to merge 11 commits into
solana-foundation:masterfrom
hoodieshq:fix/hoo-571-token-image-missing-on-token-page

Conversation

@C0mberry

@C0mberry C0mberry commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Description

some addresses have image in metadata. image is showing in search, but not on page. so this fix adding das request to get image.

Type of change

  • Bug fix

Screenshots

before after
Screenshot 2026-06-05 at 11 29 20 Screenshot 2026-06-05 at 11 27 16

Testing

  1. open Jonas token
  2. see image

Related Issues

HOO-571

Checklist

  • My code follows the project's style guidelines
  • I have added tests that prove my fix/feature works
  • All checks pass locally (pnpm test, pnpm lint, pnpm typecheck)
  • I have run build:info script to update build information
  • CI/CD checks pass on the PR
  • Screenshots included — required for protocol screens, recommended for other UI changes

@vercel

vercel Bot commented Jun 5, 2026

Copy link
Copy Markdown

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

A member of the Team first needs to authorize it.

@greptile-apps

greptile-apps Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a DAS-based image fallback for token pages. When a token has an image in DAS metadata but no logoURI in the token list, the page now fetches it via a new /api/token-image/[mintAddress] route and surfaces it in the header.

  • A new server route fetches the DAS image for a single mint, with input validation, custom-cluster rejection (SSRF guard), and conditional caching (NO_STORE when DAS is unreachable, 1-hour cache when DAS responds).
  • A new useDasImage SWR hook calls this route from the client and is integrated into TokenMintHeader as a fallback when no logoURI or on-chain NFT image is already available; the DAS image is also passed as fallbackLogoURI to Token22MintHeader.
  • DigitalAssetSchema is slimmed down to only the fields actually needed (content.links.image and id), with nullable wrappers to handle real-world DAS responses that include null values.

Confidence Score: 5/5

Safe to merge. The new token-image route is well-guarded, the SSRF vector from previous review threads is fully addressed, and all error paths return sensible responses.

The route correctly rejects custom clusters, applies NO_STORE headers when DAS is unreachable, and validates input. The schema relaxation is intentional and backward-compatible. The one remaining note (hook firing for custom-cluster users) is a minor efficiency issue, not a correctness one.

app/entities/digital-asset/model/use-das-image.ts — the hook can skip the SWR key for custom cluster users since the server will always reject those requests.

Important Files Changed

Filename Overview
app/api/token-image/[mintAddress]/route.ts New API route that fetches DAS image for a mint address; correctly blocks custom cluster (SSRF fix), uses NO_STORE_HEADERS when DAS is unreachable, and caches successful lookups for 1 h.
app/entities/digital-asset/model/use-das-image.ts New SWR hook that calls the token-image API; still fires for custom-cluster users even though the server always returns 400 for that case.
app/entities/digital-asset/types.ts Schema pared down to only content/links/image and id; nullable wrappers added to tolerate null fields from real DAS responses.
app/entities/digital-asset/api.ts Switched from is() to validate() for richer error messages, added RPC-level error check, and filters null items from result array.
app/components/account/AccountHeader.tsx Integrates useDasImage as a fallback; correctly skips the DAS fetch when tokenInfo.logoURI or nftData image is already available; passes fallbackLogoURI to Token22MintHeader.
app/api/token-image/[mintAddress]/tests/route.spec.ts Good test coverage including cache-header assertions, SSRF/custom-cluster rejection, and the no-store case when DAS returns null.
app/features/search/api/resolve-search-tokens.ts Defensive optional chain added to content?.links?.image to tolerate the newly-nullable content field.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Browser
    participant AccountHeader
    participant useDasImage
    participant TokenImageAPI as /api/token-image/[mint]
    participant DAS as DAS RPC (getAssets)

    Browser->>AccountHeader: render token page
    AccountHeader->>useDasImage: useDasImage(address) (if no logoURI / nftData image)
    useDasImage->>TokenImageAPI: "GET /api/token-image/{mint}?cluster=..."
    Note over TokenImageAPI: validate mint (400 if invalid)<br/>validate cluster (400 if unknown)<br/>reject Custom cluster (400)
    TokenImageAPI->>DAS: POST getAssets([mint])
    DAS-->>TokenImageAPI: result[] (nullable items)
    Note over TokenImageAPI: NO_STORE if assets null<br/>IMAGE_CACHE (1h) if assets present
    TokenImageAPI-->>useDasImage: "{ image } or {}"
    useDasImage-->>AccountHeader: "dasImage string | undefined"
    AccountHeader->>Browser: render TokenMintHeaderCard with dasImage as logoURI fallback
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Browser
    participant AccountHeader
    participant useDasImage
    participant TokenImageAPI as /api/token-image/[mint]
    participant DAS as DAS RPC (getAssets)

    Browser->>AccountHeader: render token page
    AccountHeader->>useDasImage: useDasImage(address) (if no logoURI / nftData image)
    useDasImage->>TokenImageAPI: "GET /api/token-image/{mint}?cluster=..."
    Note over TokenImageAPI: validate mint (400 if invalid)<br/>validate cluster (400 if unknown)<br/>reject Custom cluster (400)
    TokenImageAPI->>DAS: POST getAssets([mint])
    DAS-->>TokenImageAPI: result[] (nullable items)
    Note over TokenImageAPI: NO_STORE if assets null<br/>IMAGE_CACHE (1h) if assets present
    TokenImageAPI-->>useDasImage: "{ image } or {}"
    useDasImage-->>AccountHeader: "dasImage string | undefined"
    AccountHeader->>Browser: render TokenMintHeaderCard with dasImage as logoURI fallback
Loading

Reviews (11): Last reviewed commit: "null support" | Re-trigger Greptile

Comment thread app/api/token-image/[mintAddress]/route.ts Outdated
Comment thread app/components/account/AccountHeader.tsx Outdated
@vercel

vercel Bot commented Jun 5, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
explorer Ready Ready Preview, Comment Jun 16, 2026 10:34am

Request Review

Comment thread app/components/account/AccountHeader.tsx Outdated
Comment thread app/api/token-image/[mintAddress]/route.ts Outdated
Comment thread app/api/token-image/[mintAddress]/route.ts Outdated
Comment thread app/api/token-image/[mintAddress]/route.ts Outdated
Comment thread app/components/account/AccountHeader.tsx Outdated
Comment thread app/api/token-image/[mintAddress]/route.ts Outdated
Comment thread app/api/token-image/[mintAddress]/route.ts Outdated
Comment thread app/api/token-image/[mintAddress]/route.ts Outdated
Comment thread app/components/account/AccountHeader.tsx Outdated
@mikhd

mikhd commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

There is a misprint in PR title fethicng -> fetching.

@C0mberry C0mberry force-pushed the fix/hoo-571-token-image-missing-on-token-page branch from 6b8acb5 to ddcdad8 Compare June 15, 2026 10:45
Comment thread app/api/token-image/[mintAddress]/route.ts Outdated
@askov askov changed the title fix: added image fethicng from das fix: added image fetching from das Jun 19, 2026
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.

3 participants