This policy describes what data the ZendIQ browser extension collects, why, and how it is handled. We've written it to be readable, not just legally defensible.
ZendIQ is a browser extension for Chrome and Brave that provides real-time risk analysis for Solana swaps on Jupiter, Raydium, and pump.fun. Both extensions are provided by the ZendIQ project and are fully open source:
For questions about this policy, contact us at privacy@zendiq.ai.
Both ZendIQ Lite and ZendIQ Pro send anonymous usage events to our backend
(zendiq-backend.onrender.com). Every event is identified by an install_id
— a UUID-v4 generated on first install and stored locally in chrome.storage.local.
No wallet address, no name, no email, and no IP address is ever stored.
Not every event applies to both extensions. Lite and Pro protect different surfaces, so Lite sends a smaller set of events with fewer fields. Where they differ, it is stated on the table concerned.
| Event category | ZendIQ Lite | ZendIQ Pro |
|---|---|---|
| Install | Yes | Yes |
| Session | Yes | Yes |
| Token check & decision | Yes | Covered by Trade |
| Swap intercept & outcome | No | Yes — when a swap is detected, and again when you proceed or ZendIQ's route is signed |
| Trade | Yes — reduced field set | Yes — all fields |
| Wallet security scan | No | Yes — only when you run the check |
| Funnel | Yes — widget_shown only | Yes — widget_shown only |
| Heartbeat | Yes | Yes |
| Error | No | Yes |
| MEV detection | No — Lite has no sandwich detection | Yes |
| Dynamic slippage | No — Raydium bundle path is Pro only | Yes |
Every event category in full:
Install — fired once on fresh install or extension update
| Field | Why |
|---|---|
| OS (windows / mac / linux) | Understand platform distribution |
| Browser (brave / chrome) | Understand browser distribution |
| Locale (full browser language tag, e.g. "en-US") | Aggregate language distribution |
| Country (2-char ISO derived from browser locale) | Understand global reach — not from geolocation |
| Reason (install / update) + previous version | Track upgrade paths |
Session — fired when a wallet is detected on page load and on page close
| Field | Why |
|---|---|
| Type (start / end) | Measure session duration |
| Wallet adapter name (e.g. "phantom") | Which wallets are most used — never the public key |
| DEX site (jup.ag / raydium.io / pump.fun / axiom.trade) | Which DEX the session was on |
Token check & decision — ZendIQ Lite only; fired when a token is scored and again when you choose Proceed or Cancel
| Field | Why |
|---|---|
| Token mint address | Which token was scored — tunes risk signal accuracy |
| Risk score (0–100) and level | What the extension showed you at decision time |
| Decision (proceeded / cancelled) | Whether the warning changed the outcome |
| Trade size in USD or SOL | Whether risk tolerance varies with trade size |
| Site (jup.ag / raydium.io / pump.fun / axiom.trade) | Which supported site the swap was on |
Not collected: wallet public key, transaction signature, transaction bytes.
Swap intercept — ZendIQ Pro only; fired when a swap is detected on the page, before you choose anything
| Field | Why |
|---|---|
site | Which DEX the swap was detected on |
input_mint / output_mint | The pair being traded — tunes risk scoring accuracy |
amount_in | Input amount, in token units |
trade_usd | Trade size in USD — capped at $50k |
slippage_bps | Your slippage tolerance as set on the DEX — measures what users actually trade with |
risk_level / mev_level / token_level | The three risk verdicts shown to you at intercept time |
profile | Which protection profile was active |
This event records that a swap was seen and what it looked like. It is sent whether or not you go on to trade, so a swap you cancel still produces one. Not collected: wallet address, transaction signature, transaction bytes.
Swap outcome — ZendIQ Pro only; swap_proceeded when you continue with the site's own route, swap_optimised when ZendIQ's route is signed
| Field | Why |
|---|---|
site | Which DEX the swap was on |
input_mint / output_mint | The pair traded |
amount_in / amount_out | Input and output amounts, in token units |
trade_usd | Trade size in USD — capped at $50k |
slippage_bps | Slippage tolerance the trade went out with |
profile | Which protection profile was active |
reason | swap_proceeded only — why the site's route was used (e.g. you chose it, or ZendIQ found no net benefit) |
net_benefit_usd / routing_gain_usd / mev_value_usd / fees_usd | swap_optimised only — the estimates shown to you when you signed |
route_type / jito_used / auto_sign | swap_optimised only — which route ZendIQ used, whether it went as a Jito bundle, and whether auto-accept signed it |
Not collected: wallet address, transaction signature, transaction bytes. The signature of a completed trade is recorded only on the Trade event below.
Trade — fired after the user makes a swap decision (optimise, proceed, or cancel)
| Field | Why |
|---|---|
dex | Which DEX executed the trade |
input_mint | Token sold — needed to measure routing gain accuracy |
output_mint | Token bought — needed for risk signal accuracy |
trade_usd | Trade size in USD — capped at $50k in both extensions |
user_action | What the user chose: optimised / proceeded / cancelled |
success | Whether the transaction landed on-chain |
tx_sig | Transaction signature — deduplication + on-chain verification. Publicly visible on Solana block explorers. |
bot_risk_score | MEV / sandwich risk score (0–100) |
token_risk_score | Output-token risk score (0–100) |
net_benefit_usd | Estimated routing gain minus fees at time of sign |
routing_gain_usd | Raw routing gain vs Jupiter's concurrent quote |
mev_value_usd | Statistical MEV protection value from Jito tip |
fees_usd | Priority fee + Jito tip cost |
jito_tip_lamports | Jito tip used — verifiable on-chain |
profile | Which protection profile was active |
auto_sign | Whether auto-accept fired |
exec_path | How the transaction was submitted: direct / jito / rfq / gasless / axiom_mev / axiom_direct |
route_chosen | Route type: AMM / RFQ / gasless / bundle |
trade_sol | Trade size in SOL — null when the venue's native asset is not SOL |
quoted_slippage | Slippage the trade actually executed with — axiom.trade only |
slot_latency_ms | How long the venue took to execute, capped at 300,000 — axiom.trade only |
tx_classification | Risk band of the trade at decision time: safe / caution / danger |
data_json | Extra fields not in fixed columns — future-proofs schema (≤4KB) |
Not collected: wallet public key, full transaction bytes, counterparty wallet.
Trade — axiom.trade only (Axiom support is not yet available; these fields apply once it is released). Axiom executes through its own infrastructure and charges its own fees, so a few extra fields are recorded there:
| Field | Why |
|---|---|
fee_currency | Which asset Axiom charged its fees in — SOL, or null on chains ZendIQ does not cover |
priority_fee_sol | Priority fee Axiom actually charged — recorded separately from fees_usd so fee floors can be told apart from fees that scale with trade size |
bribe_fee_sol | Bribe fee Axiom actually charged — same reason |
optimize_applied | Whether an optimisation ZendIQ applied actually reached the trade — separates "we did not try" from "we tried and the venue traded on the old values" |
provider / region | Which sender Axiom routed through — diagnoses execution quality |
ZendIQ does not set any of these fees. They are read from Axiom's own trade result after the fact.
dex, output_mint, trade_usd, trade_sol,
user_action, success, and the token risk score (recorded in the
bot_risk_score column).
Lite never sends tx_sig, input_mint, or any of the routing, fee,
profile or execution-path fields — it has no routing engine, so those values do not exist.
MEV detection — ZendIQ Pro only; fired when detectSandwich() identifies a sandwich attack around a user swap
| Field | Why |
|---|---|
tx_sig | Transaction signature of the user swap being attacked — deduplication; publicly visible on Solana |
detected | Whether an attack was confirmed |
loss_usd | Estimated USD loss from the attack — measures real-world impact |
loss_bps | Attack severity in basis points |
attacker_hash | SHA-256 of the attacker's wallet, truncated to 12 hex chars. This is a deduplication token, not anonymisation — the hash is unsalted and Solana addresses are public and enumerable, so anyone holding a candidate list can match it. We use it to count distinct attackers and never publish it. |
method | Detection method: vault_neighbor / bonding_curve_pda / front_run_only |
event_subtype | Why the event fired when no attack was confirmed — e.g. an internal sanity cap being hit |
prevented_count | Attacks in the same block that Jito tips blocked |
time_to_detect_s | Seconds from the swap to the detection result — sent, but currently always empty |
data_json | Detection internals — strategy name, estimated amounts, slot (≤4KB) |
Not collected: user wallet address, transaction bytes, victim identity beyond the public tx signature.
Error — ZendIQ Pro only; fired when an internal error degrades protection, or when ZendIQ lets a transaction through without opening its panel. Capped at 20 error events per page load, all kinds together.
| Field | Why |
|---|---|
category | Error class — wallet_hook (the wallet could not be hooked, or a transaction was passed through) or injection (a page script failed to load) |
detail | The error message, truncated to 120 characters — no stack traces, no user data. For a pass-through: intercept_passthrough: whether the transaction was not a swap or could not be read, then the first 8 characters of each program it calls |
dex | Pass-through reports only — which supported site |
ZendIQ only steps in on recognised swaps. Anything else on a supported site — Raydium's Reclaim Rent, for example — goes straight to your wallet, and the pass-through report tells us if a real swap is being missed. It names public program addresses only, once per kind of transaction per page load. Not collected: wallet address, amounts, transaction signature, transaction bytes.
Funnel — key UX steps in the widget flow
| Field | Why |
|---|---|
event | widget_shown — the only funnel event either extension currently sends |
dex | Which DEX |
Records that the widget appeared, and on which site. It carries no user-identifying data, no trade details, and nothing about what you did next.
Heartbeat — at most once per UTC calendar day on service-worker wake
| Field | Why |
|---|---|
day | Calendar date (YYYY-MM-DD) — deduplication key: one install = one heartbeat/day |
site | Which DEX site triggered the wake |
Powers DAU/WAU/MAU metrics without any persistent user identifier beyond install_id.
Dynamic slippage — ZendIQ Pro only; fired per trade when dynamic slippage is enabled
| Field | Why |
|---|---|
token_class | Volatility class used to size the threshold |
user_slip_bps | Your original slippage tolerance |
tightened_bps | The tighter threshold ZendIQ computed |
price_impact_bps | Observed price impact |
outcome | shadow_log / landed / reverted / overridden |
shadow_mode / active | Whether the setting was measuring only or actually applied |
override_applied | Whether you chose to keep your original slippage |
ts | When the event happened |
quoted_out_raw / min_out_original_raw / min_out_tightened_raw | Quoted output and the two minimum-output limits, in raw token units — whether the tighter limit would have caused a failed trade |
tx_sig | Transaction signature — public on-chain identifier; only when the trade landed |
trade_size_usd | Trade size in USD — only when the trade landed or reverted |
counterfactual_usd | Estimated extraction avoided — only when a trade reverted |
Measures whether tightening slippage actually prevents value extraction, or just causes failed trades.
Wallet security scan — ZendIQ Pro only; fired when you run a Wallet Security Check
| Field | Why |
|---|---|
wallet_type | Which wallet was scanned (e.g. "phantom") — never the public key |
score_tier | Security score bucketed to 0 / 60 / 80 / 100 — not the exact score |
unlimited_count | How many unlimited token approvals were found |
Not collected: your wallet address, the approvals themselves, or the contracts they point to — those stay on your device.
We do not use this data for advertising, profiling, or any purpose beyond the above.
tx_sig) are collected by ZendIQ Pro only, on trade,
MEV detection and dynamic slippage events. A transaction signature is a public on-chain
identifier — visible to anyone on Solana block explorers (Solscan, SolanaFM, etc.). It does
not contain your wallet address, trade amounts, or personal data. Pro stores it solely for
deduplication (preventing double-counting) and on-chain quote accuracy verification.
Events are stored in a SQLite database on our backend server hosted at Render.com (US region). Render's infrastructure privacy policy is available at render.com/privacy.
Our retention target for individual event rows is 12 months. Automated deletion is not yet deployed, so rows older than that may still be present until it is — we would rather say so than describe a limit we do not currently enforce. Aggregated counts (totals with no individual event rows) may be retained indefinitely.
Our host, Render, terminates the connection and keeps platform-level request logs that include originating IP addresses, as any web host does. Those logs are Render's, subject to their retention policy, and are not part of our database or accessible to our analytics.
We do not sell, rent, or share individual event data with any third party. The only external services that receive data as part of a normal extension session are:
taker on every quote request, because the transaction is built for that specific address. When you sign, the signed transaction is sent to Jupiter to be broadcast.RugCheck, DexScreener, GeckoTerminal and Binance are read-only lookups that receive a token mint or nothing at all. The rest are not. Jupiter, Raydium, PumpPortal and the Solana RPC nodes receive your wallet's public key, because a Solana transaction has to be built for a specific address — this is inherent to trading on these venues, not something ZendIQ adds. Jito receives your signed transaction, as described. And, once Axiom support is released (it is not yet available), when you enable slippage optimisation on axiom.trade, ZendIQ writes to your Axiom settings.
That write is limited to three fields on your currently-selected Axiom preset, and only when your preset is looser than the measured risk warrants:
| Field | Written as | Purpose |
|---|---|---|
slippage | 10, 15 or 20 | Caps how much a sandwich bot can extract, sized to the token's risk |
enhancedMevProtection | true | Axiom's "Secure" MEV protection mode |
mevProtection | false | Axiom's "Fast" mode — "Secure" is the enhanced flag on its own |
No fee field is ever written. ZendIQ does not change your priority fee, bribe, or max-fee cap, and never turns Axiom's Auto Fee on or off. It reads those values to score them as a risk factor and displays them to you; it does not modify them. ZendIQ also never loosens a setting — if yours is already tighter than the target, it is left alone. If a field ZendIQ expects is missing from Axiom's settings, it refuses to write anything and hands the trade back to you.
The settings read and write go to Axiom's own API (api.axiom.trade, or whichever
numbered host your session is using — the host is learned from Axiom's own requests, never
guessed) and are authenticated with your existing Axiom session cookie, the same way the site
itself works. ZendIQ has no Axiom account and cannot sign in on your behalf. ZendIQ also
observes Axiom's own settings messages over its WebSocket connection, read-only, to confirm a
change has taken effect before releasing your trade.
Before any change is made, ZendIQ records an undo record locally listing every
field, its old value and its new value. If that record cannot be saved, the change is not made.
Your original values are restored when the trade settles, on a fallback timer if it does not,
and when you close or navigate away from the tab — the last of these uses the browser's
sendBeacon so the restore survives the page closing. A restore that keeps failing
stops retrying after five attempts rather than repeatedly posting from your logged-in session,
and after 48 hours ZendIQ asks before restoring rather than writing silently, because by then
you may have changed those settings yourself.
Optimisation is off by default, you are asked before it is ever used, and you approve each trade. It runs on Solana only — on Axiom's other chains ZendIQ writes nothing, intercepts nothing, and says so in the widget. Writing the settings and confirming they have taken effect delays the trade by roughly a second, varying with how quickly Axiom's own servers respond. That delay is what it costs to be able to put your settings back afterwards. It applies only when you choose to optimise — declining costs you nothing, and risk scoring adds no delay to any trade. ZendIQ never touches your funds or keys. If a setting cannot be put back, ZendIQ tells you and lets you restore it yourself.
On axiom.trade ZendIQ also reads Axiom's own trade-result messages to record the outcome, the fees actually paid, and whether the optimisation reached the trade. This is the same trade record described in section 2 and is subject to the same limits.
ZendIQ stores the following data locally in your browser using
chrome.storage.local:
Heartbeat event to once per day)This data stays on your device. The one exception is that when an analytics event fails to send, ZendIQ stores a short failure summary locally and attaches it to the next event that succeeds, so we can tell a backend outage apart from a drop in usage. That summary contains counts and error categories — no trade data, no wallet address, no settings values. You can clear local data at any time via Chrome's extension storage settings.
ZendIQ Pro is live on the Chrome Web Store and follows the same privacy guarantees as Lite. Pro sends ten of the eleven event categories listed in section 2; Lite sends six. Pro never sends your wallet address or public key to ZendIQ's backend. As with Lite, running the optional Wallet Security Check sends your wallet's public key to public Solana RPC nodes — that is what the check reads. See section 6.
Pro's trade events include additional fields not present in Lite:
Quote accuracy — how much of the quoted output actually arrived on-chain — is calculated on your device and shown in the Activity tab. It is not sent to our backend.
Pro's MEV detection events include the same truncated attacker hash described in section 2, with the same caveat: it is a deduplication token, not anonymisation.
Pro and Lite each generate their own separate
install_id
on install. Installing both does not link them, and we cannot tell that the same person is running
both extensions. There is no ZendIQ account or identity in either product.
Axiom support for Pro, including the opt-in slippage optimisation described in section 6, is not yet available. Lite does not support Axiom.
ZendIQ events are not directly identifying: they contain no name, email, or account. Beyond that, the two extensions differ, and the difference matters.
ZendIQ Lite. Lite events contain no transaction signature and no wallet address —
only a random install_id,
token mint addresses, trade size, the risk score shown, and which supported site you were on.
There is no field in a Lite event that can be resolved to you or to your wallet — not by us, and
not by anyone combining our data with public blockchain data. The practical consequence is that
we cannot locate "your" Lite records on request, because nothing in them points at you. We would
rather say that plainly than offer a deletion process that cannot work.
ZendIQ Pro. Pro's trade and MEV events include a transaction signature, which is public on-chain and can be resolved to the wallet that signed it. An install's events could therefore be linked to a wallet address by anyone combining our data with public blockchain data. We do not perform that linkage, but we would rather state the possibility than claim an anonymity we cannot guarantee.
If you would like your Pro events removed, contact us at privacy@zendiq.ai. Because we hold no account or identifier that maps to you, we will ask you to sign a message with the wallet you traded from so we can identify the right records without you sending us anything sensitive. This works by matching your wallet's public transactions against the transaction signatures we store — so if you have never completed a trade with Pro, we hold no record that can be connected to you, by us or by anyone else.
For any deletion request or privacy concern, we will investigate and respond within 30 days.
If you are in the EU/EEA and believe we have processed personal data about you, you have the right to lodge a complaint with your local data protection authority.
We will update this page when our data practices change. The "Last updated" date at the top of this page reflects the most recent revision. Significant changes will also be disclosed in the extension's release notes.
Both ZendIQ Lite and ZendIQ Pro are fully open source. You can inspect exactly what data is collected and when in each repository:
src/utils/analytics.js,
src/scripts/page-interceptor.js
scripts/page-analytics.js,
scripts/page-interceptor.js