-- | Information about produced blocks

module Blockfrost.Types.Cardano.Blocks
  ( Block (..)
  ) where

import Data.Text (Text)
import Data.Aeson
import Data.Aeson.Types (explicitParseField)
import qualified Data.Vector
import Deriving.Aeson
import Servant.Docs (ToSample (..), singleSample)

import Blockfrost.Types.Shared

-- | Information about a block
data Block = Block
  { Block -> POSIXTime
_blockTime          :: POSIXTime -- ^ Block creation time in UNIX time
  , Block -> Maybe Integer
_blockHeight        :: Maybe Integer -- ^ Block number
  , Block -> BlockHash
_blockHash          :: BlockHash -- ^ Hash of the block
  , Block -> Maybe Slot
_blockSlot          :: Maybe Slot -- ^ Slot number
  , Block -> Maybe Epoch
_blockEpoch         :: Maybe Epoch -- ^ Epoch number
  , Block -> Maybe Integer
_blockEpochSlot     :: Maybe Integer -- ^ Slot within the epoch
  , Block -> Text
_blockSlotLeader    :: Text -- ^ Bech32 ID of the slot leader or specific block description in case there is no slot leader
  , Block -> Integer
_blockSize          :: Integer -- ^ Block size in Bytes
  , Block -> Integer
_blockTxCount       :: Integer -- ^ Number of transactions in the block
  , Block -> Maybe Lovelaces
_blockOutput        :: Maybe Lovelaces -- ^ Total output within the block in Lovelaces
  , Block -> Maybe Lovelaces
_blockFees          :: Maybe Lovelaces -- ^ Total fees within the block in Lovelaces
  , Block -> Maybe Text
_blockBlockVrf      :: Maybe Text -- ^ VRF key of the block
  , Block -> Maybe Text
_blockOpCert        :: Maybe Text -- ^ The hash of the operational certificate of the block producer
  , Block -> Maybe Quantity
_blockOpCertCounter :: Maybe Quantity -- ^ The value of the counter used to produce the operational certificate
  , Block -> Maybe BlockHash
_blockPreviousBlock :: Maybe BlockHash -- ^ Hash of the previous block
  , Block -> Maybe BlockHash
_blockNextBlock     :: Maybe BlockHash -- ^ Hash of the next block
  , Block -> Integer
_blockConfirmations :: Integer -- ^ Number of block confirmations
  }
  deriving stock (Int -> Block -> ShowS
[Block] -> ShowS
Block -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Block] -> ShowS
$cshowList :: [Block] -> ShowS
show :: Block -> String
$cshow :: Block -> String
showsPrec :: Int -> Block -> ShowS
$cshowsPrec :: Int -> Block -> ShowS
Show, Block -> Block -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Block -> Block -> Bool
$c/= :: Block -> Block -> Bool
== :: Block -> Block -> Bool
$c== :: Block -> Block -> Bool
Eq, forall x. Rep Block x -> Block
forall x. Block -> Rep Block x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Block x -> Block
$cfrom :: forall x. Block -> Rep Block x
Generic)
  deriving (Maybe Block
Value -> Parser [Block]
Value -> Parser Block
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
omittedField :: Maybe Block
$comittedField :: Maybe Block
parseJSONList :: Value -> Parser [Block]
$cparseJSONList :: Value -> Parser [Block]
parseJSON :: Value -> Parser Block
$cparseJSON :: Value -> Parser Block
FromJSON, [Block] -> Encoding
[Block] -> Value
Block -> Bool
Block -> Encoding
Block -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
omitField :: Block -> Bool
$comitField :: Block -> Bool
toEncodingList :: [Block] -> Encoding
$ctoEncodingList :: [Block] -> Encoding
toJSONList :: [Block] -> Value
$ctoJSONList :: [Block] -> Value
toEncoding :: Block -> Encoding
$ctoEncoding :: Block -> Encoding
toJSON :: Block -> Value
$ctoJSON :: Block -> Value
ToJSON)
  via CustomJSON '[FieldLabelModifier '[StripPrefix "_block", CamelToSnake]] Block

instance ToSample Block where
  toSamples :: Proxy Block -> [(Text, Block)]
toSamples Proxy Block
_ = forall a. a -> [(Text, a)]
singleSample forall a b. (a -> b) -> a -> b
$ Block
    { _blockTime :: POSIXTime
_blockTime = POSIXTime
1641338934
    , _blockHeight :: Maybe Integer
_blockHeight = forall (f :: * -> *) a. Applicative f => a -> f a
pure Integer
15243593
    , _blockHash :: BlockHash
_blockHash = BlockHash
"4ea1ba291e8eef538635a53e59fddba7810d1679631cc3aed7c8e6c4091a516a"
    , _blockSlot :: Maybe Slot
_blockSlot = forall (f :: * -> *) a. Applicative f => a -> f a
pure Slot
412162133
    , _blockEpoch :: Maybe Epoch
_blockEpoch = forall (f :: * -> *) a. Applicative f => a -> f a
pure Epoch
425
    , _blockEpochSlot :: Maybe Integer
_blockEpochSlot = forall (f :: * -> *) a. Applicative f => a -> f a
pure Integer
12
    , _blockSlotLeader :: Text
_blockSlotLeader = Text
"pool1pu5jlj4q9w9jlxeu370a3c9myx47md5j5m2str0naunn2qnikdy"
    , _blockSize :: Integer
_blockSize = Integer
3
    , _blockTxCount :: Integer
_blockTxCount = Integer
1
    , _blockOutput :: Maybe Lovelaces
_blockOutput = forall (f :: * -> *) a. Applicative f => a -> f a
pure Discrete' "ADA" '(1000000, 1)
128314491794
    , _blockFees :: Maybe Lovelaces
_blockFees = forall (f :: * -> *) a. Applicative f => a -> f a
pure Discrete' "ADA" '(1000000, 1)
592661
    , _blockBlockVrf :: Maybe Text
_blockBlockVrf = forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"vrf_vk1wf2k6lhujezqcfe00l6zetxpnmh9n6mwhpmhm0dvfh3fxgmdnrfqkms8ty"
    , _blockOpCert :: Maybe Text
_blockOpCert = forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"da905277534faf75dae41732650568af545134ee08a3c0392dbefc8096ae177c"
    , _blockOpCertCounter :: Maybe Quantity
_blockOpCertCounter = forall (f :: * -> *) a. Applicative f => a -> f a
pure Quantity
18
    , _blockPreviousBlock :: Maybe BlockHash
_blockPreviousBlock = forall (f :: * -> *) a. Applicative f => a -> f a
pure BlockHash
"43ebccb3ac72c7cebd0d9b755a4b08412c9f5dcb81b8a0ad1e3c197d29d47b05"
    , _blockNextBlock :: Maybe BlockHash
_blockNextBlock = forall (f :: * -> *) a. Applicative f => a -> f a
pure BlockHash
"8367f026cf4b03e116ff8ee5daf149b55ba5a6ec6dec04803b8dc317721d15fa"
    , _blockConfirmations :: Integer
_blockConfirmations = Integer
4698
    }

-- instances for getBlockAffectedAddreses response
instance {-# OVERLAPS #-} ToJSON (Address, [TxHash]) where
  toJSON :: (Address, [TxHash]) -> Value
toJSON (Address
addr, [TxHash]
txs) = [Pair] -> Value
object [
        Key
"address" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= forall a. ToJSON a => a -> Value
toJSON Address
addr
      , Key
"transactions" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= forall a b. (a -> b) -> [a] -> [b]
map (\TxHash
tx -> [Pair] -> Value
object [ Key
"tx_hash" forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= forall a. ToJSON a => a -> Value
toJSON TxHash
tx ]) [TxHash]
txs
      ]

instance {-# OVERLAPS #-} FromJSON (Address, [TxHash]) where
  parseJSON :: Value -> Parser (Address, [TxHash])
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"addrTxs" forall a b. (a -> b) -> a -> b
$ \Object
o -> do
    Address
addr <- Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"address"
    [TxHash]
txs <- forall a. (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseField
      (forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray String
"a" forall a b. (a -> b) -> a -> b
$ \Array
a -> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"txHashes" forall a b. (a -> b) -> a -> b
$ \Object
to -> Object
to forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"tx_hash") (forall a. Vector a -> [a]
Data.Vector.toList Array
a))
      Object
o
      Key
"transactions"
    forall (f :: * -> *) a. Applicative f => a -> f a
pure (Address
addr, [TxHash]
txs)