Case Study · Product Management · Web3 Privacy

From Fork to Mainnet: Shipping a Zero-Knowledge Privacy Wallet on Telos

A product management case study.

Snapshot

Client Telos Foundation (delivered through Protofire)
Mandate Take zero-knowledge private transactions from "impressive cryptography" to a shipped consumer wallet on Telos EVM — web and desktop
Timeline ~9 months from initial fork to mainnet, plus seven releases
Team A lean Protofire squad — a handful of engineers, me as PM
My role Product management end to end: scope, UX, release management, security triage, and on-chain reporting

The challenge

Telos wanted privacy as a first-class feature of its EVM ecosystem: a wallet where users could shield TLOS or USDC.e into a zero-knowledge pool, transact privately, and unshield when done. Building a zk system from scratch means years of cryptography work and audits a lean team can't afford.

The pragmatic answer was to fork zkBob — a battle-tested privacy protocol with an existing UI. But a fork is not a head start you get for free. We inherited another product's branding, another chain's assumptions, debugging hooks left in production code, deprecated build tooling, and UX decisions made for a different audience. And the deliverable wasn't just a web app: the client wanted native desktop applications for macOS, Windows, and Linux too.

So the real challenge was less "build a privacy wallet" and more "turn someone else's privacy wallet into ours — and make ordinary users trust it with their money."

Move 1 — Fork deliberately, and budget for the repayments

Choosing to fork was easy; choosing how to fork was the actual product decision. I framed it to the team as taking out a loan: we were borrowing years of protocol and UI work at the interest rate of someone else's decisions, and the repayments had to be scheduled like any other work — not discovered in production.

The first stretch of the project was almost entirely repayment. We stripped out the previous chain's references, rebranded every user-facing string, wired in Telos network configuration and pool contracts, stood up the relayer, and wrapped the React app in Electron for desktop builds. None of it demos well. All of it was load-bearing.

The discipline that made this work was refusing to let "it's just a fork" become an excuse to skip product thinking. Every inherited screen got the same question a new screen would: does this serve our user on our chain? A surprising amount of it didn't — which is exactly the debt a fork hides if you don't go looking for it.

Move 2 — Ship the rails before the features

Before mainnet, we built an almost boring operational layer: CI/CD pipelines deploying the web app to S3 behind CloudFront with staging and production environments, automated multi-platform Electron builds, a Playwright end-to-end suite, and monitoring on the relayer that keeps the whole system alive.

This is the part of the job with no screenshots, and it's also why we could sustain a real release cadence — seven tagged versions from v0.0.1 to v0.0.7 — with a small team and no release-day heroics. When a fee-display bug or a chain-sync issue surfaced, the path from fix to production was minutes of pipeline, not an afternoon of manual steps.

For a financial product, the rails are a feature. Users don't see the deployment pipeline, but they feel its absence the first time a broken build ships or a fix takes a week to reach them. Paying this cost early meant the later, more visible product work — onboarding, bridging, UX polish — could ship continuously instead of in big risky batches.

Move 3 — Treat UX as the actual privacy feature

Privacy products don't usually fail on cryptography; they fail on confusion. A user who doesn't understand where privacy starts and stops will leak more through their own behavior than any protocol flaw ever will. So we treated the interface as part of the threat model.

We replaced the inherited guided-tour library with a clean three-step onboarding modal, designed proper empty states that tell a new user what to do first, and made the balance-visibility toggle actually consistent — hiding not just balances but transaction amounts and fees across activity and history, because a "hidden" balance you can reconstruct from the history list isn't hidden.

The sharpest example was the in-app bridge. We integrated LI.FI so users could fund their wallet without leaving the app — but a bridge transaction is public, and dropping it inside a privacy wallet invites a dangerous assumption. We added an explicit, dismissible notice inside the widget: this action happens on your public wallet. Teaching users the boundary of their privacy became a design requirement, not a docs footnote. We also shipped the interface in four languages, because a privacy tool you half-understand is a privacy tool that fails you.

Move 4 — Audit your own product like a hostile reviewer

Mid-project, I ran a structured security and privacy review of our own codebase and wrote it up the way an external auditor would: seven findings, each with a severity rating and an effort-to-fix estimate.

The findings were uncomfortable in exactly the way they needed to be. The most ironic: the wallet — a privacy product — was fetching each user's IP address from a third-party geolocation API and attaching it to error-tracking events. Inherited debugging hooks exposed cryptographic functions globally. The review also flagged deeper structural risks: deprecated build tooling, an 800-line context file at the heart of the privacy logic, and the fact that the single centralized relayer wasn't disclosed to users.

The format mattered as much as the findings. Severity-plus-effort turns security debt into a plannable backlog instead of a vague cloud of anxiety: the criticals were cheap to fix and got prioritized immediately; the structural items became scheduled workstreams. Many teams treat security review as something done to them at the end. Doing it to ourselves, mid-flight, meant we controlled the timeline instead of the findings controlling us.

Move 5 — Measure truth on-chain, not in dashboards

Once the wallet was live on mainnet, the question became: is anyone actually using it? Rather than trust the UI or an internal dashboard, I built a zero-dependency Node script that reads the pool contracts directly from the Telos RPC — every shield and unshield transfer, TVL straight from balanceOf, methodology documented so anyone could verify the numbers themselves on the block explorer.

The numbers were humbling, and we reported them anyway: utilization was a small fraction of what the business case anticipated, concentrated in a handful of large deposits rather than broad usage, with one pool effectively dormant. That's not a fun report to write. It's also the most useful artifact the project produced in that period, because it moved the conversation from "which feature next?" to the real problem — distribution and adoption.

A polished product with honest, bad usage numbers is a solvable situation. A polished product with flattering, wrong numbers is how teams spend a year building features nobody was waiting for. The chain doesn't flatter you; that's exactly why it's the right place to measure.

Results

What I'd tell other PMs

  1. A fork is a loan, not a gift. You're borrowing years of someone else's work at the interest rate of their decisions. Schedule the repayments explicitly, or they'll schedule themselves — in production.
  2. For privacy products, UX is the threat model. Users leak more through confusion than through cryptography. Every screen that touches the public/private boundary needs to teach it.
  3. Audit yourself before someone else does. A findings document with severity and effort estimates turns security debt into a backlog you can plan. Waiting for an external audit means the findings control your timeline.
  4. Get your metrics from the source of truth. If the dashboard and the chain disagree, believe the chain. Build the verification tooling early enough that nobody has to argue about whose numbers are right.
  5. Report the bad numbers. Low utilization was the most valuable finding of the entire project — it redirected the roadmap toward the real problem. Flattering metrics would have bought us another quarter of building the wrong thing.

Written by João Capinha, Product Manager.

Want to talk product, privacy, or shipping with lean teams?

Book a 30-min call ← Back to profile