Is HAVAH Wallet safe?
HAVAH Wallet sends wallet interaction events (connect, sign, transaction URLs) to Google Analytics with a persistent client UUID.
Each time a user connects a site, signs a message, or sends a transaction, the extension transmits the origin URL and transaction details to Google Analytics GA4 endpoints. A persistent client UUID stored in chrome.storage.local ties these events together across sessions, allowing cross-session linkage of wallet activity to a single user.
Who publishes itHAVAH - no other listings under this identity, 1 shared hostname
HAVAH - no other listings under this identity, 1 shared hostname
What this publisher told the store about itself, and the other listings that told it the same thing.
Shared hosts - 1 hostname
Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Wallet action origins sent to Google Analytics GA4
Connecting HAVAH Wallet to a site, signing, or requesting a transaction sends the site host to GA4, with a persistent client UUID and session ID.
A GA4 request with those IDs was observed, but no action event body was captured.
What actually happens
You use HAVAH Wallet to connect to a site, sign data, or request a transaction.
The extension sends the site host for that wallet action to Google Analytics GA4.
Fields the code places in wallet-action analytics events
- Wallet-action sitehavah.io
Shows which site was involved when you connected the wallet, signed data, or requested a transaction.
- Wallet action typetransaction
Shows whether the event came from a connect, signing, or transaction request.
- Network nameVEGANET
Adds which HAVAH network was active for transaction telemetry.
- API methodicx_sendTransaction
Adds the transaction request method for transaction telemetry.
- Client identifier8f2a4e1c-0b6e-4a10-9f9f-2d6a7b8c1e53
Lets analytics link wallet events from the same browser profile over time.
- Session identifier1720837354123
Groups wallet activity that happens in the same browser session.
Captured request
The code that does this
Analytics sender adds persistent IDs and posts to GA4
Readable analytics sender from the deobfuscated background script
deobfuscated/background.jsconst google_analytics = new class { network = ""; constructor(debug = !1) { this.debug = debug } async getOrCreateClientId() { let { clientId } = await chrome.storage.local.get("clientId"); return clientId || (clientId = self.crypto.randomUUID(), await chrome.storage.local.set({ clientId })), clientId } async getOrCreateSessionId() { let { sessionData } = await chrome.storage.session.get("sessionData"); const currentTimeInMs = Date.now(); if (sessionData && sessionData.timestamp) { (currentTimeInMs - sessionData.timestamp) / 6e4 > 30 ? sessionData = null : (sessionData.timestamp = currentTimeInMs, await chrome.storage.session.set({ sessionData })) } return sessionData || (sessionData = { session_id: currentTimeInMs.toString(), timestamp: currentTimeInMs.toString() }, await chrome.storage.session.set({ sessionData })), sessionData.session_id } async fireEvent(name, params = {}) { params.session_id || (params.session_id = await this.getOrCreateSessionId()), params.engagement_time_msec || (params.engagement_time_msec = 100); let MEASUREMENT_ID = "", API_SECRET = ""; switch (this.network) { case "VEGANET": MEASUREMENT_ID = "G-1M074S78H0", API_SECRET = "<redacted>"; break; case "DENEBNET": MEASUREMENT_ID = DENEB_MEASUREMENT_ID, API_SECRET = DENEB_API_SECRET; break; default: MEASUREMENT_ID = "G-2BXRDK4436", API_SECRET = "<redacted>" } try { await fetch(`${this.debug?"https://www.google-analytics.com/debug/mp/collect":"https://www.google-analytics.com/mp/collect"}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`, { method: "POST", body: JSON.stringify({ client_id: await this.getOrCreateClientId(), events: [{ name, params }] }) }); if (!this.debug) return } catch (e) { console.error("Google Analytics request failed with an exception", e) } } async firePageViewEvent(pageTitle, pageLocation, additionalParams = {}, network) { return this.network = network, this.fireEvent("page_view", { page_title: pageTitle, page_location: pageLocation, ...additionalParams }) } async fireErrorEvent(error, additionalParams = {}) { return this.fireEvent("extension_error", { ...error, ...additionalParams }) }};The code that does this
Wallet message handlers pass the site host into analytics events
CONNECT handler sends connect_url
deobfuscated/background.jsconst host = message.detail.host;return GoogleAnalytics.sendEventGoogleAnalytics("connect_url", { connect_url: host}), isAllowSite = !(!accountInfo.allowSites || 0 == accountInfo.allowSites.length) && Array.from(accountInfo.allowSites).includes(host)SIGN handler sends sign
deobfuscated/background.jsconst host = message.detail.host;isAllowSite = !(!accountInfo.allowSites || 0 == accountInfo.allowSites.length) && Array.from(accountInfo.allowSites).includes(host), GoogleAnalytics.sendEventGoogleAnalytics("sign", { sign: host});SEND_TRANSACTION handler sends transaction, network, and API method
deobfuscated/background.jsconst host = message.detail.host;isAllowSite = !(!accountInfo.allowSites || 0 == accountInfo.allowSites.length) && Array.from(accountInfo.allowSites).includes(host);try { GoogleAnalytics.sendEventGoogleAnalytics("transaction", { transaction: host, network, api_method: message.detail.body.method })} catch (e) { console.error("e", e)}External analytics destination
- www.google-analytics.com
Receives GA4 Measurement Protocol POST requests containing the wallet-action event name, event parameters, client UUID, and session ID.
What it can do
Permissions this extension asks for, as declared in version 2.3.7. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.
Read and change your data on bridge.dcentwallet.com
*://bridge.dcentwallet.com/*
Read and change your data on every site you visit
http://*/*
Read and change your data on every secure site you visit
https://*/*
Store data in your browser
storage
See the address and title of every tab you have open
tabs
Run its own code inside the pages you visit
scripting
Where it sends data
Destinations our analysis observed HAVAH Wallet contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.
- www.google-analytics.comwidely used
HAVAH Wallet sends data to www.google-analytics.com. A widely used service: 388 other extensions we have analyzed send data here.
