module Signet.Unstable.Type.PublicKey where

import qualified Crypto.Error as Error
import qualified Crypto.PubKey.Ed25519 as Ed25519
import qualified Data.ByteArray.Encoding as Encoding
import qualified Data.ByteString as ByteString
import qualified Data.ByteString.Char8 as Ascii
import qualified Signet.Unstable.Exception.InvalidPublicKey as InvalidPublicKey
import qualified Signet.Unstable.Extra.Either as Either
import qualified Signet.Unstable.Extra.Maybe as Maybe

newtype PublicKey
  = MkPublicKey Ed25519.PublicKey
  deriving (PublicKey -> PublicKey -> Bool
(PublicKey -> PublicKey -> Bool)
-> (PublicKey -> PublicKey -> Bool) -> Eq PublicKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PublicKey -> PublicKey -> Bool
== :: PublicKey -> PublicKey -> Bool
$c/= :: PublicKey -> PublicKey -> Bool
/= :: PublicKey -> PublicKey -> Bool
Eq, Int -> PublicKey -> ShowS
[PublicKey] -> ShowS
PublicKey -> String
(Int -> PublicKey -> ShowS)
-> (PublicKey -> String)
-> ([PublicKey] -> ShowS)
-> Show PublicKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PublicKey -> ShowS
showsPrec :: Int -> PublicKey -> ShowS
$cshow :: PublicKey -> String
show :: PublicKey -> String
$cshowList :: [PublicKey] -> ShowS
showList :: [PublicKey] -> ShowS
Show)

unwrap :: PublicKey -> Ed25519.PublicKey
unwrap :: PublicKey -> PublicKey
unwrap (MkPublicKey PublicKey
publicKey) = PublicKey
publicKey

prefix :: ByteString.ByteString
prefix :: ByteString
prefix = String -> ByteString
Ascii.pack String
"whpk_"

parse :: ByteString.ByteString -> Either InvalidPublicKey.InvalidPublicKey PublicKey
parse :: ByteString -> Either InvalidPublicKey PublicKey
parse ByteString
prefixed = InvalidPublicKey
-> Maybe PublicKey -> Either InvalidPublicKey PublicKey
forall e a. e -> Maybe a -> Either e a
Maybe.note (ByteString -> InvalidPublicKey
InvalidPublicKey.MkInvalidPublicKey ByteString
prefixed) (Maybe PublicKey -> Either InvalidPublicKey PublicKey)
-> Maybe PublicKey -> Either InvalidPublicKey PublicKey
forall a b. (a -> b) -> a -> b
$ do
  encoded <- ByteString -> ByteString -> Maybe ByteString
ByteString.stripPrefix ByteString
prefix ByteString
prefixed
  byteString <- Either.hush $ Encoding.convertFromBase Encoding.Base64 encoded
  fmap MkPublicKey
    . Error.maybeCryptoError
    $ Ed25519.publicKey (byteString :: ByteString.ByteString)

render :: PublicKey -> ByteString.ByteString
render :: PublicKey -> ByteString
render = ByteString -> ByteString -> ByteString
forall a. Monoid a => a -> a -> a
mappend ByteString
prefix (ByteString -> ByteString)
-> (PublicKey -> ByteString) -> PublicKey -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base -> PublicKey -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
Base -> bin -> bout
Encoding.convertToBase Base
Encoding.Base64 (PublicKey -> ByteString)
-> (PublicKey -> PublicKey) -> PublicKey -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicKey -> PublicKey
unwrap