use bitcoin::hex::DisplayHex;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{AddrBytes, OutputType};
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct AddrValidation {
#[schemars(example = true)]
pub isvalid: bool,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "address")]
pub addr: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "scriptPubKey")]
pub script_pub_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub isscript: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub iswitness: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub witness_version: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
pub witness_program: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error_locations: Option<Vec<usize>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
}
impl AddrValidation {
pub fn invalid(error: String) -> Self {
Self {
isvalid: false,
addr: None,
script_pub_key: None,
isscript: None,
iswitness: None,
witness_version: None,
witness_program: None,
error_locations: Some(vec![]),
error: Some(error),
}
}
pub fn from_addr(addr: &str) -> Self {
let script = match AddrBytes::addr_to_script(addr) {
Ok(s) => s,
Err(e) => return Self::invalid(e.to_string()),
};
let output_type = OutputType::from(&script);
let script_hex = script.as_bytes().to_lower_hex_string();
let is_script = matches!(output_type, OutputType::P2SH | OutputType::P2TR);
let is_witness = matches!(
output_type,
OutputType::P2WPKH | OutputType::P2WSH | OutputType::P2TR | OutputType::P2A
);
let (witness_version, witness_program) = if is_witness {
let version = script.witness_version().map(|v| v.to_num());
let program = if script.len() > 2 {
Some(script.as_bytes()[2..].to_lower_hex_string())
} else {
None
};
(version, program)
} else {
(None, None)
};
Self {
isvalid: true,
addr: Some(addr.to_string()),
script_pub_key: Some(script_hex),
isscript: Some(is_script),
iswitness: Some(is_witness),
witness_version,
witness_program,
error_locations: None,
error: None,
}
}
}