{-# OPTIONS_GHC -fno-warn-orphans #-} module Tendermint.SDK.Modules.Auth.Types where import Control.Lens (Wrapped (..), from, iso, view, (&), (.~), (^.), (^..), _Unwrapped') import Data.Bifunctor (bimap) import qualified Data.ProtoLens as P import Data.Proxy (Proxy (..)) import Data.String.Conversions (cs) import Data.Text (Text) import Data.Word import GHC.Generics (Generic) import GHC.TypeLits (symbolVal) import qualified Proto.Modules.Auth as A import qualified Proto.Modules.Auth_Fields as A import Tendermint.SDK.BaseApp (AppError (..), IsAppError (..), IsKey (..), Queryable (..)) import Tendermint.SDK.Codec (HasCodec (..)) import Tendermint.SDK.Types.Address (Address) type AuthModule = "auth" data Coin = Coin { coinDenomination :: Text , coinAmount :: Word64 } deriving Generic instance Wrapped Coin where type Unwrapped Coin = A.Coin _Wrapped' = iso t f where t Coin {..} = P.defMessage & A.denomination .~ coinDenomination & A.amount .~ coinAmount f message = Coin { coinDenomination = message ^. A.denomination , coinAmount = message ^. A.amount } data Account = Account { accountCoins :: [Coin] , accountNonce :: Word64 } deriving Generic instance Wrapped Account where type Unwrapped Account = A.Account _Wrapped' = iso t f where t Account {..} = P.defMessage & A.coins .~ accountCoins ^.. traverse . _Wrapped' & A.nonce .~ accountNonce f message = Account { accountCoins = message ^.. A.coins. traverse . _Unwrapped' , accountNonce = message ^. A.nonce } instance HasCodec Account where encode = P.encodeMessage . view _Wrapped' decode = bimap cs (view $ from _Wrapped') . P.decodeMessage instance IsKey Address AuthModule where type Value Address AuthModule = Account instance Queryable Account where type Name Account = "account" data AuthError = AccountAlreadExists Address instance IsAppError AuthError where makeAppError (AccountAlreadExists addr) = AppError { appErrorCode = 1 , appErrorCodespace = cs (symbolVal $ Proxy @AuthModule) , appErrorMessage = "Account Already Exists " <> (cs . show $ addr) <> "." }