fix: tracked tokens' balances are read through the RPC endpoint (closes #669)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run

refreshBalances() now reads the balance of every token tracked on the
active network, at every address, with balanceOf through the same
provider as the ETH balance. The entry takes its holder count and
decimals from Blockscout's entry for the token in the same refresh, or
keeps them from before while Blockscout fails. A failed balanceOf keeps
the token's previous entry, or takes Blockscout's entry when there is
none, and is logged. Blockscout's answer still adds the tokens the user
has not tracked, as before.

The browser test for a hostile symbol now untracks the stub token
first, because a tracked token is listed under the symbol it was added
with.

Model: opus-5-5
This commit is contained in:
2026-10-21 11:29:54 +00:00
parent b9bb1569fd
commit d16a2de747
5 changed files with 489 additions and 42 deletions
+10 -4
View File
@@ -18,6 +18,11 @@ const {
const RPC_URL = "https://rpc.example.invalid";
const EXPLORER_URL = "https://explorer.example.invalid/api/v2";
const ADDRESS = "0x1111111111111111111111111111111111111111";
const TRACKED = {
address: "0x7777777777777777777777777777777777777777",
symbol: "TRK",
decimals: 6,
};
const realFetch = globalThis.fetch;
let logged;
@@ -30,9 +35,9 @@ beforeEach(() => {
const failedToFetch = async () => {
throw new TypeError("Failed to fetch");
};
// The RPC calls (ETH balance, ENS name, and the scan's balance and
// transaction count) and the explorer request (token balances) all fail
// the same way.
// The RPC calls (ETH balance, ENS name, the tracked token's balance, and
// the scan's balance and transaction count) and the explorer request (the
// other token balances) all fail the same way.
FetchRequest.registerGetUrl(failedToFetch);
globalThis.fetch = jest.fn(failedToFetch);
});
@@ -49,7 +54,7 @@ function refresh(signal) {
wallets,
RPC_URL,
EXPLORER_URL,
[],
[TRACKED],
"mainnet",
signal,
);
@@ -60,6 +65,7 @@ test("a failure while the popup is open is reported", async () => {
for (const label of [
"ETH balance failed",
"ENS reverse failed",
"token balance failed",
"fetchTokenBalances failed: Failed to fetch",
]) {
expect(logged.some((line) => line.includes(label))).toBe(true);