{-# OPTIONS_GHC -fno-warn-orphans #-}

module Tendermint.SDK.Types.Address where

import qualified Crypto.Secp256k1         as Crypto
import qualified Data.Aeson               as A
import qualified Data.ByteArray.HexString as Hex
import           Data.ByteString          (ByteString)
import           Data.String              (fromString)
import           Data.Text                (unpack)
import           GHC.Generics             (Generic)
import           Proto3.Suite             (HasDefault (..), MessageField,
                                           Primitive (..))
import qualified Proto3.Suite.DotProto    as DotProto
import qualified Proto3.Wire.Decode       as Decode
import qualified Proto3.Wire.Encode       as Encode
import           Tendermint.SDK.Codec     (HasCodec (..))
import           Web.HttpApiData          (FromHttpApiData (..),
                                           ToHttpApiData (..))

-- | Used as a unique identifier for an account.
newtype Address =
    Address Hex.HexString
    deriving (Address -> Address -> Bool
(Address -> Address -> Bool)
-> (Address -> Address -> Bool) -> Eq Address
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Address -> Address -> Bool
$c/= :: Address -> Address -> Bool
== :: Address -> Address -> Bool
$c== :: Address -> Address -> Bool
Eq, Int -> Address -> ShowS
[Address] -> ShowS
Address -> String
(Int -> Address -> ShowS)
-> (Address -> String) -> ([Address] -> ShowS) -> Show Address
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Address] -> ShowS
$cshowList :: [Address] -> ShowS
show :: Address -> String
$cshow :: Address -> String
showsPrec :: Int -> Address -> ShowS
$cshowsPrec :: Int -> Address -> ShowS
Show, (forall x. Address -> Rep Address x)
-> (forall x. Rep Address x -> Address) -> Generic Address
forall x. Rep Address x -> Address
forall x. Address -> Rep Address x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Address x -> Address
$cfrom :: forall x. Address -> Rep Address x
Generic, Eq Address
Eq Address =>
(Address -> Address -> Ordering)
-> (Address -> Address -> Bool)
-> (Address -> Address -> Bool)
-> (Address -> Address -> Bool)
-> (Address -> Address -> Bool)
-> (Address -> Address -> Address)
-> (Address -> Address -> Address)
-> Ord Address
Address -> Address -> Bool
Address -> Address -> Ordering
Address -> Address -> Address
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Address -> Address -> Address
$cmin :: Address -> Address -> Address
max :: Address -> Address -> Address
$cmax :: Address -> Address -> Address
>= :: Address -> Address -> Bool
$c>= :: Address -> Address -> Bool
> :: Address -> Address -> Bool
$c> :: Address -> Address -> Bool
<= :: Address -> Address -> Bool
$c<= :: Address -> Address -> Bool
< :: Address -> Address -> Bool
$c< :: Address -> Address -> Bool
compare :: Address -> Address -> Ordering
$ccompare :: Address -> Address -> Ordering
$cp1Ord :: Eq Address
Ord, [Address] -> Encoding
[Address] -> Value
Address -> Encoding
Address -> Value
(Address -> Value)
-> (Address -> Encoding)
-> ([Address] -> Value)
-> ([Address] -> Encoding)
-> ToJSON Address
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [Address] -> Encoding
$ctoEncodingList :: [Address] -> Encoding
toJSONList :: [Address] -> Value
$ctoJSONList :: [Address] -> Value
toEncoding :: Address -> Encoding
$ctoEncoding :: Address -> Encoding
toJSON :: Address -> Value
$ctoJSON :: Address -> Value
A.ToJSON, Value -> Parser [Address]
Value -> Parser Address
(Value -> Parser Address)
-> (Value -> Parser [Address]) -> FromJSON Address
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Address]
$cparseJSONList :: Value -> Parser [Address]
parseJSON :: Value -> Parser Address
$cparseJSON :: Value -> Parser Address
A.FromJSON)

instance Primitive Address where
  encodePrimitive :: FieldNumber -> Address -> MessageBuilder
encodePrimitive n :: FieldNumber
n a :: Address
a = FieldNumber -> ByteString -> MessageBuilder
Encode.byteString FieldNumber
n (ByteString -> MessageBuilder) -> ByteString -> MessageBuilder
forall a b. (a -> b) -> a -> b
$ Address -> ByteString
addressToBytes Address
a
  decodePrimitive :: Parser RawPrimitive Address
decodePrimitive = ByteString -> Address
addressFromBytes (ByteString -> Address)
-> Parser RawPrimitive ByteString -> Parser RawPrimitive Address
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser RawPrimitive ByteString
Decode.byteString
  primType :: Proxy# Address -> DotProtoPrimType
primType _ = DotProtoPrimType
DotProto.Bytes
instance HasDefault Hex.HexString
instance HasDefault Address
instance MessageField Address
instance HasCodec Address where
  decode :: ByteString -> Either Text Address
decode = Address -> Either Text Address
forall a b. b -> Either a b
Right (Address -> Either Text Address)
-> (ByteString -> Address) -> ByteString -> Either Text Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Address
addressFromBytes
  encode :: Address -> ByteString
encode = Address -> ByteString
addressToBytes
instance ToHttpApiData Address where
  toQueryParam :: Address -> Text
toQueryParam (Address aHex :: HexString
aHex) = HexString -> Text
Hex.format HexString
aHex
instance FromHttpApiData Address where
  parseQueryParam :: Text -> Either Text Address
parseQueryParam = Address -> Either Text Address
forall a b. b -> Either a b
Right (Address -> Either Text Address)
-> (Text -> Address) -> Text -> Either Text Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HexString -> Address
Address (HexString -> Address) -> (Text -> HexString) -> Text -> Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> HexString
forall a. IsString a => String -> a
fromString (String -> HexString) -> (Text -> String) -> Text -> HexString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack

addressToBytes :: Address -> ByteString
addressToBytes :: Address -> ByteString
addressToBytes (Address addrHex :: HexString
addrHex) = HexString -> ByteString
forall ba. ByteArray ba => HexString -> ba
Hex.toBytes HexString
addrHex

addressFromBytes :: ByteString -> Address
addressFromBytes :: ByteString -> Address
addressFromBytes = HexString -> Address
Address (HexString -> Address)
-> (ByteString -> HexString) -> ByteString -> Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> HexString
forall ba. ByteArrayAccess ba => ba -> HexString
Hex.fromBytes

pubKeyToAddress :: Crypto.PubKey -> Address
pubKeyToAddress :: PubKey -> Address
pubKeyToAddress = ByteString -> Address
addressFromBytes (ByteString -> Address)
-> (PubKey -> ByteString) -> PubKey -> Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> PubKey -> ByteString
Crypto.exportPubKey Bool
False