Compare commits

..
Author SHA1 Message Date
clawbot adff1e0b9d docs: a change adds no Completed Steps entry to TODO.md (closes #222)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run
Every change used to add an entry at the top of Completed Steps in its
own commit, so each merge into `next` left every other open PR
conflicting on that list. The Workflow section now says to add no
entry: what landed is recorded on the tracker and in `git log`, where
each commit title names the issue it closes. The step that moved Next
Step into Completed Steps and pulled the top of Future Steps into Next
Step goes with it. The entries already in Completed Steps stay.

Model: opus-5-5
2026-10-14 05:15:05 +02:00
5 changed files with 8 additions and 60 deletions
+1 -6
View File
@@ -2124,12 +2124,7 @@ view would leave a wallet one click from deletion.
blocklist)
- Site origin (bold, scheme and port included) + "wants you to sign a
message"
- Warning box, shown for `eth_sign`: "This site used the older eth_sign
method. The data will be signed as a personal message." An `eth_sign`
request names the address first and the data second. Its data is signed
exactly as a `personal_sign` message is, as an EIP-191 personal message,
which is what the Ethereum JSON-RPC specification defines `eth_sign` to
return.
- Danger warning box (shown for `eth_sign`, which signs a raw hash)
- Type: "Personal message" or "Typed data (EIP-712)"
- From: color dot + full address + etherscan link
- Message: for `personal_sign` and `eth_sign`, the text the message's bytes
+3 -4
View File
@@ -2,10 +2,9 @@
- `git pull` `next` and cut a branch from it — one branch per issue, named
`issue-<N>-<slug>`. Never branch from `main`.
- Do the work as one commit whose title ends with ` (closes #N)`, with the
`TODO.md` update in that same commit.
- Move Next Step to the top of Completed Steps; move the top item of Future
Steps into Next Step.
- Do the work as one commit whose title ends with ` (closes #N)`.
- Add no entry to Completed Steps. What landed is recorded on the tracker and in
`git log`, where each commit title names the issue it closes.
- Run `make fmt`, then `make check`. A feature branch may be red; `next` and
`main` may not.
- Rebase onto current `next` immediately before pushing — other branches land on
+3 -2
View File
@@ -984,8 +984,9 @@ async function handleRpc(method, params, origin) {
if (method === "eth_sign") {
signParams.dangerWarning =
"This site used the older eth_sign method. " +
"The data will be signed as a personal message.";
"\u26a0\ufe0f DANGER: This site is requesting to sign a raw hash. " +
"This can be used to sign transactions that drain your funds. " +
"Only proceed if you fully understand what you are signing.";
}
if (findPendingApproval(origin, "sign")) {
+1 -1
View File
@@ -721,7 +721,7 @@ function showSignApproval(details) {
"This message is plain text, not hex, so it cannot be signed.";
}
// The warning the background attaches to an eth_sign request.
// Display danger warning for eth_sign (raw hash signing)
const warningEl = $("approve-sign-danger-warning");
if (warningEl) {
if (sp.dangerWarning) {
-47
View File
@@ -1551,53 +1551,6 @@ describe("what the approval is verified against", () => {
});
});
// eth_sign names the address first and the data second, the reverse of
// personal_sign, and is answered as the JSON-RPC specification defines it:
// with an EIP-191 personal message signature over the data, the same
// signature personal_sign returns
// (https://git.eeqj.de/sneak/AutistMask/issues/409).
describe("eth_sign", () => {
test("is read address first, and returns a personal message signature over the data", async () => {
const bg = loadBackground();
const page = bg.send(
{
type: "AUTISTMASK_RPC",
method: "eth_sign",
params: [signer.address, MESSAGE],
},
{ origin: ORIGIN },
);
await settle();
const id = approvalIdIn(bg.created.map((c) => c.url));
const details = bg.send(
{ type: "AUTISTMASK_GET_APPROVAL", id },
{ url: bg.fromPopup.url },
);
const { signParams } = details.sendResponse.mock.calls[0][0];
expect(signParams).toMatchObject({
method: "eth_sign",
message: MESSAGE,
from: signer.address,
});
expect(signParams.dangerWarning).toBe(
"This site used the older eth_sign method. " +
"The data will be signed as a personal message.",
);
const signature = await signer.signMessage(
Buffer.from(MESSAGE.slice(2), "hex"),
);
bg.send(
{ type: "AUTISTMASK_SIGN_RESPONSE", id, approved: true, signature },
{ url: bg.fromPopup.url },
);
await settle();
expect(page.sendResponse).toHaveBeenCalledWith({ result: signature });
});
});
// The interlock must not cost the retry the approval exists to allow.
describe("the interlock releases a failed attempt", () => {
test("a retryable failure before the broadcast leaves the approval usable", async () => {