← The Journal Build Notes

The site has no database. It rebuilds itself from Base

Published July 23, 2026 · Buy One Second

Open the home page and you get a running count of minted seconds, a leaderboard, a timeline of what is taken, and, if your wallet is connected, a list of the seconds you hold. It looks like the sort of thing that needs a server behind it, quietly keeping a table of owners in sync. It does not. There is no database here, and no back office copy of who owns what. Every number you see is read from Base at the moment you load the page.

I want to walk through how that works, because it is the most honest thing about the build and also the part most likely to feel slow on a bad day. Both are worth understanding.

Where the numbers come from

The front end opens a plain read-only connection to Base at https://mainnet.base.org and points it at the contract. No wallet, no signature, no key. Two objects do all the reading: a provider that can ask the network general questions, and a contract handle that knows the ABI. That is the whole data layer. There is no fetch to an API of ours anywhere in the page, because there is no API of ours.

The minted counter is the simplest case. It comes from one cheap call, getJackpotInfo(), which returns a mintedCount among its fields. The page reads that, prints it, and subtracts from 86,400 to show how many seconds are still free. This is kept deliberately separate from the bigger scan, so the count stays correct and instant even if the heavier read stalls.

Rebuilding the map of owners

The leaderboard and the timeline need more: not just how many seconds are taken, but which ones, and who holds them now. The site rebuilds that in two passes.

First it collects events. Every mint emits a SecondMinted log, so the page asks Base for all of those logs from the deploy block up to the latest block. It cannot ask for the whole range at once, because public RPCs cap a single log query at ten thousand blocks, so it walks forward in chunks of nine thousand and gathers the second number from each event into a set. That set is the list of every second that has ever been minted.

Second, it reads their current state. Knowing a second was minted once is not enough, because seconds can change hands. So the page takes that list and calls getBatchSecondData() in slices of five hundred, which returns the present owner and stored URL for each one. That second step is why a resale shows up correctly: the leaderboard reflects who holds a second today, not who first minted it.

The chain is the state. The page is a view of it. Nothing about ownership is decided or stored by this website. If it went dark tomorrow, the ownership it was showing would still be sitting on Base, unchanged, readable by anyone.

Why do it the hard way

An easier build would keep a database, listen for events on a server, and serve pre-chewed JSON to the browser. That would be faster and it would also be a second source of truth, one that can drift, lie, or quietly go missing. By reading the chain on every visit, the page cannot show you an ownership record that disagrees with Base, because it has none of its own to disagree with. The tradeoff is real work on each load, and I would rather pay that than ask you to trust a copy.

There is a smaller design choice tucked in here that I like. The full scan scales with the number of mints, not with 86,400. Early versions swept every possible second; this one asks the events which seconds actually exist and reads only those. On a phone over a public RPC, that difference is the gap between usable and not.

What that means when the network is slow

Reading live has a cost, and being honest about the build means naming it. If the public RPC is rate-limiting or a chunk of the log query fails, the page does not pretend. A failed batch is skipped rather than treated as fatal, results render as they arrive so early seconds appear before the whole sweep finishes, and two loads are never allowed to run at once, because they would clobber each other and blank the leaderboard. So on a bad connection you might watch the board fill in progressively, or briefly see less than the full picture. That is the read catching up, not data going missing. Reload and it rebuilds again from the same source.

The counter is protected from this on purpose. Because it comes from its own single call, a partial scan of the timeline can never overwrite it with a low number. You should not see the count jump down just because the network hiccuped mid-load.

The one thing the browser does remember

To be precise, the page is not perfectly stateless. It keeps exactly one small thing in your browser: a referral address, saved to localStorage when you arrive with a ?ref= link, so it survives to your mint. That is a convenience local to your device, not a record of ownership on a server. Everything about who owns which second still lives on Base and nowhere else.

None of this is financial advice, and a second is not an investment. What this build does buy you is a specific kind of trust: not "trust our database," but "check ours against the chain, or skip us and read the chain yourself." The website is a convenience. The record is not ours to keep, and that is the point.

Read your second straight off Base · Your second is permanent, the link is not · See the live board rebuild

Project references