1#![forbid(missing_docs)]
2#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
3use std::{array::TryFromSliceError, io};
6
7use bdk::bitcoin::Network as BitcoinNetwork;
8use codec::{Codec, CodecError};
9use serde::{Deserialize, Serialize};
10use strum::{Display, EnumIter, EnumString, FromRepr};
11use thiserror::Error;
12use uint::Uint256;
13
14pub mod address;
16pub mod c32;
18pub mod codec;
19pub mod contract_name;
20pub mod crypto;
22pub mod uint;
24pub mod utils;
26pub mod wallet;
27
28#[derive(Error, Debug)]
30pub enum StacksError {
31 #[error("Invalid arguments: {0}")]
32 InvalidArguments(&'static str),
34 #[error("Could not crackford32 encode or decode: {0}")]
35 C32Error(#[from] c32::C32Error),
37 #[error("Address version is invalid: {0}")]
38 InvalidAddressVersion(u8),
40 #[error("Could not build array from slice: {0}")]
41 InvalidSliceLength(#[from] TryFromSliceError),
43 #[error("Could not encode or decode hex: {0}")]
44 BadHex(#[from] hex::FromHexError),
46 #[error("Could not create Uint from {0} bytes")]
47 InvalidUintBytes(usize),
49 #[error("Codec error: {0}")]
50 CodecError(#[from] CodecError),
52 #[error("Invalid data: {0}")]
53 InvalidData(&'static str),
55 #[error("BIP32 error: {0}")]
57 BIP32(#[from] bdk::bitcoin::util::bip32::Error),
58 #[error("BIP39 error: {0}")]
60 BIP39(#[from] bdk::keys::bip39::Error),
61 #[error("SECP error: {0}")]
63 SECP(#[from] bdk::bitcoin::secp256k1::Error),
64 #[error("Base58 error: {0}")]
66 Base58(#[from] bdk::bitcoin::util::base58::Error),
67}
68
69pub type StacksResult<T> = Result<T, StacksError>;
71
72pub struct BlockId(Uint256);
74
75impl BlockId {
76 pub fn new(number: Uint256) -> Self {
78 Self(number)
79 }
80}
81
82impl Codec for BlockId {
83 fn codec_serialize<W: io::Write>(&self, dest: &mut W) -> io::Result<()> {
84 self.0.codec_serialize(dest)
85 }
86
87 fn codec_deserialize<R: io::Read>(data: &mut R) -> io::Result<Self>
88 where
89 Self: Sized,
90 {
91 Ok(Self(Uint256::codec_deserialize(data)?))
92 }
93}
94
95#[repr(u8)]
97#[derive(
98 Debug,
99 Clone,
100 Copy,
101 PartialEq,
102 Eq,
103 EnumString,
104 Display,
105 EnumIter,
106 FromRepr,
107 Serialize,
108 Deserialize,
109)]
110#[strum(ascii_case_insensitive)]
111#[strum(serialize_all = "lowercase")]
112#[serde(try_from = "String", into = "String")]
113pub enum Network {
114 Mainnet = 0,
116 Testnet = 1,
118}
119
120impl TryFrom<String> for Network {
121 type Error = strum::ParseError;
122
123 fn try_from(value: String) -> Result<Self, Self::Error> {
124 Self::try_from(value.as_str())
125 }
126}
127
128#[allow(clippy::from_over_into)]
130impl Into<String> for Network {
131 fn into(self) -> String {
132 self.to_string()
133 }
134}
135
136#[allow(clippy::from_over_into)]
138impl Into<Network> for BitcoinNetwork {
139 fn into(self) -> Network {
140 match self {
141 BitcoinNetwork::Bitcoin => Network::Mainnet,
142 _ => Network::Testnet,
143 }
144 }
145}
146
147#[allow(clippy::from_over_into)]
149impl Into<BitcoinNetwork> for Network {
150 fn into(self) -> BitcoinNetwork {
151 match self {
152 Network::Mainnet => BitcoinNetwork::Bitcoin,
153 Network::Testnet => BitcoinNetwork::Testnet,
154 }
155 }
156}