Author SHA1 Message Date
sneak bccfd61f60 docs: RULES.md states the branch-per-issue model (closes #193)
check / check (push) Failing after 18m14s
e2e / e2e-chrome (push) Successful in 19m31s
e2e / e2e-firefox (push) Successful in 4m29s
Replaces the "merge to main when done" checklist line with the wording
sneak approved on the issue.

Model: opus-5-5
2026-11-10 19:55:03 +00:00
6 changed files with 22 additions and 28 deletions

No files matched your search

+5 -4
View File
@@ -1645,10 +1645,11 @@ The development dependencies ship nowhere:
### Crypto policy
In the extension, hashing, key derivation, signing and encryption go through
`ethers` or `libsodium-wrappers-sumo`. A new recovery phrase takes its random
bytes from `ethers`. `build.js` and `script/lib/package.js` also hash files with
`ethers`. No primitive is implemented in this repository.
Hashing, key derivation, signing and encryption go through `ethers` or
`libsodium-wrappers-sumo`. No primitive is implemented in this repository. A new
recovery phrase draws its random bytes from the browser's
`crypto.getRandomValues()`. The build tooling, `build.js` and `script/lib/`,
hashes files with Node's `crypto`; none of it ships in the extension.
### Content Security Policy
+4 -1
View File
@@ -108,7 +108,10 @@ contradicts either, the originals govern.
- [ ] All tool invocations via `make` targets, never directly
- [ ] `make check` = `make test` + `make lint` + `make fmt-check`
- [ ] `main` always passes `make check`
- [ ] Feature branches for all changes, merge to main when done
- [ ] Branch per issue, cut from `next`. One PR per issue, based on `next`,
squash-merged into `next` on a passed independent review. `main` is
reached only by the per-milestone PR from `next`; releases are tagged from
`main`. `next` and `main` must stay green; feature branches may be red.
- [ ] No force-push to `main`
- [ ] Pre-commit hook runs `make check`
+5 -3
View File
@@ -1,8 +1,8 @@
const fs = require("fs");
const path = require("path");
const crypto = require("crypto");
const { execSync } = require("child_process");
const esbuild = require("esbuild");
const { sha256 } = require("ethers");
const { resolveVersion } = require("./script/lib/version");
const {
BACKGROUND_ENTRY_PREFIX,
@@ -314,8 +314,10 @@ function copyIcons(distDir) {
}
function sha256File(absPath) {
// ethers prefixes the hex with 0x; the receipt holds bare hex.
return sha256(fs.readFileSync(absPath)).slice(2);
return crypto
.createHash("sha256")
.update(fs.readFileSync(absPath))
.digest("hex");
}
// Write the receipt for the files this build emitted. Deliberately records no
+3 -9
View File
@@ -25,9 +25,9 @@
"use strict";
const crypto = require("crypto");
const fs = require("fs");
const path = require("path");
const ethers = require("ethers");
const { readZip, writeZip } = require("./zip");
const { resolveVersion } = require("./version");
@@ -60,9 +60,8 @@ function fail(message) {
throw new Error(message);
}
// Lowercase hex without the 0x prefix ethers adds, as sha256sum prints it.
function sha256(buf) {
return ethers.sha256(buf).slice(2);
return crypto.createHash("sha256").update(buf).digest("hex");
}
// Every regular file under dir, as archive-root-relative forward-slashed
@@ -292,9 +291,4 @@ if (require.main === module) {
}
}
module.exports = {
checkSelfContained,
htmlReferences,
manifestReferences,
sha256,
};
module.exports = { checkSelfContained, htmlReferences, manifestReferences };
+5 -2
View File
@@ -1,7 +1,7 @@
// Wallet operations: mnemonic generation, HD derivation, signing.
// All crypto delegated to ethers.js.
const { Mnemonic, HDNodeWallet, Wallet, randomBytes } = require("ethers");
const { Mnemonic, HDNodeWallet, Wallet } = require("ethers");
const { DEBUG, DEBUG_MNEMONIC, BIP44_ETH_PATH } = require("./constants");
function generateMnemonic() {
@@ -10,7 +10,10 @@ function generateMnemonic() {
// settings toggle drives, which would let a user of a release build turn
// the hardcoded, publicly known test phrase back on for real wallets.
if (DEBUG) return DEBUG_MNEMONIC;
return Mnemonic.fromEntropy(randomBytes(16)).phrase;
const m = Mnemonic.fromEntropy(
globalThis.crypto.getRandomValues(new Uint8Array(16)),
);
return m.phrase;
}
// Every extended key (xprv or xpub) entering the app goes through this.
-9
View File
@@ -17,7 +17,6 @@ const {
checkSelfContained,
htmlReferences,
manifestReferences,
sha256,
} = require("../script/lib/package");
const { readZip, writeZip } = require("../script/lib/zip");
@@ -143,14 +142,6 @@ describe("archive self-containment", () => {
});
});
// release/SHA256SUMS is checked with `sha256sum -c`, which needs the digest
// as bare lowercase hex. The expected value is the FIPS 180-2 digest of "abc".
test("sha256 prints the digest as sha256sum does", () => {
expect(sha256(Buffer.from("abc"))).toBe(
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
);
});
describe("the zip container", () => {
const files = [
{ name: "manifest.json", data: Buffer.from('{"a":1}') },