# PAR-008: Protocol Type Re-exports

> **Authoritative requirement:** [PAR-008](../NORMATIVE.md#PAR-008)
> **Verification:** [VERIFICATION.md](../VERIFICATION.md)
> **Tracking:** [TRACKING.yaml](../TRACKING.yaml)
> **Spec reference:** [SPEC.md](../../../../resources/SPEC.md) — Section 5.2

---

## Summary

`dig-clvm` MUST re-export the canonical protocol types `Coin`, `CoinSpend`, `SpendBundle`, and `Program` from the `chia-protocol` crate rather than defining its own versions of these types. This ensures wire-format compatibility with the Chia ecosystem, eliminates conversion overhead between `dig-clvm` types and protocol types, and prevents subtle serialization divergences that could cause consensus failures.

These four types are the core data structures of the Chia UTXO model. `Coin` represents a unit of value in the UTXO set (parent_coin_info, puzzle_hash, amount). `CoinSpend` pairs a coin with its puzzle reveal and solution. `SpendBundle` aggregates multiple coin spends with a single BLS signature. `Program` represents a serialized CLVM program (puzzle reveal or solution). By re-exporting these types, `dig-clvm` consumers work directly with the canonical types that `chia-consensus`, `chia-bls`, and other ecosystem crates expect.

On Chia L1, the Python codebase imports these types from `chia.types.blockchain_format` — for example, `CoinSpend` from [`coin_spend.py:6`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/types/blockchain_format/coin_spend.py#L6) and mempool items from [`mempool_item.py:6`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/full_node/mempool_item.py#L6). The Rust ecosystem equivalent is `chia-protocol`, which provides Streamable-compatible serialization matching the L1 wire format exactly. Re-exporting from `chia-protocol` guarantees that `dig-clvm` types are byte-for-byte compatible with the network protocol.

---

## Specification

### Re-export Declarations

In the crate's public API (e.g., `src/lib.rs` or `src/types.rs`):

```rust
// Re-export canonical protocol types.
// These MUST come from chia-protocol, not be redefined.
pub use chia_protocol::Coin;
pub use chia_protocol::CoinSpend;
pub use chia_protocol::SpendBundle;
pub use chia_protocol::Program;
```

### Type Definitions (from chia-protocol)

For reference, these are the canonical types being re-exported:

```rust
// From chia-protocol (simplified):

/// A coin in the UTXO set.
#[derive(Streamable, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Coin {
    pub parent_coin_info: Bytes32,
    pub puzzle_hash: Bytes32,
    pub amount: u64,
}

impl Coin {
    /// Compute the unique coin ID: sha256(parent_coin_info || puzzle_hash || amount)
    pub fn coin_id(&self) -> Bytes32 { ... }
}

/// A coin being spent, with its puzzle reveal and solution.
#[derive(Streamable, Clone, Debug, PartialEq, Eq)]
pub struct CoinSpend {
    pub coin: Coin,
    pub puzzle_reveal: Program,
    pub solution: Program,
}

/// An aggregation of coin spends with a single BLS signature.
#[derive(Streamable, Clone, Debug, PartialEq, Eq)]
pub struct SpendBundle {
    pub coin_spends: Vec<CoinSpend>,
    pub aggregated_signature: G2Element,
}

/// A serialized CLVM program.
#[derive(Streamable, Clone, Debug, PartialEq, Eq)]
pub struct Program(Bytes);
```

### What NOT To Do

```rust
// WRONG: Redefining types
pub struct Coin {
    pub parent_coin_info: [u8; 32],  // Wrong: should be Bytes32
    pub puzzle_hash: [u8; 32],
    pub amount: u64,
}

// WRONG: Wrapper types
pub struct DigCoin(chia_protocol::Coin);  // Unnecessary wrapper

// WRONG: Type aliases with different serialization
type Coin = MyCoin;  // Not wire-compatible
```

### Wire Format Compatibility

The `Streamable` derive macro on `chia-protocol` types ensures that serialization matches the Chia network protocol exactly:

```rust
use chia_traits::Streamable;

// Serialization is byte-for-byte compatible with L1:
let bytes = coin.to_bytes();        // Chia Streamable format
let coin2 = Coin::from_bytes(&bytes); // Round-trip

// These bytes can be sent over the network to Chia nodes
// and will be correctly parsed.
```

### Zero Conversion Overhead

Because `dig-clvm` uses the exact same types as `chia-consensus` and other ecosystem crates, there is no conversion step:

```rust
// Direct use — no conversion needed:
let result = chia_consensus::validate_clvm_and_signature(
    &spend_bundle,  // SpendBundle from chia-protocol, used directly
    &conditions,
    &constants,
    cache,
);

// If dig-clvm defined its own types, this would require:
// let chia_bundle: chia_protocol::SpendBundle = dig_bundle.into(); // overhead!
```

### Cargo.toml Dependency

```toml
[dependencies]
chia-protocol = { version = "..." }
# The exact version should match what chia-consensus expects
# to avoid duplicate type definitions from different versions.
```

---

## Acceptance Criteria

- [ ] `Coin`, `CoinSpend`, `SpendBundle`, and `Program` are re-exported from `chia-protocol`, not redefined in `dig-clvm`.
- [ ] The re-exported types appear in `dig-clvm`'s public API (accessible via `dig_clvm::Coin`, etc.).
- [ ] No wrapper types or type aliases are used that would break wire-format compatibility.
- [ ] Zero conversion overhead: `chia-consensus` functions accept `dig-clvm` types directly without `.into()` calls.
- [ ] The `chia-protocol` version in `Cargo.toml` is compatible with the `chia-consensus` dependency.

---

## Implementation Notes

- **Primary file:** `src/lib.rs` or `src/types.rs` (re-export declarations), `Cargo.toml` (dependency).
- **Version alignment:** The `chia-protocol` version used by `dig-clvm` MUST match the version used by `chia-consensus`. If they differ, Rust will treat them as different types even if they have the same name and layout, causing compilation errors. Use workspace dependencies or explicit version pinning.
- **Additional re-exports:** Beyond the four required types, consider re-exporting `Bytes32`, `G1Element`, `G2Element` if they appear frequently in the public API.
- **Feature flags:** If `chia-protocol` has optional features (e.g., `py-bindings`), `dig-clvm` should only enable the features it needs to minimize compile time and dependency weight.
- **Documentation:** The re-exported types should appear in `dig-clvm`'s rustdoc with links back to their original definitions in `chia-protocol`.
- **No From/Into impls:** Because the types are identical (same crate, same version), no conversion traits are needed or should be implemented.

---

## Verification

### Test Plan

| Test | Type | Description | Expected Result |
|------|------|-------------|-----------------|
| Type identity | Compile test | `let c: dig_clvm::Coin = chia_protocol::Coin { ... }` | Compiles without conversion |
| API accessibility | Compile test | `use dig_clvm::{Coin, CoinSpend, SpendBundle, Program}` | All four types importable |
| Wire format | Unit test | Serialize a Coin via dig_clvm, deserialize via chia_protocol | Identical bytes, successful round-trip |
| No redefinition | Code review | Search for `struct Coin` in dig-clvm source | Not found (only re-exports) |
| chia-consensus compatibility | Integration test | Pass dig_clvm::SpendBundle to chia-consensus function | Compiles and works directly |
| Version alignment | Build test | Ensure single version of chia-protocol in dependency tree | `cargo tree -d` shows no duplicates |

---

## Source Citations

- **SPEC.md Section 5.2**: "Coin, CoinSpend, SpendBundle, Program MUST be re-exported from chia-protocol, not redefined."
- **SPEC.md Section 5.2**: "Wire-format compatibility. No conversion overhead."
- **L1 reference — mempool_item.py:6:** [`mempool_item.py`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/full_node/mempool_item.py#L6) — imports from chia.types.
- **L1 reference — coin_spend.py:6:** [`coin_spend.py`](https://github.com/Chia-Network/chia-blockchain/blob/main/chia/types/blockchain_format/coin_spend.py#L6) — canonical CoinSpend definition.

---

## References

- [PAR-009](PAR-009.md) — Condition type re-exports (same principle for conditions)
- [VAL-014](../../validation/specs/VAL-014.md) — SpendResult uses these types (additions: Vec<Coin>)
- [BLK-001](../../block_generator/specs/BLK-001.md) — Block generator accepts SpendBundle inputs
- [CON-007](../../constants/specs/CON-007.md) — Minimal dependencies (chia-protocol is a required dep)
