You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(web,api): a market link unfurled as one line, and a stalled market never said so
TWO ENDPOINTS THAT NOTHING WAS READING
Both already existed, fully built and documented, and both named the reader they
were missing.
`/markets/:token/preview.svg` renders a 1200x630 card per market — the thing a
link to a token becomes when it is pasted into X, Telegram or Discord.
`generateMetadata` on the market page returned a bare `title` and nothing else,
so the card had never been referenced and never been seen.
`/graduations/pending` carries `waitingBlocks`, and its own note says who wants
it: "the keeper reads it, the operator alerts on it, and a UI can offer the
finalise to whoever is looking at a stalled market. All three want the same
list." Two of the three were using it. `MarketDetail` has no graduation
timestamp, so without this the finalise panel could not tell a market that
entered GRADUATING a minute ago from one that entered a week ago — which is the
entire decision it asks someone to make.
The panel now says which. Under the threshold it reads as context, in the same
grey as the rest of the prose: a few hundred blocks is waiting for the large
lane, produced about once in 120. Past it, the sentence changes to a reason to
act and takes the warning colour §42 reserves for exactly that. The read fails
silently — the finalise works without knowing the age, so a reconnecting
endpoint takes the sentence away and not the button.
WHO DECIDES "STALLED"
The API, now per row. The client had been importing `STALLED_AFTER_BLOCKS` from
the handlers module to compare for itself, which is either a server module in a
browser bundle or a copied threshold that drifts (§1064). Each pending row
carries its own `stalled` and the panel renders the judgement rather than
repeating it.
I expected removing that import to shrink the bundle and it did not — /t/[token]
is 13.7 kB either way. The growth is `lib/chain.ts` pulling viem's ABI
encode/decode into the client, which the wrap flow genuinely needs. The change
stands on the one-definition argument, not the size one.
THE IMAGE IS SVG, AND THAT IS THE OPEN HALF
X, Discord and Telegram do not render SVG in an unfurl. Slack does, and the rest
omit the image and show the text card — strictly better than the bare title they
showed before. `og:image:type` is declared so a crawler skips it cleanly instead
of guessing at the bytes.
Rasterising to PNG needs a native dependency and a runtime §434 has not fixed.
That is a deployment decision; picking one here would be choosing for someone
else. When a PNG endpoint lands, only the URL and the type change.
Verified in Chrome against a market held in GRADUATING: og:title, og:description,
og:image and the twitter card all carry the market's own values; at 240 blocks
the panel shows the calm line, at 4820 it shows the amber one and the intent's
review gains a "4820 blocks ago" row. 181 API checks green.
0 commit comments