Skip to content

feat(send): pay a person: the person first, the fee line pinned over review send - #1795

Open
alejoamiras wants to merge 27 commits into
devfrom
send-build-1-a1
Open

alejoamiras wants to merge 27 commits into
devfrom
send-build-1-a1

Conversation

@alejoamiras

@alejoamiras alejoamiras commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Send becomes B, "pay a person": a person step asks who is paid first, then one form for that person, with the fee line pinned over Review send. Every send now passes the review sheet (its body is unchanged in this arc; arc a2 rebuilds it). Plan: implementations-plan/send-build-1/plan.md; owner asks with what ships now: implementations-plan/send-build-1/OWNER-ASKS.md. Part of the three-arc send-build-1 stack (the form, the review, the close-out). No issue is linked on pages 129, 131 or 133, so this PR closes none.

Changed after page 138

One answer on page 138's notes reaches this PR's form. It ships in #1797, the stack's review arc, which builds every page-138 answer, so this PR stays the form as signed on page 137.

P138-06, the FPC wording: dot "FPC" with the existing glossary entry (2026-11-12 16:04 UTC)

  • Asked: the owner's P138-06 note ("fee paying contract? Or FPC with glossary? We are assuming the user knows what an FPC is."). The orchestrator put two ways to the owner: dot "FPC" with the glossary's existing fpc entry on the form and the review, or spell it out as the glossary writes it, "Fee Payment Contract".
  • Answer: the owner in chat, 2026-11-12 at about 16:04 UTC: ""Your P138-06 question needs one answer from you. " => dot the FPC then. your rec."

In #1797, "FPC" in "Nulo can't tell what this FPC publishes about you." and "Nulo can't tell what this FPC charges you." is a dotted term keyed to the glossary's existing fpc entry, on the form and the review; #1797's body states the dotted terms per screen.

Changed after page 137

The owner did not approve this PR as built on page 137 (signed 2026-11-12 14:44:49 UTC); this round makes the four changes asked there. Each item quotes the page verbatim.

  • The check line (PayeeBlock.vue). P137-01 (14:42:35 UTC): "I don't like "check it's start and it's end" => we should just say to review carefully." It now reads "You have not paid this address before. Review it carefully before you send." (D21)
  • The warning's fix never relies on the sponsor (PublishLine.vue, FeeSettingsCard.vue). P137-01 (14:42:35 UTC): "We shouldn't rely on the "use sponsored" since that's only for Testnet. On mainnet, they should get private fee juice." P137-06 = b (14:44:37 UTC): "Today's review remedy, the bridge link Get private Fee Juice, as the warning's fix." On a private send paid from public Fee Juice the fix is Pay it from private Fee Juice when the account's private Fee Juice covers the fee (the PrivateFPC row can pay and its balance holds the current estimate's max fee; no estimate yet, a balance above zero), otherwise the link Get private Fee Juice to FEE_JUICE_BRIDGE_URL, new tab, noopener noreferrer, on every network. The fix only ever picks the PrivateFPC the wallet derives; the sponsor stays one press away through Change. "Covers" is an approximation of the PrivateFPC's own estimate, put to the owner as OA-18. (D22)
  • The token row's band (SelectTokenCard.vue, send.vue). P137-03 (14:43:46 UTC): ""A" but the hover state looks pretty awful because it does not change it's color till the top and bottom of the component? it looks like a very slim highlighted thing, which looks really bad." The row now pads itself to its section's rules, so its hover, focus-visible and new press tints fill the whole 64 px band, both themes; a flagged banner or the caveat in the section keeps its spacing. Proven in send-keyboard's smoke spec (the box's edges against the rules, 64 px, tinted at hover, focus and press). (D23)
  • What Change opens (FeeMethodRadios.vue, new; FeeSettingsCard.vue; send.vue). P137-04 = b (14:44:03 UTC): "The prototype's sheet: the payers as radios with definitions and balances, priority, Done." On Send the card draws "Who pays the fee" as one native radio per payer (private Fee Juice, public Fee Juice, then the sponsors in the menu's order), each with its glossary definition and what it can spend or why it cannot, then priority, then the card's notices and You pay, then Done. The sheet opens on the chosen payer, else the first that can pay; Escape, the X and Done return to Change with the pick kept. A pick the card's rules refuse has its browser check put back on the card's payer. The menu's "NAMES YOUR ADDRESS" tag and its prop leave (only Send drew them; the form's warning says it). The dApp windows keep the menu, unchanged. What the prototype never drew ships as listed in OA-17. (D24)

No change, as answered: P137-02, OA-2 = a (14:40:46 UTC); P137-05, OA-8 = a (14:44:23 UTC); P137-07, OA-14 = a (14:44:47 UTC).

UI impact, before and after

Surface Before After
Pasted address's check line "You have not paid this address before. Check its start and end." "You have not paid this address before. Review it carefully before you send."
Warning on a private send paid from public Fee Juice "Pay it from private Fee Juice" when the PrivateFPC row could pay, else "Use Sponsored" where the sponsor exists, else no fix "Pay it from private Fee Juice" when private Fee Juice covers the fee, else the link "Get private Fee Juice"
Token row hover, focus, press A slim tint over the row's 36 px content The tint fills the 64 px band between the section's rules (press tint new)
Fee sheet Today's fee card: the payer menu with its tag, the Available row, priority, You pay "Who pays the fee" radios with definitions and balances, priority, notices, You pay, Done

Owner asks opened this round: OA-17 (the sheet's parts the prototype never drew) and OA-18 (what the reviews surfaced: the "covers" approximation, an arrow through public Fee Juice is a pick, the tint with a banner or caveat, the bridge link's network), each with what ships now in implementations-plan/send-build-1/OWNER-ASKS.md.

Testids

  • Added: send-fee-payers (the radio group, data-fee-method), send-fee-payer-{private,public,sponsored} (each radio, data-fpc-id on sponsors) and their -choice labels, send-fee-done, send-fee-warning-bridge.
  • Retired: send-fee-privacy-notice (the tag; only Send drew it). Off Send, kept by the dApp windows: send-fee-method-trigger, send-fee-method-*. The specs that read them moved to the radios: send-page.ts, send-burst.ts, fee-methods, fee-sponsor-funding, send-chaos, send-fee-privacy, send-keyboard.

Reviews

Codex (GPT-6.1 Sol, high, read-only) and Opus 5.5 beside it, both conditional approve; the resumed Codex round approved the fixes. Adopted: the native radio check kept on a pick the card refused (reproduced in memory, now put back after every change, with a component test red without it); the e2e invariant read the radios' preview of a saved pick, which reddened fee-methods on a real run (now the fee line's payer in effect); the sheet opening on no control when nothing is checked; a hand-added sponsor's row carried Sponsored's definition (now the glossary's FPC definition). Records: plan.md § Audit verdicts.

Validation of this round

Every run at retry 0 on head 477d1f040 (the capture commits after it change no code), on a shared host at load 85 to 380 on 188 cores.

After these gates dev moved three commits (#1792, #1800, #1803) and this PR could no longer merge, so its CI never started; the stack was rebased onto dev with no conflict in code (two plan files only). On the rebased head 246e6bdfb: bun run lint, bun run typecheck:all and bun run test:all green at retry 0. The e2e suites run again in CI here and locally on #1797's head, which carries this one. CI then failed one non-required check, CodeQL, on one new alert: "insecure randomness" for the Math.random() that named the payer radios' group (FeeMethodRadios.vue). The id only has to be unique on the page, so it now comes from Vue's useId(), as the other components that label by id do (one commit, 03027e005; its component, page and integration tests and typecheck green). On 03027e005 every check here is green, CodeQL included, and #1797's head, which carries it, passed the full local gates (smoke and the 24 network specs on both browsers).

  • Static: bun run lint, bun run typecheck:all, bun run test:ci-gating (755 pass), bun run check:plans: green. bun run test:all: the first run had one red, price/convert.test.ts timing out at 5 s at load 278 (its 21 tests take 143 ms alone; nothing here touches it); rerun green (extension 18,384 passed).
  • Smoke, full suite: Chrome 290 passed, 0 red. Firefox 294 passed and 1 red, sealed-storage (the unlock's sealing pass outran its 120 s wait at load ~330; nothing here touches sealing, and it passed in 31 s in the arc's earlier Firefox gate); that file rerun green.
  • Network, the 24 specs the form's fixtures reach: Chrome 62 passed. Firefox 62 passed. The opt-in ones, armed on Chrome (send-chaos, store-captures, stale-network-a10-capture): 3 of 3.
Smoke suite, retry 0 Chrome Firefox
Before this round (the arc's last gate) 1839 s 2926 s
After 2044 s 3466 s

The host load differed between the runs (far higher on this round's Firefox run), so the rise is load, not cost. Network, the 24 specs, after: Chrome 2663 s, Firefox 3394 s.

Changed e2e scenarios (none added):

  • send-keyboard, "the token row is the whole band between its rules, and focus, hover and press tint all of it" (was "the token card draws the accent ring when focused"). The failure mode is a tint that covers the row's content box but not the band between the section's rules, which only real layout shows; jsdom has none. Estimated +4 s over the old scenario; measured 24.1 s on Chrome and 12.6 s on Firefox (was 8.3 s and 15.2 s; Chrome ran at higher load).
  • send-keyboard, "the fee sheet's payers: Change opens it on the chosen radio with the ring, the arrows pick, Tab leaves, Escape and Done return" (was the fee method picker's). The failure mode is native radios' arrow keys and the teleported card inside the sheet's focus trap, which differ by engine and jsdom has neither. Estimated as the old scenario; measured 26.7 s on Chrome and 14.5 s on Firefox (was 9.7 s and 15.8 s).

Captures of this round

From the real popup over the local sandbox (never Testnet), 360 x 600 unless marked, light theme unless marked; every frame also exists in the other theme.

The check line on a pasted address, at 360 and 240 px; dark

a1b-form-pasted-top a1b-form-pasted-top-240 a1b-form-pasted-top-dark

The warning's fix: private Fee Juice covers the fee (Pay it from private Fee Juice); none held (Get private Fee Juice, on a network whose sponsor could pay); dark

a1b-warning-fix a1b-warning-bridge a1b-warning-bridge-dark

The token row at rest, hovered and pressed: the tint fills the band between its rules

a1b-token-row-rest a1b-token-row-hover a1b-token-row-pressed

The token row hovered and pressed, dark

a1b-token-row-hover-dark a1b-token-row-pressed-dark

The Fee sheet: at rest (private Fee Juice chosen), public Fee Juice picked, at 240 px

a1b-fee-sheet a1b-fee-sheet-picked a1b-fee-sheet-240

The Fee sheet, dark

a1b-fee-sheet-dark a1b-fee-sheet-240-dark

What changed and why (arc 1 as first built)

  • Person step (SendPersonStep.vue, around RecipientField): "Who are you paying?", the field, "Pay this address" for a valid paste, Recent (this account's own popup sends the node took, newest first, up to four, own accounts left out), Your accounts. The field emits choose once its pick may be shown; a press held on any row, or a tap, chooses what it landed on, never the contact the field's blur matched. An off-curve candidate is never chosen.
  • The form: PayeeBlock ("To", the name, the whole address in two lines of 33, the check line for an address with no record), SendAgainRow (Same as last time, from the operation journal, recent-sends.ts), the token row with no label, AmountCard (Max on the label line, the refusal under the field, no balance segment), two native radio groups (SideChoice.vue), PublishLine.vue (one sentence, or the one warning with its fix).
  • Footer: SendFeeLine.vue (fee-line-words.ts) and Review send, whose off label names what is missing (send-labels.ts). Change opens the fee card, whole, in a Fee sheet; the card stays mounted in a hidden holder and is teleported into the sheet, so its estimate and picks live across opens.
  • Fee words: "private gas" → "private Fee Juice", "Private FPC" → "Private Fee Juice", "fee juice" → "Fee Juice" in the fee card (every window that mounts it), publish-facts.ts, Send and today's review sheet.
  • RecipientCard and SendTypesCard are deleted; CLAUDE.md § Keyboard admits a native radio group beside the roving tablist.

UI impact (the owner's sign-offs, verbatim)

  • Person step: P129-06 = B, "Build B, Pay a person, now: the fastest repeat send and the one that answers who first; its card scrolls at 360 x 600 with the fee line and Review pinned."
  • Person block: P131-01 = A4, "No initials and no square: the name in bold, the whole address under it in two even lines of 33 with its bold start and end at the line edges; a pasted address shows no name line, only the address and the yellow check line." P131-15 = T1, "A section label: "To" set as the form's other labels are, 6 px above A4's block, which is otherwise unchanged."
  • Same as last time: P131-02 = SL1, "Keep the one-press Same as last time row, placed in the person block as round three did, hidden once the form holds the values; the token row is one press with a chevron."
  • Token row: P133-01, "The row now sits on the rule with 14 px above and 14 below, offset 0, in both states (at rest and with Same as last time shown) and in every fee place; the band stays 54 px, so nothing below it moves; the capture fails past 1 px." (OA-3: the signed 36 px picture makes the band 64 px.)
  • Amount card: P131-03 = M3, "Max on a label line above the field, over the unit switch, and so before the field in Tab order." P129-06 note, "3.a. I don't think we need to put "{private icon} Private balance {balance}" when the balance it's exactly below that phrase." P131-13 = S1, "The redesign may revisit both: the build lane proposes the refusal's slot and the caveat's place for B, with pictures, before anything ships." (OA-2.)
  • Side pairs: P131-12 = K2, "Wait: every proposal replaces the pairs with native radios, so the fix comes with the redesign."
  • Publish line: P131-04, "the publish-facts line is one plain sentence in the body tint, written once, never a warning, and the Publicly choice is no longer yellow. The only warning left is a private send paid from public Fee Juice: yellow with its glyph, it names what the fee shows and offers Pay it from private Fee Juice."
  • Fee line and Sponsored: P133-08 = FP1, "Round three's line pinned over Review send, with Change: the fee reads on every send without scrolling, 47 px of the button area, three presses to a new payer." P131-06, "Round four's fee row reads Fee ≈ $0.03* (0.00214 FJ), private Fee Juice; on a private send paid from public Fee Juice it names public Fee Juice and the one warning's fix reads Pay it from private Fee Juice". P133-01, "It is gone from every dollar figure inside the frame". P133-02 = SP2, "Fee Nothing · Sponsored on the line, nothing struck, and the sponsor's cost as a plain note on a second line (The sponsor covers ≈ $0.03 (0.00214 FJ))."
  • Button: P131-05 = H2, "The off button carries what is missing as its label, as today's Send button does." P133-08's "pinned over Review send" (OA-8).
  • Fee words: P131-07 = FX2, "With the redesign: the words change when B ships, not before." P133-06 = FJ1, "Keep the capital, Aztec's and the glossary's name for the asset, and fix the two outliers so the wallet is consistent: the fee card's nudge ("fee juice" → "Fee Juice") and the Terms' phrase at the next Terms patch."

Owner asks this arc ships in their "what ships now" form: OA-2 (refusal under the field, caveat under the token row), OA-3 (64 px band), OA-4 (today's fee card in the sheet), OA-5 (the line's other states in today's words), OA-6 (other off causes keep "Review send"), OA-7 (the FX2 sentences listed there), OA-8 (every send through the review), OA-9 (the line's figures), OA-11 (four lines at 240 px), OA-12 (the warning without a fix when nothing can pay), OA-13, OA-14.

Captures

From the real popup over the local sandbox (never Testnet), 360 x 600 unless marked, light theme unless marked; every frame also exists in the other theme. Today's review sheet is unchanged in this arc (a2 rebuilds it).

The person step, before any send and after one (Recent: Ana, Last: 1 TST, publicly)

a1-person-step-first a1-person-step a1-person-step-dark

The person step at 240 px; the form for a named payee at 360 and 240 px, Same as last time showing

a1-person-step-240 a1-form-named-top a1-form-named-top-240

Dark theme; Same as last time pressed (the row goes, the fee line reads Sponsored with the sponsor's cost); the token row

a1-form-named-top-dark a1-form-named-again-hidden a1-token-row

A refused amount (Fix the amount); the fee line sponsored at 360 and 240 px

a1-amount-refusal a1-fee-line-sponsored a1-fee-line-sponsored-240

The fee line paid from public and from private Fee Juice (no price on the local network, so FJ only); the fee sheet

a1-fee-line-paid-public a1-fee-line-paid-private a1-fee-sheet

A pasted address nobody has paid, with its check line, at 360 and 240 px, and scrolled to the fee line

a1-form-pasted-top a1-form-pasted-top-240 a1-form-pasted-fee-line-240

The publish sentence: all hidden on the sponsor, a public send; the one warning (private to private)

publish-all-hidden publish-public-send warning-private-private

The warning's second wording (private to public)

warning-private-public

Accessibility calls (under the 2026-10-19 delegation)

  • Focus on entering the form: Same as last time when shown, else the amount; when the amount takes no focus (a token with no transfer kind), the token row.
  • Change carries aria-haspopup="dialog" and aria-expanded, refuses a repeat Enter, and receives the keyboard when a focused Try again is replaced by the estimate it started.
  • Native radio groups for the two side pairs: one Tab stop each, the arrows move within; the ring sits on the choice's label (:focus-within).
  • 240 px: a Recent row's age wraps under the row (a people container query) rather than splitting the name; the address halves wrap anywhere (OA-11).

Testids

  • New: send-page, send-person-step, send-pay-address, send-recent, send-recent-address, send-own-account, send-own-account-address, send-payee, send-payee-name, send-payee-address, send-payee-half-first, send-payee-half-second, send-payee-check, send-again, send-{from,to}-{private,public} and their -choice labels, send-publish, send-publish-line, send-fee-warning, send-fee-warning-fix, send-fee-line, send-fee-line-value, send-fee-line-note, send-fee-line-retry, send-fee-change, send-fee-sheet.
  • Retired from Send, with the specs that moved: recipient-card* (RecipientCard deleted; fixtures/send-page.ts, send-keyboard, type-roles, send-amount-exact, store-captures), send-amount-balance and send-amount-balance-loading (fiat-send, send-amount-exact, send-picker, store-captures; the From hint carries the balance), send-publish-strip (fixtures/send-page.ts, fixtures/shots.ts, fee-methods, send-amount-exact, type-roles-windows, send-fee-privacy; the component stays for a2's review), and the fixtures' data-action (fixtures/send-page.ts, snack-placement, send-fee-privacy; submitSend always passes the review). send-from-type and send-to-type are kept, now on the radio groups.

Validation (arc 1 as first built)

Every run at retry 0 on this head, on a shared host (load 150 to 840 on 188 cores).

  • Static: bun run lint, bun run typecheck:all, bun run test:all (extension 18,378 passed), bun run test:ci-gating (755 pass), bun run check:plans: green.
  • Smoke, full suite: Chrome 287 passed, with 3 reds in two specs the migration had missed (legal-acceptance S4 and S7, token-list: both read Send's form without the person step); fixed and rerun green (16/16). Firefox 295 passed, 0 red.
  • Network, the 24 specs this arc touches: Chrome 62 passed. Firefox 61 passed and 1 red, send-amount-exact: Max's right edge read 336.0000153 px against the row's 336 (Firefox reports its 1/60 px layout unit through float32). The spec now compares edges at that unit; green on both browsers. The three opt-in specs among them (send-chaos, store-captures, stale-network-a10-capture) skip in a plain run, so they ran armed on Chrome: green.
  • Update in place from v1.2.0 to this head (armed candidate): Chrome 2/2, Firefox 2/2.
  • Review loop: Codex (GPT-6.1 Sol, high) reject, reject, approve, with one Opus 5.5 review alongside round 1. Every finding was fixed with a test that fails without its fix: a press or tap on a Recent or own-account row while the field holds a contact's whole address, Back out of USD mode, Change's repeat Enter and focus, an off-curve contact, the fee line's queued cap, the amount words' places.
Smoke suite, retry 0 Chrome Firefox
Before (this arc's base) 2362 s 3971 s
After 1839 s 2926 s

The host load differed between the runs, so the fall is noise, not a saving. Network, the 24 touched specs, after: Chrome 2309 s, Firefox 2711 s.

One added e2e scenario: send-keyboard, "a mouse press held on a Recent row while the field holds a contact's whole address pays the pressed row". The failure mode is the browser's own dispatch of a held press, its blur, release and click, choosing the field's contact over the pressed row. Component tests fake that order, so only a real browser establishes it. Estimated 10 s; measured 9.1 s on Chrome and 16.1 s on Firefox.

Found on the way and filed: #1794 (the execute window's type-roles sweep reads its "Reading arguments…" line as it settles; the twin of #1763, in a window this PR does not touch).

🤖 Generated with Claude Code

@alejoamiras alejoamiras changed the title send build 1 a1 feat(send): pay a person: the person first, the fee line pinned over review send Nov 11, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Nov 11, 2026 •

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 03027e0 Commit Preview URL

Branch Preview URL
Nov 12 2026, 08:58 PM

@github-actions

github-actions Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Extension preview build — 03027e0

Version 1.2.0-pr.1795 · 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.

alejoamiras and others added 24 commits November 12, 2026 20:21
…9, 131 and 133)

Three stacked arcs: the form (person step, person block, token row, amount,
native radios, publish line, fee line pinned over review send, every send
through the review), the review (to, amount, privacy strip, fee row), and
the close-out. Audited by Codex (reject, then approve after revision and a
fresh pass) and Opus (conditional approve); every finding recorded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
addressHalves, the journal's past sends (parse, recent recipients, last send, known address,
age words), the fee line's figure, the publish sentence and the one fee warning, and the button
label that names what is missing.

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

PayeeBlock, SendAgainRow, SideChoice and PublishLine; the person step and the pinned fee line. The
fee card hands a closed host its notices and the one payer that stops a private send's fee naming
the account, and picks it on applyRemedy; its payer names the method. The review re-arms when its
disclosure changes. Private gas, the fee contract and Private FPC read as Fee Juice and FPC.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ee line and its sheet

Send asks who is paid first (a contact, a pasted address, a recent
recipient or an own account), then shows the form: the payee whole in
two lines of 33 with bold ends, Same as last time, the token, the amount
with Max on its label line, two native radio groups, and the publish
line or the warning with its fix. The footer pins the fee line over
Review send; Change opens the fee card in a sheet, the card itself
staying mounted for the estimate. Every send goes through the review.

RecipientCard and SendTypesCard retire with their tests: Send was the
card's one host, and the field now emits its pick once a held press
ends, so the step never swaps out under the press's own click.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- With nothing to spend the amount takes no focus, so the form opens on
  the token row instead of dropping focus to the page.
- A query-string contact goes through the person step's own choice: an
  address that is no point stays in the field, which says so; a valid
  one opens the form with its focus.
- "Pay this address" stays while a held press defers the field's
  match, so the rows under the press never move.
- At 240 px a recent row's age takes its own line, so the address is
  never split; each payee half carries its mono role.
- The fee line's notes are paragraphs, read apart.

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

Every Send flow chooses the person first, sets the sides through the
radios, picks a fee inside the Fee sheet and passes the review. The
publish invariant reads the card's tag, the form's warning and the
publish line's `you`. The released build's Send keeps today's steps in
`fixtures/update/release-ui.ts`. Smoke covers the person step, the
M3 Tab order, the radios' arrows, the fee sheet's trap and a held press
over a suggestion; fee-methods reopens Send after a real send for Recent
and Same as last time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ange refuses a repeat

- The field's held pick no longer captures the click its release delivers, so a press on
  a Recent or own-account row while the field holds a contact's whole address pays the
  pressed row.
- An off-curve candidate is never chosen, so no form opens that can never send.
- Back from the form ends USD mode on the amount it settled on, and drops one still
  converting.
- The fee line's Change says it opens a dialog and whether it is open, refuses a repeat
  Enter, and takes the keyboard when a focused Try again is replaced; its dead `pending`
  prop goes.
- The queued cap on the fee line is the card's own figure, never a second price read; the
  amount sentence keeps every decimal of the token amount.
- E2E: `chooseRecipient` proves the payee; the fee sheet's state is read from Change; a
  regression for the held press on a Recent row; the authwit leg types an amount within
  the rig's balance; the backup-import send answers the trust prompt a restore raises; a
  covered click names what covers it.

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

- A tap's compatibility mousedown blurs the field after its pointerup, and its click comes in the
  same task: every blur with no tracked press now holds the field's pick for that task, so what
  the tap landed on chooses first.
- A test holds Same as last time and Recent to every place of an 18-decimal amount.
- E2E: send-keyboard seeds its contacts at addresses on the curve, which Send can pay.

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

The Terms banner stands over both steps and the form's button stays off under it; the flagged
token's banner is the form's, so the token-list walk chooses a person first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ox's layout unit

Max now sits on the label line, flush with the row's right edge, and Firefox reports that edge
through float32 as 0.00002 px past the row. The failure names each part's span.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd transfers no longer cycle

`fixtures/fee-method.ts` holds the shared FeeSettingsCard picker the Send sheet, the dApp windows
and the release's Send use; `helpers.ts` re-exports it. The plan records the a1 gates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Committed for the PR body to link and removed in the next commit.

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

The sponsor exists on some networks only. The fix offers the account's
private Fee Juice when it holds the estimated fee, and the bridge link
otherwise, on every network.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The row pads itself to the rules around it, so the tint spans the 64 px
band and the row's full width; a banner or caveat in the band keeps its
spacing.

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

Send's card shows who pays as native radios, each with its glossary
definition and balance; priority follows, and Done closes the sheet with
the pick kept. The dApp windows keep the menu; the tag the menu drew for
Send alone goes with it.

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

A pick the card's rules refuse left the browser's check on it, since Vue patches `checked` only
when the bound value changes: every check is put back to the card's choice after a change. The
Fee sheet asks the radios for its first focus (the chosen payer, else the first that can pay),
so `Popup`'s `initialFocus` also takes a function. A sponsor added by hand carries the glossary's
FPC definition, not Sponsored's, since it may charge. Comments corrected where they still named a
dropdown or claimed the payer-in-use estimate bounds the PrivateFPC's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ved pick's preview

The radios preview a saved pick while balances load, so a tag derived from them fired before
the pick paid; the tag now reads the fee line's payer, the source the warning shares, and a
checked radio must be the card's payer. The unfunded-sponsor spec waits on that payer, not on
the browser's check.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
alejoamiras and others added 2 commits November 12, 2026 20:21
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…random

CodeQL reads `Math.random()` behind the group's label id and radio `name`
as insecure randomness. The id needs only to be unique on the page, which
`useId()` gives, as the other components that label by id use it.

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

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.

2 participants