Skip to content
t2z

t2z

transparent to shielded (PCZT) polyglot library

Created on 4th December 2025

t2z

t2z

transparent to shielded (PCZT) polyglot library

The problem t2z solves

Problem

Zcash shielded transactions require Rust-based tooling, locking out developers working in Go, TypeScript, Kotlin, and Java. There's no cross-language solution for building and signing shielded transactions (PCZTs).

until now

Solution

Rust core with idiomatic native bindings for Go, TypeScript, Kotlin, and Java.

Build and sign shielded Zcash transactions in your language. No Rust knowledge needed. The crypto stays in battle-tested Rust, you just call it from whatever stack you're already using.

More devs can build on Zcash without learning a new language.

Challenges I ran into

CHALLANGES

Understanding the ecosystem

I started from 0 the only thing I knew of ZEC was that it has privacy features, the ticker and my balance on CEX. The zcash ecosystem can be a bit confusing, nodes, wallets, libraries.

I acquired the knowledge for the appropriate and up2date tools. (And thx to NEAR intents I was confident to fully offboard from CEX)


ZIP-317 Fee Calculation Mismatch

I calculated fees differently than the Builder, causing "ChangeRequired" errors when amounts didn't balance

I matched the Builder's exact formula:

5000 * max(2, logical_actions)

.


Upstream Library Breaking Changes

Initially I created a fork and fixed the bugs (https://github.com/gstohl/librustzcash/tree/pczt-append-transparent-sigs) and added needed features of library branch https://github.com/zcash/librustzcash/tree/pczt-append-transparent-sigs. When upstream fixed things and added features, method names and signatures changed.

After upstream updated I had to migrated to it, so I needed to update renamed methods and new error variants.


Cross-Language Memory Management

Rust uses ownership/borrowing, but Go/TypeScript/Kotlin/Java have garbage collection.

I serialize PCZT to bytes at FFI boundary, each language manages its own copy.


Bridge Solution Selection

I had to choose from multiple options for each language (cgo vs pure Go, N-API vs WASM vs KOFFI, JNI vs JNA) with different tradeoffs.

I selected based on maintainability:

  • Go → cgo
  • TypeScript → koffi
  • Kotlin/Java → JNA

Unified Workflow Across Languages

Each language has different idioms for error handling, async, and byte arrays.

I wrapped the same C FFI but made each binding feel native, for example:

  • Go: multiple return values for errors
  • TypeScript: promises and thrown exceptions
  • Kotlin/Java: exceptions with ByteArray/byte[]

Submission Video

The hardest challenge was to make the submission video

Tracks Applied (3)

Privacy Infrastructure & Developer Tools

Fulfilling all requirements based on the technical specs. All four requested languages implemented in their idiomatic wa...Read More

Electric Coin Company

Privacy Infrastructure & Developer Tools

t2z is a multi-language library (TypeScript, Go, Java, Kotlin) with idiomatic bindings that lets developers easily add Z...Read More

Zcash Community Grants

General Bounty

t2z is a multi-language library (TypeScript, Go, Java, Kotlin) with idiomatic bindings that lets developers easily add Z...Read More

Project Tachyon

Discussion

Builders also viewed

See more projects on Devfolio