Self-custody wallet

Your keys never
leave the device.

The wallet built into Searxly is real self-custody — standard BIP-39 keys, generated and encrypted on your Mac, signing every transaction locally. We hold nothing. We can't see your phrase, we can't move your funds, and there's no server that could.

The key model

From phrase to signature, all on-device.

Your wallet starts as a standard 12/24-word BIP-39 recovery phrase. From it, keys are derived with BIP-32 hierarchical derivation at the standard Ethereum path, so the same phrase restores your accounts in MetaMask or any standard wallet. The seed is then encrypted and locked away — it only ever decrypts in memory, for the instant it takes to sign.

  • Real BIP-39 entropy + checksum, not a homemade scheme
  • Standard m/44'/60'/0'/0/x derivation — portable everywhere
  • secp256k1 signing via a vetted, known-answer-tested core
BIP-39 recovery phrase
Entropy + SHA-256 checksum · 2048-word list
↓  PBKDF2-SHA512
HD seed → BIP-32 derivation
m/44'/60'/0'/0/x · one phrase, every account
secp256k1 private keys
Address + recoverable, low-S signatures
↓  encrypt at rest
🔒 AES-256-GCM, PIN-derived key
PBKDF2-SHA256 · per-wallet random salt
🔒 Device-only Keychain
Secure-Enclave-bound · non-syncable · this device only
The seed never leaves the Mac — not to us, not to a cloud
Cryptography

The primitives, named.

Mnemonic
BIP-39 — real entropy, SHA-256 checksum, 2048-word list (typos rejected on import)
Seed derivation
PBKDF2-SHA512 → BIP-32 HD at m/44'/60'/0'/0/x
Signing curve
secp256k1 — recoverable, low-S signatures (known-answer tested)
Transactions
EIP-1559 (type-0x02) build, sign & serialize; EIP-191 / EIP-712 message signing
Seed encryption
AES-256-GCM with a PIN/passphrase-derived key (PBKDF2-SHA256, per-wallet random salt)
Key storage
Device-only Keychain, WhenUnlockedThisDeviceOnly, non-syncable
PIN verification
By attempting seed decryption — the GCM tag is the verifier; no separate hash to crack
Networks
Five EVM chains (Base, Ethereum, Optimism, Arbitrum, Polygon) from one phrase
Defense in depth

Even with your Mac, an attacker hits a wall.

Keeping keys on-device is the foundation. On top of it sits a stack of controls aimed at the realistic attacks — a stolen prefs file, a malicious dApp, a look-alike address.

PIN with a real lockout

The PIN is verified by decrypting the seed, not against a fast hash an attacker could brute-force offline. Five wrong tries triggers an escalating cooldown (30s → up to 15m) with a live countdown.

Secure-Enclave biometrics

Touch ID unlock is gated by the Secure Enclave with .biometryCurrentSet, so the key is invalidated if fingerprints change. On hardware without an Enclave, a PIN-only seed is refused in favor of a passphrase.

Phishing-domain guard

Before any connect or signature, the origin is checked against a local scam blocklist plus a punycode / homograph heuristic. A flagged site gets a loud red banner and a deliberate "connect anyway" override.

Transaction simulation

Pending transactions are dry-run against the chain first. If the real transaction would revert, you're warned "likely to fail — you'd still pay gas" before you sign, not after.

Plain-language decode

Approvals are decoded locally into what they actually do — "Send 1.0 SEARXLY to 0x…", or a bright warning on an unlimited token allowance — so you're never blind-signing opaque calldata.

Approval revocation

A built-in allowance manager lists what you've approved (unlimited grants first) and revokes any of them in a click — the cleanup that drains so often exploit.

Address-poisoning protection

A recipient that mimics the first- and last-four characters of an address you've actually sent to — the classic poisoning trick — is flagged and needs an explicit acknowledgement.

Origin-bound dApp approvals

The injected provider only answers on standard tabs once you've connected; every sign/send is bound to the requesting origin (taken from the frame, never page-supplied), and eth_sign is refused outright.

Rotating per-dApp addresses

Optionally give every site its own fresh address from a hidden derived pool, so on-chain watchers can't link your activity across dApps — and switching accounts never changes what a connected site sees.

The bottom line

What we can never do.

Self-custody isn't a setting — it's the absence of a capability. There is no server, no escrow, and no recovery backdoor on our side. The flip side is real responsibility: your recovery phrase is the only way back in, so back it up offline and never share it.

How keys are stored at rest
  • We can't see your recovery phrase or private keys — they're encrypted on your device and never transmitted.
  • We can't move, freeze, or claw back your funds — every transaction is signed locally by you.
  • We can't sign on your behalf — there's no custodial key and no server with signing power.
  • We can't reset your PIN remotely — recovery happens locally, from your phrase or recovery code.
  • We can't be compelled to hand over what we don't hold — there's nothing custodial to subpoena.

Verifiable on-chain, signed on-device.

Your holding is your membership — proven by a signature, never parked on our servers.