Portable libraries for transparent → shielded Zcash transactions
t2z enables existing transparent-only Zcash infrastructure to send to shielded Orchard addresses without requiring a full wallet implementation. Built on the PCZT (Partially Constructed Zcash Transaction) format.
- 🔐 Privacy upgrade path — Send from transparent inputs to shielded Orchard outputs
- 📦 PCZT format — Multi-party transaction construction, hardware wallet support
- ⚡ No downloads — Orchard uses Halo 2, proving key built on demand (~10s, cached)
- 🦀 Battle-tested — Built on official Zcash Rust libraries
| Platform | Package | Status |
|---|---|---|
| TypeScript | @d4mr/t2z-wasm |
✅ Available |
| Go | github.com/d4mr/t2z/sdks/go |
✅ Available (build from source) |
| Kotlin | com.d4mr:t2z |
✅ Available (build from source) |
npm install @d4mr/t2z-wasmimport * as t2z from '@d4mr/t2z-wasm';
// 1. Create the transaction
let pczt = t2z.propose_transaction(
[new t2z.WasmTransparentInput(
pubkeyHex, // 33-byte compressed pubkey
prevoutTxidLE, // Previous tx ID (little-endian)
0, // Output index
1_000_000n, // 0.01 ZEC in zatoshis
scriptPubkeyHex, // P2PKH script
null // Sequence (default)
)],
[new t2z.WasmPayment(
'u1recipient...', // Unified address with Orchard
900_000n, // Amount in zatoshis
null, // Memo (hex)
null // Label
)],
'u1change...', // Change address
'testnet', // Network
3720100 // Expiry height
);
// 2. Sign transparent inputs (external signing supported)
const sighash = t2z.get_sighash(pczt, 0);
const signature = await yourSigner.sign(sighash); // Hardware wallet, HSM, etc.
pczt = t2z.append_signature(pczt, 0, pubkeyHex, signature);
// 3. Generate Orchard proofs
pczt = t2z.prove_transaction(pczt);
// 4. Finalize and broadcast
const txHex = t2z.finalize_and_extract_hex(pczt);
await broadcast(txHex);- Full Documentation — Guides, API reference, examples
- Live Demo — Interactive transaction builder
- API Reference — Complete function docs
┌─────────┐ ┌────────┐ ┌──────┐ ┌───────┐ ┌──────────┐
│ Propose │───▶│ Verify │───▶│ Sign │───▶│ Prove │───▶│ Finalize │
└─────────┘ └────────┘ └──────┘ └───────┘ └──────────┘
(optional)
- Propose — Create PCZT from inputs and payments
- Verify — Validate PCZT matches request (if from third party)
- Sign — Add signatures for transparent inputs
- Prove — Generate Orchard ZK proofs
- Finalize — Extract raw transaction for broadcast
t2z/
├── crates/
│ ├── t2z-core/ # Core Rust library
│ ├── t2z-wasm/ # WebAssembly bindings
│ └── t2z-uniffi/ # Go/Kotlin bindings (UniFFI)
├── demo/ # Interactive demo (React + Vite)
└── docs/ # Documentation (Mintlify)
# Install LLVM and wasi-libc
brew install llvm
brew install --HEAD aspect-build/aspect/wasi-libc
# Add wasm32 target
rustup target add wasm32-unknown-unknown
# Build the WASM package
cd crates/t2z-wasm
CC="$(brew --prefix llvm)/bin/clang" \
AR="$(brew --prefix llvm)/bin/llvm-ar" \
RUSTUP_TOOLCHAIN=nightly \
wasm-pack build --scope d4mr# Install dependencies (Ubuntu/Debian)
sudo apt install clang lld
# Add wasm32 target
rustup target add wasm32-unknown-unknown
# Build
cd crates/t2z-wasm
RUSTUP_TOOLCHAIN=nightly wasm-pack build --scope d4mrThe built package will be in crates/t2z-wasm/pkg/.
- ZIP 374: PCZT Specification (Draft)
- ZIP 317: Proportional Fee Mechanism
- ZIP 244: Transaction Signature Validation
- ZIP 321: Payment Request URIs
MIT © d4mr
