Compare commits
3 Commits
8c805537c0
...
c37ffcc864
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c37ffcc864 | ||
| 6b40fa8836 | |||
| bc2aedaab6 |
@@ -4,6 +4,7 @@
|
||||
|
||||
const { DEFAULT_RPC_URL } = require("../shared/constants");
|
||||
const { SUPPORTED_CHAIN_IDS, networkByChainId } = require("../shared/networks");
|
||||
const { onChainSwitch } = require("../shared/chainSwitch");
|
||||
const { getBytes } = require("ethers");
|
||||
const {
|
||||
state,
|
||||
@@ -345,12 +346,8 @@ async function handleRpc(method, params, origin) {
|
||||
return { result: null };
|
||||
}
|
||||
if (SUPPORTED_CHAIN_IDS.has(chainId)) {
|
||||
// Switch to the requested network
|
||||
const target = networkByChainId(chainId);
|
||||
state.networkId = target.id;
|
||||
state.rpcUrl = target.defaultRpcUrl;
|
||||
state.blockscoutUrl = target.defaultBlockscoutUrl;
|
||||
await saveState();
|
||||
await onChainSwitch(target.id);
|
||||
broadcastChainChanged(target.chainId);
|
||||
return { result: null };
|
||||
}
|
||||
|
||||
@@ -50,6 +50,10 @@ function etherscanAddressLink(address) {
|
||||
return `${currentNetwork().explorerUrl}/address/${address}`;
|
||||
}
|
||||
|
||||
function etherscanTokenLink(tokenContract, holderAddress) {
|
||||
return `${currentNetwork().explorerUrl}/token/${tokenContract}?a=${holderAddress}`;
|
||||
}
|
||||
|
||||
function isoDate(timestamp) {
|
||||
const d = new Date(timestamp * 1000);
|
||||
const pad = (n) => String(n).padStart(2, "0");
|
||||
@@ -156,7 +160,10 @@ function show() {
|
||||
$("address-token-dot").innerHTML = addressDotHtml(addr.address);
|
||||
$("address-token-full").dataset.full = addr.address;
|
||||
$("address-token-full").textContent = addr.address;
|
||||
const addrLink = etherscanAddressLink(addr.address);
|
||||
const addrLink =
|
||||
tokenId !== "ETH"
|
||||
? etherscanTokenLink(tokenId, addr.address)
|
||||
: etherscanAddressLink(addr.address);
|
||||
$("address-token-etherscan-link").innerHTML =
|
||||
`<a href="${addrLink}" target="_blank" rel="noopener" class="inline-flex items-center">${EXT_ICON}</a>`;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ const {
|
||||
} = require("./helpers");
|
||||
const { state, saveState, currentNetwork } = require("../../shared/state");
|
||||
const { formatEther, formatUnits, Interface, toUtf8String } = require("ethers");
|
||||
const { getPrice, formatUsd } = require("../../shared/prices");
|
||||
const { ERC20_ABI } = require("../../shared/constants");
|
||||
const { TOKEN_BY_ADDRESS } = require("../../shared/tokenList");
|
||||
const txStatus = require("./txStatus");
|
||||
@@ -243,8 +244,14 @@ function showTxApproval(details) {
|
||||
$("approve-tx-to").innerHTML = escapeHtml("(contract creation)");
|
||||
}
|
||||
|
||||
const ethValueFormatted = formatTxValue(
|
||||
formatEther(details.txParams.value || "0"),
|
||||
);
|
||||
const ethPrice = getPrice("ETH");
|
||||
const ethUsd = ethPrice ? parseFloat(ethValueFormatted) * ethPrice : null;
|
||||
const usdStr = formatUsd(ethUsd);
|
||||
$("approve-tx-value").textContent =
|
||||
formatTxValue(formatEther(details.txParams.value || "0")) + " ETH";
|
||||
ethValueFormatted + " ETH" + (usdStr ? " (" + usdStr + ")" : "");
|
||||
|
||||
// Decode calldata (reuse decoded from above)
|
||||
const decodedEl = $("approve-tx-decoded");
|
||||
|
||||
@@ -2,7 +2,7 @@ const { $, showView, showFlash, escapeHtml } = require("./helpers");
|
||||
const { applyTheme } = require("../theme");
|
||||
const { state, saveState, currentNetwork } = require("../../shared/state");
|
||||
const { NETWORKS, SUPPORTED_CHAIN_IDS } = require("../../shared/networks");
|
||||
const { clearPrices } = require("../../shared/prices");
|
||||
const { onChainSwitch } = require("../../shared/chainSwitch");
|
||||
const { log, debugFetch } = require("../../shared/log");
|
||||
const deleteWallet = require("./deleteWallet");
|
||||
|
||||
@@ -221,15 +221,9 @@ function init(ctx) {
|
||||
if (networkSelect) {
|
||||
networkSelect.addEventListener("change", async () => {
|
||||
const newId = networkSelect.value;
|
||||
const net = NETWORKS[newId];
|
||||
if (!net) return;
|
||||
state.networkId = newId;
|
||||
state.rpcUrl = net.defaultRpcUrl;
|
||||
state.blockscoutUrl = net.defaultBlockscoutUrl;
|
||||
const net = await onChainSwitch(newId);
|
||||
$("settings-rpc").value = state.rpcUrl;
|
||||
$("settings-blockscout").value = state.blockscoutUrl;
|
||||
if (net.isTestnet) clearPrices();
|
||||
await saveState();
|
||||
showFlash("Switched to " + net.name + ".");
|
||||
});
|
||||
}
|
||||
|
||||
57
src/shared/chainSwitch.js
Normal file
57
src/shared/chainSwitch.js
Normal file
@@ -0,0 +1,57 @@
|
||||
// Consolidated chain-switch handler.
|
||||
//
|
||||
// Every state change required when the active network changes is
|
||||
// performed here so that callers (settings UI, background
|
||||
// wallet_switchEthereumChain, future chain additions) all go
|
||||
// through a single code path.
|
||||
//
|
||||
// Adding a new chain (e.g. ETC) requires only a new entry in
|
||||
// networks.js — no per-caller wiring is needed.
|
||||
|
||||
const { networkById } = require("./networks");
|
||||
const { clearPrices } = require("./prices");
|
||||
|
||||
// Switch the active chain and reset all chain-specific cached state.
|
||||
// Returns the network configuration object for the new chain.
|
||||
async function onChainSwitch(newNetworkId) {
|
||||
const { state, saveState } = require("./state");
|
||||
|
||||
const net = networkById(newNetworkId);
|
||||
|
||||
// --- core identity ---
|
||||
state.networkId = net.id;
|
||||
state.rpcUrl = net.defaultRpcUrl;
|
||||
state.blockscoutUrl = net.defaultBlockscoutUrl;
|
||||
|
||||
// --- price cache ---
|
||||
// Prices are chain-specific (testnet tokens are worthless,
|
||||
// ETC has different pricing, etc.).
|
||||
clearPrices();
|
||||
|
||||
// --- balance / refresh state ---
|
||||
// Reset last-refresh timestamp so the next polling cycle
|
||||
// triggers an immediate balance refresh on the new chain.
|
||||
state.lastBalanceRefresh = 0;
|
||||
|
||||
// Clear per-address balances and token balances so stale data
|
||||
// from the previous chain is never displayed while the first
|
||||
// refresh on the new chain is in flight.
|
||||
for (const wallet of state.wallets) {
|
||||
for (const addr of wallet.addresses) {
|
||||
addr.balance = "0";
|
||||
addr.tokenBalances = [];
|
||||
}
|
||||
}
|
||||
|
||||
// --- chain-specific caches ---
|
||||
// Token holder counts and fraud contract lists are
|
||||
// chain-specific and must not carry over.
|
||||
state.tokenHolderCache = {};
|
||||
state.fraudContracts = [];
|
||||
|
||||
await saveState();
|
||||
|
||||
return net;
|
||||
}
|
||||
|
||||
module.exports = { onChainSwitch };
|
||||
@@ -26,6 +26,8 @@ async function refreshPrices() {
|
||||
}
|
||||
}
|
||||
|
||||
// Clear all cached prices and reset the fetch timestamp so the
|
||||
// next refreshPrices() call will fetch fresh data.
|
||||
function clearPrices() {
|
||||
for (const key of Object.keys(prices)) {
|
||||
delete prices[key];
|
||||
@@ -33,6 +35,7 @@ function clearPrices() {
|
||||
lastFetchedAt = 0;
|
||||
}
|
||||
|
||||
// Return the USD price for a symbol, or null on testnet / unknown.
|
||||
function getPrice(symbol) {
|
||||
const { currentNetwork } = require("./state");
|
||||
if (currentNetwork().isTestnet) return null;
|
||||
|
||||
Reference in New Issue
Block a user