Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions packages/wasm-utxo/js/fixedScriptWallet/ZcashBitGoPsbt.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
BitGoPsbt as WasmBitGoPsbt,
getZcashTransactionVersionFromPsbt,
zcash_branch_id_for_height,
zcash_ironwood_version_group_id,
} from "../wasm/wasm_utxo.js";
Expand Down Expand Up @@ -28,6 +29,43 @@ export type ZcashParsedOutput = ParsedOutput & {
isShielded: boolean;
};

/**
* Zcash transaction version (v4 or v6).
*/
export enum ZcashTransactionVersion {
V4 = "v4",
V6 = "v6",
}

/**
* Detect whether the given PSBT bytes represent a Zcash v4 or v6 (Ironwood) transaction.
*
* @param psbtBytes - Serialized PSBT bytes (as Uint8Array or Buffer)
* @returns The Zcash transaction version as a {@link ZcashTransactionVersion} enum value (`"v4"` or `"v6"`)
* @throws Error if the bytes are not a valid PSBT or not a recognized Zcash transaction
*
* @example
* ```typescript
* const version = getZcashTransactionVersion(psbtBytes);
* if (version === ZcashTransactionVersion.V6) {
* const psbt = ZcashIronwoodBitGoPsbt.fromBytes(psbtBytes, "zcashTest");
* } else if (version === ZcashTransactionVersion.V4) {
* const psbt = ZcashBitGoPsbt.fromBytes(psbtBytes, "zcash");
* }
* ```
*/
export function getZcashTransactionVersion(psbtBytes: Uint8Array): ZcashTransactionVersion {
const versionStr = getZcashTransactionVersionFromPsbt(psbtBytes);
switch (versionStr) {
case "v4":
return ZcashTransactionVersion.V4;
case "v6":
return ZcashTransactionVersion.V6;
default:
throw new Error(`Unexpected Zcash transaction version: ${versionStr}`);
}
}

/**
* Zcash v6 (Ironwood) version group id (0xd884b698). Its presence marks a PSBT as v6 — see
* `ZcashIronwoodBitGoPsbt`.
Expand Down Expand Up @@ -318,6 +356,23 @@ export class ZcashBitGoPsbt extends BitGoPsbt<ZcashParsedOutput> {
return zcash_branch_id_for_height(network, height);
}

/**
* Detect whether the given PSBT bytes represent a Zcash v4 or v6 (Ironwood) transaction.
*
* @param bytes - Serialized PSBT bytes
* @returns The Zcash transaction version enum
*/
static getTransactionVersion(bytes: Uint8Array): ZcashTransactionVersion {
return getZcashTransactionVersion(bytes);
}

/**
* Alias for {@link getTransactionVersion}.
*/
static getZcashTransactionVersion(bytes: Uint8Array): ZcashTransactionVersion {
return getZcashTransactionVersion(bytes);
}

/**
* Extract the final Zcash transaction from a finalized PSBT
*
Expand Down
3 changes: 2 additions & 1 deletion packages/wasm-utxo/js/fixedScriptWallet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ export { BitGoKeySubtype, type PsbtKvKey } from "./BitGoKeySubtype.js";
// Zcash-specific PSBT subclass
export {
ZcashBitGoPsbt,
ZcashTransactionVersion,
getZcashTransactionVersion,
type ZcashNetworkName,
type ZcashParsedOutput,
type CreateEmptyZcashOptions,
IRONWOOD_VERSION_GROUP_ID,
} from "./ZcashBitGoPsbt.js";

// Zcash v6 (Ironwood / NU6.3) shielding PSBT
export {
ZcashIronwoodBitGoPsbt,
Expand Down
9 changes: 9 additions & 0 deletions packages/wasm-utxo/js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ export { ECPair } from "./ecpair.js";
export { BIP32 } from "./bip32.js";
export { Dimensions } from "./fixedScriptWallet/Dimensions.js";
export { ZcashDimensions } from "./fixedScriptWallet/ZcashDimensions.js";
export {
ZcashTransactionVersion,
getZcashTransactionVersion,
ZcashBitGoPsbt,
ZcashIronwoodBitGoPsbt,
ZcashUnifiedAddress,
ZcashV6Transaction,
ZcashIronwoodWitness,
} from "./fixedScriptWallet/index.js";

export type WasmUtxoVersionInfo = { version: string; gitHash: string };
export function getWasmUtxoVersion(): WasmUtxoVersionInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ pub use propkv::{
};
pub use sighash::validate_sighash_type;
pub use zcash_psbt::{
decode_zcash_transaction_meta, ZcashBitGoPsbt, ZcashTransactionMeta,
ZCASH_SAPLING_VERSION_GROUP_ID,
decode_zcash_transaction_meta, detect_zcash_transaction_version, ZcashBitGoPsbt,
ZcashTransactionMeta, ZcashTransactionVersion, ZCASH_SAPLING_VERSION_GROUP_ID,
};

#[derive(Debug, strum::IntoStaticStr)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use miniscript::bitcoin::{Transaction, VarInt};
use std::io::Read;

pub use crate::zcash::transaction::{
decode_zcash_transaction_meta, ZcashTransactionMeta, ZCASH_SAPLING_VERSION_GROUP_ID,
decode_zcash_transaction_meta, detect_zcash_transaction_version, ZcashTransactionMeta,
ZcashTransactionVersion, ZCASH_SAPLING_VERSION_GROUP_ID,
};

/// A Zcash-compatible PSBT that can handle overwintered transactions
Expand Down Expand Up @@ -441,6 +442,14 @@ impl ZcashBitGoPsbt {
Self::decode_with_zcash_tx(bytes, network, true)
}

/// Detect whether the given PSBT bytes represent a Zcash v4 or v6 (Ironwood) transaction.
pub fn get_psbt_transaction_version(
bytes: &[u8],
) -> Result<crate::zcash::transaction::ZcashTransactionVersion, super::DeserializeError> {
crate::zcash::transaction::detect_zcash_transaction_version(bytes)
.map_err(super::DeserializeError::Network)
}

/// Convert to a standard Bitcoin PSBT (losing Zcash-specific fields)
pub fn into_bitcoin_psbt(self) -> Psbt {
self.psbt
Expand Down
11 changes: 11 additions & 0 deletions packages/wasm-utxo/src/wasm/fixed_script_wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,17 @@ impl BitGoPsbt {
})
}

/// Detect whether the given PSBT bytes represent a Zcash v4 or v6 (Ironwood) transaction.
///
/// Returns `"v4"` or `"v6"`.
/// Throws [`WasmUtxoError`] if the bytes are not a valid PSBT or not a Zcash transaction.
#[wasm_bindgen(js_name = get_zcash_transaction_version)]
pub fn get_zcash_transaction_version(bytes: &[u8]) -> Result<String, WasmUtxoError> {
crate::zcash::transaction::detect_zcash_transaction_version(bytes)
.map(|v| v.as_str().to_string())
.map_err(|e| WasmUtxoError::new(&e))
}

/// Create an empty PSBT for the given network with wallet keys
///
/// # Arguments
Expand Down
11 changes: 11 additions & 0 deletions packages/wasm-utxo/src/wasm/zcash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ pub fn zcash_ironwood_version_group_id() -> u32 {
crate::zcash::transaction::ZCASH_IRONWOOD_VERSION_GROUP_ID
}

/// Detect whether the given PSBT bytes represent a Zcash v4 or v6 (Ironwood) transaction.
///
/// Returns `"v4"` or `"v6"`.
/// Throws [`WasmUtxoError`] if the bytes are not a valid PSBT or not a Zcash transaction.
#[wasm_bindgen(js_name = getZcashTransactionVersionFromPsbt)]
pub fn get_zcash_transaction_version_from_psbt(psbt_bytes: &[u8]) -> Result<String, WasmUtxoError> {
crate::zcash::transaction::detect_zcash_transaction_version(psbt_bytes)
.map(|v| v.as_str().to_string())
.map_err(|e| WasmUtxoError::new(&e))
}

/// A validated Merkle witness for an Ironwood/Orchard note commitment, from
/// [`ironwood_build_witness`].
///
Expand Down
1 change: 1 addition & 0 deletions packages/wasm-utxo/src/zcash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub mod ironwood_pczt;
pub mod transaction;
pub mod unified_address;
pub mod v6;
pub use transaction::{detect_zcash_transaction_version, ZcashTransactionVersion};

/// Zcash network upgrade identifiers
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
Expand Down
Loading
Loading