* refactor(wallet): drive the approval popup from the request type
A single `isSign` boolean set the title, the button label and the content
branch, so adding an approval type would have rendered it as "Connect dApp".
An exhaustive switch makes that a compile error instead.
* feat(wallet): sign EIP-712 typed data for dApps
`eth_signTypedData_v4` threw 4200. It now signs through the same per-origin
pinning and approval path as `personal_sign`.
Parameters are swapped relative to `personal_sign` -- address first, payload
second, per status-go `commands/sign.go`. The payload is parsed and validated
before the popup opens, `domain.chainId` included, so malformed input cannot
reach viem as an opaque -32603 after the user has already approved. The popup
renders it as hostile input, capped by depth, row count and value length.
* test(wallet): cover typed data signing
The swapped parameter order, malformed payloads refused before the popup, the
domain chain check across the three spellings dApps use, and the display caps.
* chore(wallet): add changeset
* fix(status.app): lint with eslint instead of next lint
`next lint` injects eslint-config-next, whose absolute-path `import/resolver`
entries replace the repo's own. Under pnpm's non-hoisted layout they resolve
from the config rather than the linted file, so an app-local dependency such as
`entities` reports as unresolved while root-hoisted ones do not.
The flat config already registers @next/next, so the Next rules still run.
`next lint` is deprecated and removed in Next 16.
* fix(wallet): render typed data rows from the signed type
Only the fields declared in types[primaryType] reach the EIP-712 hash.
Walking the raw message let a dApp pad it with unsigned keys until the
fields that are actually signed fell past the row cap, unseen. The
domain header had the same hole: a dApp-declared EIP712Domain decides
what the separator covers, so a name left out of it was displayed as
the dApp's identity without being signed.
* fix(wallet): bind the typed-data chain check to the signed domain
A dApp declaring its own EIP712Domain decides which domain fields reach
the separator, so a chainId present in domain but absent from that type
satisfied the chain check while binding the signature to no chain.
* test(wallet): cover the derived EIP712Domain chain check
* refactor(status.app): restore the shipped news feed rendering as v1
The clients in the wild parse what production serves today, so that build
is kept verbatim in its own module: unnamespaced `newsLink`, markup
stripped down to text, Ghost's escaping passed through. It imports nothing
but the XML parser, so a change to the reworked build cannot reach it.
`handleRssFeed` picks the build from a version that defaults to `v1`,
leaving the existing routes untouched.
* feat(status.app): serve the reworked news feeds under /v2
`/desktop-news/rss/v2` and `/mobile-news/rss/v2` carry the lists, the body
links, the escaping fixes and the namespaced call-to-action. The clients
move over once status-go reads the new elements; until then
`/desktop-news/rss` and `/mobile-news/rss` keep serving what they serve
today.
Anchors were flattened to their label. The parser now carries them as
inline nodes, so a link in a paragraph or a list item reaches the desktop
client as `<a href>` with the href escaped, quotes included.
The mobile feed keeps the label alone -- plain text cannot carry a link --
and the call-to-action is still lifted out of the body. Validity is
unaffected: the whole body is escaped on its way into `description`.
* fix(status.app): prevent desktop navbar overflow
The top bar renders from 1150px but its full-text CTAs push the row past
the viewport until ~1315px, causing horizontal page overflow. Collapse the
download CTAs to icon-only below 1320px; full labels return above it.
* chore: add changeset
* fix(status.app): collapse floating navbar CTAs to icon-only
Mirror the top navbar: icon-only download CTAs below 1320px so the
floating scroll-up navbar can't overflow the viewport.
* fix(status.app): use native scroll listener for floating navbar
react-spring useScroll's rAF frameloop doesn't fire reliably under
Turbopack dev, so the overlay never appeared locally (worked in the
webpack prod build). Read window.scrollY via a plain scroll listener;
same detection logic.
* fix(status.app): stop keycard section text column collapse
Drop w-full on the media wrapper; it pinned the flex basis to 100% and
starved the flex-1 text column to ~0. Fixes status.app and get.status.app
(shared HomePage). Regression from #1248.
* fix(status.app): stack keycard section below 1221px
* chore(status.app): add changeset
* Add structured data for status.app pages
* fix(status.app): correct Article datePublished and heading excerpt in structured data
* fix(status.app): ignore code-fence comments as headings, recognize FAQs/Frequently Asked Questions
* test(status.app): add vitest config so structured-data tests actually run in CI
* refactor(status.app): share author-parsing between page and structured-data
* chore(status.app): remove test file and vitest infra from this PR
* fix(status.app): use valid structured data logo
* fix(ci): use develop for changeset checks
* fix(status.app): strip MDX comments from structured data
* fix(status.app): noindex placeholder help docs for noindex audit
* test(status.app): add coverage for isHelpDocWorkInProgress
* test(status.app): add vitest config so help-doc tests actually run in CI
* chore(status.app): remove test file and vitest infra from this PR
* Fix blog table rendering for crawler errors
* chore(status.app): add changeset for blog table 5xx fix
* fix(status.app): fix same table-crash bug in specsComponents, shared via renderTable
* chore(status.app): remove test file and vitest infra from this PR
* fix(status.app): preserve <th> row headers in table body cells (Copilot review)
* refactor(status.app): share content table rendering
* fix(blog): style Ghost post tables and reduce blockquote size
* chore: add changeset
* fix(blog): make blockquote left border more visible
* refactor(blog): reuse Table design system component for blog tables
* fix(table): adjust width properties for better responsiveness