Skip to content
Z

ZyphBridge

Cross-chain transfers that preserve privacy.

Created on 4th December 2025

Z

ZyphBridge

Cross-chain transfers that preserve privacy.

The problem ZyphBridge solves

Bridging Privacy-Preserving Blockchains

Zcash users have access to industry-leading privacy through shielded transactions, but their assets are siloed within the Zcash ecosystem. Meanwhile, Miden offers a new paradigm of private, scalable computation through zero-knowledge proofs. ZyphBridge solves the critical problem of moving value between these two privacy-focused chains.

Key Use Cases:

  • Private DeFi Access: Zcash holders can now access Miden's private smart contract ecosystem without sacrificing privacy at the bridge layer
  • Cross-Chain Privacy Preservation: Unlike most bridges that expose transaction details, ZyphBridge maintains privacy guarantees on both sides—shielded ZEC transactions on Zcash, private notes on Miden
  • Unified Liquidity: Enables ZEC liquidity to flow into Miden dApps while maintaining the privacy properties users expect

How It Works:

  1. Deposit (ZEC → wZEC): Users send shielded ZEC to the bridge's Zcash address. Once confirmed, the bridge mints equivalent wZEC tokens on Miden as private notes
  2. Withdraw (wZEC → ZEC): Users burn wZEC on Miden, then claim their ZEC which is sent to their shielded Zcash address

The bridge operator monitors both chains, verifying deposits/burns and executing the corresponding mint/send operations—all while preserving the privacy guarantees of both networks.

Challenges I ran into

1. Miden Wallet Address Format Mismatch

The Bug: The bridge UI showed

0 wZEC

balance even after successfully minting tokens via the faucet.

Root Cause: The Miden wallet adapter returns asset faucet IDs in bech32m format (e.g.,

mtst1azwuvc3clmzrqgz988cg09clssuq4jsq_qruqqypuyph

), but our code was comparing against hex format (

0x9dc66238fec430204539f087971f84

).

Solution: Implemented bech32m decoding in the frontend to convert wallet-returned addresses to hex for comparison:

const decoded = bech32m.decode(addressPart, 90); const bytes = bech32m.fromWords(decoded.words); const hex = '0x' + bytes.map(b => b.toString(16).padStart(2, '0')).join('');


2. Wallet Transaction API Confusion

The Bug: Burn transactions failed with

INVALID_PARAMS: Invalid CustomTransaction payload

.

Root Cause: The Miden wallet adapter has multiple transaction methods. Using

requestTransaction()

with a generic

Transaction

wrapper didn't work for send operations.

Solution: Used

adapter.requestSend()

directly with a properly typed

MidenSendTransaction

object, and discovered all address fields must be in bech32 format (not hex):

const sendTransaction: MidenSendTransaction = { senderAddress: address, // bech32 recipientAddress: WZEC_FAUCET_ADDRESS, // bech32 faucetId: WZEC_FAUCET_ADDRESS, // bech32 noteType: 'private', amount: amountInSmallestUnits, }; await adapter.requestSend(sendTransaction);


3. Zcash Shielded Balance Timing

The Bug: After claiming a withdrawal,

z_getbalance

returned

0

even though the transaction was sent.

Root Cause: Zcash shielded (Sapling) transactions require block confirmations before the balance is spendable and visible.

Solution: Mine at least one block after the withdrawal transaction before checking balance. In production, the UI should poll or wait for confirmations.

Tracks Applied (1)

Cross-Chain Privacy Solutions

How ZyphBridge Fits the Cross-Chain Privacy Solutions Track ZyphBridge is a privacy-preserving bridge between Zcash and...Read More

Miden

Technologies used

Cheer Project

Cheering for a project means supporting a project you like with as little as 0.0025 ETH. Right now, you can Cheer using ETH on Arbitrum, Optimism and Base.

Discussion

Builders also viewed

See more projects on Devfolio