NFT inventory
The NFTs page enumerates real ERC-721 holdings for a contract × wallet group, in seconds. List view, card view, multi-select transfer, per-contract PnL trigger.
Adding a contract
- Pick a chain in the chain selector.
- Click + Add Contract, paste the contract address.
- Pick the wallet group to enumerate against.
The app probes the contract via a three-tier strategy and falls back as needed:
| Tier | Method | When it works |
|---|---|---|
| 1 | tokenOfOwnerByIndex | Contract implements ERC-721 Enumerable. |
| 2 | tokensOfOwner(address) | Common non-standard helper on many launchpad templates. |
| 3 | eth_getLogs Transfer scan | Last resort. Walks the Transfer log from contract deployment. |
For tier 3, the app binary-searches the deployment block so it doesn’t
have to scan the whole chain. The deploy block is cached in
nft_deploy_cache.txt under your data dir — first-time enumeration is the
slow case.
Performance
All RPC calls in the inventory path are batched 100-per-HTTP-POST. A 100-wallet group resolves in ~5 seconds instead of ~2 minutes.
Token metadata (name + image URL) is cached in nft_metadata_cache.txt
under your data dir.
Views
- List — table with wallet, token ID, name. Right-click for per-token actions.
- Card — grid with token images. Best for visual sweeps.
Both views support multi-select. Hold shift for range, ctrl for individual toggles.
Multi-select send
Select N tokens across N wallets, click Send Selected. The dialog asks for a destination address. The runner sends each token from its current owner, batched per-wallet.
This works across wallets in the same group — no need to consolidate first.
Per-contract PnL trigger
Each contract card has a PnL button. Click it to open the PnL panel, which computes a FIFO cost-basis for the group against this contract and renders a shareable PNG card.
What’s not supported
- ERC-1155. No on-chain enumeration for 1155s in this build — multi-token contracts won’t appear here. On the roadmap.
- Solana / Bitcoin NFTs. EVM only.
- Cross-chain rollups. Contracts on different chains live in separate cards even if they share a name.