> ## Documentation Index
> Fetch the complete documentation index at: https://t2z.d4mr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Go

> Use t2z in Go applications via UniFFI

<Badge variant="success">Available</Badge>

The Go SDK is available at `github.com/d4mr/t2z/sdks/go`. It uses [UniFFI](https://mozilla.github.io/uniffi-rs/) bindings to the Rust core.

## Installation

Since the Go SDK requires the native `libt2z_uniffi` library, you need to build from source:

```bash theme={null}
# Clone the repository
git clone https://github.com/d4mr/t2z
cd t2z/crates

# Build the UniFFI library
cargo build --release -p t2z-uniffi

# macOS: target/release/libt2z_uniffi.dylib
# Linux: target/release/libt2z_uniffi.so
```

Set the library path:

```bash theme={null}
# macOS
export DYLD_LIBRARY_PATH=/path/to/t2z/crates/target/release:$DYLD_LIBRARY_PATH

# Linux
export LD_LIBRARY_PATH=/path/to/t2z/crates/target/release:$LD_LIBRARY_PATH
```

## Quick Start

```go theme={null}
package main

import (
    "fmt"
    "log"
    
    t2z "github.com/d4mr/t2z/sdks/go/t2z_uniffi"
)

func main() {
    // 1. Create transparent input
    input := t2z.UniffiTransparentInput{
        Pubkey:       "03abc123...",  // 33-byte compressed pubkey (hex)
        PrevoutTxid:  "ce15f716...",  // 32-byte txid (little-endian hex)
        PrevoutIndex: 0,
        Value:        1_000_000,      // 0.01 ZEC in zatoshis
        ScriptPubkey: "76a914...88ac", // P2PKH script (hex)
        Sequence:     nil,
    }

    // 2. Create payment
    payment := t2z.UniffiPayment{
        Address: "u1recipient...", // Unified address with Orchard
        Amount:  900_000,
        Memo:    nil,
        Label:   nil,
    }

    request := t2z.UniffiTransactionRequest{
        Payments: []t2z.UniffiPayment{payment},
    }

    // 3. Propose transaction
    changeAddr := "u1change..."
    pczt, err := t2z.ProposeTransaction(
        []t2z.UniffiTransparentInput{input},
        request,
        &changeAddr,
        "testnet",
        3720100,
    )
    if err != nil {
        log.Fatal(err)
    }

    // 4. Sign transparent inputs (external signing)
    sighash, err := t2z.GetSighash(pczt, 0)
    if err != nil {
        log.Fatal(err)
    }
    
    // Sign the sighash with your key (ECDSA secp256k1)
    signature := sign(sighash, privateKey) // Your signing logic
    
    pczt, err = t2z.AppendSignature(pczt, 0, pubkeyHex, signature)
    if err != nil {
        log.Fatal(err)
    }

    // 5. Generate Orchard proofs (~10 seconds first time)
    pczt, err = t2z.ProveTransaction(pczt)
    if err != nil {
        log.Fatal(err)
    }

    // 6. Finalize and get raw transaction
    txHex, err := t2z.FinalizeAndExtractHex(pczt)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Transaction ready:", txHex)
}
```

## API Reference

### Transaction Construction

| Function              | Description                            |
| --------------------- | -------------------------------------- |
| `ProposeTransaction`  | Create a PCZT from inputs and payments |
| `VerifyBeforeSigning` | Verify PCZT matches original request   |

### Signing

| Function               | Description                      |
| ---------------------- | -------------------------------- |
| `GetSighash`           | Get sighash for external signing |
| `AppendSignature`      | Add a pre-computed signature     |
| `SignTransparentInput` | Sign with in-memory private key  |

### Proving & Finalization

| Function                | Description                     |
| ----------------------- | ------------------------------- |
| `ProveTransaction`      | Generate Orchard ZK proofs      |
| `FinalizeAndExtract`    | Extract final transaction bytes |
| `FinalizeAndExtractHex` | Extract as hex string           |
| `CombinePczts`          | Combine multiple PCZTs          |

### Utilities

| Function             | Description                      |
| -------------------- | -------------------------------- |
| `PrebuildProvingKey` | Pre-build proving key at startup |
| `IsProvingKeyReady`  | Check if proving key is cached   |
| `Version`            | Get library version              |

## Types

### UniffiTransparentInput

```go theme={null}
type UniffiTransparentInput struct {
    Pubkey       string   // 33-byte compressed pubkey (hex)
    PrevoutTxid  string   // 32-byte txid (little-endian hex)
    PrevoutIndex uint32   // Output index
    Value        uint64   // Value in zatoshis
    ScriptPubkey string   // P2PKH scriptPubkey (hex)
    Sequence     *uint32  // Optional sequence number
}
```

### UniffiPayment

```go theme={null}
type UniffiPayment struct {
    Address string   // Unified or transparent address
    Amount  uint64   // Amount in zatoshis
    Memo    *string  // Optional memo (hex-encoded)
    Label   *string  // Optional label
}
```

### UniffiExpectedTxOut

```go theme={null}
type UniffiExpectedTxOut struct {
    Address string  // Expected address
    Amount  uint64  // Expected amount (0 = wildcard)
}
```

### UniffiPczt

```go theme={null}
// Create from bytes or hex
pczt, err := t2z.NewUniffiPcztFromBytes(bytes)
pczt, err := t2z.NewUniffiPcztFromHex(hexString)

// Serialize
bytes := pczt.ToBytes()
hexStr := pczt.ToHex()
```

## Error Handling

All functions return Go-style errors:

```go theme={null}
pczt, err := t2z.ProposeTransaction(inputs, request, &changeAddr, network, expiry)
if err != nil {
    // UniffiError with detailed message
    log.Printf("Failed to propose: %v", err)
    return
}
```

## Performance Tips

### Pre-build Proving Key

The first proof generation takes \~10 seconds. Pre-build at startup:

```go theme={null}
func init() {
    if !t2z.IsProvingKeyReady() {
        log.Println("Building Orchard proving key...")
        t2z.PrebuildProvingKey()
        log.Println("Proving key ready")
    }
}
```

## Type Mappings

| TypeScript             | Go                       |
| ---------------------- | ------------------------ |
| `WasmTransparentInput` | `UniffiTransparentInput` |
| `WasmPayment`          | `UniffiPayment`          |
| `WasmPczt`             | `*UniffiPczt`            |
| `bigint`               | `uint64`                 |
| `string` (hex)         | `string` (hex)           |
| `null`                 | `nil` / pointer          |

## Building from Source

```bash theme={null}
# Clone the repository
git clone https://github.com/d4mr/t2z
cd t2z/crates

# Build the UniFFI library
cargo build --release -p t2z-uniffi

# Regenerate Go bindings (requires uniffi-bindgen-go)
cargo install uniffi-bindgen-go \
  --git https://github.com/NordSecurity/uniffi-bindgen-go \
  --tag v0.4.0+v0.28.3

uniffi-bindgen-go \
  --library target/release/libt2z_uniffi.dylib \
  --out-dir ../sdks/go
```

## Related

* [t2z Documentation](https://t2z.d4mr.com)
* [ZIP 374: PCZT Specification](https://github.com/zcash/zips/pull/1063)
* [NordSecurity/uniffi-bindgen-go](https://github.com/NordSecurity/uniffi-bindgen-go)
