Indexer
How the site knows who owns what, without an indexer service and without log scanning.
The constraint
Public BSC nodes reject eth_getLogs over wide ranges, and neither the processor nor the wrapper implements ERC-721 Enumerable. So there is no way to ask "list every card" directly.
The approach
Both id spaces are contiguous and start at 1. That makes enumeration deterministic:
- Binary-search the highest existing circuit id —
ownerOf(mid)reverts above the tip. - Read every id from 1 to that tip.
- For each:
circuitInfo,ownerOf,editionOf,wrapperOf, and the TFD owner if wrapped. - Write one JSON file.
Output
{
"updated": 1792664402,
"block": 129116597,
"total_cards": 9,
"total_gates": 420,
"cards": [
{"cpu":"0x5a4e…","circuit":7,"drawing":"ADD4","gates":46,
"edition":5,"wrapped":6,"owner":"0x2021…"}
]
}
wrapped is the TFD id, or 0. owner is the current holder — the TFD owner if wrapped, otherwise the circuit owner.
Schedule and delivery
| Property | Value |
|---|---|
| Run interval | Every 2 minutes (cron) |
| Runtime | 1–3 seconds for the current set |
| Outputs | web/assets/holdings.json and web/test/assets/holdings.json |
| Cache header | no-cache on the JSON |
What the page does with it
My cards filters the index by connected address, then falls back to a direct chain read for the connected wallet when the index has not caught up. That two-path design is why a freshly bought card can appear before the next index run.
Known limits
- Latency: up to two minutes for a transfer to appear.
- Enumeration stops at the highest existing id, so a card minted between the binary search and the read loop can be missed for one cycle.
- Metadata is not indexed — the page reads editions and gate counts, never token URIs.
Why not a database
The whole state is a few hundred reads on a public node. A database would add a component to operate and a second source of truth to disagree with the chain.