// SPDX-License-Identifier: CC0-1.0

//! The JSON-RPC API for Bitcoin Core `v22` - wallet.
//!
//! Types for methods found under the `== Wallet ==` section of the API docs.

mod into;

use serde::{Deserialize, Serialize};

pub use super::{GetAddressInfoEmbeddedError, GetAddressInfoError, ScriptType};

/// Result of the JSON-RPC method `getaddressinfo`.
///
/// > getaddressinfo "address"
/// >
/// > Return information about the given bitcoin address. Some information requires the address
/// > to be in the wallet.
/// >
/// > Arguments:
/// > 1. "address"                    (string, required) The bitcoin address to get the information of.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct GetAddressInfo {
    /// The bitcoin address validated.
    pub address: String,
    /// The hex encoded scriptPubKey generated by the address.
    #[serde(rename = "scriptPubKey")]
    pub script_pubkey: String,
    /// If the address is yours or not.
    #[serde(rename = "ismine")]
    pub is_mine: bool,
    /// If the address is watchonly.
    #[serde(rename = "iswatchonly")]
    pub is_watch_only: bool,
    /// Whether we know how to spend coins sent to this address, ignoring the possible lack of private keys.
    pub solvable: bool,
    /// A descriptor for spending coins sent to this address (only when solvable).
    #[serde(rename = "desc")]
    pub descriptor: Option<String>,
    /// The descriptor used to derive this address if this is a descriptor wallet
    #[serde(rename = "parent_desc")]
    pub parent_descriptor: Option<String>,
    /// If the key is a script.
    #[serde(rename = "isscript")]
    pub is_script: bool,
    /// If the address was used for change output.
    #[serde(rename = "ischange")]
    pub is_change: bool,
    /// If the address is a witness address.
    #[serde(rename = "iswitness")]
    pub is_witness: bool,
    /// The version number of the witness program.
    pub witness_version: Option<i64>,
    /// The hex value of the witness program.
    pub witness_program: Option<String>,
    /// The output script type.
    ///
    /// Only if "isscript" is true and the redeemscript is known.
    pub script: Option<ScriptType>,
    /// The redeemscript for the p2sh address.
    pub hex: Option<String>,
    /// Array of pubkeys associated with the known redeemscript (only if "script" is "multisig").
    pub pubkeys: Option<Vec<String>>,
    /// Number of signatures required to spend multisig output (only if "script" is "multisig").
    #[serde(rename = "sigsrequired")]
    pub sigs_required: Option<i64>,
    /// The hex value of the raw public key, for single-key addresses (possibly embedded in P2SH or P2WSH).
    pub pubkey: Option<String>,
    /// Information about the address embedded in P2SH or P2WSH, if relevant and known.
    pub embedded: Option<GetAddressInfoEmbedded>,
    /// If the pubkey is compressed.
    #[serde(rename = "iscompressed")]
    pub is_compressed: Option<bool>,
    /// The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT).
    pub timestamp: Option<u32>,
    /// The HD keypath if the key is HD and available.
    #[serde(rename = "hdkeypath")]
    pub hd_key_path: Option<String>,
    /// The Hash160 of the HD seed.
    #[serde(rename = "hdseedid")]
    pub hd_seed_id: Option<String>,
    /// The fingerprint of the master key.
    #[serde(rename = "hdmasterfingerprint")]
    pub hd_master_fingerprint: Option<String>,
    /// Array of labels associated with the address.
    pub labels: Vec<String>,
}

/// The `embedded` address info field. Part of `getaddressinfo`.
///
/// It includes all getaddressinfo output fields for the embedded address, excluding metadata
/// ("timestamp", "hdkeypath", "hdseedid") and relation to the wallet ("ismine", "iswatchonly").
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct GetAddressInfoEmbedded {
    /// The bitcoin address validated.
    pub address: String,
    /// The hex encoded scriptPubKey generated by the address.
    #[serde(rename = "scriptPubKey")]
    pub script_pubkey: String,
    /// Whether we know how to spend coins sent to this address, ignoring the possible lack of private keys.
    pub solvable: Option<bool>,
    /// A descriptor for spending coins sent to this address (only when solvable).
    #[serde(rename = "desc")]
    pub descriptor: Option<String>,
    /// The descriptor used to derive this address if this is a descriptor wallet
    #[serde(rename = "parent_desc")]
    pub parent_descriptor: Option<String>,
    /// If the key is a script.
    #[serde(rename = "isscript")]
    pub is_script: bool,
    /// If the address was used for change output.
    #[serde(rename = "ischange")]
    pub is_change: Option<bool>,
    /// If the address is a witness address.
    #[serde(rename = "iswitness")]
    pub is_witness: bool,
    /// The version number of the witness program.
    pub witness_version: Option<i64>,
    /// The hex value of the witness program.
    pub witness_program: Option<String>,
    /// The output script type.
    ///
    /// Only if "isscript" is true and the redeemscript is known.
    pub script: Option<ScriptType>,
    /// The redeemscript for the p2sh address.
    pub hex: Option<String>,
    /// Array of pubkeys associated with the known redeemscript (only if "script" is "multisig").
    pub pubkeys: Option<Vec<String>>,
    /// Number of signatures required to spend multisig output (only if "script" is "multisig").
    #[serde(rename = "sigsrequired")]
    pub sigs_required: Option<i64>,
    /// The hex value of the raw public key, for single-key addresses (possibly embedded in P2SH or P2WSH).
    pub pubkey: Option<String>,
    /// If the pubkey is compressed.
    #[serde(rename = "iscompressed")]
    pub is_compressed: Option<bool>,
    /// Array of labels associated with the address.
    pub labels: Option<Vec<String>>,
}

/// Result of JSON-RPC method `listdescriptors`.
///
/// > List descriptors imported into a descriptor-enabled wallet.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct ListDescriptors {
    /// Name of wallet this operation was performed on.
    pub wallet_name: String,
    /// Array of descriptor objects.
    pub descriptors: Vec<DescriptorInfo>,
}

/// A descriptor object from `listdescriptors`.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct DescriptorInfo {
    /// Descriptor string representation.
    #[serde(rename = "desc")]
    pub descriptor: String,
    /// The creation time of the descriptor.
    pub timestamp: u64,
    /// Activeness flag.
    pub active: bool,
    /// Whether this is an internal or external descriptor; defined only for active descriptors.
    pub internal: Option<bool>,
    /// Defined only for ranged descriptors.
    pub range: Option<[u64; 2]>,
    /// The next index to generate addresses from; defined only for ranged descriptors.
    pub next: Option<u64>,
}

/// Result of JSON-RPC method `walletdisplayaddress`.
///
/// > Display address on an external signer for verification.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct WalletDisplayAddress {
    /// The address as confirmed by the signer
    pub address: String,
}
