use super::macros::u32_to_array_le;
use elements_miniscript::elements::{
encode::VarInt, pset, pset::raw, pset::GlobalTxData, pset::PartiallySignedTransaction as Psbt,
};
const PSET_GLOBAL_XPUB: u8 = 0x01;
const PSET_GLOBAL_TX_VERSION: u8 = 0x02;
const PSET_GLOBAL_FALLBACK_LOCKTIME: u8 = 0x03;
const PSET_GLOBAL_INPUT_COUNT: u8 = 0x04;
const PSET_GLOBAL_OUTPUT_COUNT: u8 = 0x05;
const PSET_GLOBAL_TX_MODIFIABLE: u8 = 0x06;
const PSET_GLOBAL_VERSION: u8 = 0xFB;
const PSBT_ELEMENTS_GLOBAL_SCALAR: u8 = 0x00;
const PSBT_ELEMENTS_GLOBAL_TX_MODIFIABLE: u8 = 0x01;
pub fn get_v2_global_pairs(psbt: &Psbt) -> Vec<raw::Pair> {
let mut rv: Vec<raw::Pair> = Default::default();
let GlobalTxData {
version,
fallback_locktime,
tx_modifiable,
..
} = psbt.global.tx_data;
let input_count_vint = VarInt(psbt.n_inputs() as u64);
let output_count_vint = VarInt(psbt.n_outputs() as u64);
impl_pset_get_pair! {
rv.push_mandatory(version as <PSET_GLOBAL_TX_VERSION, _>)
}
impl_pset_get_pair! {
rv.push(fallback_locktime as <PSET_GLOBAL_FALLBACK_LOCKTIME, _>)
}
impl_pset_get_pair! {
rv.push_mandatory(input_count_vint as <PSET_GLOBAL_INPUT_COUNT, _>)
}
impl_pset_get_pair! {
rv.push_mandatory(output_count_vint as <PSET_GLOBAL_OUTPUT_COUNT, _>)
}
impl_pset_get_pair! {
rv.push(tx_modifiable as <PSET_GLOBAL_TX_MODIFIABLE, _>)
}
for (xpub, (fingerprint, derivation)) in &psbt.global.xpub {
rv.push(raw::Pair {
key: raw::Key {
type_value: PSET_GLOBAL_XPUB,
key: xpub.encode().to_vec(),
},
value: {
let mut ret = Vec::with_capacity(4 + derivation.len() * 4);
ret.extend(fingerprint.as_bytes());
derivation
.into_iter()
.for_each(|n| ret.extend(&u32_to_array_le((*n).into())));
ret
},
});
}
let ver = psbt.global.version; impl_pset_get_pair!(
rv.push_mandatory(ver as <PSET_GLOBAL_VERSION, _>)
);
for scalar in &psbt.global.scalars {
let key = raw::ProprietaryKey::from_pset_pair(
PSBT_ELEMENTS_GLOBAL_SCALAR,
scalar.as_ref().to_vec(),
);
rv.push(raw::Pair {
key: key.to_key(),
value: vec![], })
}
let global = &psbt.global; impl_pset_get_pair! {
rv.push_prop(global.elements_tx_modifiable_flag as <PSBT_ELEMENTS_GLOBAL_TX_MODIFIABLE, _>)
}
for (key, value) in psbt.global.proprietary.iter() {
rv.push(raw::Pair {
key: key.to_key(),
value: value.clone(),
});
}
for (key, value) in psbt.global.unknown.iter() {
rv.push(raw::Pair {
key: key.clone(),
value: value.clone(),
});
}
rv
}