1 Commits
Author SHA1 Message Date
sneak 2bdcfae629 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 and each
recipient to Etherscan. Two settings, "Use Blockscout" and "Check recipients on
Etherscan", now gate those requests. Both are off in a new install and offered
unticked on Welcome and in Settings. While one is off, the screens that relied
on it say so in a plain line. Each gated request reads its setting from storage
before it asks and when the answer lands, and drops a late answer. An open popup
takes another page's change and draws its screens again. While "Use Blockscout"
is off, no address keeps an untracked token, and no screen names a token from
Blockscout's report. ENS lookups ask only the RPC endpoint.

Model: opus-5-5
2026-10-26 11:53:43 +00:00
26 changed files with 183 additions and 203 deletions

No files matched your search

+62 -69
View File
@@ -15,21 +15,19 @@ Hence, a minimally viable ERC20 browser wallet/signer that works cross-platform.
Everything you need, nothing you don't. We import as few libraries as possible Everything you need, nothing you don't. We import as few libraries as possible
and don't implement any crypto. By default the wallet sends user-specific data and don't implement any crypto. By default the wallet sends user-specific data
only to the Ethereum RPC endpoint. The user can change that endpoint in only to the Ethereum RPC endpoint. The user can change that endpoint in
Settings. The endpoint defaults to a public node. Settings. It defaults to a public node.
Out of the box the extension contacts two services: Out of the box the extension contacts two services:
- the configured RPC node, for blockchain interactions - the configured RPC node, for blockchain interactions
- a public CoinDesk API (no API key), for realtime prices. The API receives - a public CoinDesk API (no API key), for realtime prices. It is sent token
token symbols and nothing else. symbols and nothing else.
Two more services are sent none of the user's data until the user turns them on. Two more services are sent none of the user's data until the user turns them on.
Each has a checkbox on the Welcome screen and in Settings: Each has a checkbox on the Welcome screen and in Settings:
- "Use Blockscout": a Blockscout block-explorer API, used for: - "Use Blockscout": a Blockscout block-explorer API, for transaction history,
- transaction history the tokens the user has not tracked, and transaction details
- the tokens the user has not tracked
- transaction details
- "Check recipients on Etherscan": a best-effort Etherscan label lookup of the - "Check recipients on Etherscan": a best-effort Etherscan label lookup of the
recipient during transaction confirmation recipient during transaction confirmation
@@ -439,14 +437,13 @@ It also covers what a new install sends to Blockscout and Etherscan
([#668](https://git.eeqj.de/sneak/AutistMask/issues/668)). The harness installs ([#668](https://git.eeqj.de/sneak/AutistMask/issues/668)). The harness installs
a route handler before the first popup page opens. From then on, the handler a route handler before the first popup page opens. From then on, the handler
records every request the extension makes, from its pages and from its records every request the extension makes, from its pages and from its
background worker. The background worker also makes requests while it starts up. background worker. A request the background worker makes while it starts up
Those come earlier, so they are not recorded. The tests take these steps in comes earlier and is not recorded. The tests take these steps in order:
order:
- Welcome must offer "Use Blockscout" and "Check recipients on Etherscan" - Welcome must offer "Use Blockscout" and "Check recipients on Etherscan"
unticked. unticked.
- With neither ticked, each of these screens must show the line saying what is - With neither ticked, Home, AddressDetail, AddressToken and ConfirmTx must each
off: Home, AddressDetail, AddressToken and ConfirmTx. show the line saying what is off.
- The popup is then closed until the background has run a balance refresh of its - The popup is then closed until the background has run a balance refresh of its
own. No recorded request may have gone to Blockscout or Etherscan. own. No recorded request may have gone to Blockscout or Etherscan.
- "Use Blockscout" is ticked from AddressDetail's gear. On "Back", AddressDetail - "Use Blockscout" is ticked from AddressDetail's gear. On "Back", AddressDetail
@@ -463,7 +460,7 @@ order:
Both settings stay on for the rest of the run. TransactionDetail with "Use Both settings stay on for the rest of the run. TransactionDetail with "Use
Blockscout" off is not driven here, because no history row leads to it then. The Blockscout" off is not driven here, because no history row leads to it then. The
unit tests cover that case. unit tests cover it.
It also covers the confirmation screen, for both a native ETH send and an ERC-20 It also covers the confirmation screen, for both a native ETH send and an ERC-20
send: Send disabled while the fee estimate is in flight, enabled once it lands, send: Send disabled while the fee estimate is in flight, enabled once it lands,
@@ -1168,21 +1165,20 @@ with the same floor (`.5` reads `.5000`).
**Specific Exception — unknown token scale:** Calldata carries base units and no **Specific Exception — unknown token scale:** Calldata carries base units and no
scale, so every amount on the dApp approval screen needs the token's `decimals`. scale, so every amount on the dApp approval screen needs the token's `decimals`.
The wallet takes the `decimals` from these sources, in this order It is resolved from these sources, in this order (`resolveTokenDecimals()` in
(`resolveTokenDecimals()` in `src/shared/approvalAmount.js`): `src/shared/approvalAmount.js`):
- the bundled token list - the bundled token list
- the tokens the user tracks on the network the transaction is for - the tokens the user tracks on the network the transaction is for
- what the block explorer reported for the contract in the wallet's balances. - what the block explorer reported for the contract in the wallet's balances.
Those balances cover the active network only. This source is used only while These are the active network's only, and they are used only while "Use
"Use Blockscout" is on (`tokenSourcesByChainId()` in Blockscout" is on (`tokenSourcesByChainId()` in `src/popup/views/helpers.js`).
`src/popup/views/helpers.js`).
The token's name comes from the same sources. While "Use Blockscout" is off, a The token's name comes from the same sources. While "Use Blockscout" is off, a
token's name or decimals may be missing from the bundled list and the tracked token's name or decimals may be missing from the bundled list and the tracked
tokens. Then a line under the token says "Blockscout's report of your balances tokens. Then a line under the token says "Blockscout's report of your balances
is not used to name this token, because "Use Blockscout" is off in Settings." is not used to name this token, because "Use Blockscout" is off in Settings."
These screens show the line: These screens show it:
- TxApproval and SignApproval - TxApproval and SignApproval
- WaitTx, SuccessTx and ErrorTx, which follow TxApproval - WaitTx, SuccessTx and ErrorTx, which follow TxApproval
@@ -1225,11 +1221,11 @@ refusal the wallet has any reason to make.
While "Use Blockscout" is on, the Send screen also consults every address's While "Use Blockscout" is on, the Send screen also consults every address's
explorer reports. Two addresses may report different `decimals` for one explorer reports. Two addresses may report different `decimals` for one
contract. That token then has no scale on Send. Its stored balance is withdrawn contract. That token then has no scale on Send, and its stored balance is
as well. The Send screen's `Current balance` and the confirmation screen's withdrawn with it. The Send screen's `Current balance` and the confirmation
balance line then both read `unknown (SYMBOL)`. The balance list formats each screen's balance line then both read `unknown (SYMBOL)`. The balance list
explorer row as it is fetched, without that cross-address check, and shows the formats each explorer row as it is fetched, without that cross-address check,
row's figure. and shows the row's figure.
**Decoded amount lines on the transaction approval screen:** the `Amount` line **Decoded amount lines on the transaction approval screen:** the `Amount` line
of a decoded ERC-20 call, and the `Amount` and `Min. received` lines of a of a decoded ERC-20 call, and the `Amount` and `Min. received` lines of a
@@ -1460,10 +1456,9 @@ setting is off until the user turns it on. While it is off:
- A tracked token's balance uses the decimals from the bundled list, or else the - A tracked token's balance uses the decimals from the bundled list, or else the
decimals saved when the token was tracked. decimals saved when the token was tracked.
Blockscout may answer just before the user turns the setting off. So the popup's Blockscout may answer just before the user turns the setting off. So if the
refresh and the background's both check the stored setting again when they save. stored setting is off when the refresh saves, in the popup or the background,
If the setting is off by then, the save drops every token the user has not the save drops every token the user has not tracked.
tracked.
A tracked token is shown when its balance is nonzero, and any other ERC-20 when A tracked token is shown when its balance is nonzero, and any other ERC-20 when
its balance is nonzero and it is in the bundled known-token list or has 1,000 or its balance is nonzero and it is in the bundled known-token list or has 1,000 or
@@ -1662,9 +1657,9 @@ the stack, as a network switch does (below). The cut drops Send, whose token
dropdown was filled under the old setting. "Back" cannot render Send again. A dropdown was filled under the old setting. "Back" cannot render Send again. A
change to "Check recipients on Etherscan" leaves the stack as it is. change to "Check recipients on Etherscan" leaves the stack as it is.
Any other open popup takes either change from the stored record, as it takes a Any other popup open meanwhile takes either change from the stored record, as it
network switch (below). That popup then redraws its top screen as a reopened takes a network switch (below). It then draws its screen on top again as a
popup would. So Home takes the place of a screen such as Send. reopened popup draws it, so Home takes the place of a screen such as Send.
A network switch leaves every screen on the page showing the previous network. A network switch leaves every screen on the page showing the previous network.
The user makes it in Settings, or approves a site's request and the background The user makes it in Settings, or approves a site's request and the background
@@ -1707,9 +1702,8 @@ view would leave a wallet one click from deletion.
screen in that case. screen in that case.
- **Elements**: - **Elements**:
- "Welcome! To get started, add a wallet." text - "Welcome! To get started, add a wallet." text
- A well with a line about the user's data. The wallet sends that data only - A well with a line saying that the wallet sends the user's data only to
to the Ethereum RPC endpoint, unless one of the two checkboxes below is the Ethereum RPC endpoint unless one of the two checkboxes below is ticked
ticked
- In the well, the "Use Blockscout" and "Check recipients on Etherscan" - In the well, the "Use Blockscout" and "Check recipients on Etherscan"
checkboxes, the same two as in Settings. Each has a sentence saying what checkboxes, the same two as in Settings. Each has a sentence saying what
it sends and where. Both are unticked until the user ticks them it sends and where. Both are unticked until the user ticks them
@@ -1990,11 +1984,11 @@ view would leave a wallet one click from deletion.
a contract, burn address, and an Etherscan phishing/scam label. An address a contract, burn address, and an Etherscan phishing/scam label. An address
that has received ETH but never sent a transaction still holds that ETH, that has received ETH but never sent a transaction still holds that ETH,
so it gets no warning. The Etherscan label check is made only while "Check so it gets no warning. The Etherscan label check is made only while "Check
recipients on Etherscan" is on. While the setting is off, the Etherscan recipients on Etherscan" is on. While it is off, the Etherscan box is left
box is left out. A line in its place says "This address was not checked on out. A line in its place says "This address was not checked on Etherscan,
Etherscan, because "Check recipients on Etherscan" is off in Settings." because "Check recipients on Etherscan" is off in Settings." The box or
The box or the line is chosen when the screen is drawn, so neither moves the line is chosen when the screen is drawn, so neither moves anything
anything later later
- Errors (an invalid amount), plus five reserved error boxes, so the balance - Errors (an invalid amount), plus five reserved error boxes, so the balance
and the fee arriving later move nothing — the amount exceeds the balance and the fee arriving later move nothing — the amount exceeds the balance
(for a token whose scale is unknown it says the token's balance is (for a token whose scale is unknown it says the token's balance is
@@ -2106,8 +2100,9 @@ view would leave a wallet one click from deletion.
- **Elements**: - **Elements**:
- "Transaction Confirmed" heading - "Transaction Confirmed" heading
- Decoded action well (shown when the transaction carried recognized - Decoded action well (shown when the transaction carried recognized
calldata; the top-level Amount and To are hidden in that case). Each token calldata; the top-level Amount and To are hidden in that case). While "Use
in the well gets TxApproval's line under it, in the same case. Blockscout" is off, it has TxApproval's line under each token whose name
or decimals are missing from the bundled list and the tracked tokens.
- Amount + symbol - Amount + symbol
- To: color dot + full address + etherscan link, or for a contract creation - To: color dot + full address + etherscan link, or for a contract creation
the same sentence as on WaitTx the same sentence as on WaitTx
@@ -2165,11 +2160,11 @@ view would leave a wallet one click from deletion.
AddressToken. The screen describes the transaction on the network it was sent AddressToken. The screen describes the transaction on the network it was sent
on, whichever network is active: its block, network details, decoded details on, whichever network is active: its block, network details, decoded details
and raw data are read from that network's Blockscout, the one Settings has for and raw data are read from that network's Blockscout, the one Settings has for
it, and its etherscan links open that network's explorer. While "Use it, and its etherscan links open that network's explorer. The block, network
Blockscout" is off, Blockscout is not asked. One line then takes the place of details, decoded details and raw data are read only while "Use Blockscout" is
the block, network details, decoded details and raw data: "This screen shows on. While it is off, a line in their place says "No block, decoded details,
no block, decoded details, network details or raw data, because "Use network details or raw data are shown, because "Use Blockscout" is off in
Blockscout" is off in Settings." Settings."
- **Elements** (grouped into logical blocks using light well containers; field - **Elements** (grouped into logical blocks using light well containers; field
labels are self-explanatory so groups have no headings): labels are self-explanatory so groups have no headings):
- "Transaction" heading, "Back" button - "Transaction" heading, "Back" button
@@ -2254,17 +2249,17 @@ view would leave a wallet one click from deletion.
`eth_chainId` before being saved) `eth_chainId` before being saved)
- Blockscout API: - Blockscout API:
- "Use Blockscout" checkbox, unticked until the user ticks it - "Use Blockscout" checkbox, unticked until the user ticks it
- A sentence saying what the setting shows and what it sends. With the - A sentence saying what it shows and what it sends. It sends the
setting on, the wallet sends the Blockscout API the user's addresses Blockscout API the user's addresses and the hash of each transaction
and the hash of each transaction opened opened
- Endpoint URL input + "Save" button. "Save" checks the URL by asking it - Endpoint URL input + "Save" button. "Save" checks the URL by asking it
for `/stats` before saving it. That request carries no user data. It for `/stats` before saving it. That request carries no user data. It
is made whether or not "Use Blockscout" is ticked. is made whether or not "Use Blockscout" is ticked.
- Etherscan: - Etherscan:
- "Check recipients on Etherscan" checkbox, unticked until the user - "Check recipients on Etherscan" checkbox, unticked until the user
ticks it ticks it
- A sentence saying the setting sends each recipient's address to - A sentence saying it sends each recipient's address to Etherscan to
Etherscan, to check the address for a phishing or scam label check it for a phishing or scam label
- Each of the two settings applies to every network. Welcome offers the same - Each of the two settings applies to every network. Welcome offers the same
two checkboxes two checkboxes
- Token Spam Protection: - Token Spam Protection:
@@ -2291,10 +2286,9 @@ view would leave a wallet one click from deletion.
turns on the red banner and verbose logging turns on the red banner and verbose logging
- **Transitions**: - **Transitions**:
- Ticking or unticking "Use Blockscout" or "Check recipients on Etherscan" → - Ticking or unticking "Use Blockscout" or "Check recipients on Etherscan" →
stores the setting (no screen change). The next balance refresh uses the stores the setting (no screen change). The next balance refresh and every
new setting. So does every screen drawn after that. Unticking "Use screen drawn after that follow it. Unticking "Use Blockscout" also drops
Blockscout" also drops every token the user has not tracked from every every token the user has not tracked from every address
address
- "+ Add wallet" → **AddWallet** - "+ Add wallet" → **AddWallet**
- "+ Add token" → **SettingsAddToken** - "+ Add token" → **SettingsAddToken**
- `[recovery phrase]` on an HD wallet → **ShowRecoveryPhrase** - `[recovery phrase]` on an HD wallet → **ShowRecoveryPhrase**
@@ -2836,9 +2830,9 @@ settings:
Both settings are on the Welcome screen and in Settings. Both are off in a new Both settings are on the Welcome screen and in Settings. Both are off in a new
install. Each setting applies to every network. install. Each setting applies to every network.
Before each of these requests, the wallet reads its setting from storage. The Before each of these requests, the wallet reads its setting from storage. It
wallet reads the setting again when the answer lands. While the setting is off, reads it again when the answer lands. While the setting is off, nothing is
nothing is asked, and an answer that lands is dropped. asked, and an answer that lands is dropped.
Contacted by default: Contacted by default:
@@ -2847,10 +2841,10 @@ Contacted by default:
them the balance of every tracked token at every address (`balanceOf`), them the balance of every tracked token at every address (`balanceOf`),
estimate gas (`eth_estimateGas`), fetch nonces (`eth_getTransactionCount`), estimate gas (`eth_estimateGas`), fetch nonces (`eth_getTransactionCount`),
broadcast transactions (`eth_sendRawTransaction`), and check transaction broadcast transactions (`eth_sendRawTransaction`), and check transaction
receipts. Every ENS lookup is made through it alone. So a name does not receipts. Every ENS lookup is made through it alone. A name whose resolver
resolve when its resolver says the name is resolved off-chain. The default says it is resolved off-chain therefore does not resolve. The default endpoint
endpoint is a public RPC (configurable by the user to any endpoint they is a public RPC (configurable by the user to any endpoint they prefer,
prefer, including a local node). By default the extension talks to including a local node). By default the extension talks to
`https://ethereum-rpc.publicnode.com`. `https://ethereum-rpc.publicnode.com`.
- **Data sent**: Ethereum addresses, transaction data, contract call - **Data sent**: Ethereum addresses, transaction data, contract call
parameters. The RPC endpoint can see all on-chain queries and submitted parameters. The RPC endpoint can see all on-chain queries and submitted
@@ -2884,9 +2878,9 @@ Sent the user's data only while the user has turned the setting on:
- **While the setting is off**: each of those screens shows a line saying - **While the setting is off**: each of those screens shows a line saying
what it leaves out and that "Use Blockscout" is off. Only tracked tokens what it leaves out and that "Use Blockscout" is off. Only tracked tokens
are listed. are listed.
- **Saving the URL**: pressing "Save" beside the URL in Settings asks that - **Saving the URL**: whether or not the setting is on, pressing "Save"
URL for `/stats`, whether or not the setting is on. This request carries beside the URL in Settings asks that URL for `/stats`. This request
no user data. carries no user data.
- **Data sent**: Ethereum addresses, and the hash of each transaction the - **Data sent**: Ethereum addresses, and the hash of each transaction the
user opens. Blockscout receives the user's addresses to query their user opens. Blockscout receives the user's addresses to query their
transaction history and token balances. No private keys, passwords, or transaction history and token balances. No private keys, passwords, or
@@ -2894,10 +2888,9 @@ Sent the user's data only while the user has turned the setting on:
- **Etherscan address labels** ("Check recipients on Etherscan"): While the - **Etherscan address labels** ("Check recipients on Etherscan"): While the
setting is on, ConfirmTx looks up the recipient's address on Etherscan each setting is on, ConfirmTx looks up the recipient's address on Etherscan each
time the screen is shown. The lookup checks for a phishing or scam label, time it is shown. It checks for a phishing or scam label, best-effort. This is
best-effort. This is a direct page fetch with no API key; the user's browser a direct page fetch with no API key; the user's browser makes the request.
makes the request. While the setting is off, ConfirmTx says that no Etherscan While the setting is off, ConfirmTx says that no Etherscan check was made.
check was made.
- **Data sent**: the recipient's address and nothing else. - **Data sent**: the recipient's address and nothing else.
The etherscan links on the screens open a page in the browser when the user The etherscan links on the screens open a page in the browser when the user
+9 -9
View File
@@ -106,7 +106,7 @@ addresses are necessarily visible to the RPC provider when querying balances.
`eth-sepolia.blockscout.com/api/v2` on Sepolia) `eth-sepolia.blockscout.com/api/v2` on Sepolia)
Blockscout is an open-source blockchain explorer. AutistMask sends it your data Blockscout is an open-source blockchain explorer. AutistMask sends it your data
only while "Use Blockscout" is on. AutistMask then asks Blockscout for: only while "Use Blockscout" is on. It then asks Blockscout for:
- your recent transactions and token transfers - your recent transactions and token transfers
- the balances of the tokens you have not tracked, with the holder counts used - the balances of the tokens you have not tracked, with the holder counts used
@@ -124,8 +124,8 @@ When it is contacted, while "Use Blockscout" is on:
- whenever a screen showing transaction history is opened - whenever a screen showing transaction history is opened
- when you open a transaction - when you open a transaction
Pressing "Save" beside the Blockscout URL in Settings asks that URL for `/stats` Whether or not the setting is on, pressing "Save" beside the Blockscout URL in
to check it, whether or not the setting is on. That request sends none of your Settings asks that URL for `/stats` to check it. That request sends none of your
data. data.
What gets sent: your Ethereum addresses (to look up balances and transactions) What gets sent: your Ethereum addresses (to look up balances and transactions)
@@ -147,7 +147,7 @@ address.
**Etherscan address labels** (`etherscan.io`; `sepolia.etherscan.io` on Sepolia) **Etherscan address labels** (`etherscan.io`; `sepolia.etherscan.io` on Sepolia)
While "Check recipients on Etherscan" is on, AutistMask fetches the recipient's While "Check recipients on Etherscan" is on, AutistMask fetches the recipient's
public Etherscan address page when you review a send. AutistMask looks for a public Etherscan address page when you review a send. It looks for a
"Fake_Phishing"/"Phish/Hack" label or a scam warning, and shows a red warning if "Fake_Phishing"/"Phish/Hack" label or a scam warning, and shows a red warning if
it finds one. This is a plain page fetch with no API key, made by your browser. it finds one. This is a plain page fetch with no API key, made by your browser.
It is best-effort: if it fails, it is silently ignored. This endpoint is not It is best-effort: if it fails, it is silently ignored. This endpoint is not
@@ -252,14 +252,14 @@ always produce the same sequence of addresses.
### Adding ERC-20 Tokens ### Adding ERC-20 Tokens
The wallet finds the tokens you hold by itself only while "Use Blockscout" is Tokens you hold show up automatically only while "Use Blockscout" is on. Even
on. Even then, a token shows up only if it is in the extension's bundled list of then, a token shows up only if it is in the extension's bundled list of
well-known tokens or has at least 1,000 holders. Everything else is treated as well-known tokens or has at least 1,000 holders. Everything else is treated as
spam and hidden. spam and hidden.
The wallet shows every token you track, whether or not "Use Blockscout" is on. A token you track is shown whether or not "Use Blockscout" is on. By default it
By default a tracked token is shown at zero balance too (see Display in is shown at zero balance too (see Display in Settings). To track a token, add it
Settings). To track a token, add it by contract address: by contract address:
1. Go to an address detail view (click `[info]` on any address). 1. Go to an address detail view (click `[info]` on any address).
2. Click "+ Token". 2. Click "+ Token".
+2 -2
View File
@@ -1392,8 +1392,8 @@ const RECENT_BALANCE_REFRESH_MS = Math.floor(BALANCE_REFRESH_PERIOD_MS / 2);
// the new network. // the new network.
// //
// Blockscout may have answered before the user turned "Use Blockscout" off. So // Blockscout may have answered before the user turned "Use Blockscout" off. So
// the save drops every token the user has not tracked if storage NOW holds "Use // when "Use Blockscout" stored NOW is off, the save drops every token the user
// Blockscout" off. // has not tracked.
async function backgroundRefresh() { async function backgroundRefresh() {
const s = await getState(); const s = await getState();
const now = Date.now(); const now = Date.now();
+9 -9
View File
@@ -56,9 +56,9 @@
Use Blockscout Use Blockscout
</label> </label>
<p class="text-xs text-muted mb-2"> <p class="text-xs text-muted mb-2">
Shows transaction history, transaction details and the Shows transaction history, tokens you have not tracked
tokens you have not tracked. Sends your addresses, and and transaction details. Sends your addresses, and the
the hash of each transaction you open, to the Blockscout hash of each transaction you open, to the Blockscout
API. API.
</p> </p>
<label <label
@@ -1072,10 +1072,10 @@
Use Blockscout Use Blockscout
</label> </label>
<p class="text-xs text-muted mb-2"> <p class="text-xs text-muted mb-2">
Shows transaction history, transaction details and the Shows transaction history, tokens you have not tracked
tokens you have not tracked. Sends your addresses, and and transaction details. Sends your addresses, and the
the hash of each transaction you open, to the Blockscout hash of each transaction you open, to the Blockscout API
API below. below.
</p> </p>
<p class="text-xs text-muted mb-1"> <p class="text-xs text-muted mb-1">
Change this if you run your own Blockscout instance. Change this if you run your own Blockscout instance.
@@ -1608,8 +1608,8 @@
id="tx-detail-blockscout-note" id="tx-detail-blockscout-note"
class="text-xs text-muted mx-1 mb-3 hidden" class="text-xs text-muted mx-1 mb-3 hidden"
> >
This screen shows no block, decoded details, network details No block, decoded details, network details or raw data are
or raw data, because "Use Blockscout" is off in Settings. shown, because "Use Blockscout" is off in Settings.
</p> </p>
<!-- ── Decoded details ── --> <!-- ── Decoded details ── -->
+11 -12
View File
@@ -71,9 +71,8 @@ let refreshInFlight = false;
// the recovery screen: there is no profile left to refresh. // the recovery screen: there is no profile left to refresh.
let refreshTimer = null; let refreshTimer = null;
// The refresh first takes the stored network, "Use Blockscout" and "Check // The refresh first takes any change to the network or to either setting saved
// recipients on Etherscan" (followStoredSettings() below). So it draws its // elsewhere (followStoredSettings() below), so what it draws follows them.
// screens under any change saved elsewhere.
// //
// The refresh writes into a copy of the wallets. Inside the save, under the // The refresh writes into a copy of the wallets. Inside the save, under the
// lock, its results are copied onto the address records in `state` only if the // lock, its results are copied onto the address records in `state` only if the
@@ -86,8 +85,8 @@ let refreshTimer = null;
// (https://git.eeqj.de/sneak/AutistMask/issues/577). A dropped refresh is not // (https://git.eeqj.de/sneak/AutistMask/issues/577). A dropped refresh is not
// recorded as done. Results are copied by address, so an address added or // recorded as done. Results are copied by address, so an address added or
// removed meanwhile is left as it is. Blockscout may have answered before the // removed meanwhile is left as it is. Blockscout may have answered before the
// user turned "Use Blockscout" off. So the save drops every token the user has // user turned "Use Blockscout" off. So if the stored setting is off when the
// not tracked if the stored setting is off by then. // refresh saves, the save drops every token the user has not tracked.
async function doRefreshAndRender() { async function doRefreshAndRender() {
if (refreshInFlight) return; if (refreshInFlight) return;
refreshInFlight = true; refreshInFlight = true;
@@ -240,9 +239,9 @@ function fallbackView() {
// here while this waits for the lock is made after it. // here while this waits for the lock is made after it.
// //
// Another page may change "Use Blockscout" or "Check recipients on Etherscan". // Another page may change "Use Blockscout" or "Check recipients on Etherscan".
// This page takes either change the same way and draws its screens again. This // This page takes either change the same way and draws its screens again. Its
// page's own changes to the two settings are made under the lock too // own changes to them are made under the lock too (views/settings.js,
// (views/settings.js, views/welcome.js). // views/welcome.js).
async function followStoredSettings() { async function followStoredSettings() {
let changed = false; let changed = false;
// A failed save is reported by saveState() itself: see onSaveFailure(). // A failed save is reported by saveState() itself: see onSaveFailure().
@@ -414,10 +413,10 @@ async function init() {
settingsAddToken.init(ctx); settingsAddToken.init(ctx);
deleteAddress.init(ctx); deleteAddress.init(ctx);
// This page follows a record only when its network, "Use Blockscout" or // Only a record whose network, "Use Blockscout" or "Check recipients on
// "Check recipients on Etherscan" differs from this page's. A record // Etherscan" differs from this page's is followed. A record this page's
// written by this page's own save matches this page. A record naming no // own save wrote matches this page. A record naming no network is no
// network is no switch. // switch.
onStorageChanged((changes) => { onStorageChanged((changes) => {
const written = changes.autistmask && changes.autistmask.newValue; const written = changes.autistmask && changes.autistmask.newValue;
if (!written || !written.networkId) return; if (!written || !written.networkId) return;
+2 -2
View File
@@ -46,8 +46,8 @@ function markViewRendered(view) {
// - after "Use Blockscout" or "Check recipients on Etherscan" changes, here // - after "Use Blockscout" or "Check recipients on Etherscan" changes, here
// or on another page, since those screens were drawn under the old setting // or on another page, since those screens were drawn under the old setting
// //
// The unit tests ask for one too. They simulate several page loads against one // The unit tests, which simulate several page loads against one module
// module instance. // instance, ask for one too.
function resetRenderedViews() { function resetRenderedViews() {
renderedViews.clear(); renderedViews.clear();
} }
+1 -1
View File
@@ -84,7 +84,7 @@ function show() {
ctx.showAddressToken(); ctx.showAddressToken();
}); });
}); });
// Only Blockscout reports the tokens the user has not tracked. // Tokens the user has not tracked are Blockscout's to report.
$("address-tokens-note").classList.toggle("hidden", !!state.useBlockscout); $("address-tokens-note").classList.toggle("hidden", !!state.useBlockscout);
renderSendTokenSelect(addr); renderSendTokenSelect(addr);
$("tx-list").innerHTML = $("tx-list").innerHTML =
+1 -1
View File
@@ -119,7 +119,7 @@ function show(walletIdx, addrIdx) {
$("delete-address-recovery").textContent = recoveryPathText(wallet); $("delete-address-recovery").textContent = recoveryPathText(wallet);
$("delete-address-balance").innerHTML = balanceWarningHtml(addr); $("delete-address-balance").innerHTML = balanceWarningHtml(addr);
// Only Blockscout reports the tokens the user has not tracked. // Tokens the user has not tracked are Blockscout's to report.
$("delete-address-tokens-note").classList.toggle( $("delete-address-tokens-note").classList.toggle(
"hidden", "hidden",
!!state.useBlockscout, !!state.useBlockscout,
+8 -9
View File
@@ -326,12 +326,12 @@ function tokenSourcesByChainId(chainId) {
}; };
} }
// The line shown under a token while "Use Blockscout" is off. The token gets // The line shown under a token while "Use Blockscout" is off, when its name or
// the line only when the bundled list and the tracked tokens lack its name or // decimals are missing from the bundled list and the tracked tokens. Otherwise
// decimals. Otherwise this returns "". The token is a contract address on the // "". The token is a contract address on the network with `chainId`, or on the
// network with `chainId`, or on the active network when none is given. "ETH" // active network when none is given. "ETH" and null are no contract, and get
// and null are no contract, and get "". A token that is not text also gets "": // "". A token that is not text also gets "": WaitTx and ErrorTx pass a token
// WaitTx and ErrorTx pass a token restored from storage unchecked. // restored from storage unchecked.
function blockscoutOffTokenNoteHtml(token, chainId) { function blockscoutOffTokenNoteHtml(token, chainId) {
if (typeof token !== "string") return ""; if (typeof token !== "string") return "";
if (state.useBlockscout || !token || token === "ETH") return ""; if (state.useBlockscout || !token || token === "ETH") return "";
@@ -571,9 +571,8 @@ function addressTitle(address, wallets) {
const CONTRACT_CREATION_TEXT = const CONTRACT_CREATION_TEXT =
"This transaction creates a new contract. It has no recipient."; "This transaction creates a new contract. It has no recipient.";
// The line shown in place of the transaction history on Home, AddressDetail and // What the transaction lists on Home, AddressDetail and AddressToken say while
// AddressToken while "Use Blockscout" is off. That history comes from // the user has "Use Blockscout" off. Their history comes from Blockscout alone.
// Blockscout alone.
const HISTORY_OFF_TEXT = const HISTORY_OFF_TEXT =
'No transaction history is shown, because "Use Blockscout" is off in Settings.'; 'No transaction history is shown, because "Use Blockscout" is off in Settings.';
+1 -1
View File
@@ -305,7 +305,7 @@ function walletListHtml() {
function render(ctx) { function render(ctx) {
const container = $("wallet-list"); const container = $("wallet-list");
// Only Blockscout reports the tokens the user has not tracked. // Tokens the user has not tracked are Blockscout's to report.
$("home-tokens-note").classList.toggle("hidden", !!state.useBlockscout); $("home-tokens-note").classList.toggle("hidden", !!state.useBlockscout);
if (state.wallets.length === 0) { if (state.wallets.length === 0) {
container.innerHTML = container.innerHTML =
+1 -1
View File
@@ -142,7 +142,7 @@ function updateToValidation() {
} }
function renderSendTokenSelect(addr) { function renderSendTokenSelect(addr) {
// Only Blockscout reports the tokens the user has not tracked. // Tokens the user has not tracked are Blockscout's to report.
$("send-tokens-note").classList.toggle("hidden", !!state.useBlockscout); $("send-tokens-note").classList.toggle("hidden", !!state.useBlockscout);
const sel = $("send-token"); const sel = $("send-token");
sel.innerHTML = `<option value="ETH">${escapeHtml(nativeCurrency())}</option>`; sel.innerHTML = `<option value="ETH">${escapeHtml(nativeCurrency())}</option>`;
+1 -1
View File
@@ -311,7 +311,7 @@ function populateOnChainDetails(txData, chainId) {
// Reads the block, network details and calldata from Blockscout, and decodes // Reads the block, network details and calldata from Blockscout, and decodes
// the calldata. While the stored "Use Blockscout" is off, Blockscout is not // the calldata. While the stored "Use Blockscout" is off, Blockscout is not
// asked. An answer that lands after the setting went off is dropped // asked, and an answer that lands after it went off is dropped
// (src/shared/storedSettings.js). Either way none of them is shown. // (src/shared/storedSettings.js). Either way none of them is shown.
async function loadFullTxDetails(txHash, chainId) { async function loadFullTxDetails(txHash, chainId) {
if (!(await storedSettingIsOn("useBlockscout"))) return; if (!(await storedSettingIsOn("useBlockscout"))) return;
+5 -5
View File
@@ -3,7 +3,7 @@
// - ETH balances, and the balances of the tokens the user tracks, via RPC // - ETH balances, and the balances of the tokens the user tracks, via RPC
// - the other ERC-20 token balances and the holder counts via Blockscout, // - the other ERC-20 token balances and the holder counts via Blockscout,
// while the user has "Use Blockscout" on. Those balances are dropped when // while the user has "Use Blockscout" on. Those balances are dropped when
// the setting is off. // it is off.
// - ENS reverse lookup via RPC // - ENS reverse lookup via RPC
const { const {
@@ -96,10 +96,10 @@ function rawUnits(value) {
// Fetch token balances for a single address from Blockscout. // Fetch token balances for a single address from Blockscout.
// Returns [{ address, name, symbol, decimals, balance, holders }]. // Returns [{ address, name, symbol, decimals, balance, holders }].
// //
// While the stored "Use Blockscout" is off, Blockscout is not asked. An answer // While the stored "Use Blockscout" is off, Blockscout is not asked, and an
// that lands after the setting went off is dropped // answer that lands after it went off is dropped (src/shared/storedSettings.js).
// (src/shared/storedSettings.js). Either way this returns an empty list, so // Either way the answer is an empty list, so no token the user has not tracked
// only tracked tokens are listed. // is listed.
// //
// Filters out spam: only shows tokens that are in the known token list, // Filters out spam: only shows tokens that are in the known token list,
// explicitly tracked by the user, or have >= 1000 holders. A tracked token's // explicitly tracked by the user, or have >= 1000 holders. A tracked token's
+1 -1
View File
@@ -80,7 +80,7 @@ function parseEtherscanPage(html) {
* Sepolia. * Sepolia.
* *
* While the stored "Check recipients on Etherscan" is off, Etherscan is not * While the stored "Check recipients on Etherscan" is off, Etherscan is not
* asked. An answer that lands after the setting went off is dropped * asked, and an answer that lands after it went off is dropped
* (src/shared/storedSettings.js). Either way the answer is null. * (src/shared/storedSettings.js). Either way the answer is null.
* *
* @param {string} address - Ethereum address to check. * @param {string} address - Ethereum address to check.
+4 -5
View File
@@ -469,11 +469,10 @@ function mergeNetworkEndpoints(base, ours, theirs) {
// exists to remove, just delayed and confined to one page instead of two // exists to remove, just delayed and confined to one page instead of two
// (caught by tests/txStatus.test.js). A page's live picture of a field it // (caught by tests/txStatus.test.js). A page's live picture of a field it
// does not own goes on being whatever its last loadState() saw, same as // does not own goes on being whatever its last loadState() saw, same as
// before this fix; only the persisted record is guaranteed current. Three // before this fix; only the persisted record is guaranteed current. The
// fields are the exceptions: the network, "Use Blockscout" and "Check // network, "Use Blockscout" and "Check recipients on Etherscan" are the
// recipients on Etherscan". Through `beforeWrite`, the popup takes a change to // exceptions: the popup takes a change another context saved through
// any of them that another context saved (followStoredSettings() in // `beforeWrite` (followStoredSettings() in src/popup/index.js).
// src/popup/index.js).
async function saveStateOnce(beforeWrite) { async function saveStateOnce(beforeWrite) {
const result = await storageGet("autistmask"); const result = await storageGet("autistmask");
// The record in storage right now is about to be merged into and written // The record in storage right now is about to be merged into and written
+3 -4
View File
@@ -2,10 +2,9 @@
// profile. // profile.
// //
// Before each request to Blockscout or Etherscan, the wallet reads its setting // Before each request to Blockscout or Etherscan, the wallet reads its setting
// from storage. The wallet reads the setting again when the answer lands. While // from storage. It reads it again when the answer lands. While the setting is
// the setting is off, nothing is asked, and an answer that lands is dropped. A // off, nothing is asked, and an answer that lands is dropped. A page's own copy
// page's own copy of the setting is not used, because another page may have // of the setting is not used, because another page may have just changed it.
// just changed it.
const { storageGet } = require("./browserApi"); const { storageGet } = require("./browserApi");
const { normalizePersisted } = require("./persistedState"); const { normalizePersisted } = require("./persistedState");
+3 -3
View File
@@ -237,9 +237,9 @@ function mergeTransactions(txs, tokenTransfers) {
// carries it, and a native entry is labelled with that network's // carries it, and a native entry is labelled with that network's
// `nativeCurrency` from networks.js (`ETH`, `SepoliaETH`). // `nativeCurrency` from networks.js (`ETH`, `SepoliaETH`).
// //
// While the stored "Use Blockscout" is off, Blockscout is not asked. An answer // While the stored "Use Blockscout" is off, Blockscout is not asked, and an
// that lands after the setting went off is dropped // answer that lands after it went off is dropped (src/shared/storedSettings.js).
// (src/shared/storedSettings.js). Either way the answer is an empty list. // Either way the answer is an empty list.
async function fetchRecentTransactions( async function fetchRecentTransactions(
address, address,
blockscoutUrl, blockscoutUrl,
+6 -7
View File
@@ -1,10 +1,9 @@
// While "Use Blockscout" is off, the approval screens, and the screens that // While "Use Blockscout" is off, the approval screens and the screens after
// follow TxApproval, take a token's name and scale from the bundled list and // TxApproval name a token, and scale its amount, from the bundled list and the
// the tracked tokens alone (https://git.eeqj.de/sneak/AutistMask/issues/668). // tracked tokens alone (https://git.eeqj.de/sneak/AutistMask/issues/668). A
// A token missing from both gets a line under it. The line says Blockscout's // token they lack gets a line saying Blockscout's report of the user's balances
// report of the user's balances is not used to name the token. While the // is not used to name it. While the setting is on, Blockscout's report of the
// setting is on, the token's name and scale come from Blockscout's report of // user's holding names and scales the token, as before.
// the user's holding, as before.
// //
// Booted through the real popup entry point, as the approval window or as a // Booted through the real popup entry point, as the approval window or as a
// popup reopened onto SuccessTx, WaitTx or ErrorTx. The vault is mocked so that // popup reopened onto SuccessTx, WaitTx or ErrorTx. The vault is mocked so that
+22 -27
View File
@@ -1,24 +1,24 @@
// Blockscout and Etherscan are sent none of the user's data until the user // Blockscout and Etherscan are sent none of the user's data until the user
// turns them on (https://git.eeqj.de/sneak/AutistMask/issues/668). A new // turns them on (https://git.eeqj.de/sneak/AutistMask/issues/668). A new
// profile has "Use Blockscout" and "Check recipients on Etherscan" both off. // profile has "Use Blockscout" and "Check recipients on Etherscan" both off.
// While a setting is off, no code asks its service. // While a setting is off, the code that would ask its service asks nothing.
// //
// Only one request is made with the setting off: the check behind "Save" beside // The one request made with the setting off is the check behind "Save" beside
// the Blockscout URL in Settings. That check asks the URL only for `/stats` and // the Blockscout URL in Settings. It asks that URL only for `/stats` and sends
// sends none of the user's data. // none of the user's data.
// //
// Before any other request to Blockscout or Etherscan, the wallet reads its // Before any other request to Blockscout or Etherscan, the wallet reads its
// setting from storage, not the page's copy. The wallet reads the setting again // setting from storage, not the page's copy. It reads it again when the answer
// when the answer lands. So a change saved by another page applies at once. An // lands. So a change another page saved applies at once. An open page also
// open page also takes such a change and draws its screens again. // takes such a change and draws its screens again.
// //
// Only Blockscout reports the tokens the user has not tracked. While "Use // Only Blockscout reports the tokens the user has not tracked. While "Use
// Blockscout" is off, no address keeps them and no screen lists them. // Blockscout" is off, no address keeps them and no screen lists them.
// //
// The functions that make the requests are driven directly, against a fetch() // The functions that make the requests are driven directly, against a fetch()
// that records every URL it is asked for. The screens are driven through the // that records every URL it is asked for. The screens are driven through the
// real popup over a stored profile (tests/support/popupBoot.js). The fetch() // real popup over a stored profile (tests/support/popupBoot.js). Its fetch()
// stub in popupBoot.js records the same way. // stub records the same way.
"use strict"; "use strict";
@@ -109,7 +109,7 @@ describe("a new profile", () => {
}); });
describe("where each request is made", () => { describe("where each request is made", () => {
// Every URL that fetch() was asked for, in order. // Every URL fetch() was asked for, in order.
let asked; let asked;
// What Blockscout and Etherscan answer: USDC among ADDRESS's tokens, // What Blockscout and Etherscan answer: USDC among ADDRESS's tokens,
@@ -208,8 +208,8 @@ describe("where each request is made", () => {
}); });
// Asks with `setting` on in storage. Once every request is out, storage // Asks with `setting` on in storage. Once every request is out, storage
// holds `after` for the setting, as when the user changes it here or on // holds `after` for it, as when the user changes it here or on another
// another page. Only then does each request get its answer. // page. Only then does each request get its answer.
async function answeredAfter(setting, after, ask) { async function answeredAfter(setting, after, ask) {
storing({ [setting]: true }); storing({ [setting]: true });
let release; let release;
@@ -232,12 +232,8 @@ describe("where each request is made", () => {
return result; return result;
} }
// One row per request, giving: // Each request, the setting that gates it, how to make it, and its answer
// // while that setting is off.
// - its name
// - the setting that gates it
// - how to make it
// - its answer while that setting is off
test.each([ test.each([
[ [
"Blockscout's token balances", "Blockscout's token balances",
@@ -294,8 +290,8 @@ describe("where each request is made", () => {
FetchRequest.registerGetUrl(FetchRequest.createGetUrlFunc()); FetchRequest.registerGetUrl(FetchRequest.createGetUrlFunc());
}); });
// An address refreshed while "Use Blockscout" was on. It holds the USDC // An address that was refreshed while Use Blockscout was on, and holds
// that Blockscout reported then. // the USDC Blockscout reported then.
function addressWithUsdc() { function addressWithUsdc() {
return { return {
address: ADDRESS, address: ADDRESS,
@@ -543,9 +539,9 @@ describe("the popup", () => {
); );
}); });
// A token the user tracks, and an untracked one that Blockscout reported. // A token the user tracks, and one Blockscout reported that the user has
// Both are written in lower case, as the balance rows' and the dropdown's // not tracked. Both are written in lower case, as the balance rows' and
// token ids are compared below. // the dropdown's token ids are compared below.
const TRACKED = "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; const TRACKED = "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
const UNTRACKED = TOKEN_ADDRESS.toLowerCase(); const UNTRACKED = TOKEN_ADDRESS.toLowerCase();
const SECOND_ADDRESS = "0x3333333333333333333333333333333333333333"; const SECOND_ADDRESS = "0x3333333333333333333333333333333333333333";
@@ -702,8 +698,8 @@ describe("the popup", () => {
} }
// Turning the setting off dropped the untracked token. A refresh that // Turning the setting off dropped the untracked token. A refresh that
// started while the setting was on still saves its balances when it // started while it was on still saves its balances when it returns, but
// returns, but not that token. The same refresh in the background is in // not that token. The same refresh in the background is in
// tests/backgroundStateIsolation.test.js. // tests/backgroundStateIsolation.test.js.
test("a refresh that returns after Use Blockscout was turned off saves its balances without the untracked token", async () => { test("a refresh that returns after Use Blockscout was turned off saves its balances without the untracked token", async () => {
const page = await bootPopup(onAddressDetail(true)); const page = await bootPopup(onAddressDetail(true));
@@ -798,8 +794,7 @@ describe("the popup", () => {
await page.settle(); await page.settle();
// The page also takes the change and draws ConfirmTx again, which // The page also takes the change and draws ConfirmTx again, which
// checks once more. So the test counts each URL once, however often // checks once more. So each URL asked for is counted once.
// it was asked for.
const asked = new Set( const asked = new Set(
fetched().slice(from).filter(blockscoutOrEtherscan), fetched().slice(from).filter(blockscoutOrEtherscan),
); );
+1 -1
View File
@@ -247,7 +247,7 @@ async function openSend(token, tokenUnits = null) {
state.selectedWallet = 0; state.selectedWallet = 0;
state.selectedAddress = 0; state.selectedAddress = 0;
// Blockscout is asked only while the stored "Use Blockscout" is on. The // Blockscout is asked only while the stored "Use Blockscout" is on. The
// screens save this page's copy of the setting over the stored one. // screens save this page's copy of it over the stored one.
state.useBlockscout = true; state.useBlockscout = true;
await refreshBalances( await refreshBalances(
state.wallets, state.wallets,
+3 -3
View File
@@ -656,9 +656,9 @@ function traceEnabled(raw) {
* @param {string} [opts.etherscanLabel] the label Etherscan's page gives the * @param {string} [opts.etherscanLabel] the label Etherscan's page gives the
* address asked about, such as "Fake_Phishing1"; none when unset. Read at * address asked about, such as "Fake_Phishing1"; none when unset. Read at
* request time. * request time.
* @param {object[]} [opts.requests] a list for the requests this handler * @param {object[]} [opts.requests] every request this handler sees, from the
* sees. Each is appended in order as { method, url, fromWorker }, whether it * popup's pages and the background worker alike, appended in order as
* came from a popup page or the background worker. * { method, url, fromWorker }.
* @returns {Promise<{waitForServiceWorkerTraffic: (ms: number) => * @returns {Promise<{waitForServiceWorkerTraffic: (ms: number) =>
* Promise<string|null>}>} * Promise<string|null>}>}
*/ */
+19 -22
View File
@@ -274,27 +274,24 @@ test("the exact confirmation phrase erases the record and reloads into Welcome (
// A fresh install sends Blockscout and Etherscan none of the user's data until // A fresh install sends Blockscout and Etherscan none of the user's data until
// the user turns on "Use Blockscout" or "Check recipients on Etherscan". One // the user turns on "Use Blockscout" or "Check recipients on Etherscan". One
// request is made with the setting off: pressing "Save" beside the Blockscout // request is made with the setting off: pressing "Save" beside the Blockscout
// URL asks that URL for `/stats`. That request carries no user data. // URL asks that URL for `/stats`. It carries no user data.
// //
// The route handler in tests/e2e/network.js records in env.routeOpts.requests // The route handler in tests/e2e/network.js records every request the
// every request the extension makes, from its pages and its background worker. // extension makes in env.routeOpts.requests, from its pages and its background
// Recording starts when launch() in tests/e2e/harness.js installs that handler, // worker. Recording starts when launch() in tests/e2e/harness.js installs that
// before the first popup page opens. The background worker also makes requests // handler, before the first popup page opens. A request the background worker
// while it starts up. Those come earlier, so they are not recorded. // makes while it starts up comes earlier and is not recorded.
// //
// Before either setting is changed, these tests drive: // Before either setting is changed, these tests drive Home, AddressDetail,
// // AddressToken and ConfirmTx, and the background's own balance refresh. Then
// - Home, AddressDetail, AddressToken and ConfirmTx // they turn each setting on and watch its requests start. "Use Blockscout" is
// - the background's own balance refresh // also turned off once and on again, to see a token the user has not tracked
// // leave every list. TransactionDetail, which also asks Blockscout, is left to
// Then they turn each setting on and watch its requests start. "Use Blockscout" // the unit tests in tests/blockscoutEtherscanSettings.test.js.
// is also turned off once and on again, to see an untracked token leave every
// list. TransactionDetail, which also asks Blockscout, is left to the unit
// tests in tests/blockscoutEtherscanSettings.test.js.
// The line shown in place of the three transaction histories while "Use // What the three transaction lists say while Use Blockscout is off. Written
// Blockscout" is off. Written out here rather than imported, so the assertion // out here rather than imported, so the assertion does not compare the popup
// does not compare the popup with itself. // with itself.
const HISTORY_OFF = const HISTORY_OFF =
'No transaction history is shown, because "Use Blockscout" is off in Settings.'; 'No transaction history is shown, because "Use Blockscout" is off in Settings.';
@@ -402,8 +399,8 @@ test("with neither setting changed, Home, AddressDetail, AddressToken and Confir
}); });
// The background refreshes balances on its alarm, once a minute. It skips a // The background refreshes balances on its alarm, once a minute. It skips a
// refresh when the stored record says one ran in the last 30 seconds. The open // refresh when the stored record says one ran in the last 30 seconds, and the
// popup's own refresh runs every 10. So the popup is closed first. The // open popup's own refresh runs every 10. So the popup is closed first. The
// background worker then writes that record back to say no refresh has run, as // background worker then writes that record back to say no refresh has run, as
// another extension page saving it would. // another extension page saving it would.
test("with neither setting changed, nothing has reached Blockscout or Etherscan, the background's refresh included (#668)", async (env) => { test("with neither setting changed, nothing has reached Blockscout or Etherscan, the background's refresh included (#668)", async (env) => {
@@ -438,7 +435,7 @@ test("with neither setting changed, nothing has reached Blockscout or Etherscan,
); );
await sleep(250); await sleep(250);
} }
// The refresh's RPC reads and any Blockscout request start together. // Its RPC reads and any Blockscout request start together.
await sleep(3000); await sleep(3000);
const seen = explorerRequests(env); const seen = explorerRequests(env);
@@ -452,7 +449,7 @@ test("with neither setting changed, nothing has reached Blockscout or Etherscan,
env.routeOpts.requests.some((r) => !r.fromWorker), env.routeOpts.requests.some((r) => !r.fromWorker),
"no request from the popup was recorded", "no request from the popup was recorded",
); );
// The popup reopens on the address screen the test above left it on. // It reopens on the address screen the test above left it on.
env.page = await openPopup(env.ctx, env.popupUrl); env.page = await openPopup(env.ctx, env.popupUrl);
await visible(env.page, "#view-address"); await visible(env.page, "#view-address");
}); });
+5 -5
View File
@@ -1,14 +1,14 @@
// ENS lookups ask nothing but the RPC endpoint. A resolver can answer that a // ENS lookups ask nothing but the RPC endpoint. A resolver can answer that a
// name is resolved off-chain, naming a web address to fetch the answer from. // name is resolved off-chain, naming a web address to fetch the answer from.
// ethers fetches that address unless the provider has `disableCcipRead` set. // ethers fetches it unless the provider has `disableCcipRead` set. That request
// That request would carry the name to a server other than the RPC endpoint // would carry the name to a server other than the RPC endpoint
// (https://git.eeqj.de/sneak/AutistMask/issues/668). With the flag set, such a // (https://git.eeqj.de/sneak/AutistMask/issues/668). With the flag set, such a
// name does not resolve. // name does not resolve.
// //
// The test builds its provider with getProvider() and runs it against a fake // The test builds its provider with getProvider() and runs it against a fake
// JSON-RPC node. The fake node answers through ethers' own request hook. The // JSON-RPC node. Its answers go through ethers' own request hook, which also
// hook also records the address of every request ethers makes, the off-chain // records the address of every request ethers makes, the off-chain fetch
// fetch included. // included.
const { FetchRequest, Interface } = require("ethers"); const { FetchRequest, Interface } = require("ethers");
const { getProvider } = require("../src/shared/balances"); const { getProvider } = require("../src/shared/balances");
+1 -1
View File
@@ -221,7 +221,7 @@ async function refreshWith(balanceWei, tokenItems = []) {
state.selectedWallet = 0; state.selectedWallet = 0;
state.selectedAddress = 0; state.selectedAddress = 0;
// Blockscout is asked only while the stored "Use Blockscout" is on. The // Blockscout is asked only while the stored "Use Blockscout" is on. The
// screens save this page's copy of the setting over the stored one. // screens save this page's copy of it over the stored one.
state.useBlockscout = true; state.useBlockscout = true;
await refreshBalances( await refreshBalances(
state.wallets, state.wallets,
+1 -1
View File
@@ -217,7 +217,7 @@ async function refreshWith(balanceWei, tokenItems = []) {
state.selectedWallet = 0; state.selectedWallet = 0;
state.selectedAddress = 0; state.selectedAddress = 0;
// Blockscout is asked only while the stored "Use Blockscout" is on. The // Blockscout is asked only while the stored "Use Blockscout" is on. The
// screens save this page's copy of the setting over the stored one. // screens save this page's copy of it over the stored one.
state.useBlockscout = true; state.useBlockscout = true;
await refreshBalances( await refreshBalances(
state.wallets, state.wallets,
+1 -1
View File
@@ -273,7 +273,7 @@ beforeEach(() => {
state.hideLowHolderTokens = false; state.hideLowHolderTokens = false;
state.currentView = null; state.currentView = null;
// The screens save this page's copy of "Use Blockscout" over the stored // The screens save this page's copy of "Use Blockscout" over the stored
// one. So the page's copy is turned on here too. // one, so it is on here too.
state.useBlockscout = true; state.useBlockscout = true;
}); });