fix: tracked tokens' balances are read through the RPC endpoint (closes #669)
refreshBalances() now reads the balance of every token tracked on the active network, at every address, with balanceOf through the same provider as the ETH balance. The entry takes its holder count and decimals from Blockscout's entry for the token in the same refresh, or keeps them from before while Blockscout fails. A failed balanceOf keeps the token's previous entry, or takes Blockscout's entry when there is none, and is logged. Blockscout's answer still adds the tokens the user has not tracked, as before. The browser test for a hostile symbol now untracks the stub token first, because a tracked token is listed under the symbol it was added with. Model: opus-5-5
This commit was merged in pull request #670.
This commit is contained in:
@@ -845,7 +845,7 @@ src/
|
||||
views/ — one JS module per screen (home, send, approval, etc.)
|
||||
shared/ — modules used by both popup and background
|
||||
alarms.js — recurring background jobs (extension alarms API)
|
||||
balances.js — ETH + ERC-20 balance fetching via RPC + Blockscout
|
||||
balances.js — ETH and tracked token balances via RPC, others via Blockscout
|
||||
constants.js — chain IDs, default RPC endpoint, ERC-20 ABI
|
||||
ens.js — ENS forward/reverse resolution (popup only)
|
||||
holders.js — holder-count parsing and the low-holder rule
|
||||
@@ -1379,23 +1379,30 @@ The core hierarchy is **Wallets → Addresses**:
|
||||
- The user can have multiple wallets, each with multiple addresses (HD) or a
|
||||
single address (key).
|
||||
|
||||
Which tokens an address shows is decided by `fetchTokenBalances()` in
|
||||
`src/shared/balances.js`, from the Blockscout `token-balances` response, so
|
||||
tokens do appear without the user adding them. An ERC-20 is shown when its
|
||||
balance is nonzero and it is in the bundled known-token list, is tracked by the
|
||||
user, or has 1,000 or more holders; a token claiming a symbol from the bundled
|
||||
list from any other contract address is always dropped, and so is any token
|
||||
claiming a symbol that belongs to the native asset and therefore has no
|
||||
legitimate contract at all (`"ETH"`, and every network's `nativeCurrency`, such
|
||||
as `"SepoliaETH"`, on every network). That filter is unconditional — the "Hide
|
||||
tokens with fewer than 1,000 holders" setting governs the transaction history
|
||||
and the send-screen token selector, not this list. A token's holder count is
|
||||
unknown when the explorer reports none, or reports anything other than a whole
|
||||
number written in digits alone, such as `1,000` or `1e3` (`parseHoldersCount()`
|
||||
in `src/shared/holders.js`). This list does not take an unknown count as 1,000
|
||||
or more, so such a token is shown only when it is on the bundled list or
|
||||
tracked. `fetchTokenBalances()` stores every nonzero holding of a token it
|
||||
admits, however small, but a holding below 0.000001 is left out of the balance
|
||||
Which tokens an address shows is decided on every refresh by `refreshBalances()`
|
||||
in `src/shared/balances.js`. The balance of each token tracked on the active
|
||||
network is read with `balanceOf` through the RPC endpoint, for every address.
|
||||
Its holder count and `decimals` are those of Blockscout's entry for it in the
|
||||
same refresh, kept from before while Blockscout fails. A read that fails keeps
|
||||
that token's previous entry, as a failed ETH balance keeps its figure, or takes
|
||||
Blockscout's entry from the same refresh when there is none. Every other token
|
||||
comes from the Blockscout `token-balances` response (`fetchTokenBalances()`), so
|
||||
tokens do appear without the user adding them, and they keep their previous
|
||||
figures while Blockscout fails. 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 more holders. A token claiming a symbol
|
||||
from the bundled list from any other contract address is always dropped, tracked
|
||||
or not, and so is any token claiming a symbol that belongs to the native asset
|
||||
and therefore has no legitimate contract at all (`"ETH"`, and every network's
|
||||
`nativeCurrency`, such as `"SepoliaETH"`, on every network). That filter is
|
||||
unconditional — the "Hide tokens with fewer than 1,000 holders" setting governs
|
||||
the transaction history and the send-screen token selector, not this list. A
|
||||
token's holder count is unknown when the explorer reports none, or reports
|
||||
anything other than a whole number written in digits alone, such as `1,000` or
|
||||
`1e3` (`parseHoldersCount()` in `src/shared/holders.js`). This list does not
|
||||
take an unknown count as 1,000 or more, so such a token is shown only when it is
|
||||
on the bundled list or tracked. Every nonzero holding of a token shown is stored
|
||||
exactly, however small, but a holding below 0.000001 is left out of the balance
|
||||
lists, the send-screen token selector, the address total and the remove-address
|
||||
warning (`isBelowOneMillionth()` in `src/shared/amountDisplay.js`). The Send and
|
||||
confirmation screens show it when its token is the one being sent. Tracked
|
||||
@@ -2662,7 +2669,8 @@ AutistMask is not a fully self-contained offline tool. It necessarily
|
||||
communicates with three external services to function as a wallet:
|
||||
|
||||
- **Ethereum JSON-RPC endpoint**: The extension needs an Ethereum node to query
|
||||
balances (`eth_getBalance`), read ERC-20 token contracts (`eth_call`),
|
||||
balances (`eth_getBalance`), read ERC-20 token contracts (`eth_call`), among
|
||||
them the balance of every tracked token at every address (`balanceOf`),
|
||||
estimate gas (`eth_estimateGas`), fetch nonces (`eth_getTransactionCount`),
|
||||
broadcast transactions (`eth_sendRawTransaction`), and check transaction
|
||||
receipts. The default endpoint is a public RPC (configurable by the user to
|
||||
|
||||
Reference in New Issue
Block a user