Repository navigation
EVM NFTs: query Ethereum, Polygon and Base for every EVM address - #18
Merged
Merged
Conversation
Split out of PR #17 (fix/evm-multichain-fanout) after independent review found its balance/token fan-out half wrong (native coin double-counted, spam ERC-20s priced by raw on-chain symbol) while judging the NFT half correct: http://192.168.50.240/data/2026-09-28/ABCT-PR17-REVIEW-2026-09-28.html Wallets are stored one-row-per-(address, blockchain), and a bare 0x address is always filed as 'ethereum' (utils/address.detect_blockchain only assigns polygon/base from an explicit prefixed address). /nfts/polygon and /nfts/base only ever asked Alchemy about addresses whose own row already said that chain, so a real Polygon/Base holder registered as 'ethereum' was invisible. Every EVM-family wallet (ethereum/polygon/base/ bsc/arbitrum/avalanche) is now a candidate address for Ethereum, Polygon and Base NFT fetches, deduplicated by address, with the existing spam filter, persistent cache and wipe-guard-on-provider-failure behaviour (#11/#16) plus the #16 wallet-set-fingerprint cache invalidation extended to Ethereum/Polygon/Base. Excludes services/evm_balance_fanout.py and the routers/portfolio.py balance-total wiring entirely -- that half is being reworked separately. Totals are unaffected by this PR. 8 unit tests in tests/unit/test_evm_fanout.py (mocked HTTP/DB, fake addresses, no live calls or real keys). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why split from #17
An independent review of #17 (fix/evm-multichain-fanout) blocked it: the
balance/token fan-out half is wrong (native coin double-counted on every
/portfolio/summaryconsumer; spam ERC-20 tokens priced by their rawon-chain symbol with no allowlist or ignore-list check — a live probe found
one spam "USDC" on Base worth more than all the legitimate fan-out value
combined). The same review judged the NFT fan-out half correct and
recommended shipping it alone while the balance half is reworked.
Full review: http://192.168.50.240/data/2026-09-28/ABCT-PR17-REVIEW-2026-09-28.html
What's included
Wallets are stored one-row-per-(address, blockchain), and a bare
0xaddress is always filed as
ethereum(detect_blockchainonly assignspolygon/basefrom an explicitpolygon:0x.../base:0x...prefix)./nfts/polygonand/nfts/baseonly ever asked Alchemy about addresseswhose own row already said that chain, so a real Polygon/Base holder
registered as
ethereumwas invisible to those pages.backend/services/alchemy_nft_utils.py:evm_fanout_wallets(),wallet_fingerprint(),EVM_ADDRESS_CHAINS,EVM_FANOUT_TARGET_CHAINS—the shared helpers the NFT path needs.
backend/services/ethereum_nft.py,polygon.py,base.py: everyEVM-family wallet (ethereum/polygon/base/bsc/arbitrum/avalanche) is now a
candidate address for that chain's NFT fetch, deduplicated by address, so
an address registered on two chains is never fetched or counted twice.
Same spam filter, persistent cache and wipe-guard-on-provider-failure
behaviour as Fix EVM NFTs: stop sending paid-plan excludeFilters=SPAM to Alchemy #11/Fix NFT page showing only Ethereum: IPFS gateway fallback, show-more, Solana wallet changes #16, plus the Fix NFT page showing only Ethereum: IPFS gateway fallback, show-more, Solana wallet changes #16 wallet-set-fingerprint cache
invalidation extended to Ethereum/Polygon/Base.
backend/routers/nfts.py: all 18 wallet-filter call sites switched toevm_fanout_wallets(wallets).tests/unit/test_evm_fanout.py: the NFT-only subset of EVM: query Ethereum, Polygon and Base for every EVM address #17's tests (8 ofits original 14 — helper tests plus the Polygon NFT fan-out tests).
What's excluded
services/evm_balance_fanout.pyand therouters/portfolio.pybalance-totalwiring are entirely excluded from this PR — that's the half the review
blocked. It is not touched in any file here;
git diff origin/main --statbelow lists only NFT files. The 6 balance-fan-out unit tests from #17's
test_evm_fanout.pyare also excluded (they exerciseservices/evm_balance_fanout.py, which does not exist on this branch).Tests
tests/unit/test_evm_fanout.py: 8/8 pass.timeout 1200 pytest tests -q, same venv the EVM: query Ethereum, Polygon and Base for every EVM address #17 review used —/home/ccata/Claude/ABCT-worktrees/_venv-review-17): 540 passed, 9 failed.The same 9 failures are present on
main(8×sqlite3.OperationalError: no such table: token_metadata_cache, 1× missingPIL/Pillow dependency) —no new failures introduced.
tests/unit/test_wallet_leak_check.py(includingtest_real_repo_tree_is_clean): 26/26 pass.Totals unchanged by this PR — no balance, token-count, or portfolio-total
code is touched. NFT counts on the Polygon/Base pages will increase (the bug
this PR fixes), and NFT value only reaches the portfolio total if the user
has "include NFTs in total" turned on (off by default).
🤖 Generated with Claude Code