OneKey hardware wallet: mandatory telemetry to .cn endpoints, persistent device fingerprinting, and contradicting legal documentation

OneKey hardware wallet phones home to Chinese servers on every launch,

and their own legal docs can’t agree on which country runs the servers

Spent the last few days digging into what OneKey Desktop actually does
on the wire, and reading their Privacy Policy and Terms of Service side
by side. What I found is messy enough to share.

Short version: the app makes unavoidable background requests to `.cn`
domains, persistently tracks users across sessions via a locally-stored
UUID, transmits the hardware wallet’s serial number during firmware
checks, and their three legal documents tell three different stories
about which jurisdiction controls the servers. Nothing here is catastrophic
— your keys don’t leak, the device works as designed — but the metadata
flow and the legal ambiguity around it are worth knowing about before
you trust the app.

I also built a bubblewrap + Tor sandbox that isolates the app completely.
Scripts at the bottom if that’s useful to anyone.

What the software does on launch

Test setup: OneKey Desktop v6.2.0 on a clean Debian install in a VM,
with `tcpdump` and `ss` watching from the host. The app was freshly
extracted from the AppImage published on OneKey’s official download page,
SHA256 matched their release. Hardware: OneKey Pro with current firmware.

Within the first 15 seconds of launching, every launch, with no way to
turn it off in the UI, the app fires these requests:

```
GET https://wallet.onekeycn.com/wallet/v1/health
GET https://*.onekey-asset.com/… (various assets)
GET /utility/v1/app-update
GET /utility/v1/firmware/detail
GET /utility/v1/setting
GET /utility/v2/market/basic-config
GET /utility/v1/perp-config
GET /utility/v1/currency/exchange-rates/map
POST /notification/v1/config/query
POST /notification/v1/account/register ← this one’s interesting
GET /swap/v1/networks
GET /earn/v1/available-assets
GET /earn/v2/available-assets
```

The `wallet.onekeycn.com` is not a typo. The `.cn` TLD is literal. That
domain resolves to infrastructure that looks like Alibaba Cloud or
Tencent based on ASN lookups, though I didn’t do a deep trace.

The `/notification/v1/account/register` POST is what caught my attention.
The payload looks like this:

```json
{
“instanceId”: “7f2e9a81-3c5d-4b8a-9e12-a84f0d623c71”,
“socketId”: “Kw8RvPmN2XqT4YhLbFjE”,
“syncAccountsCount”: 0,
“syncMethod”: “override”
}
```

(Values here are examples — I’m not doxxing my own IDs.)

That `instanceId` is a UUID stored locally in the app’s config directory
(`~/.config/@onekeyhq/desktop/`). It survives across launches. It’s
tied to the machine’s `/etc/machine-id` during generation. This means
OneKey’s servers have a stable long-term identifier for each installation,
which combined with:

  • Your IP address (unless you use Tor/VPN)
  • Timing patterns of your requests
  • Your operating system and browser fingerprint from the Electron
    renderer’s requests
  • The hardware wallet serial that gets attached to firmware queries

…gives them a durable pseudonymous profile per user. Resetting the
seed on the hardware wallet doesn’t break this link, because the
identifier lives on your computer, not the device.

Hardware serial goes over the wire

During firmware version checks, the app sends the full hardware identification
over the API. Here’s what a response looks like during `getFeatures`:

```json
{
“device_id”: “415A7291D4FB38CE8247AB56”,
“serial_no”: “TCD48M1174C”,
“onekey_serial_no”: “PRD48M1174C”,
“revision”: “8e45a1b3f27dc2904fca3e72d8b91ef6134a0c72”,
“onekey_firmware_version”: “4.14.0”,
“onekey_device_type”: “PRO”
}
```

(Again, example values, not mine.)

That’s a direct 1:1 link between the physical serial on your device and
your installation’s network fingerprint. If you ever bought the device
with a card, or registered for a warranty, or a shipment address can
be correlated, that physical serial connects the wallet to you.

Three legal documents, three different stories

This is the part that gets weird. OneKey has at least three live documents
on their help center that describe who they are and what they do with
your data. They don’t match.

Document 1: Privacy Policy (dated May 15, 2025)

Registers the company at:

“ONEKEY LIMITED (Registered number: 3110648), located at ENTREPRENEURSHIP
CENTER, LEVEL 5 CORE F CYBERPORT 3, 100 CYBERPORT ROAD, POK FU LAM,
HONG KONG”

Says about data storage:

“When you use the Services, Personal Information about you will be
stored in the United States.”

Document 2: Terms of Use (dated September 2, 2025)

Same company, different address:

“ONEKEY LIMITED, with its registered office at RM 1517, 15F AMIATA
INDUSTRIAL BUILDING, 58 LEI MUK ROAD, KWAI CHUNG, HONG KONG, and
registration number: 3110648.”

Document 3: User Service Agreement (undated, labeled “Updated over 4 months ago”)

Defines China explicitly:

“China: means the People’s Republic of China, including the Hong Kong
Special Administrative Region, Macao Special Administrative Region
and Taiwan.”

Then:

“Users from China are also covered under this definition of ‘Excluded
Person’.”

By their own definition, their own HK registration falls inside “China.”
They’re telling Chinese users they’re excluded, from a jurisdiction they
themselves classify as Chinese.

Same document, Section III, last paragraph, explicitly:

“In order to actively respond to the requirements of the ten Chinese
ministries and commissions jointly issued the ‘Notice on Further
Preventing and Disposing of the Risk of Virtual Currency Trading Hype’
… the OneKey platform has terminated relevant part of the functional
services for users in China…”

This is the September 2021 joint notice from PBOC and nine other PRC
ministries that effectively banned cryptocurrency trading in mainland
China. OneKey is confirming they comply with PRC regulatory instructions.
A company that complies with PRC regulators has a compliance relationship
with PRC regulators, which means they respond to PRC data requests
through that relationship.

And also Singapore appears out of nowhere in Section II:

“Specific Users: means Users who should cooperate with Company and
disclose Personal Information in order to comply with the laws,
regulations and policies of Singapore and other countries.”

So the actual answer to “where is my data” according to their own docs is:

  • Hong Kong (they’re registered there, at two different addresses)
  • China (their own definition includes HK)
  • United States (where the Privacy Policy says storage happens)
  • Singapore (referenced in the User Service Agreement)

Pick whichever is most convenient for them during any given incident.

What they admit they collect

Some things they’re upfront about, which is worth reading carefully.

Privacy Policy Section 3:

“Other identifiers such as device fingerprint data, IP address, and
geolocation information.”

They collect device fingerprints. They say so. The `instanceId` behavior
I described is just one component of this.

Privacy Policy Section 3:

“OneKey may also collect Personal Data about you from third parties,
such as electronic verification services, referrers, marketing agencies,
or liquidity providers.”

They buy data about you from elsewhere and merge it.

Privacy Policy Section 3:

“OneKey may also use third parties to analyze traffic on its website,
which may involve the use of cookies. Information collected through
such analysis is not anonymous.”

Their analytics is explicitly non-anonymous. That’s their phrasing, not mine.

Privacy Policy Section 6:

“Where you have provided your consent, we may share your Personal
Information with our strategic business partners in limited
circumstances, for example, for marketing and advertising purposes.”

“Consent” in context means “you installed the app.” There’s no granular
toggle.

Privacy Policy Section 6:

“Personal information about you may be disclosed to law enforcement
agencies, regulatory bodies, public authorities… if we believe, in
good faith, that such disclosure is necessary…”

“Good faith” is a low bar. With HK registration and confirmed PRC
compliance relationships, “public authorities” includes PRC authorities.

Privacy Policy Section 13:

“We may engage in automated decision-making for purposes of risk and
fraud detection.”

They run algorithms on your data to decide whether to keep serving you.
The User Service Agreement Section III backs this up:

“the wallet address of yours or your counterparty’s is identified as
suspicious addresses, such as high-risk address”
“we may suspend or limit the function of OneKey used by a particular User”

A non-custodial wallet that refuses to broadcast transactions based on
address heuristics is functionally closer to a custodial service with
censorship than a pure self-custody tool.

Rumors clause

This one made me laugh and then stopped being funny.

In the termination conditions (User Service Agreement VI.3.k, same clause
in the newer Terms of Use):

“if you spread rumours which endanger the goodwill of Company and OneKey”

…is listed as a reason they can cut off access to the service.
Technically, publishing this post qualifies. I don’t think they’d actually
disable a specific device over it — they probably can’t, given the
decentralized nature of how the hardware works — but the fact that
this clause is in a wallet’s terms of service is weird.

Maximum liability

User Service Agreement Section IX.8:

“In any case, the total liability for Company under this Agreement
shall not exceed the greater of: a) the market value of 0.1 ETH; or
b) 100 Singapore Dollars.”

If they cause you damage through negligence, their maximum liability is
roughly $350. The device costs $400 new.

What actually fixes this for you

If you already own OneKey Pro and want to keep using it, there are two
good options.

Option A: skip the OneKey app entirely

Use the hardware wallet as a signing device through Electrum, Sparrow,
or Specter Desktop. These apps speak the Trezor-compatible protocol
that OneKey Pro supports. None of them call home to OneKey servers.
You get the hardware security guarantees without the telemetry layer.

This is honestly the cleanest answer.

Option B: sandbox the OneKey app with forced Tor routing

I built this because I wanted to keep using the OneKey Desktop UI
(easier for quick portfolio checks) but didn’t want it talking to
anyone outside Tor. It’s a bash wrapper around `bubblewrap` +
`systemd-run --scope` + Tor SOCKS5 that gives you:

**Defense in depth on network**:

  • `IPAddressDeny=any` and `IPAddressAllow=127.0.0.0/8` on the scope via
    systemd cgroup — this is enforced by the kernel eBPF, not application
    config. Any connection attempt outside 127.0.0.0/8 is dropped before
    it hits the NIC
  • Chromium `–proxy-server=socks5://127.0.0.1:9050` plus env
    `ALL_PROXY` / `HTTP_PROXY` / `HTTPS_PROXY` so even non-Chromium code
    paths (axios in the Electron main process) respect the proxy
  • `–host-resolver-rules=“MAP * ~NOTFOUND, EXCLUDE localhost, EXCLUDE
    127.0.0.1”` which makes Chromium refuse to resolve anything locally
    except loopback — all DNS goes remote through SOCKS
  • `–proxy-bypass-list` tuned so the local `onekeyd` bridge on
    127.0.0.1:21320 works while everything else goes through Tor
  • Fake `/etc/resolv.conf` pointing at Tor’s DNSPort (127.0.0.1:5353),
    as fallback if anything bypasses SOCKS
  • `–disable-features=WebRtcHideLocalIpsWithMdns,DnsOverHttps` to block
    WebRTC mDNS leaks and DoH bypass
  • `–disable-background-networking`, `–disable-breakpad`,
    `–disable-crash-reporter`, `–disable-sync`

**Fingerprint randomization, regenerated every launch**:

  • `/etc/machine-id` replaced with 16 random hex bytes
  • `/sys/class/net/*/address` replaced with fake locally-administered MACs
    (02:xx:xx:xx:xx:xx format)
  • `/sys/class/dmi/id/product_uuid`, `board_serial`, `product_serial`,
    `chassis_serial` replaced with random values
  • `/sys/class/dmi/id/sys_vendor`, `product_name` set to generic QEMU strings
  • `/proc/cpuinfo`, `/proc/meminfo` replaced with a static minimal fake
  • Hostname set to `debian`, `/etc/hosts` rewritten to match
  • `TZ=UTC` so no timezone leaks

**bubblewrap isolation**:

  • `–unshare-user --unshare-pid --unshare-ipc --unshare-uts --unshare-cgroup`
  • `–cap-drop ALL`
  • No dbus access (`DBUS_SESSION_BUS_ADDRESS=“”`)
  • Isolated fake home at `~/.local/share/onekey-home/` — the app never
    sees your real `~`
  • `/sys` mounted read-only (required for libusb USB enumeration, without
    it `onekeyd` can’t find the hardware wallet even with correct permissions)
  • USB device access via `–dev-bind-try /dev/bus/usb` with host-side udev
    rules for the 1209:4f4a (OneKey Pro), 1209:4f4b (bootloader mode),
    and 1209:53c1 (Trezor-compat mode) VID:PIDs

**Tor hardening in torrc**:

  • `SocksPort 127.0.0.1:9050 IsolateDestAddr IsolateDestPort`
  • `DNSPort 127.0.0.1:5353`, `AutomapHostsOnResolve 1`
  • `SafeSocks 1` — refuses raw-IP SOCKS requests, forces remote DNS
  • `ClientRejectInternalAddresses 1`
  • `ClientUseIPv6 0`
  • `ExcludeExitNodes {us},{gb},{ca},{au},{nz},{ru},{cn}` with `StrictNodes 1`

**Verification after launch**:

```
$ sudo ss -tnp state established | grep -iE ‘onekey|electron’
ESTAB 127.0.0.1:43892 → 127.0.0.1:9050 users:((“onekey-wallet”,…))
ESTAB 127.0.0.1:43904 → 127.0.0.1:9050 users:((“onekey-wallet”,…))
ESTAB 127.0.0.1:56720 → 127.0.0.1:21320 users:((“onekey-wallet”,…))

everything goes to loopback, 9050=Tor and 21320=local bridge

$ sudo timeout 20 tcpdump -n -i any ‘port 53 and not host 127.0.0.1’

empty output — no DNS leaks

$ sudo ss -tn6 state established | grep -iE ‘onekey’

empty — no IPv6 leaks

SCOPE=(systemctl --user list-units ‘onekey-*.scope’ --no-legend | \
awk ‘{print $1}’ | head -1)
$ systemctl --user show “$SCOPE” -p IPAddressDeny -p IPAddressAllow
IPAddressAllow=127.0.0.0/8
IPAddressDeny=0.0.0.0/0 ::/0
```

Took a few iterations to get right. The main gotchas:

  1. `–dev /dev` creates a minimal devtmpfs; you need `–dev-bind` for
    USB or the device nodes don’t update when you re-plug
  2. `/sys` must be in the sandbox (read-only is fine) or libusb can’t
    enumerate
  3. `/run/udev` needs to be bound or udev metadata lookups fail silently
  4. If you use `–proxy-bypass-list=“<-loopback>”` (the Chromium “don’t
    bypass loopback” flag), the local `onekeyd` bridge becomes unreachable
    because the app tries to proxy its own requests to 127.0.0.1:21320
    through Tor, and Tor refuses private addresses
  5. `–host-resolver-rules` needs `EXCLUDE localhost` explicitly, not
    just `EXCLUDE 127.0.0.1`, because the app sometimes uses the name

Firmware updates work inside the sandbox, including the device rebooting
into bootloader mode (VID:PID changes from 4f4a to 4f4b during flash),
provided your libvirt/QEMU XML has hostdev entries for all three VID:PIDs
instead of a single usbredir channel (usbredir loses the handle when
the device re-enumerates).

Alternatives if you’re shopping

No wallet is perfect. But none of these are simultaneously registered
in HK, routing traffic through `.cn`, claiming US storage, referencing
Singapore compliance, and admitting compliance with PRC ministry orders:

  • **Trezor Safe 3 / Model T** (Czech Republic) — audited regularly,
    open source, Trezor Suite does phone home but clearly documented
  • **Coldcard Mk4** (US) — fully air-gappable via PSBT, no app needed
  • **Passport** by Foundation (US) — air-gapped by design, open source
  • **BitBox02** (Switzerland) — minimal network footprint
  • **Blockstream Jade** — QR-based air gap option

Pick based on your threat model. For “I don’t want my wallet metadata
in PRC-adjacent flows,” any of the above is a better default.

What this isn’t

I’m not claiming OneKey is malware. I’m not saying they’re stealing
seeds (they’re not — the keys stay on the device, as advertised, and
the device itself is solid hardware). I’m not accusing them of
intentional bad faith.

What I’m saying is:

  1. The telemetry is mandatory — no opt-out exists in the app
  2. The endpoints include `.cn` domains, which routes metadata through
    a jurisdiction with different compulsory-disclosure rules
  3. Three of their own legal documents tell three different stories about
    where the company and the data are
  4. Their own Terms confirm compliance with PRC regulatory instructions
  5. Their maximum liability if they mishandle your data is ~$350

For many users these tradeoffs will be fine. They should still be
disclosed clearly. And users who do care should have a way to isolate
the app without reverse-engineering its network behavior themselves.

Happy to take corrections. All quotes are verbatim from:

I have local copies in case the URLs or content change.


Edit: to the folks saying “just block the domains in /etc/hosts” —
tried that, breaks firmware updates and a few app panels. The sandbox
approach is more complete because it covers DNS leaks, IPv6 leaks,
fingerprint stability across sessions, and incidental bypasses. If all
you want is basic mitigation, yes, hosts blocking works for everyday use.

1 Like