pallas_wallet/
lib.rs

1use pallas_crypto::key::ed25519::{
2    PublicKey, SecretKey, SecretKeyExtended, Signature, TryFromSecretKeyExtendedError,
3};
4use thiserror::Error;
5
6pub mod hd;
7pub mod wrapper;
8
9#[derive(Error, Debug)]
10pub enum Error {
11    /// Private key wrapper data of unexpected length
12    #[error("Wrapped private key data invalid length")]
13    WrapperDataInvalidSize,
14    /// Failed to decrypt private key wrapper data
15    #[error("Failed to decrypt private key wrapper data")]
16    WrapperDataFailedToDecrypt,
17    /// Unexpected bech32 HRP prefix
18    #[error("Unexpected bech32 HRP prefix")]
19    InvalidBech32Hrp,
20    /// Unable to decode bech32 string
21    #[error("Unable to decode bech32: {0}")]
22    InvalidBech32(bech32::Error),
23    /// Decoded bech32 data of unexpected length
24    #[error("Decoded bech32 data of unexpected length")]
25    UnexpectedBech32Length,
26    /// Error relating to ed25519-bip32 private key
27    #[error("Error relating to ed25519-bip32 private key: {0}")]
28    Xprv(ed25519_bip32::PrivateKeyError),
29    /// Error relating to bip39 mnemonic
30    #[error("Error relating to bip39 mnemonic: {0}")]
31    Mnemonic(bip39::Error),
32    /// Error when attempting to derive ed25519-bip32 key
33    #[error("Error when attempting to derive ed25519-bip32 key: {0}")]
34    DerivationError(ed25519_bip32::DerivationError),
35    /// Error that may occurs when trying to decrypt a private key
36    /// which is not valid.
37    #[error("Invalid Ed25519 Extended Secret Key: {0}")]
38    InvalidSecretKeyExtended(#[from] TryFromSecretKeyExtendedError),
39}
40
41/// A standard or extended Ed25519 secret key
42pub enum PrivateKey {
43    Normal(SecretKey),
44    Extended(SecretKeyExtended),
45}
46
47impl PrivateKey {
48    #[allow(clippy::len_without_is_empty)]
49    pub fn len(&self) -> usize {
50        match self {
51            Self::Normal(_) => SecretKey::SIZE,
52            Self::Extended(_) => SecretKeyExtended::SIZE,
53        }
54    }
55
56    pub fn public_key(&self) -> PublicKey {
57        match self {
58            Self::Normal(x) => x.public_key(),
59            Self::Extended(x) => x.public_key(),
60        }
61    }
62
63    pub fn sign<T>(&self, msg: T) -> Signature
64    where
65        T: AsRef<[u8]>,
66    {
67        match self {
68            Self::Normal(x) => x.sign(msg),
69            Self::Extended(x) => x.sign(msg),
70        }
71    }
72
73    pub(crate) fn as_bytes(&self) -> Vec<u8> {
74        match self {
75            Self::Normal(x) => {
76                let bytes: [u8; SecretKey::SIZE] = unsafe { SecretKey::leak_into_bytes(x.clone()) };
77                bytes.to_vec()
78            }
79            Self::Extended(x) => {
80                let bytes: [u8; SecretKeyExtended::SIZE] =
81                    unsafe { SecretKeyExtended::leak_into_bytes(x.clone()) };
82                bytes.to_vec()
83            }
84        }
85    }
86}
87
88impl From<SecretKey> for PrivateKey {
89    fn from(key: SecretKey) -> Self {
90        PrivateKey::Normal(key)
91    }
92}
93
94impl From<SecretKeyExtended> for PrivateKey {
95    fn from(key: SecretKeyExtended) -> Self {
96        PrivateKey::Extended(key)
97    }
98}