Skip to content

feat(execute): contracts and the app become chips, with a seal for nulo verified - #1805

Open
alejoamiras wants to merge 13 commits into
devfrom
verified-contracts-build-1-a1
Open

alejoamiras wants to merge 13 commits into
devfrom
verified-contracts-build-1-a1

Conversation

@alejoamiras

@alejoamiras alejoamiras commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

What and why

The approval window now names every contract a send touches by a chip carrying its level, so a person can tell a contract Nulo knows from one it doesn't without reading addresses:

  • Each step's contract and each authorization's consumer is a chip. A token on Nulo's signed list reads by the list's symbol with its picture and a solid seal (Nulo verified); the pinned PrivateFPC reads "Private Fee Juice", sealed. Anything else shows its short address and no mark (unverified). A flagged held token keeps its red badge and is never sealed. Only the signed list (verified in the worker) or the compiled-in PrivateFPC can place a seal; nothing a dApp sends can.
  • A press on a chip says what the level rests on and ends on the short address beside "View on " (or the address alone with no explorer). One Tab stop per chip; the press keeps Popover's focus hand-off and Escape.
  • The app's self-declared name is a chip with no seal in the approval and connect windows; its press names the site and says who chose the name.
  • Unreadable calls are named once, after the steps, in the owner's wording: "Nulo can't parse calls from steps 3, 5 and 7." / "…the call from step 3." / "…this call." The orange notice under each call and the closing advice go on a send; an unreadable authorization gets one line of its own.
  • Settings → Glossary gains a Contracts section with the two seals.
  • A level not yet known is a real pending state (short address, no mark; its press says Nulo is still checking), the base the owner's page-143 "held chips" choice renders over in arc 2.

The level is computed in the popup by a pure resolver (utils/contract-level.ts) over what the worker already sends (the price snapshot now carries the list's symbols and names). Popover gains an inline mode whose card stays inside the view (popover-place.ts).

Plan: implementations-plan/verified-contracts-build-1/plan.md (arc 1 of 2). Owner asks with what ships now: OWNER-ASKS.md (A4 to A16).

Sign-offs (verbatim)

  • P135-01 = read: "I'd go "A" but I just don't like the design of the chips. We need to keep iterating. A checkbox without the tick looks really really awful. Let's try 4/5 creative ways of communicating this."
  • P135-02 = a: "As drawn: the app's name is a chip with its level in both windows, the press explains it; "on Nulo's list for this site" never appears. One Tab stop added per window."
  • P135-03 = D2: ""Its code is verified on Aztecscan. Nulo hasn't checked who runs it." (67 characters). The glossary line reads the same way: "Its code is verified on Aztecscan, but Nulo hasn't checked who runs it." The lane's recommendation."
  • P135-06 = approve (the build-time defaults): "approved"
  • P139-01 = s1: "Seal: a solid seal (Tabler's filled rosette with a tick) after the name for Nulo verified, the same seal in outline for Aztecscan verified, no mark for unverified. The shape products commonly use for "verified", the smallest change from round two, and no square left to echo the fee row."
  • P139-03 = b: "The short address beside the link; the address alone where there is no link. The lane's recommendation."
  • P139-04 = W1: "Rewritten: one line saying who chose the name and what Nulo checked. The lane's recommendation."
  • P139-06 = a: "As drawn: solid against drawn, the press and the glossary's legend naming the level. The lane's frames."
  • P140-01 = c, P140-02 = c1 (the unreadable-call line). Owner's note: "I'd do "c" but I wouldn't do the "can only check transfers and mints" it gets too verbose. I'd say: "Nulo can't parse calls from steps 3, 5 and ..."."
  • P140-03 = b (the fee row's seal), scoped to arc 2: this PR leaves the fee row exactly as it was. Owner's note: "Actually, now that you mention it, there is a world in which the applications publish (through aztecscan + we verify) their fee paying contracts, and hence, they can have the check. So I guess "b" is kinda right? Though the double-liner of "You pay..." + "Your Private Fee Juice must cover"... I'd remove the last one. I feel we should kinda work on a matrix here: […]"
  • P140-04 = read (loading): this PR builds the pending state as the base. Owner's note: "I don't quite understand this in it's completeness... Because... Also once the chip loads, we could change the addresses for the names of the contracts, right? Maybe we should implement this PoCs on an artifact so I can decide checking out how they'd look "live"?"
  • P140-05 = a: an unmarked contract's press shows "Nulo hasn't checked this contract." alone.
  • Page 143 (P143-01 b2, 02 b3, 03 d, 04 n1, 05 s1): "All five are arc 2's; arc 1 keeps the fee row as today and the pending chip as (a), as its plan says."

Drafts (shipping now, each with its options in OWNER-ASKS.md): the legend's three entries (A4), the press lines beyond the signed ones (A5), the PrivateFPC's label (A6), a flagged token's press (A12), the unreadable authorization's line (A13), the pending press (A14). New asks from review: the raised-fee window carries the same chips because it renders the same card (A15); "The name X came from an app." also shows for a name the wallet's own artifact gives, such as a bundled Token or a protocol contract (A16; Codex recommends "comes from the contract's code").

Accessibility calls

Made under the owner's 2026-10-19 delegation:

  • The chip is a native button with the 2 px accent ring on :focus-visible.
  • Every chip is one Tab stop (one per contract per step, so each step's press is reachable where it is read); the app chip is one stop.
  • The accessible name carries the level ("USDC, Nulo verified"); the seal is aria-hidden.
  • The press keeps Popover's Tab hand-off and Escape returns focus to the chip.
  • The chip and the link refuse a repeat Enter; Enter, Space and a click open the press and never toggle the step.

Validation

All at retry 0, run once each in order:

Gate Result
bun run lint, typecheck:all, test, test:components, audit:vue, test:all, check:plans green at 3bae98620 (the commits after it are plan notes and captures)
Smoke, Chrome (armed build, whole suite) green at cf041d84b: 291 passed, 31 skipped. After the test-only key fix, execute-steps.test.ts was rerun green at 359316d43
Smoke, Firefox (armed build, whole suite) green on the rerun at 359316d43: 296 passed, 26 skipped. The first run at cf041d84b failed one case, E2, because the spec pressed "Space", a key name Puppeteer's BiDi driver lacks (FIREFOX.md already says to press " "). The fix was test-only
e2e:agent Chrome: tx-sendTx-default, tx-transfer-row, type-roles-windows, connect-dapp, tx-sendTx-multicall, connect-check-window green: 6 files, 17 tests, 665 s
e2e:agent Firefox, same files green: 6 files, 17 tests, 1139 s

An earlier test:all run hit a 5 s timeout in src/e2e/config.test.ts while the host was under heavy load. That file is untouched and its test runs in 257 ms on its own. It was rerun once and passed, and it was green again on the final pass.

Smoke wall-clock per browser (whole suite, retry 0, on a host shared with other projects):

Browser Before (1593cf027) After
Chrome 2148 s (289 passed) 2035 s (291 passed)
Firefox 3641 s (294 passed) 2965 s (296 passed, rerun at 359316d43)

New e2e scenarios, measured on Chrome / Firefox:

  • E1, the worker's list reaching each chip: 8.2 s / 20.7 s.
  • E2, a chip's keyboard path: 3.1 s / 6.7 s.
  • Long app strings, where a chip clips and a press wraps at 400 and 240 px: 2.4 s / 7.1 s.

Reviews:

  • Codex (gpt-6.1-sol, high), round 1: conditional approve, on two layout defects plus nits. All were fixed, and the reviewer confirmed that reverting either CSS rule fails the new smoke case.
  • Opus: conditional approve. It found the raised-fee window and the decoded name's path, and both were fixed or asked about.
  • Codex, round 2: approve.

dev moved two commits (#1800, #1803) after this branch's base. The textual merge is clean, and CI runs the merge ref.

Captures

Chrome, light and dark, from pr-captures/verified-contracts-build-1/. These were committed in 35c8588cc and removed in the next commit. Two shapes were capture-only fixtures, kept out of every commit: the mixed request and the ten calls with five unreadable. The Aztecscan verified press exists only in component tests, because there is no reader yet.

What it shows Light Dark
Approval window at 400 px (capture-only fixture): a listed token with its picture and solid seal, an unverified contract that names itself, an unreadable call; one count line after the steps.
The same request at 240 px.
Approval window at 400 px (armed fixture listed): a listed token, a flagged held token with its red badge and no seal, an unknown contract, the PrivateFPC sealed.
Ten calls, five unreadable (capture-only fixture, the owner's ask on A1), scrolled to the count line: "Nulo can't parse calls from steps 2, 4, 6, 8 and 10."
A 64-character app name and a 63-character host at 240 px (armed fixture long-names): the app chip clips inside its row.
A Nulo verified token's press: level, symbol and name, the two lines, the short address beside the explorer link.
The same press at 240 px, inside the window.
The PrivateFPC's press (A6): Nulo verified, "Private Fee Juice", the first line only.
An unverified contract's press: "Nulo hasn't checked this contract." and the signed W1 line naming who chose the name (A16 asks about wallet-bundled names).
A flagged token's press: "Nulo flagged this token as a scam" (A12), no seal.
The app chip's press: the site, the A5 line and the W1 line; no address row, no link.
The app chip's press with a 63-character host and a 64-character name at 240 px: every word wraps inside the card.
Settings, Glossary: the Contracts section with the two seals (A4 drafts).
Connect window on the local network: the app's self-declared name as a chip, no seal (the press is the approval window's).
Raised-fee window (A15): the step's unlisted sandbox token as a chip with its short address and no mark; the app's caption stays as today.
A live dApp transfer on the local network: the head carries the amount and the token's chip, the line names sender and recipient.
A live three-call send: one count line names the calls Nulo can't parse.

🤖 Generated with Claude Code

alejoamiras and others added 13 commits November 12, 2026 17:03
… and app chips)

Pages 135 and 139 signed model A and the s1 seal; the owner scoped the
first build to the sources the wallet already holds. The plan builds the
level resolver over the signed token list and the pinned PrivateFPC, the
seal glyphs, the contract chip and its press, the app chip in the
approval and connect windows, and the legend, with page 139's three open
slots at their fallbacks. Codex plan audit, Opus plan audit and the final
fresh Codex pass are recorded in plan.md; the final pass approves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eads a contract's level

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… inside the view

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…end in the glossary

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…names the unparsed calls

Each step and each authorization names its contract by a chip whose level
comes from the signed list; the approval and connect windows show the app's
self-declared name as a chip with no seal. A send names its unreadable calls
once, by step, after the steps, in place of each call's notice and the advice;
an unreadable authorization keeps one line of its own. With no list reader a
chip reads as pending.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ct chips

The smoke suite recounts the Tab walk with a stop per chip and the app's, and
proves the worker's list reaches each chip and a press's keyboard path over the
held list; the network specs read the chip's label and the count line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e fee window links the explorer

The inline popover's root shrinks inside a flex row, so the app chip clips a
long name; the press wraps an unbroken host or contract name. The raised-fee
window passes the picked explorer to its card. Tests pin the pending and
PrivateFPC presses, the decoded name's path to an unverified press, Space on
a chip, and a 64-character app name at 400 and 240 px.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…aised

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rivers know

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l request

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… them

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…iew pass

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alejoamiras alejoamiras changed the title verified contracts build 1 a1 feat(execute): contracts and the app become chips, with a seal for nulo verified Nov 12, 2026
@github-actions

Copy link
Copy Markdown

Extension preview build — 0b20d75

Version 1.2.0-pr.1805 · workflow run · artifacts expire after 7 days.

Load it
  1. Download and unzip (GitHub wraps the dist/ folder in a zip).
  2. Chrome: chrome://extensions → Developer mode → Load unpacked → pick the unzipped folder.
    Firefox: about:debugging#/runtime/this-firefox → Load Temporary Add-on… → pick manifest.json.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
nulo-landing 0b20d75 Commit Preview URL

Branch Preview URL
Nov 12 2026, 11:27 PM

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant