fix: read USD prices from Chainlink price feeds through the RPC endpoint (closes #525)
CoinDesk now refuses every request without an API key, so mainnet showed no USD prices. On mainnet the wallet now reads latestRoundData() from Chainlink's USD price feeds through the configured RPC endpoint. ETH and the held or tracked tokens with a feed are read as one batched request, at most every 5 minutes. src/shared/tokenList.js lists the feeds of 53 bundled tokens, keyed by contract address, and the ETH/USD feed. A reading older than its feed's heartbeat plus 30 minutes, or not positive, is no price. A failed read leaves no price and is logged. getPrice() takes a contract address instead of a symbol. The CoinDesk request is removed. Model: opus-5-5
This commit is contained in:
@@ -17,11 +17,11 @@ 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
|
||||
Settings. The endpoint defaults to a public node.
|
||||
|
||||
Out of the box the extension contacts two services:
|
||||
Out of the box the extension contacts one service, the configured RPC node. The
|
||||
wallet uses the node for:
|
||||
|
||||
- the configured RPC node, for blockchain interactions
|
||||
- a public CoinDesk API (no API key), for realtime prices. The API receives
|
||||
token symbols and nothing else.
|
||||
- blockchain interactions
|
||||
- USD prices on mainnet, read from Chainlink price feed contracts
|
||||
|
||||
Two more services are sent none of the user's data until the user ticks a
|
||||
checkbox for each. Welcome and Settings both offer the two checkboxes:
|
||||
@@ -902,13 +902,14 @@ src/
|
||||
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
|
||||
prices.js — ETH/USD and token/USD via CoinDesk API
|
||||
prices.js — ETH/USD and token/USD from Chainlink price feeds
|
||||
scamlist.js — known fraud contract addresses
|
||||
state.js — persisted state (extension storage)
|
||||
storedSettings.js — "Use Blockscout" and "Check recipients on Etherscan",
|
||||
read from storage for the requests those settings gate
|
||||
symbolSpoof.js — the known-symbol spoof rule, shared by all surfaces
|
||||
tokenList.js — top ERC-20 tokens by market cap (hardcoded)
|
||||
tokenList.js — top ERC-20 tokens by market cap, and their Chainlink
|
||||
price feeds (hardcoded)
|
||||
transactions.js — tx history fetching + anti-poisoning filters
|
||||
uniswap.js — Uniswap Universal Router calldata decoder
|
||||
vault.js — password-based encryption via libsodium
|
||||
@@ -1371,10 +1372,10 @@ whole swap undecoded.
|
||||
|
||||
#### Partial USD totals
|
||||
|
||||
Prices are fetched for the top 25 tokens only, so an address can hold assets the
|
||||
extension has no price for. Worth zero and worth an unknown amount are different
|
||||
facts and are never collapsed into one number. `getAddressValue()` in
|
||||
`src/shared/prices.js` returns `{ usd, partial }` — the value of the priced
|
||||
Only a token with a Chainlink price feed has a price, so an address can hold
|
||||
assets the extension has no price for. Worth zero and worth an unknown amount
|
||||
are different facts and are never collapsed into one number. `getAddressValue()`
|
||||
in `src/shared/prices.js` returns `{ usd, partial }` — the value of the priced
|
||||
holdings, and whether an unpriced holding was left out of it — and every screen
|
||||
renders it through `formatAddressTotal()`, so the wording cannot drift:
|
||||
|
||||
@@ -2854,9 +2855,9 @@ view would leave a wallet one click from deletion.
|
||||
|
||||
### External Services
|
||||
|
||||
AutistMask is not a fully self-contained offline tool. By default it sends the
|
||||
user's data only to the Ethereum RPC endpoint. It also asks the CoinDesk price
|
||||
API for prices, sending token symbols and nothing else.
|
||||
AutistMask is not a fully self-contained offline tool. By default it contacts
|
||||
only the Ethereum RPC endpoint. USD prices are read from Chainlink price feed
|
||||
contracts through that endpoint.
|
||||
|
||||
Two more services are sent none of the user's data until the user turns on a
|
||||
setting for each:
|
||||
@@ -2880,21 +2881,18 @@ Contacted by default:
|
||||
estimate gas (`eth_estimateGas`), fetch nonces (`eth_getTransactionCount`),
|
||||
broadcast transactions (`eth_sendRawTransaction`), and check transaction
|
||||
receipts. Every ENS lookup is made through the RPC endpoint alone. So a name
|
||||
does not resolve when its resolver says the name is resolved off-chain. The
|
||||
default endpoint is a public RPC (configurable by the user to any endpoint
|
||||
they prefer, including a local node). By default the extension talks to
|
||||
does not resolve when its resolver says the name is resolved off-chain. On
|
||||
mainnet the extension also reads USD prices from Chainlink price feed
|
||||
contracts (`latestRoundData`). The prices of ETH and of each held or tracked
|
||||
token with a feed are read as one batched request. That request is sent at
|
||||
most every 5 minutes while the popup is open. The default endpoint is a public
|
||||
RPC (configurable by the user to any endpoint they prefer, including a local
|
||||
node). By default the extension talks to
|
||||
`https://ethereum-rpc.publicnode.com`.
|
||||
- **Data sent**: Ethereum addresses, transaction data, contract call
|
||||
parameters. The RPC endpoint can see all on-chain queries and submitted
|
||||
transactions.
|
||||
|
||||
- **CoinDesk CADLI price API**: Used to fetch ETH/USD and token/USD prices for
|
||||
displaying fiat values. The price is cached for 5 minutes to avoid excessive
|
||||
requests. No API key required. No user data is sent — only a list of token
|
||||
symbols. Note that CoinDesk will receive your client IP.
|
||||
- **Data sent**: Token symbol strings only (e.g. "ETH", "USDC"). No
|
||||
addresses or user-specific data.
|
||||
|
||||
Sent the user's data only while its setting is on:
|
||||
|
||||
- **Blockscout block-explorer API** ("Use Blockscout"): The default endpoint is
|
||||
@@ -3070,14 +3068,13 @@ hardcoded test phrase.
|
||||
|
||||
At the raised log level the console also shows the wallet's addresses with their
|
||||
balances and ENS names, the token contracts looked up, and a line for each
|
||||
request made through `debugFetch` in `src/shared/log.js` (the explorer, the
|
||||
price feed, the RPC calls a site makes, and the endpoint checks in settings) and
|
||||
for its response. A request is logged by its HTTP method, the origin of its URL
|
||||
(scheme, host and port) and, for a JSON-RPC call, the method name; the balance
|
||||
refresh, the token lookup and a failed endpoint check in settings name the
|
||||
endpoint by its origin too. The URL's path and query string, where RPC providers
|
||||
put API keys, any user name and password in it, and the request body are never
|
||||
logged.
|
||||
request made through `debugFetch` in `src/shared/log.js` (the explorer, the RPC
|
||||
calls a site makes, and the endpoint checks in settings) and for its response. A
|
||||
request is logged by its HTTP method, the origin of its URL (scheme, host and
|
||||
port) and, for a JSON-RPC call, the method name; the balance refresh, the token
|
||||
lookup and a failed endpoint check in settings name the endpoint by its origin
|
||||
too. The URL's path and query string, where RPC providers put API keys, any user
|
||||
name and password in it, and the request body are never logged.
|
||||
|
||||
### Key Decisions
|
||||
|
||||
|
||||
Reference in New Issue
Block a user