diff --git a/crates/astria-core/src/crypto.rs b/crates/astria-core/src/crypto.rs index 6150751913..54574f09b0 100644 --- a/crates/astria-core/src/crypto.rs +++ b/crates/astria-core/src/crypto.rs @@ -99,6 +99,12 @@ impl<'a> From<&'a SigningKey> for VerificationKey { } } +impl From for SigningKey { + fn from(key: Ed25519SigningKey) -> Self { + Self(key) + } +} + impl TryFrom<&[u8]> for SigningKey { type Error = ed25519_consensus::Error; @@ -210,6 +216,14 @@ impl AsRef<[u8]> for VerificationKey { } } +impl From for VerificationKey { + fn from(key: Ed25519VerificationKey) -> Self { + Self { + key, + } + } +} + impl TryFrom<&[u8]> for VerificationKey { type Error = Error; @@ -262,6 +276,12 @@ impl From<[u8; 64]> for Signature { } } +impl From for Signature { + fn from(signature: Ed25519Signature) -> Self { + Self(signature) + } +} + impl TryFrom<&[u8]> for Signature { type Error = Error; diff --git a/crates/astria-core/src/primitive/v1/mod.rs b/crates/astria-core/src/primitive/v1/mod.rs index 4c81638aab..ba7b83762a 100644 --- a/crates/astria-core/src/primitive/v1/mod.rs +++ b/crates/astria-core/src/primitive/v1/mod.rs @@ -327,6 +327,23 @@ impl AddressBuilder { } } + /// Use the given verification key for address generation. + /// + /// The verification key is hashed with SHA256 and the first 20 bytes are used as the address + /// bytes. + #[allow(clippy::missing_panics_doc)] // allow clippy, as the conversion is infallible + #[must_use = "the builder must be built to construct an address to be useful"] + pub fn verification_key( + self, + key: &crate::crypto::VerificationKey, + ) -> AddressBuilder, TPrefix> { + let hash = Sha256::digest(key.as_bytes()); + let array: [u8; ADDRESS_LEN] = hash[0..ADDRESS_LEN] + .try_into() + .expect("hash is 32 bytes long, so must always be able to convert to 20 bytes"); + self.array(array) + } + #[must_use = "the builder must be built to construct an address to be useful"] pub fn prefix<'a, T: Into>>( self,