fix: Blockscout and Etherscan lookups are off until the user turns them on (closes #668)
check / check (push) Canceled after 0s
e2e / e2e-chrome (push) Canceled after 0s
e2e / e2e-firefox (push) Canceled after 0s

Out of the box the wallet sent the user's addresses to Blockscout for history
and token lookups, and each recipient to Etherscan for its label. Two settings,
"Use Blockscout" and "Check recipients on Etherscan", now gate those requests
where they are made. Both are off in a new profile and offered unticked on
Welcome and in Settings. While one is off, the screens that relied on it say so
in a plain line naming the setting; after either changes in Settings, Back
draws the screen it lands on again. README and the user guide say what is
contacted by default and what each setting adds.

Model: opus-5-5
This commit is contained in:
2026-10-21 14:29:38 +00:00
parent c316d9ee78
commit bd2b5ce96a
49 changed files with 1342 additions and 139 deletions
+23 -10
View File
@@ -582,12 +582,14 @@ describe("surface 3: the balance list", () => {
// 1,000-holder floor and was listed as a holding named ETH.
test("a fake ETH token clearing the holder floor is filtered", async () => {
respondWith([fakeEthItem()]);
expect(await fetchTokenBalances(HOLDER, BLOCKSCOUT, [])).toEqual([]);
expect(await fetchTokenBalances(HOLDER, BLOCKSCOUT, true, [])).toEqual(
[],
);
});
test("tracking the fake token manually does not admit it either", async () => {
respondWith([fakeEthItem({ holders_count: "0" })]);
const balances = await fetchTokenBalances(HOLDER, BLOCKSCOUT, [
const balances = await fetchTokenBalances(HOLDER, BLOCKSCOUT, true, [
{ address: FAKE_ETH_CONTRACT },
]);
expect(balances).toEqual([]);
@@ -597,12 +599,16 @@ describe("surface 3: the balance list", () => {
// their belief about what they own, and it renders the symbol into HTML.
test("a padded fake ETH token is filtered too", async () => {
respondWith([fakeEthItem({ symbol: " ETH " })]);
expect(await fetchTokenBalances(HOLDER, BLOCKSCOUT, [])).toEqual([]);
expect(await fetchTokenBalances(HOLDER, BLOCKSCOUT, true, [])).toEqual(
[],
);
});
test("a fake ETH token padded with a no-break space is filtered", async () => {
respondWith([fakeEthItem({ symbol: NBSP + "ETH" + NBSP })]);
expect(await fetchTokenBalances(HOLDER, BLOCKSCOUT, [])).toEqual([]);
expect(await fetchTokenBalances(HOLDER, BLOCKSCOUT, true, [])).toEqual(
[],
);
});
// The false-positive direction on the surface that matters most: a real
@@ -617,7 +623,7 @@ describe("surface 3: the balance list", () => {
decimals: "6",
}),
]);
const balances = await fetchTokenBalances(HOLDER, BLOCKSCOUT, []);
const balances = await fetchTokenBalances(HOLDER, BLOCKSCOUT, true, []);
expect(balances).toHaveLength(1);
expect(balances[0].symbol).toBe(" USDC ");
});
@@ -631,7 +637,7 @@ describe("surface 3: the balance list", () => {
decimals: "6",
}),
]);
const balances = await fetchTokenBalances(HOLDER, BLOCKSCOUT, []);
const balances = await fetchTokenBalances(HOLDER, BLOCKSCOUT, true, []);
expect(balances).toHaveLength(1);
expect(balances[0].symbol).toBe("USDC");
});
@@ -642,7 +648,9 @@ describe("surface 3: the balance list", () => {
// before the symbol rule is consulted.
test("a non-ERC-20 row claiming ETH never reaches the symbol rule", async () => {
respondWith([fakeEthItem({ type: "ERC-721" })]);
expect(await fetchTokenBalances(HOLDER, BLOCKSCOUT, [])).toEqual([]);
expect(await fetchTokenBalances(HOLDER, BLOCKSCOUT, true, [])).toEqual(
[],
);
});
// The adjacent finding from the same review as issue #260: the type gate
@@ -660,16 +668,20 @@ describe("surface 3: the balance list", () => {
decimals: "6",
}),
]);
const balances = await fetchTokenBalances(HOLDER, BLOCKSCOUT, []);
const balances = await fetchTokenBalances(HOLDER, BLOCKSCOUT, true, []);
expect(balances).toHaveLength(1);
expect(balances[0].symbol).toBe("USDC");
});
test("case insensitivity does not admit another token type", async () => {
respondWith([fakeEthItem({ type: "erc-721" })]);
expect(await fetchTokenBalances(HOLDER, BLOCKSCOUT, [])).toEqual([]);
expect(await fetchTokenBalances(HOLDER, BLOCKSCOUT, true, [])).toEqual(
[],
);
respondWith([fakeEthItem({ type: "ERC-20-EXTRA" })]);
expect(await fetchTokenBalances(HOLDER, BLOCKSCOUT, [])).toEqual([]);
expect(await fetchTokenBalances(HOLDER, BLOCKSCOUT, true, [])).toEqual(
[],
);
});
// The money test: the user holds real ETH and has been airdropped a fake
@@ -682,6 +694,7 @@ describe("surface 3: the balance list", () => {
[{ addresses: [addr] }],
"https://rpc.example.invalid",
BLOCKSCOUT,
true,
[],
"mainnet",
);