Add keypair & update pubkey
Keypair & FullKeypair match structs in damus ios Signed-off-by: kernelkind <kernelkind@gmail.com> Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
committed by
William Casarin
parent
b8177459ab
commit
e04c8821d5
@@ -8,8 +8,10 @@ pub enum Error {
|
||||
Empty,
|
||||
DecodeFailed,
|
||||
HexDecodeFailed,
|
||||
InvalidBech32,
|
||||
InvalidByteSize,
|
||||
InvalidSignature,
|
||||
InvalidPublicKey,
|
||||
// Secp(secp256k1::Error),
|
||||
Json(serde_json::Error),
|
||||
Generic(String),
|
||||
@@ -23,6 +25,7 @@ impl std::cmp::PartialEq for Error {
|
||||
(Error::HexDecodeFailed, Error::HexDecodeFailed) => true,
|
||||
(Error::InvalidSignature, Error::InvalidSignature) => true,
|
||||
(Error::InvalidByteSize, Error::InvalidByteSize) => true,
|
||||
(Error::InvalidPublicKey, Error::InvalidPublicKey) => true,
|
||||
// This is slightly wrong but whatevs
|
||||
(Error::Json(..), Error::Json(..)) => true,
|
||||
(Error::Generic(left), Error::Generic(right)) => left == right,
|
||||
@@ -40,6 +43,8 @@ impl fmt::Display for Error {
|
||||
Self::InvalidSignature => write!(f, "invalid signature"),
|
||||
Self::HexDecodeFailed => write!(f, "hex decoding failed"),
|
||||
Self::InvalidByteSize => write!(f, "invalid byte size"),
|
||||
Self::InvalidBech32 => write!(f, "invalid bech32 string"),
|
||||
Self::InvalidPublicKey => write!(f, "invalid public key"),
|
||||
//Self::Secp(e) => write!(f, "{e}"),
|
||||
Self::Json(e) => write!(f, "{e}"),
|
||||
Self::Generic(e) => write!(f, "{e}"),
|
||||
|
||||
73
enostr/src/keypair.rs
Normal file
73
enostr/src/keypair.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
use crate::Pubkey;
|
||||
use crate::SecretKey;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub struct Keypair {
|
||||
pub pubkey: Pubkey,
|
||||
pub secret_key: Option<SecretKey>,
|
||||
}
|
||||
|
||||
impl Keypair {
|
||||
pub fn new(secret_key: SecretKey) -> Self {
|
||||
let cloned_secret_key = secret_key.clone();
|
||||
let nostr_keys = nostr::Keys::new(secret_key);
|
||||
Keypair {
|
||||
pubkey: Pubkey::new(&nostr_keys.public_key().to_bytes()),
|
||||
secret_key: Some(cloned_secret_key),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn only_pubkey(pubkey: Pubkey) -> Self {
|
||||
Keypair {
|
||||
pubkey,
|
||||
secret_key: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_full(self) -> Option<FullKeypair> {
|
||||
if let Some(secret_key) = self.secret_key {
|
||||
Some(FullKeypair {
|
||||
pubkey: self.pubkey,
|
||||
secret_key,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub struct FullKeypair {
|
||||
pub pubkey: Pubkey,
|
||||
pub secret_key: SecretKey,
|
||||
}
|
||||
|
||||
impl FullKeypair {
|
||||
pub fn new(pubkey: Pubkey, secret_key: SecretKey) -> Self {
|
||||
FullKeypair { pubkey, secret_key }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Keypair {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Keypair:\n\tpublic: {}\n\tsecret: {}",
|
||||
self.pubkey,
|
||||
match self.secret_key {
|
||||
Some(_) => "Some(<hidden>)",
|
||||
None => "None",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for FullKeypair {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Keypair:\n\tpublic: {}\n\tsecret: {}",
|
||||
self.pubkey, "<hidden>"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ mod client;
|
||||
mod error;
|
||||
mod event;
|
||||
mod filter;
|
||||
mod keypair;
|
||||
mod profile;
|
||||
mod pubkey;
|
||||
mod relay;
|
||||
@@ -11,6 +12,8 @@ pub use error::Error;
|
||||
pub use event::{Event, EventId};
|
||||
pub use ewebsock;
|
||||
pub use filter::Filter;
|
||||
pub use keypair::{FullKeypair, Keypair};
|
||||
pub use nostr::SecretKey;
|
||||
pub use profile::Profile;
|
||||
pub use pubkey::Pubkey;
|
||||
pub use relay::message::{RelayEvent, RelayMessage};
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::Error;
|
||||
use hex;
|
||||
use log::debug;
|
||||
//use nostr::key::XOnlyPublicKey;
|
||||
use nostr::bech32::Hrp;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||
pub struct Pubkey([u8; 32]);
|
||||
|
||||
static HRP_NPUB: Hrp = Hrp::parse_unchecked("npub");
|
||||
|
||||
impl Pubkey {
|
||||
pub fn new(data: &[u8; 32]) -> Self {
|
||||
Self(*data)
|
||||
@@ -25,6 +26,41 @@ impl Pubkey {
|
||||
pub fn from_hex(hex_str: &str) -> Result<Self, Error> {
|
||||
Ok(Pubkey(hex::decode(hex_str)?.as_slice().try_into()?))
|
||||
}
|
||||
|
||||
pub fn try_from_hex_str_with_verify(hex_str: &str) -> Result<Self, Error> {
|
||||
let vec: Vec<u8> = hex::decode(hex_str)?;
|
||||
if vec.len() != 32 {
|
||||
Err(Error::HexDecodeFailed)
|
||||
} else {
|
||||
let _ = match nostr::secp256k1::XOnlyPublicKey::from_slice(&vec) {
|
||||
Ok(r) => Ok(r),
|
||||
Err(_) => Err(Error::InvalidPublicKey),
|
||||
}?;
|
||||
|
||||
Ok(Pubkey(vec.try_into().unwrap()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_from_bech32_string(s: &str, verify: bool) -> Result<Self, Error> {
|
||||
let data = match nostr::bech32::decode(s) {
|
||||
Ok(res) => Ok(res),
|
||||
Err(_) => Err(Error::InvalidBech32),
|
||||
}?;
|
||||
|
||||
if data.0 != HRP_NPUB {
|
||||
Err(Error::InvalidBech32)
|
||||
} else if data.1.len() != 32 {
|
||||
Err(Error::InvalidByteSize)
|
||||
} else {
|
||||
if verify {
|
||||
let _ = match nostr::secp256k1::XOnlyPublicKey::from_slice(&data.1) {
|
||||
Ok(r) => Ok(r),
|
||||
Err(_) => Err(Error::InvalidPublicKey),
|
||||
}?;
|
||||
}
|
||||
Ok(Pubkey(data.1.try_into().unwrap()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Pubkey {
|
||||
|
||||
Reference in New Issue
Block a user