Skip to content

feat: NFT-aware contract page (recent mints + NFT transfer filter)#609

Merged
davidecarpini merged 7 commits into
mainfrom
feat/nft-contract-page
Jul 14, 2026
Merged

feat: NFT-aware contract page (recent mints + NFT transfer filter)#609
davidecarpini merged 7 commits into
mainfrom
feat/nft-contract-page

Conversation

@Agilulfo1820

@Agilulfo1820 Agilulfo1820 commented Jul 14, 2026

Copy link
Copy Markdown
Member

What & why

Makes an ERC-721 contract's address page NFT-aware, and adds the missing links between NFT pages and their collection contract.

When you open a contract that is an ERC-721 collection:

  • The Activity card becomes a focused Collection view: Name / Symbol / Total Supply (on-chain getters) plus creation date, master and creation tx — instead of the generic VET/VTHO/gas cards, which are rarely meaningful for a token contract.
  • A Latest Minted Tokens section lists the collection's most recently minted tokens (last 10), each linking to the existing /nft/{contract}/{tokenId} detail page.
  • The NFT detail header's collection name now links back to the contract's address page (this was the only missing path from the agent NFT view, which doesn't render NftDetailsSection).

How

  • DetectionuseIsErc721Contract uses an on-chain ERC-165 supportsInterface(0x80ac58cd) call, which works through proxies (most modern collections are proxy-deployed, so bytecode sniffing alone misses them). Bytecode sniff kept as a fallback for pre-ERC-165 collections. Shared across the summary badge, mints section and collection view.
  • Recent mints — the indexer has no per-collection endpoint (every NFT query requires an owner address). So mints are read on-chain from the Thor node via Transfer event logs where from is the zero address, newest first, limit 10. Works on Solo too (hits the node, not the indexer).
  • Total Supply — falls back to - when the collection doesn't implement ERC721Enumerable.
image image image

Notes

  • The originally-scoped "show all interactions on a contract page" was dropped: /transactions/contract already returns interactions (verified on the live mainnet indexer); the empty state seen on Solo was the Solo indexer not running.
  • A tentative NFT filter on the Token Transfers table was added then reverted — the dedicated mints section covers NFT discovery, and the owner-scoped transfers endpoint returns nothing for a collection contract.
  • Follow-up (separate PR): link the tokenId in a transaction's ERC-721 Transfer event to its token page.

Validation

ts-check, lint, knip, prettier, and the full test suite (234 tests) all pass. Mint query + ERC-165 detection validated against both the mainnet node and the local Solo node.

On ERC-721 contract pages, add a "Latest Minted Tokens" section listing the
collection's most recently minted tokens (last 10), each linking to the
existing /nft/{contract}/{tokenId} detail page.

Because the indexer has no per-collection endpoint (all NFT queries require an
owner address), the mints are read on-chain from the Thor node via
`Transfer` event logs where `from` is the zero address, newest first. This
also works on Solo, since it hits the node directly rather than the indexer.

Contract type is detected with the existing bytecode sniff (useContractSniff),
so the section self-hides on non-ERC-721 contracts.

Also add an "NFT" filter to the address Token Transfers table (the shared
TransfersTable already renders NFT rows), addressing the ERC-20-only gap.

Adds i18n keys "Latest Minted Tokens", "No tokens have been minted yet" and
"Owner" across all 11 locales.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Agilulfo1820 Agilulfo1820 added the increment:minor PR adds functionality in a backwards compatible manner label Jul 14, 2026
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

Block explorer – Preview

Name Status Preview Updated (UTC)
block-explorer-preview 🗑️ Destroyed (1dbfe37) Preview deleted 2026-07-14 13:32:40

Preview environment destroyed after PR was closed

@Agilulfo1820 Agilulfo1820 marked this pull request as draft July 14, 2026 10:31
Bytecode sniffing misses proxy-deployed collections (ERC-1967/minimal
proxy), because the ERC-721 selectors live in the implementation, not the
proxy bytecode. Detect ERC-721 with an on-chain ERC-165
`supportsInterface(0x80ac58cd)` call instead, which is executed by the
implementation through the proxy. Bytecode sniffing is kept as a fallback
for older collections that predate ERC-165.

Applies to both the "Latest Minted Tokens" section gating and the ERC-721
badge in the contract summary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The dedicated "Latest Minted Tokens" section covers NFT discovery on contract
pages, and the owner-scoped transfers endpoint returns nothing for a collection
contract anyway, so the NFT toggle was redundant. Restores the section to its
original ERC-20/VET filter set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…llection

- On an ERC-721 contract's address page, the Activity card becomes a focused
  "Collection" view (Name / Symbol / Total Supply from on-chain getters, plus
  creation date, master and creation tx) instead of the generic VET/VTHO/gas
  cards, which are rarely meaningful for a token contract. Total Supply falls
  back to "-" when the collection doesn't implement ERC721Enumerable.

- Extract useIsErc721Contract (ERC-165 + bytecode-sniff fallback) so contract
  detection is shared across ContractSummary, the mints section and the
  collection view.

- The collection name in the NFT detail header now links to the collection
  contract's address page. This was the only path back to the contract from
  the agent NFT view, which doesn't render NftDetailsSection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Node event-log timestamps are in seconds, but AgeText and the date
formatters expect milliseconds (indexer responses are normalised to ms via
timestampSchema). The Latest Minted Tokens ages were all showing "57y ago"
(seconds read as ms → ~1970). Multiply by 1000 to match app convention.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The agent NFT view dropped the standard NFT info the rest of the explorer
shows. It now:

- shows the Owner / Minted-on stats cards above the tabs (NftStatsCards),
  matching the standard NFT view;
- adds an "NFT" tab rendering NftDetailsSection, so contract address,
  token standard, mint info, collection details and attributes are all
  available in readable rows (no longer only buried in the raw metadata JSON).

Agent-specific tabs stay primary; standard NFT data is one click away and
uses the same DetailRow/SectionCard styling. Reuses the existing components,
threading the token metadata through from NftDetailPageContent.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@davidecarpini davidecarpini enabled auto-merge (squash) July 14, 2026 13:19

@davidecarpini davidecarpini left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTClaude 🤖

@davidecarpini davidecarpini deployed to preview-auto July 14, 2026 13:24 — with GitHub Actions Active
@davidecarpini davidecarpini merged commit 700e296 into main Jul 14, 2026
15 checks passed
@davidecarpini davidecarpini deleted the feat/nft-contract-page branch July 14, 2026 13:31
@davidecarpini davidecarpini deployed to preview-pr-609 July 14, 2026 13:31 — with GitHub Actions Active
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

increment:minor PR adds functionality in a backwards compatible manner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants