// AutistMask inpage script — injected into the page's JS context. // Creates window.ethereum (EIP-1193 provider) and announces via EIP-6963. (function () { // Defaults to mainnet; updated dynamically via eth_chainId on init and // chainChanged events from the extension. let currentChainId = "0x1"; let currentNetworkVersion = "1"; const listeners = {}; let nextId = 1; const pending = {}; // Listen for responses from the content script window.addEventListener("message", function onUuid(event) { if (event.source !== window) return; if (event.data?.type !== "AUTISTMASK_RESPONSE") return; const { id, result, error } = event.data; const p = pending[id]; if (!p) return; delete pending[id]; if (error) { p.reject(new Error(error.message || "Request failed")); } else { p.resolve(result); } }); // Listen for events pushed from the extension window.addEventListener("message", function onUuid(event) { if (event.source !== window) return; if (event.data?.type !== "AUTISTMASK_EVENT") return; const { eventName, data } = event.data; if (eventName === "chainChanged") { currentChainId = data; currentNetworkVersion = String(parseInt(data, 16)); provider.chainId = currentChainId; provider.networkVersion = currentNetworkVersion; } emit(eventName, data); }); function emit(eventName, data) { const cbs = listeners[eventName]; if (!cbs) return; for (const cb of cbs) { try { cb(data); } catch (e) { // ignore listener errors } } } function sendRequest(args) { return new Promise((resolve, reject) => { const id = nextId++; pending[id] = { resolve, reject }; window.postMessage( { type: "AUTISTMASK_REQUEST", id, ...args }, "*", ); }); } const provider = { isAutistMask: true, isMetaMask: true, // compatibility — many dApps check this chainId: currentChainId, networkVersion: currentNetworkVersion, selectedAddress: null, 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; } if (args.method === "eth_chainId" && result) { currentChainId = result; currentNetworkVersion = String(parseInt(result, 16)); provider.chainId = currentChainId; provider.networkVersion = currentNetworkVersion; } return result; }, // Legacy methods (still used by some dApps) enable() { return this.request({ method: "eth_requestAccounts" }); }, send(methodOrPayload, paramsOrCallback) { // Handle both send(method, params) and send({method, params}) if (typeof methodOrPayload === "string") { return this.request({ method: methodOrPayload, params: paramsOrCallback || [], }); } return this.request({ method: methodOrPayload.method, params: methodOrPayload.params || [], }); }, sendAsync(payload, callback) { this.request({ method: payload.method, params: payload.params || [], }) .then((result) => callback(null, { id: payload.id, jsonrpc: "2.0", result }), ) .catch((err) => callback(err)); }, on(event, cb) { if (!listeners[event]) listeners[event] = []; listeners[event].push(cb); return this; }, removeListener(event, cb) { if (!listeners[event]) return this; listeners[event] = listeners[event].filter((c) => c !== cb); return this; }, removeAllListeners(event) { if (event) { delete listeners[event]; } else { for (const key of Object.keys(listeners)) { delete listeners[key]; } } return this; }, // Some dApps (wagmi) check this to confirm MetaMask-like behavior _metamask: { isUnlocked() { return Promise.resolve(provider.selectedAddress !== null); }, }, }; // 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( '' + '' + 'A' + "", ); let providerUuid = crypto.randomUUID(); // fallback until real UUID arrives function buildProviderInfo() { return { uuid: providerUuid, name: "AutistMask", icon: ICON_SVG, rdns: "berlin.sneak.autistmask", }; } function announceProvider() { window.dispatchEvent( new CustomEvent("eip6963:announceProvider", { detail: Object.freeze({ info: buildProviderInfo(), provider, }), }), ); } // Listen for the persisted UUID from the content script function onProviderUuid(event) { if (event.source !== window) return; if (event.data?.type !== "AUTISTMASK_PROVIDER_UUID") return; window.removeEventListener("message", onProviderUuid); providerUuid = event.data.uuid; announceProvider(); } window.addEventListener("message", onProviderUuid); window.addEventListener("eip6963:requestProvider", announceProvider); announceProvider(); // Fetch the current chain ID from the extension on load so the provider // reflects the selected network immediately (covers Sepolia etc.). sendRequest({ method: "eth_chainId", params: [] }) .then((chainId) => { if (chainId) { currentChainId = chainId; currentNetworkVersion = String(parseInt(chainId, 16)); provider.chainId = currentChainId; provider.networkVersion = currentNetworkVersion; } }) .catch(() => { // Best-effort — keep defaults. }); })();