Token auto-discovery, tx history, balance polling, EIP-6963, UI overhaul
All checks were successful
check / check (push) Successful in 14s

Major changes:
- Fetch token balances and tx history from Blockscout API (configurable)
- Remove manual token discovery (discoverTokens) in favor of Blockscout
- HD address gap scanning on mnemonic import
- Duplicate mnemonic detection on wallet add
- EIP-6963 multi-wallet discovery + selectedAddress updates in inpage
- Two-tier balance refresh: 10s while popup open, 60s background
- Fix $0.00 flash before prices load (return null when no prices)
- No-layout-shift: min-height on total value element
- Aligned balance columns (42ch address width, consistent USD column)
- All errors use flash messages instead of off-screen error divs
- Settings gear in global title bar, add-wallet moved to settings pane
- Settings wells with light grey background, configurable Blockscout URL
- Consistent "< Back" buttons top-left on all views
- Address titles (Address 1.1, 1.2, etc.) on main and detail views
- Send view shows current balance of selected asset
- Clickable affordance policy added to README
- Shortened mnemonic backup warning
- Fix broken background script constant imports
This commit is contained in:
2026-02-26 02:13:39 +07:00
parent 2b2137716c
commit 3bd2b58543
27 changed files with 978 additions and 420 deletions

View File

@@ -1,15 +1,17 @@
// AutistMask content script — bridges between inpage (window.ethereum)
// and the background service worker via extension messaging.
// Inject the inpage script into the page's JS context
const script = document.createElement("script");
script.src = (typeof browser !== "undefined" ? browser : chrome).runtime.getURL(
"src/content/inpage.js",
);
script.onload = function () {
this.remove();
};
(document.head || document.documentElement).appendChild(script);
// In Chrome (MV3), inpage.js runs as a MAIN-world content script declared
// in the manifest, so no injection is needed here. In Firefox (MV2), the
// "world" key is not supported, so we inject via a <script> tag.
if (typeof browser !== "undefined") {
const script = document.createElement("script");
script.src = browser.runtime.getURL("src/content/inpage.js");
script.onload = function () {
this.remove();
};
(document.head || document.documentElement).appendChild(script);
}
// Relay requests from the page to the background script
window.addEventListener("message", (event) => {

View File

@@ -1,9 +1,7 @@
// AutistMask inpage script — injected into the page's JS context.
// Creates window.ethereum (EIP-1193 provider).
// Creates window.ethereum (EIP-1193 provider) and announces via EIP-6963.
(function () {
if (typeof window.ethereum !== "undefined") return;
const CHAIN_ID = "0x1"; // Ethereum mainnet
const listeners = {};
@@ -45,7 +43,7 @@
}
}
function request(args) {
function sendRequest(args) {
return new Promise((resolve, reject) => {
const id = nextId++;
pending[id] = { resolve, reject };
@@ -63,8 +61,21 @@
networkVersion: "1",
selectedAddress: null,
request(args) {
return request({ method: args.method, params: args.params || [] });
async request(args) {
const result = await sendRequest({
method: args.method,
params: args.params || [],
});
if (
args.method === "eth_requestAccounts" ||
args.method === "eth_accounts"
) {
provider.selectedAddress =
Array.isArray(result) && result.length > 0
? result[0]
: null;
}
return result;
},
// Legacy methods (still used by some dApps)
@@ -119,10 +130,46 @@
}
return this;
},
// Some dApps (wagmi) check this to confirm MetaMask-like behavior
_metamask: {
isUnlocked() {
return Promise.resolve(true);
},
},
};
window.ethereum = provider;
// Announce via EIP-6963 (multi-wallet discovery)
// Set window.ethereum if no other wallet has claimed it
if (typeof window.ethereum === "undefined") {
window.ethereum = provider;
}
window.dispatchEvent(new Event("ethereum#initialized"));
// EIP-6963: Multi Injected Provider Discovery
const ICON_SVG =
"data:image/svg+xml," +
encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">' +
'<rect width="32" height="32" rx="6" fill="#000"/>' +
'<text x="16" y="23" text-anchor="middle" font-family="monospace" font-size="20" font-weight="bold" fill="#fff">A</text>' +
"</svg>",
);
const providerInfo = {
uuid: "f3c5b2a1-8d4e-4f6a-9c7b-1e2d3a4b5c6d",
name: "AutistMask",
icon: ICON_SVG,
rdns: "berlin.sneak.autistmask",
};
function announceProvider() {
window.dispatchEvent(
new CustomEvent("eip6963:announceProvider", {
detail: Object.freeze({ info: providerInfo, provider }),
}),
);
}
window.addEventListener("eip6963:requestProvider", announceProvider);
announceProvider();
})();