The live page is /algorand/tracker/.
Open it from the Algorand hub, the footer, or Connect. Tabs and
collection cards push ?view= and ?creator=,
so the browser Back button returns to the previous view. Source
lives in cmd/nft-tracker (Go ledger) and
src/components/algorand/mountTracker.ts (the page).
Operator notes are in deploy/vps/TRACKER.md.
What it tracks
Only 1/1 NFTs: decimals === 0 and total === 1.
Tokens such as CORVID are out of this feed. Featured collections are
Nevermore, Lost Pigs, and Monsters. Nevermore uses the baked catalog
(214 1/1s) as the asset count floor.
How a sale is inferred
The chain has no "sale" type. The scanner labels a sale only when the same atomic group (including app inner transactions) has a 1/1 axfer and an ALGO pay of at least 1 ALGO: from the NFT receiver to the sender, from the buyer to anyone, or to the seller. Listing hops such as 0.3925, 0.5925, and 1.106 ALGO stay transfers. A pay from the person depositing the NFT into escrow is a listing fee, not a sale. Ground truth: ASA 3612042918 sold for 249.50 ALGO; ASA 580495416 and ASA 3604283613 are listings. Nothing here lists or sells an NFT.
Images
Nevermore art is self-hosted under /nevermore/. Other
thumbs are resolved from ASA url and reserve
(ARC-19 / ARC-3), downloaded by the scanner, and served from
/v1/image/{id}. The browser never loads Pinata or
other public IPFS gateways. The first request for an ASA downloads
the file on the scanner, then the page paints the local bytes.
API
One Go process owns the official indexer. Browsers never crawl
Algonode. Locally the origin is http://127.0.0.1:7482.
On the public site nginx proxies that as /api/tracker/.
| Path | Returns |
|---|---|
GET /v1/snapshot | Events, assets, collections, stats |
GET /v1/events | Classified 1/1 events |
GET /v1/assets | ASAs plus last inferred price and image |
GET /v1/collections | Creator rollups |
GET /v1/stats | Counts |
GET /v1/image/{id} | Cached thumb bytes |
GET /healthz | ok |
Public examples: /api/tracker/v1/snapshot,
/api/tracker/v1/stats. CORS is open on the local
process. The proxied path is same-origin. A keyed paid API is the
same tables later.
Run locally
cd cmd/nft-tracker
go test
go build -o nft-tracker .
TRACKER_DB="$PWD/nft-tracker.db" TRACKER_IMAGES="$PWD/images" ./nft-tracker
# then bun run dev and open /algorand/tracker/
Deploy
A push to main ships static HTML only. The scanner is a
systemd unit on the VPS. Full steps:
operator section
and deploy/vps/TRACKER.md.
- Build
GOOS=linux GOARCH=amd64 go build -o nft-tracker . in cmd/nft-tracker. - Install to
/usr/local/bin/nft-tracker. Data dir /var/lib/nft-tracker. - Enable
deploy/vps/nft-tracker.service. - Reload nginx so
location /api/tracker/ proxies 127.0.0.1:7482. - Site tarball deploys do not restart this unit. After scanner code changes, replace the binary and
sudo systemctl restart nft-tracker.
One replica only. Many browsers hitting Algonode would 429. One
process plus SQLite will not, if you keep a single scanner.