Skip to main content

Installation

  • TypeScript
  • Go
  • Kotlin
npm install @d4mr/t2z-wasm
# or
pnpm add @d4mr/t2z-wasm
# or
yarn add @d4mr/t2z-wasm

Basic Example

Build a transaction that sends from a transparent input to a shielded Orchard address:
  • TypeScript
  • Go
  • Kotlin
import * as t2z from '@d4mr/t2z-wasm';

// 1. Create the transaction
const pczt = t2z.propose_transaction(
  // Transparent inputs
  [new t2z.WasmTransparentInput(
    pubkeyHex,        // 33-byte compressed pubkey
    prevoutTxid,      // Previous tx ID (little-endian)
    0,                // Output index
    1000000n,         // Value: 0.01 ZEC in zatoshis
    scriptPubkey,     // P2PKH script
    null              // Sequence (default: 0xffffffff)
  )],
  // Payments
  [new t2z.WasmPayment(
    'u1...',          // Unified address with Orchard
    900000n,          // Amount in zatoshis
    null,             // Optional memo (hex)
    null              // Optional label
  )],
  'u1...',            // Change address
  'testnet',          // 'mainnet' or 'testnet'
  3720100             // Expiry height
);

// 2. Sign transparent inputs
const sighash = t2z.get_sighash(pczt, 0);
// Sign with your key (external signer, hardware wallet, etc.)
const signature = sign(sighash, privateKey);
pczt = t2z.append_signature(pczt, 0, pubkeyHex, signature);

// 3. Generate Orchard proofs
pczt = t2z.prove_transaction(pczt);

// 4. Finalize and get raw transaction
const txHex = t2z.finalize_and_extract_hex(pczt);

// 5. Broadcast to network
await broadcastTransaction(txHex);

Key Concepts

A Partially Constructed Zcash Transaction (PCZT) is a standardized format for building Zcash transactions incrementally. It allows different parties to add inputs, signatures, and proofs without needing access to all private keys.Learn more about PCZT →
Block explorers display transaction IDs in big-endian (human-readable) format, but Zcash internally uses little-endian. When using a txid from an explorer, you need to reverse the bytes.
// Explorer shows: abcd1234...
// Internal format: ...3412cdab
const internalTxid = explorerTxid.match(/../g).reverse().join('');
Every Zcash transaction has an expiry height - the block height after which the transaction is no longer valid. You should set this to currentBlockHeight + 40 or more to avoid “tx-expiring-soon” errors.
const currentHeight = await fetchCurrentBlockHeight();
const expiryHeight = currentHeight + 100; // ~2.5 hour buffer

Next Steps