1use crate::{
2 format::Format,
3 no_std::{
4 fmt::{Debug, Display},
5 hash::Hash,
6 FromStr, String,
7 },
8 public_key::{PublicKey, PublicKeyError},
9};
10
11pub trait Address:
13 'static + Clone + Debug + Display + FromStr + Hash + PartialEq + Eq + Send + Sized + Sync
14{
15 type SecretKey;
16 type Format: Format;
17 type PublicKey: PublicKey;
18
19 fn from_secret_key(
21 secret_key: &Self::SecretKey,
22 format: &Self::Format,
23 ) -> Result<Self, AddressError>;
24
25 fn from_public_key(
27 public_key: &Self::PublicKey,
28 format: &Self::Format,
29 ) -> Result<Self, AddressError>;
30
31 fn is_valid(address: &str) -> bool {
32 Self::from_str(address).is_ok()
33 }
34}
35
36#[derive(Debug, Error)]
37pub enum AddressError {
38 #[error("{0:}: {1:}")]
39 Crate(&'static str, String),
40
41 #[error("invalid format conversion from {0:} to {1:}")]
42 IncompatibleFormats(String, String),
43
44 #[error("invalid address: {0:}")]
45 InvalidAddress(String),
46
47 #[error("invalid byte length: {0:}")]
48 InvalidByteLength(usize),
49
50 #[error("invalid character length: {0:}")]
51 InvalidCharacterLength(usize),
52
53 #[error("invalid address checksum: {{ expected: {0:}, found: {1:} }}")]
54 InvalidChecksum(String, String),
55
56 #[error("invalid network: {{ expected: {0}, found: {1} }}")]
57 InvalidNetwork(String, String),
58
59 #[error("invalid address prefix: {0:}")]
60 InvalidPrefix(String),
61
62 #[error("invalid address prefix length: {0:?}")]
63 InvalidPrefixLength(usize),
64
65 #[error("{0}")]
66 Message(String),
67
68 #[error("missing public spend key and/or public view key")]
69 MissingPublicKey,
70
71 #[error("{0}")]
72 PublicKeyError(PublicKeyError),
73}
74
75impl From<crate::no_std::io::Error> for AddressError {
76 fn from(error: crate::no_std::io::Error) -> Self {
77 AddressError::Crate("crate::no_std::io", format!("{:?}", error))
78 }
79}
80
81impl From<crate::no_std::FromUtf8Error> for AddressError {
82 fn from(error: crate::no_std::FromUtf8Error) -> Self {
83 AddressError::Crate("crate::no_std", format!("{:?}", error))
84 }
85}
86
87impl From<&'static str> for AddressError {
88 fn from(msg: &'static str) -> Self {
89 AddressError::Message(msg.into())
90 }
91}
92
93impl From<PublicKeyError> for AddressError {
94 fn from(error: PublicKeyError) -> Self {
95 AddressError::PublicKeyError(error)
96 }
97}
98
99impl From<base58::FromBase58Error> for AddressError {
100 fn from(error: base58::FromBase58Error) -> Self {
101 AddressError::Crate("base58", format!("{:?}", error))
102 }
103}
104
105impl From<bech32::Error> for AddressError {
106 fn from(error: bech32::Error) -> Self {
107 AddressError::Crate("bech32", format!("{:?}", error))
108 }
109}
110
111impl From<core::str::Utf8Error> for AddressError {
112 fn from(error: core::str::Utf8Error) -> Self {
113 AddressError::Crate("core::str", format!("{:?}", error))
114 }
115}
116
117impl From<hex::FromHexError> for AddressError {
118 fn from(error: hex::FromHexError) -> Self {
119 AddressError::Crate("hex", format!("{:?}", error))
120 }
121}
122
123impl From<rand_core::Error> for AddressError {
124 fn from(error: rand_core::Error) -> Self {
125 AddressError::Crate("rand", format!("{:?}", error))
126 }
127}