nintypes 0.2.11

Nintondo shared types
Documentation
use derive_more::derive::Debug;
use dutils::error::ContextWrapper;
use fixedstr::str8;

use crate::utils::{fixed::Fixed128, sha256::IntoHash256};

use super::inscriptions::Outpoint;
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Clone, Copy, Debug, derive_more::From, Eq, PartialEq, Hash)]
pub struct OriginalBrc4Ticker(pub [u8; 4]);

#[cfg(feature = "schema")]
impl schemars::JsonSchema for OriginalBrc4Ticker {
    fn schema_name() -> std::borrow::Cow<'static, str> {
        "Brc4 token tick".into()
    }

    fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
        schemars::json_schema!({
            "type": "string",
            "pattern": "^.{4}$",
            "description": "4 byte sized token tick"
        })
    }
}

impl std::fmt::Display for OriginalBrc4Ticker {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(&String::from_utf8_lossy(&self.0))
    }
}

impl OriginalBrc4Ticker {
    pub fn from_u32(v: u32) -> Self {
        Self(v.to_le_bytes())
    }
}

impl serde::Serialize for OriginalBrc4Ticker {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_bytes(&self.0)
    }
}

impl<'de> serde::Deserialize<'de> for OriginalBrc4Ticker {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        // Deserialize the bytes into a Vec<u8> and then into the fixed-size array
        let bytes = Vec::<u8>::deserialize(deserializer)?;
        if bytes.len() != 4 {
            return Err(serde::de::Error::invalid_length(bytes.len(), &"an array of length 4"));
        }
        let mut array = [0u8; 4];
        array.copy_from_slice(&bytes);
        Ok(OriginalBrc4Ticker(array))
    }
}

#[derive(Clone, Debug, derive_more::From, serde::Serialize, serde::Deserialize, Eq, PartialEq, Hash)]
#[serde(transparent)]
pub struct Brc4Ticker(pub str8);

impl Brc4Ticker {
    pub fn from_u32(v: u32) -> Self {
        v.to_le_bytes().as_slice().try_into().unwrap()
    }

    pub fn as_str(&self) -> &str {
        self.0.as_str()
    }
}

impl IntoHash256 for Brc4Ticker {
    fn hash_256(&self) -> super::hash::Hash256 {
        "@brc4ticker_".hash_256().chain_hash(&self.0.as_bytes())
    }
}

impl<'a> TryFrom<&'a [u8]> for Brc4Ticker {
    type Error = <[u8; 4] as TryFrom<&'a [u8]>>::Error;

    fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
        <[u8; 4]>::try_from(value).map(|v| {
            let v = String::from_utf8_lossy(&v).to_lowercase();
            assert!(v.len() <= 7, "all brc4 tickers must fit into 6 bytes in lowercase form");
            Self(str8::make(&v))
        })
    }
}
impl TryFrom<OriginalBrc4Ticker> for Brc4Ticker {
    type Error = <Self as TryFrom<&'static [u8]>>::Error;

    fn try_from(value: OriginalBrc4Ticker) -> Result<Self, Self::Error> {
        value.0.as_slice().try_into()
    }
}

impl std::str::FromStr for Brc4Ticker {
    type Err = anyhow::Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.starts_with("0x") && s.len() > 4 {
            let x = u32::from_str_radix(&s[2..], 16).anyhow()?;
            Ok(Self::from_u32(x))
        } else {
            s.as_bytes().try_into().anyhow()
        }
    }
}

impl std::fmt::Display for Brc4Ticker {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.0.as_str())
    }
}

#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
#[repr(u8)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum Brc4OpErr {
    NotDeployed,
    AlreadyDeployed,
    ReachDecBound,
    ReachLimBound,
    SupplyMinted,
    InsufficientBalance,
    Transferred,
}

#[derive(Clone, Copy, serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum InscriptionProtocolErr {
    Brc4(Brc4OpErr),
    Bellmap(BellmapOpErr),
}

#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Copy, Eq, PartialEq, Hash)]
#[repr(u8)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum BellmapOpErr {
    LowFee,
    InvalidHeight,
    AlreadyExists,
}

#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum Brc4Op {
    Mint {
        tick: OriginalBrc4Ticker,
        amt: Fixed128<18>,
    },
    Deploy {
        tick: OriginalBrc4Ticker,
        max: Fixed128<18>,
        lim: Fixed128<18>,
        dec: u8,
    },
    Transfer {
        tick: OriginalBrc4Ticker,
        amt: Fixed128<18>,
    },
    Transferred {
        tick: OriginalBrc4Ticker,
        amt: Fixed128<18>,
    },
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct SnsValue {
    pub name: String,
    pub avatar: Option<Outpoint>,
    pub rev: Option<String>,
    pub relay: Option<Outpoint>,
}

#[derive(Clone, serde::Serialize, serde::Deserialize, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum InscriptionProtocol {
    Brc4 { operation: Brc4Op, error: Option<Brc4Err> },
    Bellmap { block: u32, error: Option<BellmapOpErr> },
    Numbers(i128),
    Sns(SnsValue),
}
impl InscriptionProtocol {
    pub fn is_token(&self) -> bool {
        matches!(self, InscriptionProtocol::Brc4 { .. })
    }
}

#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum Brc4Err {
    NotDeployed,
    AlreadyDeployed,
    ReachDecBound,
    ReachLimBound,
    SupplyMinted,
    InsufficientBalance,
    Transferred,
    AlreadySpent,
}