Skip to content
ninah

ninah

Private stablecoin payments on Base

Created on 16th January 2026

ninah

ninah

Private stablecoin payments on Base

The problem ninah solves

Over $1 billion in stablecoins moves on-chain every month. Transaction volumes have exploded from just $1.69 billion in January 2019 to a record $969.9 billion in August 2025 one of the fastest adoption curves in digital asset history. Stablecoins now account for over 40% of all cryptocurrency trading volume and facilitate the majority of market activity by both transaction count and value. The market cap has surged from $4.17 billion in 2020 to $283.7 billion in September 2025.

But here's the problem: every single one of these transactions is permanently visible on a public ledger. Anyone can trace what you spend, how much you hold, who you interact with, and your complete financial history.

Yet despite this massive stablecoin scale, Web3 adoption remains limited not because users don’t care about privacy, but because onboarding is a nightmare. Over 60% of potential users abandon onboarding due to wallet setup, gas fees, and seed phrase management. The core issue is that users are asked to manage 12-24 word seed phrases with the constant threat of permanent fund loss, understand why they need ETH just to send USDC, and decode cryptic hex addresses like 0x7a16...3f2b instead of simple usernames.

ninah fixes this by creating a privacy-preserving stablecoin payment system built on Base that eliminates both the privacy problem and the UX nightmare in one solution.

What ninah Makes Possible

  1. Pay anyone privately - Enter username and amount. Stealth address
    generation happens automatically. No crypto knowledge required.

  2. Receive without exposure - Your public username maps to unique
    one-time addresses. Senders never see your main wallet.

  3. Familiar UX - Email login, no gas fees, no seed phrases.

  4. No network confusion - Locked to Base. No chain switching, no wrong-network mistakes.

Who This Is For

UserProblem TodayWith ninah
FreelancersClients see your entire payment history when you invoice themSend @username, client sees nothing else
EmployersPaying salaries on-chain exposes everyone's compensationEach employee receives to a unique stealth address
Everyday usersPaying a friend reveals your wallet balancePrivate by default, no extra steps
MerchantsCustomer payments create linkable transaction graphsEach payment arrives at an unlinkable address

Privacy and usability have always been tradeoffs. ninah eliminates that
tradeoff by hiding complexity stealth addresses and ZK proofs run in the
background while users just see @usernames and one-click payments.

Challenges I ran into

Challenges I Ran Into

1. ZK Proof Generation Costs

Problem: Generating real SP1 zero-knowledge proofs requires computational
resources and funds for on-chain verification. During development and testing,
this created a bottleneck every username registration or payment claim needed
a real proof.

Solution: Implemented a MockSP1Verifier contract that accepts validly structured proofs without cryptographic verification. The frontend generates properly-encoded public values (username hash, commitment) so the architecture mirrors production.


2. Username Privacy Leak

Problem: Our initial design stored usernames in plaintext on-chain. This
defeated the privacy purpose anyone could enumerate all registered usernames
and link them to wallet addresses.

Solution: Usernames are now stored as keccak256(username) hashes. The
registration function checks usernameHash → address mapping, returning
"username taken" without revealing what usernames exist. Users store their
plaintext username locally and can recover it by re-entering it (hash comparison).
Privacy preserved, UX intact.


3. Three-Layer Payment Scanning

Problem: Detecting incoming stealth payments required extracting the
ephemeralPubkeyHash to verify ownership. But ERC-4337 smart wallet
transactions wrap the actual payment call in multiple layers:

LayerContractFunction
1EntryPointhandleOps(UserOperation[])
2Smart Walletexecute(address, value, calldata)
3NinahsendToStealth(address, amount, ephemeralPubkey)

The ephemeralPubkeyHash is emitted in the StealthPaymentSent event and
stored on-chain, but to verify a payment belongs to user, we need to recover
the full ephemeralPubkey which meant unwrapping all three layers of calldata.

Solution: Built a recursive decoder in useStealthPayments.ts that:

  1. Fetches StealthPaymentSent events from the contract
  2. Retrieves the originating transaction hash
  3. Decodes Layer 1 → extracts UserOperation calldata
  4. Decodes Layer 2 → extracts smart wallet inner call
  5. Decodes Layer 3 → extracts ephemeralPubkey from sendToStealth args
  6. Uses ephemeralPubkey + viewing key to verify if payment is ours

This handles the full ERC-4337 flow regardless of paymaster or bundler configuration.

4. Claiming Breaks Privacy

Problem: Stealth addresses hide the recipient during payment but claiming creates a new leak. When a user claims funds, the transaction is sent from their main wallet. on the on-chain this creates a visible link:

StealthAddress → claimed by → MainWallet

Anyone watching can now associate the stealth address with the user's identity,
defeating the privacy we worked to build.

Status: Active research. Current approaches being evaluated:

ApproachTradeoff
Relayer networkUser signs message, relayer submits tx. Adds trust assumption + fees.
Claim to new walletPreserves privacy but fragments funds. UX complexity.
ZK claim proofProve ownership without revealing claimer. Higher gas + complexity.
Delayed batch claimsObscure timing correlation. Partial solution only.

Tracks Applied (1)

Base Track

ninah is a privacy-preserving stablecoin payment system built on Base that solves critical UX challenges through stealth...Read More

Discussion

Builders also viewed

See more projects on Devfolio