1 Commits
Author SHA1 Message Date
sneak e0313de2ef 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 12:44:24 +00:00
26 changed files with 203 additions and 183 deletions

No files matched your search

+69 -62
View File
@@ -15,19 +15,21 @@ 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. It defaults to a public node. Settings. The endpoint 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. It is sent token - a public CoinDesk API (no API key), for realtime prices. The API receives
symbols and nothing else. token 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, for transaction history, - "Use Blockscout": a Blockscout block-explorer API, used for:
the tokens the user has not tracked, and transaction details - transaction history
- 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
@@ -437,13 +439,14 @@ 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. A request the background worker makes while it starts up background worker. The background worker also makes requests while it starts up.
comes earlier and is not recorded. The tests take these steps in order: Those come earlier, so they are not recorded. The tests take these steps in
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, Home, AddressDetail, AddressToken and ConfirmTx must each - With neither ticked, each of these screens must show the line saying what is
show the line saying what is off. off: Home, AddressDetail, AddressToken and ConfirmTx.
- 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
@@ -460,7 +463,7 @@ comes earlier and is not recorded. The tests take these steps in 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 it. unit tests cover that case.
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,
@@ -1165,20 +1168,21 @@ 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`.
It is resolved from these sources, in this order (`resolveTokenDecimals()` in The wallet takes the `decimals` from these sources, in this order
`src/shared/approvalAmount.js`): (`resolveTokenDecimals()` in `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.
These are the active network's only, and they are used only while "Use Those balances cover the active network only. This source is used only while
Blockscout" is on (`tokenSourcesByChainId()` in `src/popup/views/helpers.js`). "Use Blockscout" is on (`tokenSourcesByChainId()` in
`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 it: These screens show the line:
- TxApproval and SignApproval - TxApproval and SignApproval
- WaitTx, SuccessTx and ErrorTx, which follow TxApproval - WaitTx, SuccessTx and ErrorTx, which follow TxApproval
@@ -1221,11 +1225,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, and its stored balance is contract. That token then has no scale on Send. Its stored balance is withdrawn
withdrawn with it. The Send screen's `Current balance` and the confirmation as well. The Send screen's `Current balance` and the confirmation screen's
screen's balance line then both read `unknown (SYMBOL)`. The balance list balance line then both read `unknown (SYMBOL)`. The balance list formats each
formats each explorer row as it is fetched, without that cross-address check, explorer row as it is fetched, without that cross-address check, and shows the
and shows the row's figure. 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
@@ -1456,9 +1460,10 @@ 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 if the Blockscout may answer just before the user turns the setting off. So the popup's
stored setting is off when the refresh saves, in the popup or the background, refresh and the background's both check the stored setting again when they save.
the save drops every token the user has not tracked. If the setting is off by then, the save drops every token the user has not
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
@@ -1657,9 +1662,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 popup open meanwhile takes either change from the stored record, as it Any other open popup takes either change from the stored record, as it takes a
takes a network switch (below). It then draws its screen on top again as a network switch (below). That popup then redraws its top screen as a reopened
reopened popup draws it, so Home takes the place of a screen such as Send. popup would. 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
@@ -1702,8 +1707,9 @@ 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 saying that the wallet sends the user's data only to - A well with a line about the user's data. The wallet sends that data only
the Ethereum RPC endpoint unless one of the two checkboxes below is ticked to the Ethereum RPC endpoint, unless one of the two checkboxes below is
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
@@ -1984,11 +1990,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 it is off, the Etherscan box is left recipients on Etherscan" is on. While the setting is off, the Etherscan
out. A line in its place says "This address was not checked on Etherscan, box is left out. A line in its place says "This address was not checked on
because "Check recipients on Etherscan" is off in Settings." The box or Etherscan, because "Check recipients on Etherscan" is off in Settings."
the line is chosen when the screen is drawn, so neither moves anything The box or the line is chosen when the screen is drawn, so neither moves
later anything 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
@@ -2100,9 +2106,8 @@ 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). While "Use calldata; the top-level Amount and To are hidden in that case). Each token
Blockscout" is off, it has TxApproval's line under each token whose name in the well gets TxApproval's line under it, in the same case.
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
@@ -2160,11 +2165,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. The block, network it, and its etherscan links open that network's explorer. While "Use
details, decoded details and raw data are read only while "Use Blockscout" is Blockscout" is off, Blockscout is not asked. One line then takes the place of
on. While it is off, a line in their place says "No block, decoded details, the block, network details, decoded details and raw data: "This screen shows
network details or raw data are shown, because "Use Blockscout" is off in no block, decoded details, network details or raw data, because "Use
Settings." Blockscout" is off in 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
@@ -2249,17 +2254,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 it shows and what it sends. It sends the - A sentence saying what the setting shows and what it sends. With the
Blockscout API the user's addresses and the hash of each transaction setting on, the wallet sends the Blockscout API the user's addresses
opened and the hash of each transaction 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 it sends each recipient's address to Etherscan to - A sentence saying the setting sends each recipient's address to
check it for a phishing or scam label Etherscan, to check the address 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:
@@ -2286,9 +2291,10 @@ 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 and every stores the setting (no screen change). The next balance refresh uses the
screen drawn after that follow it. Unticking "Use Blockscout" also drops new setting. So does every screen drawn after that. Unticking "Use
every token the user has not tracked from every address Blockscout" also drops every token the user has not tracked from every
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**
@@ -2830,9 +2836,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. It Before each of these requests, the wallet reads its setting from storage. The
reads it again when the answer lands. While the setting is off, nothing is wallet reads the setting again when the answer lands. While the setting is off,
asked, and an answer that lands is dropped. nothing is asked, and an answer that lands is dropped.
Contacted by default: Contacted by default:
@@ -2841,10 +2847,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. A name whose resolver receipts. Every ENS lookup is made through it alone. So a name does not
says it is resolved off-chain therefore does not resolve. The default endpoint resolve when its resolver says the name is resolved off-chain. The default
is a public RPC (configurable by the user to any endpoint they prefer, endpoint is a public RPC (configurable by the user to any endpoint they
including a local node). By default the extension talks to prefer, 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
@@ -2878,9 +2884,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**: whether or not the setting is on, pressing "Save" - **Saving the URL**: pressing "Save" beside the URL in Settings asks that
beside the URL in Settings asks that URL for `/stats`. This request URL for `/stats`, whether or not the setting is on. This request carries
carries no user data. 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
@@ -2888,9 +2894,10 @@ 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 it is shown. It checks for a phishing or scam label, best-effort. This is time the screen is shown. The lookup checks for a phishing or scam label,
a direct page fetch with no API key; the user's browser makes the request. best-effort. This is a direct page fetch with no API key; the user's browser
While the setting is off, ConfirmTx says that no Etherscan check was made. makes the request. While the setting is off, ConfirmTx says that no Etherscan
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. It then asks Blockscout for: only while "Use Blockscout" is on. AutistMask 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
Whether or not the setting is on, pressing "Save" beside the Blockscout URL in Pressing "Save" beside the Blockscout URL in Settings asks that URL for `/stats`
Settings asks that URL for `/stats` to check it. That request sends none of your to check it, whether or not the setting is on. 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. It looks for a public Etherscan address page when you review a send. AutistMask 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
Tokens you hold show up automatically only while "Use Blockscout" is on. Even The wallet finds the tokens you hold by itself only while "Use Blockscout" is
then, a token shows up only if it is in the extension's bundled list of on. Even 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.
A token you track is shown whether or not "Use Blockscout" is on. By default it The wallet shows every token you track, whether or not "Use Blockscout" is on.
is shown at zero balance too (see Display in Settings). To track a token, add it By default a tracked token is shown at zero balance too (see Display in
by contract address: Settings). To track a token, add it 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
// when "Use Blockscout" stored NOW is off, the save drops every token the user // the save drops every token the user has not tracked if storage NOW holds "Use
// has not tracked. // Blockscout" off.
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, tokens you have not tracked Shows transaction history, transaction details and the
and transaction details. Sends your addresses, and the tokens you have not tracked. Sends your addresses, and
hash of each transaction you open, to the Blockscout the 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, tokens you have not tracked Shows transaction history, transaction details and the
and transaction details. Sends your addresses, and the tokens you have not tracked. Sends your addresses, and
hash of each transaction you open, to the Blockscout API the hash of each transaction you open, to the Blockscout
below. API 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"
> >
No block, decoded details, network details or raw data are This screen shows no block, decoded details, network details
shown, because "Use Blockscout" is off in Settings. or raw data, because "Use Blockscout" is off in Settings.
</p> </p>
<!-- ── Decoded details ── --> <!-- ── Decoded details ── -->
+12 -11
View File
@@ -71,8 +71,9 @@ 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 any change to the network or to either setting saved // The refresh first takes the stored network, "Use Blockscout" and "Check
// elsewhere (followStoredSettings() below), so what it draws follows them. // recipients on Etherscan" (followStoredSettings() below). So it draws its
// 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
@@ -85,8 +86,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 if the stored setting is off when the // user turned "Use Blockscout" off. So the save drops every token the user has
// refresh saves, the save drops every token the user has not tracked. // not tracked if the stored setting is off by then.
async function doRefreshAndRender() { async function doRefreshAndRender() {
if (refreshInFlight) return; if (refreshInFlight) return;
refreshInFlight = true; refreshInFlight = true;
@@ -239,9 +240,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. Its // This page takes either change the same way and draws its screens again. This
// own changes to them are made under the lock too (views/settings.js, // page's own changes to the two settings are made under the lock too
// views/welcome.js). // (views/settings.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().
@@ -413,10 +414,10 @@ async function init() {
settingsAddToken.init(ctx); settingsAddToken.init(ctx);
deleteAddress.init(ctx); deleteAddress.init(ctx);
// Only a record whose network, "Use Blockscout" or "Check recipients on // This page follows a record only when its network, "Use Blockscout" or
// Etherscan" differs from this page's is followed. A record this page's // "Check recipients on Etherscan" differs from this page's. A record
// own save wrote matches this page. A record naming no network is no // written by this page's own save matches this page. A record naming no
// switch. // network is no 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, which simulate several page loads against one module // The unit tests ask for one too. They simulate several page loads against one
// instance, ask for one too. // module instance.
function resetRenderedViews() { function resetRenderedViews() {
renderedViews.clear(); renderedViews.clear();
} }
+1 -1
View File
@@ -84,7 +84,7 @@ function show() {
ctx.showAddressToken(); ctx.showAddressToken();
}); });
}); });
// Tokens the user has not tracked are Blockscout's to report. // Only Blockscout reports the tokens the user has not tracked.
$("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);
// Tokens the user has not tracked are Blockscout's to report. // Only Blockscout reports the tokens the user has not tracked.
$("delete-address-tokens-note").classList.toggle( $("delete-address-tokens-note").classList.toggle(
"hidden", "hidden",
!!state.useBlockscout, !!state.useBlockscout,
+9 -8
View File
@@ -326,12 +326,12 @@ function tokenSourcesByChainId(chainId) {
}; };
} }
// The line shown under a token while "Use Blockscout" is off, when its name or // The line shown under a token while "Use Blockscout" is off. The token gets
// decimals are missing from the bundled list and the tracked tokens. Otherwise // the line only when the bundled list and the tracked tokens lack its name or
// "". The token is a contract address on the network with `chainId`, or on the // decimals. Otherwise this returns "". The token is a contract address on the
// active network when none is given. "ETH" and null are no contract, and get // network with `chainId`, or on the active network when none is given. "ETH"
// "". A token that is not text also gets "": WaitTx and ErrorTx pass a token // and null are no contract, and get "". A token that is not text also gets "":
// restored from storage unchecked. // WaitTx and ErrorTx pass a token 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,8 +571,9 @@ 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.";
// What the transaction lists on Home, AddressDetail and AddressToken say while // The line shown in place of the transaction history on Home, AddressDetail and
// the user has "Use Blockscout" off. Their history comes from Blockscout alone. // AddressToken while "Use Blockscout" is off. That history comes from
// 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");
// Tokens the user has not tracked are Blockscout's to report. // Only Blockscout reports the tokens the user has not tracked.
$("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) {
// Tokens the user has not tracked are Blockscout's to report. // Only Blockscout reports the tokens the user has not tracked.
$("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, and an answer that lands after it went off is dropped // asked. An answer that lands after the setting 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
// it is off. // the setting 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, and an // While the stored "Use Blockscout" is off, Blockscout is not asked. An answer
// answer that lands after it went off is dropped (src/shared/storedSettings.js). // that lands after the setting went off is dropped
// Either way the answer is an empty list, so no token the user has not tracked // (src/shared/storedSettings.js). Either way this returns an empty list, so
// is listed. // only tracked tokens are 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, and an answer that lands after it went off is dropped * asked. An answer that lands after the setting 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.
+5 -4
View File
@@ -469,10 +469,11 @@ 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. The // before this fix; only the persisted record is guaranteed current. Three
// network, "Use Blockscout" and "Check recipients on Etherscan" are the // fields are the exceptions: the network, "Use Blockscout" and "Check
// exceptions: the popup takes a change another context saved through // recipients on Etherscan". Through `beforeWrite`, the popup takes a change to
// `beforeWrite` (followStoredSettings() in src/popup/index.js). // any of them that another context saved (followStoredSettings() in
// 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
+4 -3
View File
@@ -2,9 +2,10 @@
// 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. It reads it again when the answer lands. While the setting is // from storage. The wallet reads the setting again when the answer lands. While
// off, nothing is asked, and an answer that lands is dropped. A page's own copy // the setting is off, nothing is asked, and an answer that lands is dropped. A
// of the setting is not used, because another page may have just changed it. // page's own copy of the setting is not used, because another page may have
// 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, and an // While the stored "Use Blockscout" is off, Blockscout is not asked. An answer
// answer that lands after it went off is dropped (src/shared/storedSettings.js). // that lands after the setting went off is dropped
// Either way the answer is an empty list. // (src/shared/storedSettings.js). Either way the answer is an empty list.
async function fetchRecentTransactions( async function fetchRecentTransactions(
address, address,
blockscoutUrl, blockscoutUrl,
+7 -6
View File
@@ -1,9 +1,10 @@
// While "Use Blockscout" is off, the approval screens and the screens after // While "Use Blockscout" is off, the approval screens, and the screens that
// TxApproval name a token, and scale its amount, from the bundled list and the // follow TxApproval, take a token's name and scale from the bundled list and
// tracked tokens alone (https://git.eeqj.de/sneak/AutistMask/issues/668). A // the tracked tokens alone (https://git.eeqj.de/sneak/AutistMask/issues/668).
// token they lack gets a line saying Blockscout's report of the user's balances // A token missing from both gets a line under it. The line says Blockscout's
// is not used to name it. While the setting is on, Blockscout's report of the // report of the user's balances is not used to name the token. While the
// user's holding names and scales the token, as before. // setting is on, the token's name and scale come from Blockscout's report of
// 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
+27 -22
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, the code that would ask its service asks nothing. // While a setting is off, no code asks its service.
// //
// The one request made with the setting off is the check behind "Save" beside // Only one request is made with the setting off: the check behind "Save" beside
// the Blockscout URL in Settings. It asks that URL only for `/stats` and sends // the Blockscout URL in Settings. That check asks the URL only for `/stats` and
// none of the user's data. // sends 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. It reads it again when the answer // setting from storage, not the page's copy. The wallet reads the setting again
// lands. So a change another page saved applies at once. An open page also // when the answer lands. So a change saved by another page applies at once. An
// takes such a change and draws its screens again. // open page also 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). Its fetch() // real popup over a stored profile (tests/support/popupBoot.js). The fetch()
// stub records the same way. // stub in popupBoot.js 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 fetch() was asked for, in order. // Every URL that 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 it, as when the user changes it here or on another // holds `after` for the setting, as when the user changes it here or on
// page. Only then does each request get its answer. // another 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,8 +232,12 @@ describe("where each request is made", () => {
return result; return result;
} }
// Each request, the setting that gates it, how to make it, and its answer // One row per request, giving:
// 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",
@@ -290,8 +294,8 @@ describe("where each request is made", () => {
FetchRequest.registerGetUrl(FetchRequest.createGetUrlFunc()); FetchRequest.registerGetUrl(FetchRequest.createGetUrlFunc());
}); });
// An address that was refreshed while Use Blockscout was on, and holds // An address refreshed while "Use Blockscout" was on. It holds the USDC
// the USDC Blockscout reported then. // that Blockscout reported then.
function addressWithUsdc() { function addressWithUsdc() {
return { return {
address: ADDRESS, address: ADDRESS,
@@ -539,9 +543,9 @@ describe("the popup", () => {
); );
}); });
// A token the user tracks, and one Blockscout reported that the user has // A token the user tracks, and an untracked one that Blockscout reported.
// not tracked. Both are written in lower case, as the balance rows' and // Both are written in lower case, as the balance rows' and the dropdown's
// the dropdown's token ids are compared below. // 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";
@@ -698,8 +702,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 it was on still saves its balances when it returns, but // started while the setting was on still saves its balances when it
// not that token. The same refresh in the background is in // returns, but 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));
@@ -794,7 +798,8 @@ 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 each URL asked for is counted once. // checks once more. So the test counts each URL once, however often
// 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 it over the stored one. // screens save this page's copy of the setting 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] every request this handler sees, from the * @param {object[]} [opts.requests] a list for the requests this handler
* popup's pages and the background worker alike, appended in order as * sees. Each is appended in order as { method, url, fromWorker }, whether it
* { method, url, fromWorker }. * came from a popup page or the background worker.
* @returns {Promise<{waitForServiceWorkerTraffic: (ms: number) => * @returns {Promise<{waitForServiceWorkerTraffic: (ms: number) =>
* Promise<string|null>}>} * Promise<string|null>}>}
*/ */
+22 -19
View File
@@ -274,24 +274,27 @@ 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`. It carries no user data. // URL asks that URL for `/stats`. That request carries no user data.
// //
// The route handler in tests/e2e/network.js records every request the // The route handler in tests/e2e/network.js records in env.routeOpts.requests
// extension makes in env.routeOpts.requests, from its pages and its background // every request the extension makes, from its pages and its background worker.
// worker. Recording starts when launch() in tests/e2e/harness.js installs that // Recording starts when launch() in tests/e2e/harness.js installs that handler,
// handler, before the first popup page opens. A request the background worker // before the first popup page opens. The background worker also makes requests
// makes while it starts up comes earlier and is not recorded. // while it starts up. Those come earlier, so they are not recorded.
// //
// Before either setting is changed, these tests drive Home, AddressDetail, // Before either setting is changed, these tests drive:
// AddressToken and ConfirmTx, and the background's own balance refresh. Then //
// they turn each setting on and watch its requests start. "Use Blockscout" is // - Home, AddressDetail, AddressToken and ConfirmTx
// also turned off once and on again, to see a token the user has not tracked // - the background's own balance refresh
// leave every list. TransactionDetail, which also asks Blockscout, is left to //
// the unit tests in tests/blockscoutEtherscanSettings.test.js. // Then they turn each setting on and watch its requests start. "Use Blockscout"
// 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.
// What the three transaction lists say while Use Blockscout is off. Written // The line shown in place of the three transaction histories while "Use
// out here rather than imported, so the assertion does not compare the popup // Blockscout" is off. Written out here rather than imported, so the assertion
// with itself. // does not compare the popup 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.';
@@ -399,8 +402,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, and the // refresh when the stored record says one ran in the last 30 seconds. The open
// open popup's own refresh runs every 10. So the popup is closed first. The // 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) => {
@@ -435,7 +438,7 @@ test("with neither setting changed, nothing has reached Blockscout or Etherscan,
); );
await sleep(250); await sleep(250);
} }
// Its RPC reads and any Blockscout request start together. // The refresh's RPC reads and any Blockscout request start together.
await sleep(3000); await sleep(3000);
const seen = explorerRequests(env); const seen = explorerRequests(env);
@@ -449,7 +452,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",
); );
// It reopens on the address screen the test above left it on. // The popup 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 it unless the provider has `disableCcipRead` set. That request // ethers fetches that address unless the provider has `disableCcipRead` set.
// would carry the name to a server other than the RPC endpoint // That request 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. Its answers go through ethers' own request hook, which also // JSON-RPC node. The fake node answers through ethers' own request hook. The
// records the address of every request ethers makes, the off-chain fetch // hook also records the address of every request ethers makes, the off-chain
// included. // fetch 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 it over the stored one. // screens save this page's copy of the setting 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 it over the stored one. // screens save this page's copy of the setting 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 it is on here too. // one. So the page's copy is turned on here too.
state.useBlockscout = true; state.useBlockscout = true;
}); });