zcash_transparent/pczt/
parse.rs1use alloc::collections::BTreeMap;
2use alloc::string::String;
3use alloc::vec::Vec;
4
5use bip32::ChildNumber;
6use zcash_protocol::{value::Zatoshis, TxId};
7
8use crate::{address::Script, sighash::SighashType};
9
10use super::{Bip32Derivation, Bundle, Input, Output};
11
12impl Bundle {
13 pub fn parse(inputs: Vec<Input>, outputs: Vec<Output>) -> Result<Self, ParseError> {
15 Ok(Self { inputs, outputs })
16 }
17}
18
19impl Input {
20 #[allow(clippy::too_many_arguments)]
22 pub fn parse(
23 prevout_txid: [u8; 32],
24 prevout_index: u32,
25 sequence: Option<u32>,
26 required_time_lock_time: Option<u32>,
27 required_height_lock_time: Option<u32>,
28 script_sig: Option<Vec<u8>>,
29 value: u64,
30 script_pubkey: Vec<u8>,
31 redeem_script: Option<Vec<u8>>,
32 partial_signatures: BTreeMap<[u8; 33], Vec<u8>>,
33 sighash_type: u8,
34 bip32_derivation: BTreeMap<[u8; 33], Bip32Derivation>,
35 ripemd160_preimages: BTreeMap<[u8; 20], Vec<u8>>,
36 sha256_preimages: BTreeMap<[u8; 32], Vec<u8>>,
37 hash160_preimages: BTreeMap<[u8; 20], Vec<u8>>,
38 hash256_preimages: BTreeMap<[u8; 32], Vec<u8>>,
39 proprietary: BTreeMap<String, Vec<u8>>,
40 ) -> Result<Self, ParseError> {
41 let prevout_txid = TxId::from_bytes(prevout_txid);
42
43 match required_time_lock_time {
44 None | Some(500000000..) => Ok(()),
45 Some(_) => Err(ParseError::InvalidRequiredTimeLocktime),
46 }?;
47
48 match required_height_lock_time {
49 None | Some(1..=499999999) => Ok(()),
50 Some(_) => Err(ParseError::InvalidRequiredHeightLocktime),
51 }?;
52
53 let script_sig = script_sig.map(Script);
55
56 let value = Zatoshis::from_u64(value).map_err(|_| ParseError::InvalidValue)?;
57
58 let script_pubkey = Script(script_pubkey);
60
61 let redeem_script = redeem_script.map(Script);
63
64 let sighash_type =
65 SighashType::parse(sighash_type).ok_or(ParseError::InvalidSighashType)?;
66
67 Ok(Self {
68 prevout_txid,
69 prevout_index,
70 sequence,
71 required_time_lock_time,
72 required_height_lock_time,
73 script_sig,
74 value,
75 script_pubkey,
76 redeem_script,
77 partial_signatures,
78 sighash_type,
79 bip32_derivation,
80 ripemd160_preimages,
81 sha256_preimages,
82 hash160_preimages,
83 hash256_preimages,
84 proprietary,
85 })
86 }
87}
88
89impl Output {
90 pub fn parse(
92 value: u64,
93 script_pubkey: Vec<u8>,
94 redeem_script: Option<Vec<u8>>,
95 bip32_derivation: BTreeMap<[u8; 33], Bip32Derivation>,
96 user_address: Option<String>,
97 proprietary: BTreeMap<String, Vec<u8>>,
98 ) -> Result<Self, ParseError> {
99 let value = Zatoshis::from_u64(value).map_err(|_| ParseError::InvalidValue)?;
100
101 let script_pubkey = Script(script_pubkey);
103
104 let redeem_script = redeem_script.map(Script);
106
107 Ok(Self {
108 value,
109 script_pubkey,
110 redeem_script,
111 bip32_derivation,
112 user_address,
113 proprietary,
114 })
115 }
116}
117
118impl Bip32Derivation {
119 pub fn parse(
121 seed_fingerprint: [u8; 32],
122 derivation_path: Vec<u32>,
123 ) -> Result<Self, ParseError> {
124 Ok(Self {
125 seed_fingerprint,
126 derivation_path: derivation_path.into_iter().map(ChildNumber).collect(),
127 })
128 }
129}
130
131#[derive(Debug)]
133pub enum ParseError {
134 InvalidRequiredHeightLocktime,
135 InvalidRequiredTimeLocktime,
136 InvalidSighashType,
138 InvalidValue,
140}