{-# LANGUAGE DeriveAnyClass      #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE FlexibleInstances   #-}
{-# LANGUAGE LambdaCase          #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE RecordWildCards     #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Haskoin.Store.Data
    ( -- * Address Balances
      Balance(..)
    , balanceToJSON
    , balanceToEncoding
    , balanceParseJSON
    , zeroBalance
    , nullBalance

      -- * Block Data
    , BlockData(..)
    , blockDataToJSON
    , blockDataToEncoding
    , confirmed

      -- * Transactions
    , TxRef(..)
    , TxData(..)
    , Transaction(..)
    , transactionToJSON
    , transactionToEncoding
    , transactionParseJSON
    , transactionData
    , fromTransaction
    , toTransaction
    , StoreInput(..)
    , storeInputToJSON
    , storeInputToEncoding
    , storeInputParseJSON
    , isCoinbase
    , StoreOutput(..)
    , storeOutputToJSON
    , storeOutputToEncoding
    , storeOutputParseJSON
    , Prev(..)
    , Spender(..)
    , BlockRef(..)
    , UnixTime
    , getUnixTime
    , putUnixTime
    , BlockPos

      -- * Unspent Outputs
    , Unspent(..)
    , unspentToJSON
    , unspentToEncoding
    , unspentParseJSON

      -- * Extended Public Keys
    , XPubSpec(..)
    , XPubBal(..)
    , xPubBalToJSON
    , xPubBalToEncoding
    , xPubBalParseJSON
    , XPubUnspent(..)
    , xPubUnspentToJSON
    , xPubUnspentToEncoding
    , xPubUnspentParseJSON
    , XPubSummary(..)
    , DeriveType(..)
    , textToDeriveType
    , deriveTypeToText

      -- * Other Data
    , TxId(..)
    , GenericResult(..)
    , SerialList(..)
    , RawResult(..)
    , RawResultList(..)
    , PeerInformation(..)
    , Healthy(..)
    , BlockHealth(..)
    , TimeHealth(..)
    , CountHealth(..)
    , MaxHealth(..)
    , HealthCheck(..)
    , Event(..)
    , Except(..)

     -- * Blockchain.info API
    , BinfoBlockId(..)
    , BinfoTxId(..)
    , encodeBinfoTxId
    , BinfoFilter(..)
    , BinfoMultiAddr(..)
    , binfoMultiAddrToJSON
    , binfoMultiAddrToEncoding
    , binfoMultiAddrParseJSON
    , BinfoShortBal(..)
    , BinfoBalance(..)
    , toBinfoAddrs
    , binfoBalanceToJSON
    , binfoBalanceToEncoding
    , binfoBalanceParseJSON
    , BinfoRawAddr(..)
    , binfoRawAddrToJSON
    , binfoRawAddrToEncoding
    , binfoRawAddrParseJSON
    , BinfoAddr(..)
    , parseBinfoAddr
    , BinfoWallet(..)
    , BinfoUnspent(..)
    , binfoUnspentToJSON
    , binfoUnspentToEncoding
    , binfoUnspentParseJSON
    , binfoHexValue
    , BinfoUnspents(..)
    , binfoUnspentsToJSON
    , binfoUnspentsToEncoding
    , binfoUnspentsParseJSON
    , BinfoBlock(..)
    , toBinfoBlock
    , binfoBlockToJSON
    , binfoBlockToEncoding
    , binfoBlockParseJSON
    , binfoBlocksToJSON
    , binfoBlocksToEncoding
    , binfoBlocksParseJSON
    , BinfoTx(..)
    , relevantTxs
    , toBinfoTx
    , toBinfoTxSimple
    , binfoTxToJSON
    , binfoTxToEncoding
    , binfoTxParseJSON
    , BinfoTxInput(..)
    , binfoTxInputToJSON
    , binfoTxInputToEncoding
    , binfoTxInputParseJSON
    , BinfoTxOutput(..)
    , binfoTxOutputToJSON
    , binfoTxOutputToEncoding
    , binfoTxOutputParseJSON
    , BinfoSpender(..)
    , BinfoXPubPath(..)
    , binfoXPubPathToJSON
    , binfoXPubPathToEncoding
    , binfoXPubPathParseJSON
    , BinfoInfo(..)
    , BinfoBlockInfo(..)
    , toBinfoBlockInfo
    , BinfoSymbol(..)
    , BinfoTicker(..)
    , BinfoRate(..)
    , BinfoHistory(..)
    , toBinfoHistory
    , BinfoDate(..)
    , BinfoHeader(..)
    , BinfoMempool(..)
    , binfoMempoolToJSON
    , binfoMempoolToEncoding
    , binfoMempoolParseJSON
    , BinfoBlocks(..)
    )

where

import           Control.Applicative     ((<|>))
import           Control.DeepSeq         (NFData)
import           Control.Exception       (Exception)
import           Control.Monad           (join, mzero, unless, (<=<))
import           Data.Aeson              (Encoding, FromJSON (..), ToJSON (..),
                                          Value (..), (.!=), (.:), (.:?), (.=))
import qualified Data.Aeson              as A
import qualified Data.Aeson.Encoding     as AE
import           Data.Aeson.Types        (Parser)
import           Data.Binary             (Binary (get, put))
import           Data.Bits               (Bits (..))
import           Data.ByteString         (ByteString)
import qualified Data.ByteString         as BS
import qualified Data.ByteString.Builder as BSB
import           Data.Bytes.Get
import qualified Data.Bytes.Get          as Bytes.Get
import           Data.Bytes.Put
import           Data.Bytes.Serial
import           Data.Default            (Default (..))
import           Data.Foldable           (toList)
import           Data.Function           (on)
import           Data.HashMap.Strict     (HashMap)
import qualified Data.HashMap.Strict     as HashMap
import           Data.HashSet            (HashSet)
import qualified Data.HashSet            as HashSet
import           Data.Hashable           (Hashable (..))
import           Data.Int                (Int32, Int64)
import qualified Data.IntMap             as IntMap
import           Data.IntMap.Strict      (IntMap)
import           Data.Maybe              (catMaybes, fromMaybe, isJust,
                                          isNothing, mapMaybe, maybeToList)
import           Data.Serialize          (Serialize (..))
import           Data.String.Conversions (cs)
import           Data.Text               (Text)
import qualified Data.Text               as T
import qualified Data.Text.Encoding      as TE
import qualified Data.Text.Lazy          as TL
import qualified Data.Text.Lazy.Encoding as TLE
import           Data.Time.Clock.POSIX   (posixSecondsToUTCTime,
                                          utcTimeToPOSIXSeconds)
import           Data.Time.Format        (defaultTimeLocale, formatTime,
                                          parseTimeM)
import           Data.Word               (Word32, Word64)
import           GHC.Generics            (Generic)
import           Haskoin                 hiding (inputAddress)
import           Web.Scotty.Trans        (Parsable (..), ScottyError (..))

data DeriveType
    = DeriveNormal
    | DeriveP2SH
    | DeriveP2WPKH
    deriving (Int -> DeriveType -> ShowS
[DeriveType] -> ShowS
DeriveType -> String
(Int -> DeriveType -> ShowS)
-> (DeriveType -> String)
-> ([DeriveType] -> ShowS)
-> Show DeriveType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DeriveType] -> ShowS
$cshowList :: [DeriveType] -> ShowS
show :: DeriveType -> String
$cshow :: DeriveType -> String
showsPrec :: Int -> DeriveType -> ShowS
$cshowsPrec :: Int -> DeriveType -> ShowS
Show, DeriveType -> DeriveType -> Bool
(DeriveType -> DeriveType -> Bool)
-> (DeriveType -> DeriveType -> Bool) -> Eq DeriveType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DeriveType -> DeriveType -> Bool
$c/= :: DeriveType -> DeriveType -> Bool
== :: DeriveType -> DeriveType -> Bool
$c== :: DeriveType -> DeriveType -> Bool
Eq, (forall x. DeriveType -> Rep DeriveType x)
-> (forall x. Rep DeriveType x -> DeriveType) -> Generic DeriveType
forall x. Rep DeriveType x -> DeriveType
forall x. DeriveType -> Rep DeriveType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DeriveType x -> DeriveType
$cfrom :: forall x. DeriveType -> Rep DeriveType x
Generic, DeriveType -> ()
(DeriveType -> ()) -> NFData DeriveType
forall a. (a -> ()) -> NFData a
rnf :: DeriveType -> ()
$crnf :: DeriveType -> ()
NFData)

textToDeriveType :: Text -> Maybe DeriveType
textToDeriveType :: Text -> Maybe DeriveType
textToDeriveType "normal" = DeriveType -> Maybe DeriveType
forall a. a -> Maybe a
Just DeriveType
DeriveNormal
textToDeriveType "compat" = DeriveType -> Maybe DeriveType
forall a. a -> Maybe a
Just DeriveType
DeriveP2SH
textToDeriveType "segwit" = DeriveType -> Maybe DeriveType
forall a. a -> Maybe a
Just DeriveType
DeriveP2WPKH
textToDeriveType _        = Maybe DeriveType
forall a. Maybe a
Nothing

deriveTypeToText :: DeriveType -> Text
deriveTypeToText :: DeriveType -> Text
deriveTypeToText DeriveNormal = "normal"
deriveTypeToText DeriveP2SH   = "compat"
deriveTypeToText DeriveP2WPKH = "segwit"

instance Serial DeriveType where
    serialize :: DeriveType -> m ()
serialize DeriveNormal = Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x00
    serialize DeriveP2SH   = Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x01
    serialize DeriveP2WPKH = Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x02

    deserialize :: m DeriveType
deserialize = m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8 m Word8 -> (Word8 -> m DeriveType) -> m DeriveType
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        0x00 -> DeriveType -> m DeriveType
forall (m :: * -> *) a. Monad m => a -> m a
return DeriveType
DeriveNormal
        0x01 -> DeriveType -> m DeriveType
forall (m :: * -> *) a. Monad m => a -> m a
return DeriveType
DeriveP2SH
        0x02 -> DeriveType -> m DeriveType
forall (m :: * -> *) a. Monad m => a -> m a
return DeriveType
DeriveP2WPKH
        _    -> DeriveType -> m DeriveType
forall (m :: * -> *) a. Monad m => a -> m a
return DeriveType
DeriveNormal

instance Binary DeriveType where
    put :: DeriveType -> Put
put = DeriveType -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get DeriveType
get = Get DeriveType
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Serialize DeriveType where
    put :: Putter DeriveType
put = Putter DeriveType
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get DeriveType
get = Get DeriveType
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Default DeriveType where
    def :: DeriveType
def = DeriveType
DeriveNormal

instance Parsable DeriveType where
    parseParam :: Text -> Either Text DeriveType
parseParam txt :: Text
txt =
        case Text -> Maybe DeriveType
textToDeriveType (Text -> Text
TL.toStrict Text
txt) of
            Nothing -> Text -> Either Text DeriveType
forall a b. a -> Either a b
Left "invalid derivation type"
            Just x :: DeriveType
x  -> DeriveType -> Either Text DeriveType
forall a b. b -> Either a b
Right DeriveType
x

data XPubSpec =
    XPubSpec
        { XPubSpec -> XPubKey
xPubSpecKey    :: !XPubKey
        , XPubSpec -> DeriveType
xPubDeriveType :: !DeriveType
        }
    deriving (Int -> XPubSpec -> ShowS
[XPubSpec] -> ShowS
XPubSpec -> String
(Int -> XPubSpec -> ShowS)
-> (XPubSpec -> String) -> ([XPubSpec] -> ShowS) -> Show XPubSpec
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [XPubSpec] -> ShowS
$cshowList :: [XPubSpec] -> ShowS
show :: XPubSpec -> String
$cshow :: XPubSpec -> String
showsPrec :: Int -> XPubSpec -> ShowS
$cshowsPrec :: Int -> XPubSpec -> ShowS
Show, XPubSpec -> XPubSpec -> Bool
(XPubSpec -> XPubSpec -> Bool)
-> (XPubSpec -> XPubSpec -> Bool) -> Eq XPubSpec
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: XPubSpec -> XPubSpec -> Bool
$c/= :: XPubSpec -> XPubSpec -> Bool
== :: XPubSpec -> XPubSpec -> Bool
$c== :: XPubSpec -> XPubSpec -> Bool
Eq, (forall x. XPubSpec -> Rep XPubSpec x)
-> (forall x. Rep XPubSpec x -> XPubSpec) -> Generic XPubSpec
forall x. Rep XPubSpec x -> XPubSpec
forall x. XPubSpec -> Rep XPubSpec x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep XPubSpec x -> XPubSpec
$cfrom :: forall x. XPubSpec -> Rep XPubSpec x
Generic, XPubSpec -> ()
(XPubSpec -> ()) -> NFData XPubSpec
forall a. (a -> ()) -> NFData a
rnf :: XPubSpec -> ()
$crnf :: XPubSpec -> ()
NFData)

instance Hashable XPubSpec where
    hashWithSalt :: Int -> XPubSpec -> Int
hashWithSalt i :: Int
i XPubSpec {xPubSpecKey :: XPubSpec -> XPubKey
xPubSpecKey = XPubKey {xPubKey :: XPubKey -> PubKey
xPubKey = PubKey
pubkey}} =
        Int -> PubKey -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
i PubKey
pubkey

instance Serial XPubSpec where
    serialize :: XPubSpec -> m ()
serialize XPubSpec {xPubSpecKey :: XPubSpec -> XPubKey
xPubSpecKey = XPubKey
k, xPubDeriveType :: XPubSpec -> DeriveType
xPubDeriveType = DeriveType
t} = do
        Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 (XPubKey -> Word8
xPubDepth XPubKey
k)
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be (XPubKey -> Word32
xPubParent XPubKey
k)
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be (XPubKey -> Word32
xPubIndex XPubKey
k)
        ChainCode -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (XPubKey -> ChainCode
xPubChain XPubKey
k)
        PubKeyI -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (Bool -> PubKey -> PubKeyI
wrapPubKey Bool
True (XPubKey -> PubKey
xPubKey XPubKey
k))
        DeriveType -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize DeriveType
t
    deserialize :: m XPubSpec
deserialize = do
        Word8
d <- m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8
        Word32
p <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        Word32
i <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        ChainCode
c <- m ChainCode
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        PubKeyI
k <- m PubKeyI
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        DeriveType
t <- m DeriveType
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        let x :: XPubKey
x = $WXPubKey :: Word8 -> Word32 -> Word32 -> ChainCode -> PubKey -> XPubKey
XPubKey
                { xPubDepth :: Word8
xPubDepth = Word8
d
                , xPubParent :: Word32
xPubParent = Word32
p
                , xPubIndex :: Word32
xPubIndex = Word32
i
                , xPubChain :: ChainCode
xPubChain = ChainCode
c
                , xPubKey :: PubKey
xPubKey = PubKeyI -> PubKey
pubKeyPoint PubKeyI
k
                }
        XPubSpec -> m XPubSpec
forall (m :: * -> *) a. Monad m => a -> m a
return $WXPubSpec :: XPubKey -> DeriveType -> XPubSpec
XPubSpec {xPubSpecKey :: XPubKey
xPubSpecKey = XPubKey
x, xPubDeriveType :: DeriveType
xPubDeriveType = DeriveType
t}

instance Serialize XPubSpec where
    put :: Putter XPubSpec
put = Putter XPubSpec
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get XPubSpec
get = Get XPubSpec
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary XPubSpec where
    put :: XPubSpec -> Put
put = XPubSpec -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get XPubSpec
get = Get XPubSpec
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

type UnixTime = Word64
type BlockPos = Word32

-- | Binary such that ordering is inverted.
putUnixTime :: MonadPut m => Word64 -> m ()
putUnixTime :: Word64 -> m ()
putUnixTime w :: Word64
w = Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be (Word64 -> m ()) -> Word64 -> m ()
forall a b. (a -> b) -> a -> b
$ Word64
forall a. Bounded a => a
maxBound Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
w

getUnixTime :: MonadGet m => m Word64
getUnixTime :: m Word64
getUnixTime = (Word64
forall a. Bounded a => a
maxBound Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
-) (Word64 -> Word64) -> m Word64 -> m Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be

-- | Reference to a block where a transaction is stored.
data BlockRef
    = BlockRef
          { BlockRef -> Word32
blockRefHeight :: !BlockHeight
          -- ^ block height in the chain
          , BlockRef -> Word32
blockRefPos    :: !Word32
          -- ^ position of transaction within the block
          }
    | MemRef
          { BlockRef -> Word64
memRefTime :: !UnixTime
          }
    deriving (Int -> BlockRef -> ShowS
[BlockRef] -> ShowS
BlockRef -> String
(Int -> BlockRef -> ShowS)
-> (BlockRef -> String) -> ([BlockRef] -> ShowS) -> Show BlockRef
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BlockRef] -> ShowS
$cshowList :: [BlockRef] -> ShowS
show :: BlockRef -> String
$cshow :: BlockRef -> String
showsPrec :: Int -> BlockRef -> ShowS
$cshowsPrec :: Int -> BlockRef -> ShowS
Show, ReadPrec [BlockRef]
ReadPrec BlockRef
Int -> ReadS BlockRef
ReadS [BlockRef]
(Int -> ReadS BlockRef)
-> ReadS [BlockRef]
-> ReadPrec BlockRef
-> ReadPrec [BlockRef]
-> Read BlockRef
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [BlockRef]
$creadListPrec :: ReadPrec [BlockRef]
readPrec :: ReadPrec BlockRef
$creadPrec :: ReadPrec BlockRef
readList :: ReadS [BlockRef]
$creadList :: ReadS [BlockRef]
readsPrec :: Int -> ReadS BlockRef
$creadsPrec :: Int -> ReadS BlockRef
Read, BlockRef -> BlockRef -> Bool
(BlockRef -> BlockRef -> Bool)
-> (BlockRef -> BlockRef -> Bool) -> Eq BlockRef
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BlockRef -> BlockRef -> Bool
$c/= :: BlockRef -> BlockRef -> Bool
== :: BlockRef -> BlockRef -> Bool
$c== :: BlockRef -> BlockRef -> Bool
Eq, Eq BlockRef
Eq BlockRef =>
(BlockRef -> BlockRef -> Ordering)
-> (BlockRef -> BlockRef -> Bool)
-> (BlockRef -> BlockRef -> Bool)
-> (BlockRef -> BlockRef -> Bool)
-> (BlockRef -> BlockRef -> Bool)
-> (BlockRef -> BlockRef -> BlockRef)
-> (BlockRef -> BlockRef -> BlockRef)
-> Ord BlockRef
BlockRef -> BlockRef -> Bool
BlockRef -> BlockRef -> Ordering
BlockRef -> BlockRef -> BlockRef
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 :: BlockRef -> BlockRef -> BlockRef
$cmin :: BlockRef -> BlockRef -> BlockRef
max :: BlockRef -> BlockRef -> BlockRef
$cmax :: BlockRef -> BlockRef -> BlockRef
>= :: BlockRef -> BlockRef -> Bool
$c>= :: BlockRef -> BlockRef -> Bool
> :: BlockRef -> BlockRef -> Bool
$c> :: BlockRef -> BlockRef -> Bool
<= :: BlockRef -> BlockRef -> Bool
$c<= :: BlockRef -> BlockRef -> Bool
< :: BlockRef -> BlockRef -> Bool
$c< :: BlockRef -> BlockRef -> Bool
compare :: BlockRef -> BlockRef -> Ordering
$ccompare :: BlockRef -> BlockRef -> Ordering
$cp1Ord :: Eq BlockRef
Ord, (forall x. BlockRef -> Rep BlockRef x)
-> (forall x. Rep BlockRef x -> BlockRef) -> Generic BlockRef
forall x. Rep BlockRef x -> BlockRef
forall x. BlockRef -> Rep BlockRef x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BlockRef x -> BlockRef
$cfrom :: forall x. BlockRef -> Rep BlockRef x
Generic, Int -> BlockRef -> Int
BlockRef -> Int
(Int -> BlockRef -> Int) -> (BlockRef -> Int) -> Hashable BlockRef
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: BlockRef -> Int
$chash :: BlockRef -> Int
hashWithSalt :: Int -> BlockRef -> Int
$chashWithSalt :: Int -> BlockRef -> Int
Hashable, BlockRef -> ()
(BlockRef -> ()) -> NFData BlockRef
forall a. (a -> ()) -> NFData a
rnf :: BlockRef -> ()
$crnf :: BlockRef -> ()
NFData)

-- | Serial entities will sort in reverse order.
instance Serial BlockRef where
    serialize :: BlockRef -> m ()
serialize MemRef {memRefTime :: BlockRef -> Word64
memRefTime = Word64
t} = do
        Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x00
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putUnixTime Word64
t
    serialize BlockRef {blockRefHeight :: BlockRef -> Word32
blockRefHeight = Word32
h, blockRefPos :: BlockRef -> Word32
blockRefPos = Word32
p} = do
        Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x01
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be (Word32
forall a. Bounded a => a
maxBound Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
h)
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be (Word32
forall a. Bounded a => a
maxBound Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
p)
    deserialize :: m BlockRef
deserialize =
        m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8 m Word8 -> (Word8 -> m BlockRef) -> m BlockRef
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        0x00 -> m BlockRef
getmemref
        0x01 -> m BlockRef
getblockref
        _    -> String -> m BlockRef
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "Cannot decode BlockRef"
      where
        getmemref :: m BlockRef
getmemref = do
            Word64 -> BlockRef
MemRef (Word64 -> BlockRef) -> m Word64 -> m BlockRef
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word64
forall (m :: * -> *). MonadGet m => m Word64
getUnixTime
        getblockref :: m BlockRef
getblockref = do
            Word32
h <- (Word32
forall a. Bounded a => a
maxBound Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
-) (Word32 -> Word32) -> m Word32 -> m Word32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
            Word32
p <- (Word32
forall a. Bounded a => a
maxBound Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
-) (Word32 -> Word32) -> m Word32 -> m Word32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
            BlockRef -> m BlockRef
forall (m :: * -> *) a. Monad m => a -> m a
return $WBlockRef :: Word32 -> Word32 -> BlockRef
BlockRef {blockRefHeight :: Word32
blockRefHeight = Word32
h, blockRefPos :: Word32
blockRefPos = Word32
p}

instance Serialize BlockRef where
    put :: Putter BlockRef
put = Putter BlockRef
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get BlockRef
get = Get BlockRef
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary BlockRef where
    put :: BlockRef -> Put
put = BlockRef -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get BlockRef
get = Get BlockRef
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

confirmed :: BlockRef -> Bool
confirmed :: BlockRef -> Bool
confirmed BlockRef {} = Bool
True
confirmed MemRef {}   = Bool
False

instance ToJSON BlockRef where
    toJSON :: BlockRef -> Value
toJSON BlockRef {blockRefHeight :: BlockRef -> Word32
blockRefHeight = Word32
h, blockRefPos :: BlockRef -> Word32
blockRefPos = Word32
p} =
        [Pair] -> Value
A.object ["height" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
h, "position" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
p]
    toJSON MemRef {memRefTime :: BlockRef -> Word64
memRefTime = Word64
t} = [Pair] -> Value
A.object ["mempool" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
t]
    toEncoding :: BlockRef -> Encoding
toEncoding BlockRef {blockRefHeight :: BlockRef -> Word32
blockRefHeight = Word32
h, blockRefPos :: BlockRef -> Word32
blockRefPos = Word32
p} =
        Series -> Encoding
AE.pairs ("height" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
h Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<> "position" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
p)
    toEncoding MemRef {memRefTime :: BlockRef -> Word64
memRefTime = Word64
t} = Series -> Encoding
AE.pairs ("mempool" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
t)

instance FromJSON BlockRef where
    parseJSON :: Value -> Parser BlockRef
parseJSON = String -> (Object -> Parser BlockRef) -> Value -> Parser BlockRef
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "blockref" ((Object -> Parser BlockRef) -> Value -> Parser BlockRef)
-> (Object -> Parser BlockRef) -> Value -> Parser BlockRef
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> Object -> Parser BlockRef
b Object
o Parser BlockRef -> Parser BlockRef -> Parser BlockRef
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Object -> Parser BlockRef
m Object
o
      where
        b :: Object -> Parser BlockRef
b o :: Object
o = do
            Word32
height <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "height"
            Word32
position <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "position"
            BlockRef -> Parser BlockRef
forall (m :: * -> *) a. Monad m => a -> m a
return $WBlockRef :: Word32 -> Word32 -> BlockRef
BlockRef{blockRefHeight :: Word32
blockRefHeight = Word32
height, blockRefPos :: Word32
blockRefPos = Word32
position}
        m :: Object -> Parser BlockRef
m o :: Object
o = do
            Word64
mempool <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "mempool"
            BlockRef -> Parser BlockRef
forall (m :: * -> *) a. Monad m => a -> m a
return $WMemRef :: Word64 -> BlockRef
MemRef{memRefTime :: Word64
memRefTime = Word64
mempool}

-- | Transaction in relation to an address.
data TxRef =
    TxRef
        { TxRef -> BlockRef
txRefBlock :: !BlockRef
    -- ^ block information
        , TxRef -> TxHash
txRefHash  :: !TxHash
    -- ^ transaction hash
        }
    deriving (Int -> TxRef -> ShowS
[TxRef] -> ShowS
TxRef -> String
(Int -> TxRef -> ShowS)
-> (TxRef -> String) -> ([TxRef] -> ShowS) -> Show TxRef
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TxRef] -> ShowS
$cshowList :: [TxRef] -> ShowS
show :: TxRef -> String
$cshow :: TxRef -> String
showsPrec :: Int -> TxRef -> ShowS
$cshowsPrec :: Int -> TxRef -> ShowS
Show, TxRef -> TxRef -> Bool
(TxRef -> TxRef -> Bool) -> (TxRef -> TxRef -> Bool) -> Eq TxRef
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TxRef -> TxRef -> Bool
$c/= :: TxRef -> TxRef -> Bool
== :: TxRef -> TxRef -> Bool
$c== :: TxRef -> TxRef -> Bool
Eq, Eq TxRef
Eq TxRef =>
(TxRef -> TxRef -> Ordering)
-> (TxRef -> TxRef -> Bool)
-> (TxRef -> TxRef -> Bool)
-> (TxRef -> TxRef -> Bool)
-> (TxRef -> TxRef -> Bool)
-> (TxRef -> TxRef -> TxRef)
-> (TxRef -> TxRef -> TxRef)
-> Ord TxRef
TxRef -> TxRef -> Bool
TxRef -> TxRef -> Ordering
TxRef -> TxRef -> TxRef
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 :: TxRef -> TxRef -> TxRef
$cmin :: TxRef -> TxRef -> TxRef
max :: TxRef -> TxRef -> TxRef
$cmax :: TxRef -> TxRef -> TxRef
>= :: TxRef -> TxRef -> Bool
$c>= :: TxRef -> TxRef -> Bool
> :: TxRef -> TxRef -> Bool
$c> :: TxRef -> TxRef -> Bool
<= :: TxRef -> TxRef -> Bool
$c<= :: TxRef -> TxRef -> Bool
< :: TxRef -> TxRef -> Bool
$c< :: TxRef -> TxRef -> Bool
compare :: TxRef -> TxRef -> Ordering
$ccompare :: TxRef -> TxRef -> Ordering
$cp1Ord :: Eq TxRef
Ord, (forall x. TxRef -> Rep TxRef x)
-> (forall x. Rep TxRef x -> TxRef) -> Generic TxRef
forall x. Rep TxRef x -> TxRef
forall x. TxRef -> Rep TxRef x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TxRef x -> TxRef
$cfrom :: forall x. TxRef -> Rep TxRef x
Generic, Int -> TxRef -> Int
TxRef -> Int
(Int -> TxRef -> Int) -> (TxRef -> Int) -> Hashable TxRef
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: TxRef -> Int
$chash :: TxRef -> Int
hashWithSalt :: Int -> TxRef -> Int
$chashWithSalt :: Int -> TxRef -> Int
Hashable, TxRef -> ()
(TxRef -> ()) -> NFData TxRef
forall a. (a -> ()) -> NFData a
rnf :: TxRef -> ()
$crnf :: TxRef -> ()
NFData)

instance Serial TxRef where
    serialize :: TxRef -> m ()
serialize (TxRef b :: BlockRef
b h :: TxHash
h) = do
        BlockRef -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize BlockRef
b
        TxHash -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize TxHash
h

    deserialize :: m TxRef
deserialize =
        BlockRef -> TxHash -> TxRef
TxRef (BlockRef -> TxHash -> TxRef) -> m BlockRef -> m (TxHash -> TxRef)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m BlockRef
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize m (TxHash -> TxRef) -> m TxHash -> m TxRef
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m TxHash
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary TxRef where
    put :: TxRef -> Put
put = TxRef -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get TxRef
get = Get TxRef
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Serialize TxRef where
    put :: Putter TxRef
put = Putter TxRef
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get TxRef
get = Get TxRef
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance ToJSON TxRef where
    toJSON :: TxRef -> Value
toJSON btx :: TxRef
btx =
        [Pair] -> Value
A.object
            [ "txid" Text -> TxHash -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TxRef -> TxHash
txRefHash TxRef
btx
            , "block" Text -> BlockRef -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TxRef -> BlockRef
txRefBlock TxRef
btx
            ]
    toEncoding :: TxRef -> Encoding
toEncoding btx :: TxRef
btx =
        Series -> Encoding
AE.pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
            "txid" Text -> TxHash -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TxRef -> TxHash
txRefHash TxRef
btx Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
            "block" Text -> BlockRef -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TxRef -> BlockRef
txRefBlock TxRef
btx

instance FromJSON TxRef where
    parseJSON :: Value -> Parser TxRef
parseJSON =
        String -> (Object -> Parser TxRef) -> Value -> Parser TxRef
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "blocktx" ((Object -> Parser TxRef) -> Value -> Parser TxRef)
-> (Object -> Parser TxRef) -> Value -> Parser TxRef
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
            TxHash
txid <- Object
o Object -> Text -> Parser TxHash
forall a. FromJSON a => Object -> Text -> Parser a
.: "txid"
            BlockRef
block <- Object
o Object -> Text -> Parser BlockRef
forall a. FromJSON a => Object -> Text -> Parser a
.: "block"
            TxRef -> Parser TxRef
forall (m :: * -> *) a. Monad m => a -> m a
return $WTxRef :: BlockRef -> TxHash -> TxRef
TxRef {txRefBlock :: BlockRef
txRefBlock = BlockRef
block, txRefHash :: TxHash
txRefHash = TxHash
txid}

-- | Address balance information.
data Balance =
    Balance
        { Balance -> Address
balanceAddress       :: !Address
        -- ^ address balance
        , Balance -> Word64
balanceAmount        :: !Word64
        -- ^ confirmed balance
        , Balance -> Word64
balanceZero          :: !Word64
        -- ^ unconfirmed balance
        , Balance -> Word64
balanceUnspentCount  :: !Word64
        -- ^ number of unspent outputs
        , Balance -> Word64
balanceTxCount       :: !Word64
        -- ^ number of transactions
        , Balance -> Word64
balanceTotalReceived :: !Word64
        -- ^ total amount from all outputs in this address
        }
    deriving (Int -> Balance -> ShowS
[Balance] -> ShowS
Balance -> String
(Int -> Balance -> ShowS)
-> (Balance -> String) -> ([Balance] -> ShowS) -> Show Balance
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Balance] -> ShowS
$cshowList :: [Balance] -> ShowS
show :: Balance -> String
$cshow :: Balance -> String
showsPrec :: Int -> Balance -> ShowS
$cshowsPrec :: Int -> Balance -> ShowS
Show, ReadPrec [Balance]
ReadPrec Balance
Int -> ReadS Balance
ReadS [Balance]
(Int -> ReadS Balance)
-> ReadS [Balance]
-> ReadPrec Balance
-> ReadPrec [Balance]
-> Read Balance
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Balance]
$creadListPrec :: ReadPrec [Balance]
readPrec :: ReadPrec Balance
$creadPrec :: ReadPrec Balance
readList :: ReadS [Balance]
$creadList :: ReadS [Balance]
readsPrec :: Int -> ReadS Balance
$creadsPrec :: Int -> ReadS Balance
Read, Balance -> Balance -> Bool
(Balance -> Balance -> Bool)
-> (Balance -> Balance -> Bool) -> Eq Balance
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Balance -> Balance -> Bool
$c/= :: Balance -> Balance -> Bool
== :: Balance -> Balance -> Bool
$c== :: Balance -> Balance -> Bool
Eq, Eq Balance
Eq Balance =>
(Balance -> Balance -> Ordering)
-> (Balance -> Balance -> Bool)
-> (Balance -> Balance -> Bool)
-> (Balance -> Balance -> Bool)
-> (Balance -> Balance -> Bool)
-> (Balance -> Balance -> Balance)
-> (Balance -> Balance -> Balance)
-> Ord Balance
Balance -> Balance -> Bool
Balance -> Balance -> Ordering
Balance -> Balance -> Balance
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 :: Balance -> Balance -> Balance
$cmin :: Balance -> Balance -> Balance
max :: Balance -> Balance -> Balance
$cmax :: Balance -> Balance -> Balance
>= :: Balance -> Balance -> Bool
$c>= :: Balance -> Balance -> Bool
> :: Balance -> Balance -> Bool
$c> :: Balance -> Balance -> Bool
<= :: Balance -> Balance -> Bool
$c<= :: Balance -> Balance -> Bool
< :: Balance -> Balance -> Bool
$c< :: Balance -> Balance -> Bool
compare :: Balance -> Balance -> Ordering
$ccompare :: Balance -> Balance -> Ordering
$cp1Ord :: Eq Balance
Ord, (forall x. Balance -> Rep Balance x)
-> (forall x. Rep Balance x -> Balance) -> Generic Balance
forall x. Rep Balance x -> Balance
forall x. Balance -> Rep Balance x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Balance x -> Balance
$cfrom :: forall x. Balance -> Rep Balance x
Generic, Int -> Balance -> Int
Balance -> Int
(Int -> Balance -> Int) -> (Balance -> Int) -> Hashable Balance
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Balance -> Int
$chash :: Balance -> Int
hashWithSalt :: Int -> Balance -> Int
$chashWithSalt :: Int -> Balance -> Int
Hashable, Balance -> ()
(Balance -> ()) -> NFData Balance
forall a. (a -> ()) -> NFData a
rnf :: Balance -> ()
$crnf :: Balance -> ()
NFData)

instance Serial Balance where
    serialize :: Balance -> m ()
serialize Balance{..} = do
        Address -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Address
balanceAddress
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
balanceAmount
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
balanceZero
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
balanceUnspentCount
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
balanceTxCount
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
balanceTotalReceived

    deserialize :: m Balance
deserialize = do
        Address
balanceAddress       <- m Address
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Word64
balanceAmount        <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Word64
balanceZero          <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Word64
balanceUnspentCount  <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Word64
balanceTxCount       <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Word64
balanceTotalReceived <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Balance -> m Balance
forall (m :: * -> *) a. Monad m => a -> m a
return $WBalance :: Address
-> Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Balance
Balance{..}

instance Binary Balance where
    put :: Balance -> Put
put = Balance -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get Balance
get = Get Balance
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Serialize Balance where
    put :: Putter Balance
put = Putter Balance
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get Balance
get = Get Balance
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

zeroBalance :: Address -> Balance
zeroBalance :: Address -> Balance
zeroBalance a :: Address
a =
    $WBalance :: Address
-> Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Balance
Balance
        { balanceAddress :: Address
balanceAddress = Address
a
        , balanceAmount :: Word64
balanceAmount = 0
        , balanceUnspentCount :: Word64
balanceUnspentCount = 0
        , balanceZero :: Word64
balanceZero = 0
        , balanceTxCount :: Word64
balanceTxCount = 0
        , balanceTotalReceived :: Word64
balanceTotalReceived = 0
        }

nullBalance :: Balance -> Bool
nullBalance :: Balance -> Bool
nullBalance
    Balance
    {
        balanceAmount :: Balance -> Word64
balanceAmount = Word64
0,
        balanceUnspentCount :: Balance -> Word64
balanceUnspentCount = Word64
0,
        balanceZero :: Balance -> Word64
balanceZero = Word64
0,
        balanceTxCount :: Balance -> Word64
balanceTxCount = Word64
0,
        balanceTotalReceived :: Balance -> Word64
balanceTotalReceived = Word64
0
    } = Bool
True
nullBalance _ = Bool
False

balanceToJSON :: Network -> Balance -> Value
balanceToJSON :: Network -> Balance -> Value
balanceToJSON net :: Network
net b :: Balance
b =
    [Pair] -> Value
A.object
        [ "address" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Network -> Address -> Value
addrToJSON Network
net (Balance -> Address
balanceAddress Balance
b)
        , "confirmed" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Balance -> Word64
balanceAmount Balance
b
        , "unconfirmed" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Balance -> Word64
balanceZero Balance
b
        , "utxo" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Balance -> Word64
balanceUnspentCount Balance
b
        , "txs" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Balance -> Word64
balanceTxCount Balance
b
        , "received" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Balance -> Word64
balanceTotalReceived Balance
b
        ]

balanceToEncoding :: Network -> Balance -> Encoding
balanceToEncoding :: Network -> Balance -> Encoding
balanceToEncoding net :: Network
net b :: Balance
b =
    Series -> Encoding
AE.pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
    "address" Text -> Encoding -> Series
`AE.pair` Network -> Address -> Encoding
addrToEncoding Network
net (Balance -> Address
balanceAddress Balance
b) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "confirmed" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Balance -> Word64
balanceAmount Balance
b Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "unconfirmed" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Balance -> Word64
balanceZero Balance
b Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "utxo" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Balance -> Word64
balanceUnspentCount Balance
b Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "txs" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Balance -> Word64
balanceTxCount Balance
b Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "received" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Balance -> Word64
balanceTotalReceived Balance
b

balanceParseJSON :: Network -> Value -> Parser Balance
balanceParseJSON :: Network -> Value -> Parser Balance
balanceParseJSON net :: Network
net =
    String -> (Object -> Parser Balance) -> Value -> Parser Balance
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "balance" ((Object -> Parser Balance) -> Value -> Parser Balance)
-> (Object -> Parser Balance) -> Value -> Parser Balance
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
        Word64
amount <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "confirmed"
        Word64
unconfirmed <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "unconfirmed"
        Word64
utxo <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "utxo"
        Word64
txs <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "txs"
        Word64
received <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "received"
        Address
address <- Network -> Value -> Parser Address
addrFromJSON Network
net (Value -> Parser Address) -> Parser Value -> Parser Address
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Object
o Object -> Text -> Parser Value
forall a. FromJSON a => Object -> Text -> Parser a
.: "address"
        Balance -> Parser Balance
forall (m :: * -> *) a. Monad m => a -> m a
return
            $WBalance :: Address
-> Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> Balance
Balance
                { balanceAddress :: Address
balanceAddress = Address
address
                , balanceAmount :: Word64
balanceAmount = Word64
amount
                , balanceUnspentCount :: Word64
balanceUnspentCount = Word64
utxo
                , balanceZero :: Word64
balanceZero = Word64
unconfirmed
                , balanceTxCount :: Word64
balanceTxCount = Word64
txs
                , balanceTotalReceived :: Word64
balanceTotalReceived = Word64
received
                }

-- | Unspent output.
data Unspent =
    Unspent
        { Unspent -> BlockRef
unspentBlock   :: !BlockRef
        , Unspent -> OutPoint
unspentPoint   :: !OutPoint
        , Unspent -> Word64
unspentAmount  :: !Word64
        , Unspent -> ByteString
unspentScript  :: !ByteString
        , Unspent -> Maybe Address
unspentAddress :: !(Maybe Address)
        }
    deriving (Int -> Unspent -> ShowS
[Unspent] -> ShowS
Unspent -> String
(Int -> Unspent -> ShowS)
-> (Unspent -> String) -> ([Unspent] -> ShowS) -> Show Unspent
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Unspent] -> ShowS
$cshowList :: [Unspent] -> ShowS
show :: Unspent -> String
$cshow :: Unspent -> String
showsPrec :: Int -> Unspent -> ShowS
$cshowsPrec :: Int -> Unspent -> ShowS
Show, Unspent -> Unspent -> Bool
(Unspent -> Unspent -> Bool)
-> (Unspent -> Unspent -> Bool) -> Eq Unspent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Unspent -> Unspent -> Bool
$c/= :: Unspent -> Unspent -> Bool
== :: Unspent -> Unspent -> Bool
$c== :: Unspent -> Unspent -> Bool
Eq, (forall x. Unspent -> Rep Unspent x)
-> (forall x. Rep Unspent x -> Unspent) -> Generic Unspent
forall x. Rep Unspent x -> Unspent
forall x. Unspent -> Rep Unspent x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Unspent x -> Unspent
$cfrom :: forall x. Unspent -> Rep Unspent x
Generic, Int -> Unspent -> Int
Unspent -> Int
(Int -> Unspent -> Int) -> (Unspent -> Int) -> Hashable Unspent
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Unspent -> Int
$chash :: Unspent -> Int
hashWithSalt :: Int -> Unspent -> Int
$chashWithSalt :: Int -> Unspent -> Int
Hashable, Unspent -> ()
(Unspent -> ()) -> NFData Unspent
forall a. (a -> ()) -> NFData a
rnf :: Unspent -> ()
$crnf :: Unspent -> ()
NFData)

-- | Follow same order as in database and cache by inverting outpoint sort
-- order.
instance Ord Unspent where
    compare :: Unspent -> Unspent -> Ordering
compare a :: Unspent
a b :: Unspent
b =
        (BlockRef, OutPoint) -> (BlockRef, OutPoint) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare
        (Unspent -> BlockRef
unspentBlock Unspent
a, Unspent -> OutPoint
unspentPoint Unspent
b)
        (Unspent -> BlockRef
unspentBlock Unspent
b, Unspent -> OutPoint
unspentPoint Unspent
a)

instance Serial Unspent where
    serialize :: Unspent -> m ()
serialize Unspent{..} = do
        BlockRef -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize BlockRef
unspentBlock
        OutPoint -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize OutPoint
unspentPoint
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
unspentAmount
        ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putLengthBytes ByteString
unspentScript
        (Address -> m ()) -> Maybe Address -> m ()
forall (m :: * -> *) a.
MonadPut m =>
(a -> m ()) -> Maybe a -> m ()
putMaybe Address -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Maybe Address
unspentAddress

    deserialize :: m Unspent
deserialize = do
        BlockRef
unspentBlock <- m BlockRef
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        OutPoint
unspentPoint <- m OutPoint
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Word64
unspentAmount <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        ByteString
unspentScript <- m ByteString
forall (m :: * -> *). MonadGet m => m ByteString
getLengthBytes
        Maybe Address
unspentAddress <- m Address -> m (Maybe Address)
forall (m :: * -> *) a. MonadGet m => m a -> m (Maybe a)
getMaybe m Address
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Unspent -> m Unspent
forall (m :: * -> *) a. Monad m => a -> m a
return $WUnspent :: BlockRef
-> OutPoint -> Word64 -> ByteString -> Maybe Address -> Unspent
Unspent{..}

instance Binary Unspent where
    put :: Unspent -> Put
put = Unspent -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get Unspent
get = Get Unspent
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Serialize Unspent where
    put :: Putter Unspent
put = Putter Unspent
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get Unspent
get = Get Unspent
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Coin Unspent where
    coinValue :: Unspent -> Word64
coinValue = Unspent -> Word64
unspentAmount

unspentToJSON :: Network -> Unspent -> Value
unspentToJSON :: Network -> Unspent -> Value
unspentToJSON net :: Network
net u :: Unspent
u =
    [Pair] -> Value
A.object
        [ "address" Text -> Maybe Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Network -> Address -> Value
addrToJSON Network
net (Address -> Value) -> Maybe Address -> Maybe Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Unspent -> Maybe Address
unspentAddress Unspent
u)
        , "block" Text -> BlockRef -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Unspent -> BlockRef
unspentBlock Unspent
u
        , "txid" Text -> TxHash -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= OutPoint -> TxHash
outPointHash (Unspent -> OutPoint
unspentPoint Unspent
u)
        , "index" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= OutPoint -> Word32
outPointIndex (Unspent -> OutPoint
unspentPoint Unspent
u)
        , "pkscript" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ByteString -> Text
encodeHex (Unspent -> ByteString
unspentScript Unspent
u)
        , "value" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Unspent -> Word64
unspentAmount Unspent
u
        ]

unspentToEncoding :: Network -> Unspent -> Encoding
unspentToEncoding :: Network -> Unspent -> Encoding
unspentToEncoding net :: Network
net u :: Unspent
u =
    Series -> Encoding
AE.pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
    "address" Text -> Encoding -> Series
`AE.pair` Encoding -> (Address -> Encoding) -> Maybe Address -> Encoding
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Encoding
AE.null_ (Network -> Address -> Encoding
addrToEncoding Network
net) (Unspent -> Maybe Address
unspentAddress Unspent
u) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "block" Text -> BlockRef -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Unspent -> BlockRef
unspentBlock Unspent
u Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "txid" Text -> TxHash -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= OutPoint -> TxHash
outPointHash (Unspent -> OutPoint
unspentPoint Unspent
u) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "index" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= OutPoint -> Word32
outPointIndex (Unspent -> OutPoint
unspentPoint Unspent
u) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "pkscript" Text -> Encoding -> Series
`AE.pair` Text -> Encoding
forall a. Text -> Encoding' a
AE.text (ByteString -> Text
encodeHex (Unspent -> ByteString
unspentScript Unspent
u)) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "value" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Unspent -> Word64
unspentAmount Unspent
u

unspentParseJSON :: Network -> Value -> Parser Unspent
unspentParseJSON :: Network -> Value -> Parser Unspent
unspentParseJSON net :: Network
net =
    String -> (Object -> Parser Unspent) -> Value -> Parser Unspent
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "unspent" ((Object -> Parser Unspent) -> Value -> Parser Unspent)
-> (Object -> Parser Unspent) -> Value -> Parser Unspent
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
        BlockRef
block <- Object
o Object -> Text -> Parser BlockRef
forall a. FromJSON a => Object -> Text -> Parser a
.: "block"
        TxHash
txid <- Object
o Object -> Text -> Parser TxHash
forall a. FromJSON a => Object -> Text -> Parser a
.: "txid"
        Word32
index <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "index"
        Word64
value <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "value"
        ByteString
script <- Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: "pkscript" Parser Text -> (Text -> Parser ByteString) -> Parser ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Parser ByteString
jsonHex
        Maybe Address
addr <- Object
o Object -> Text -> Parser (Maybe Value)
forall a. FromJSON a => Object -> Text -> Parser a
.: "address" Parser (Maybe Value)
-> (Maybe Value -> Parser (Maybe Address))
-> Parser (Maybe Address)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
            Nothing -> Maybe Address -> Parser (Maybe Address)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Address
forall a. Maybe a
Nothing
            Just a :: Value
a  -> Address -> Maybe Address
forall a. a -> Maybe a
Just (Address -> Maybe Address)
-> Parser Address -> Parser (Maybe Address)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Network -> Value -> Parser Address
addrFromJSON Network
net Value
a Parser (Maybe Address)
-> Parser (Maybe Address) -> Parser (Maybe Address)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Address -> Parser (Maybe Address)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Address
forall a. Maybe a
Nothing
        Unspent -> Parser Unspent
forall (m :: * -> *) a. Monad m => a -> m a
return
            $WUnspent :: BlockRef
-> OutPoint -> Word64 -> ByteString -> Maybe Address -> Unspent
Unspent
                { unspentBlock :: BlockRef
unspentBlock = BlockRef
block
                , unspentPoint :: OutPoint
unspentPoint = TxHash -> Word32 -> OutPoint
OutPoint TxHash
txid Word32
index
                , unspentAmount :: Word64
unspentAmount = Word64
value
                , unspentScript :: ByteString
unspentScript = ByteString
script
                , unspentAddress :: Maybe Address
unspentAddress = Maybe Address
addr
                }

-- | Database value for a block entry.
data BlockData =
    BlockData
        { BlockData -> Word32
blockDataHeight    :: !BlockHeight
        -- ^ height of the block in the chain
        , BlockData -> Bool
blockDataMainChain :: !Bool
        -- ^ is this block in the main chain?
        , BlockData -> Integer
blockDataWork      :: !Integer
        -- ^ accumulated work in that block
        , BlockData -> BlockHeader
blockDataHeader    :: !BlockHeader
        -- ^ block header
        , BlockData -> Word32
blockDataSize      :: !Word32
        -- ^ size of the block including witnesses
        , BlockData -> Word32
blockDataWeight    :: !Word32
        -- ^ weight of this block (for segwit networks)
        , BlockData -> [TxHash]
blockDataTxs       :: ![TxHash]
        -- ^ block transactions
        , BlockData -> Word64
blockDataOutputs   :: !Word64
        -- ^ sum of all transaction outputs
        , BlockData -> Word64
blockDataFees      :: !Word64
        -- ^ sum of all transaction fees
        , BlockData -> Word64
blockDataSubsidy   :: !Word64
        -- ^ block subsidy
        }
    deriving (Int -> BlockData -> ShowS
[BlockData] -> ShowS
BlockData -> String
(Int -> BlockData -> ShowS)
-> (BlockData -> String)
-> ([BlockData] -> ShowS)
-> Show BlockData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BlockData] -> ShowS
$cshowList :: [BlockData] -> ShowS
show :: BlockData -> String
$cshow :: BlockData -> String
showsPrec :: Int -> BlockData -> ShowS
$cshowsPrec :: Int -> BlockData -> ShowS
Show, ReadPrec [BlockData]
ReadPrec BlockData
Int -> ReadS BlockData
ReadS [BlockData]
(Int -> ReadS BlockData)
-> ReadS [BlockData]
-> ReadPrec BlockData
-> ReadPrec [BlockData]
-> Read BlockData
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [BlockData]
$creadListPrec :: ReadPrec [BlockData]
readPrec :: ReadPrec BlockData
$creadPrec :: ReadPrec BlockData
readList :: ReadS [BlockData]
$creadList :: ReadS [BlockData]
readsPrec :: Int -> ReadS BlockData
$creadsPrec :: Int -> ReadS BlockData
Read, BlockData -> BlockData -> Bool
(BlockData -> BlockData -> Bool)
-> (BlockData -> BlockData -> Bool) -> Eq BlockData
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BlockData -> BlockData -> Bool
$c/= :: BlockData -> BlockData -> Bool
== :: BlockData -> BlockData -> Bool
$c== :: BlockData -> BlockData -> Bool
Eq, Eq BlockData
Eq BlockData =>
(BlockData -> BlockData -> Ordering)
-> (BlockData -> BlockData -> Bool)
-> (BlockData -> BlockData -> Bool)
-> (BlockData -> BlockData -> Bool)
-> (BlockData -> BlockData -> Bool)
-> (BlockData -> BlockData -> BlockData)
-> (BlockData -> BlockData -> BlockData)
-> Ord BlockData
BlockData -> BlockData -> Bool
BlockData -> BlockData -> Ordering
BlockData -> BlockData -> BlockData
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 :: BlockData -> BlockData -> BlockData
$cmin :: BlockData -> BlockData -> BlockData
max :: BlockData -> BlockData -> BlockData
$cmax :: BlockData -> BlockData -> BlockData
>= :: BlockData -> BlockData -> Bool
$c>= :: BlockData -> BlockData -> Bool
> :: BlockData -> BlockData -> Bool
$c> :: BlockData -> BlockData -> Bool
<= :: BlockData -> BlockData -> Bool
$c<= :: BlockData -> BlockData -> Bool
< :: BlockData -> BlockData -> Bool
$c< :: BlockData -> BlockData -> Bool
compare :: BlockData -> BlockData -> Ordering
$ccompare :: BlockData -> BlockData -> Ordering
$cp1Ord :: Eq BlockData
Ord, (forall x. BlockData -> Rep BlockData x)
-> (forall x. Rep BlockData x -> BlockData) -> Generic BlockData
forall x. Rep BlockData x -> BlockData
forall x. BlockData -> Rep BlockData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BlockData x -> BlockData
$cfrom :: forall x. BlockData -> Rep BlockData x
Generic, Int -> BlockData -> Int
BlockData -> Int
(Int -> BlockData -> Int)
-> (BlockData -> Int) -> Hashable BlockData
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: BlockData -> Int
$chash :: BlockData -> Int
hashWithSalt :: Int -> BlockData -> Int
$chashWithSalt :: Int -> BlockData -> Int
Hashable, BlockData -> ()
(BlockData -> ()) -> NFData BlockData
forall a. (a -> ()) -> NFData a
rnf :: BlockData -> ()
$crnf :: BlockData -> ()
NFData)

instance Serial BlockData where
    serialize :: BlockData -> m ()
serialize BlockData{..} = do
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
blockDataHeight
        Bool -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Bool
blockDataMainChain
        Integer -> m ()
forall (m :: * -> *). MonadPut m => Integer -> m ()
putInteger Integer
blockDataWork
        BlockHeader -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize BlockHeader
blockDataHeader
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
blockDataSize
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
blockDataWeight
        (TxHash -> m ()) -> [TxHash] -> m ()
forall (m :: * -> *) a. MonadPut m => (a -> m ()) -> [a] -> m ()
putList TxHash -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize [TxHash]
blockDataTxs
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
blockDataOutputs
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
blockDataFees
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
blockDataSubsidy

    deserialize :: m BlockData
deserialize = do
        Word32
blockDataHeight <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        Bool
blockDataMainChain <- m Bool
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Integer
blockDataWork <- m Integer
forall (m :: * -> *). MonadGet m => m Integer
getInteger
        BlockHeader
blockDataHeader <- m BlockHeader
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Word32
blockDataSize <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        Word32
blockDataWeight <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        [TxHash]
blockDataTxs <- m TxHash -> m [TxHash]
forall (m :: * -> *) a. MonadGet m => m a -> m [a]
getList m TxHash
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Word64
blockDataOutputs <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Word64
blockDataFees <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Word64
blockDataSubsidy <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        BlockData -> m BlockData
forall (m :: * -> *) a. Monad m => a -> m a
return $WBlockData :: Word32
-> Bool
-> Integer
-> BlockHeader
-> Word32
-> Word32
-> [TxHash]
-> Word64
-> Word64
-> Word64
-> BlockData
BlockData{..}

instance Serialize BlockData where
    put :: Putter BlockData
put = Putter BlockData
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get BlockData
get = Get BlockData
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary BlockData where
    put :: BlockData -> Put
put = BlockData -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get BlockData
get = Get BlockData
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

blockDataToJSON :: Network -> BlockData -> Value
blockDataToJSON :: Network -> BlockData -> Value
blockDataToJSON net :: Network
net bv :: BlockData
bv =
    [Pair] -> Value
A.object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$
    [ "hash" Text -> BlockHash -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHeader -> BlockHash
headerHash (BlockData -> BlockHeader
blockDataHeader BlockData
bv)
    , "height" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Word32
blockDataHeight BlockData
bv
    , "mainchain" Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Bool
blockDataMainChain BlockData
bv
    , "previous" Text -> BlockHash -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHeader -> BlockHash
prevBlock (BlockData -> BlockHeader
blockDataHeader BlockData
bv)
    , "time" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHeader -> Word32
blockTimestamp (BlockData -> BlockHeader
blockDataHeader BlockData
bv)
    , "version" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHeader -> Word32
blockVersion (BlockData -> BlockHeader
blockDataHeader BlockData
bv)
    , "bits" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHeader -> Word32
blockBits (BlockData -> BlockHeader
blockDataHeader BlockData
bv)
    , "nonce" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHeader -> Word32
bhNonce (BlockData -> BlockHeader
blockDataHeader BlockData
bv)
    , "size" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Word32
blockDataSize BlockData
bv
    , "tx" Text -> [TxHash] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> [TxHash]
blockDataTxs BlockData
bv
    , "merkle" Text -> TxHash -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ChainCode -> TxHash
TxHash (BlockHeader -> ChainCode
merkleRoot (BlockData -> BlockHeader
blockDataHeader BlockData
bv))
    , "subsidy" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Word64
blockDataSubsidy BlockData
bv
    , "fees" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Word64
blockDataFees BlockData
bv
    , "outputs" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Word64
blockDataOutputs BlockData
bv
    , "work" Text -> Integer -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Integer
blockDataWork BlockData
bv
    ] [Pair] -> [Pair] -> [Pair]
forall a. Semigroup a => a -> a -> a
<>
    ["weight" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Word32
blockDataWeight BlockData
bv | Network -> Bool
getSegWit Network
net]

blockDataToEncoding :: Network -> BlockData -> Encoding
blockDataToEncoding :: Network -> BlockData -> Encoding
blockDataToEncoding net :: Network
net bv :: BlockData
bv =
    Series -> Encoding
AE.pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
    "hash" Text -> Encoding -> Series
`AE.pair` Text -> Encoding
forall a. Text -> Encoding' a
AE.text
    (BlockHash -> Text
blockHashToHex (BlockHeader -> BlockHash
headerHash (BlockData -> BlockHeader
blockDataHeader BlockData
bv))) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "height" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Word32
blockDataHeight BlockData
bv Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "mainchain" Text -> Bool -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Bool
blockDataMainChain BlockData
bv Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "previous" Text -> BlockHash -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHeader -> BlockHash
prevBlock (BlockData -> BlockHeader
blockDataHeader BlockData
bv) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "time" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHeader -> Word32
blockTimestamp (BlockData -> BlockHeader
blockDataHeader BlockData
bv) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "version" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHeader -> Word32
blockVersion (BlockData -> BlockHeader
blockDataHeader BlockData
bv) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "bits" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHeader -> Word32
blockBits (BlockData -> BlockHeader
blockDataHeader BlockData
bv) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "nonce" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHeader -> Word32
bhNonce (BlockData -> BlockHeader
blockDataHeader BlockData
bv) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "size" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Word32
blockDataSize BlockData
bv Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "tx" Text -> [TxHash] -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> [TxHash]
blockDataTxs BlockData
bv Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "merkle" Text -> Encoding -> Series
`AE.pair` Text -> Encoding
forall a. Text -> Encoding' a
AE.text
    (TxHash -> Text
txHashToHex (ChainCode -> TxHash
TxHash (BlockHeader -> ChainCode
merkleRoot (BlockData -> BlockHeader
blockDataHeader BlockData
bv)))) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "subsidy" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Word64
blockDataSubsidy BlockData
bv Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "fees" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Word64
blockDataFees BlockData
bv Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "outputs" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Word64
blockDataOutputs BlockData
bv Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "work" Text -> Integer -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Integer
blockDataWork BlockData
bv Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    (if Network -> Bool
getSegWit Network
net then "weight" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockData -> Word32
blockDataWeight BlockData
bv else Series
forall a. Monoid a => a
mempty)

instance FromJSON BlockData where
    parseJSON :: Value -> Parser BlockData
parseJSON =
        String -> (Object -> Parser BlockData) -> Value -> Parser BlockData
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "blockdata" ((Object -> Parser BlockData) -> Value -> Parser BlockData)
-> (Object -> Parser BlockData) -> Value -> Parser BlockData
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
        Word32
height <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "height"
        Bool
mainchain <- Object
o Object -> Text -> Parser Bool
forall a. FromJSON a => Object -> Text -> Parser a
.: "mainchain"
        BlockHash
previous <- Object
o Object -> Text -> Parser BlockHash
forall a. FromJSON a => Object -> Text -> Parser a
.: "previous"
        Word32
time <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "time"
        Word32
version <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "version"
        Word32
bits <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "bits"
        Word32
nonce <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "nonce"
        Word32
size <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "size"
        [TxHash]
tx <- Object
o Object -> Text -> Parser [TxHash]
forall a. FromJSON a => Object -> Text -> Parser a
.: "tx"
        TxHash merkle :: ChainCode
merkle <- Object
o Object -> Text -> Parser TxHash
forall a. FromJSON a => Object -> Text -> Parser a
.: "merkle"
        Word64
subsidy <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "subsidy"
        Word64
fees <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "fees"
        Word64
outputs <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "outputs"
        Integer
work <- Object
o Object -> Text -> Parser Integer
forall a. FromJSON a => Object -> Text -> Parser a
.: "work"
        Word32
weight <- Object
o Object -> Text -> Parser (Maybe Word32)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? "weight" Parser (Maybe Word32) -> Word32 -> Parser Word32
forall a. Parser (Maybe a) -> a -> Parser a
.!= 0
        BlockData -> Parser BlockData
forall (m :: * -> *) a. Monad m => a -> m a
return
            $WBlockData :: Word32
-> Bool
-> Integer
-> BlockHeader
-> Word32
-> Word32
-> [TxHash]
-> Word64
-> Word64
-> Word64
-> BlockData
BlockData
            { blockDataHeader :: BlockHeader
blockDataHeader =
                  $WBlockHeader :: Word32
-> BlockHash
-> ChainCode
-> Word32
-> Word32
-> Word32
-> BlockHeader
BlockHeader
                  { prevBlock :: BlockHash
prevBlock = BlockHash
previous
                  , blockTimestamp :: Word32
blockTimestamp = Word32
time
                  , blockVersion :: Word32
blockVersion = Word32
version
                  , blockBits :: Word32
blockBits = Word32
bits
                  , bhNonce :: Word32
bhNonce = Word32
nonce
                  , merkleRoot :: ChainCode
merkleRoot = ChainCode
merkle
                  }
            , blockDataMainChain :: Bool
blockDataMainChain = Bool
mainchain
            , blockDataWork :: Integer
blockDataWork = Integer
work
            , blockDataSize :: Word32
blockDataSize = Word32
size
            , blockDataWeight :: Word32
blockDataWeight = Word32
weight
            , blockDataTxs :: [TxHash]
blockDataTxs = [TxHash]
tx
            , blockDataOutputs :: Word64
blockDataOutputs = Word64
outputs
            , blockDataFees :: Word64
blockDataFees = Word64
fees
            , blockDataHeight :: Word32
blockDataHeight = Word32
height
            , blockDataSubsidy :: Word64
blockDataSubsidy = Word64
subsidy
            }

data StoreInput
    = StoreCoinbase
          { StoreInput -> OutPoint
inputPoint     :: !OutPoint
          , StoreInput -> Word32
inputSequence  :: !Word32
          , StoreInput -> ByteString
inputSigScript :: !ByteString
          , StoreInput -> WitnessStack
inputWitness   :: !WitnessStack
          }
    | StoreInput
          { inputPoint     :: !OutPoint
          , inputSequence  :: !Word32
          , inputSigScript :: !ByteString
          , StoreInput -> ByteString
inputPkScript  :: !ByteString
          , StoreInput -> Word64
inputAmount    :: !Word64
          , inputWitness   :: !WitnessStack
          , StoreInput -> Maybe Address
inputAddress   :: !(Maybe Address)
          }
    deriving (Int -> StoreInput -> ShowS
[StoreInput] -> ShowS
StoreInput -> String
(Int -> StoreInput -> ShowS)
-> (StoreInput -> String)
-> ([StoreInput] -> ShowS)
-> Show StoreInput
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StoreInput] -> ShowS
$cshowList :: [StoreInput] -> ShowS
show :: StoreInput -> String
$cshow :: StoreInput -> String
showsPrec :: Int -> StoreInput -> ShowS
$cshowsPrec :: Int -> StoreInput -> ShowS
Show, ReadPrec [StoreInput]
ReadPrec StoreInput
Int -> ReadS StoreInput
ReadS [StoreInput]
(Int -> ReadS StoreInput)
-> ReadS [StoreInput]
-> ReadPrec StoreInput
-> ReadPrec [StoreInput]
-> Read StoreInput
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [StoreInput]
$creadListPrec :: ReadPrec [StoreInput]
readPrec :: ReadPrec StoreInput
$creadPrec :: ReadPrec StoreInput
readList :: ReadS [StoreInput]
$creadList :: ReadS [StoreInput]
readsPrec :: Int -> ReadS StoreInput
$creadsPrec :: Int -> ReadS StoreInput
Read, StoreInput -> StoreInput -> Bool
(StoreInput -> StoreInput -> Bool)
-> (StoreInput -> StoreInput -> Bool) -> Eq StoreInput
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StoreInput -> StoreInput -> Bool
$c/= :: StoreInput -> StoreInput -> Bool
== :: StoreInput -> StoreInput -> Bool
$c== :: StoreInput -> StoreInput -> Bool
Eq, Eq StoreInput
Eq StoreInput =>
(StoreInput -> StoreInput -> Ordering)
-> (StoreInput -> StoreInput -> Bool)
-> (StoreInput -> StoreInput -> Bool)
-> (StoreInput -> StoreInput -> Bool)
-> (StoreInput -> StoreInput -> Bool)
-> (StoreInput -> StoreInput -> StoreInput)
-> (StoreInput -> StoreInput -> StoreInput)
-> Ord StoreInput
StoreInput -> StoreInput -> Bool
StoreInput -> StoreInput -> Ordering
StoreInput -> StoreInput -> StoreInput
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 :: StoreInput -> StoreInput -> StoreInput
$cmin :: StoreInput -> StoreInput -> StoreInput
max :: StoreInput -> StoreInput -> StoreInput
$cmax :: StoreInput -> StoreInput -> StoreInput
>= :: StoreInput -> StoreInput -> Bool
$c>= :: StoreInput -> StoreInput -> Bool
> :: StoreInput -> StoreInput -> Bool
$c> :: StoreInput -> StoreInput -> Bool
<= :: StoreInput -> StoreInput -> Bool
$c<= :: StoreInput -> StoreInput -> Bool
< :: StoreInput -> StoreInput -> Bool
$c< :: StoreInput -> StoreInput -> Bool
compare :: StoreInput -> StoreInput -> Ordering
$ccompare :: StoreInput -> StoreInput -> Ordering
$cp1Ord :: Eq StoreInput
Ord, (forall x. StoreInput -> Rep StoreInput x)
-> (forall x. Rep StoreInput x -> StoreInput) -> Generic StoreInput
forall x. Rep StoreInput x -> StoreInput
forall x. StoreInput -> Rep StoreInput x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep StoreInput x -> StoreInput
$cfrom :: forall x. StoreInput -> Rep StoreInput x
Generic, Int -> StoreInput -> Int
StoreInput -> Int
(Int -> StoreInput -> Int)
-> (StoreInput -> Int) -> Hashable StoreInput
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: StoreInput -> Int
$chash :: StoreInput -> Int
hashWithSalt :: Int -> StoreInput -> Int
$chashWithSalt :: Int -> StoreInput -> Int
Hashable, StoreInput -> ()
(StoreInput -> ()) -> NFData StoreInput
forall a. (a -> ()) -> NFData a
rnf :: StoreInput -> ()
$crnf :: StoreInput -> ()
NFData)

instance Serial StoreInput where
    serialize :: StoreInput -> m ()
serialize StoreCoinbase{..} = do
        Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x00
        OutPoint -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize OutPoint
inputPoint
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
inputSequence
        ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putLengthBytes ByteString
inputSigScript
        (ByteString -> m ()) -> WitnessStack -> m ()
forall (m :: * -> *) a. MonadPut m => (a -> m ()) -> [a] -> m ()
putList ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putLengthBytes WitnessStack
inputWitness

    serialize StoreInput{..} = do
        Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x01
        OutPoint -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize OutPoint
inputPoint
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
inputSequence
        ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putLengthBytes ByteString
inputSigScript
        ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putLengthBytes ByteString
inputPkScript
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
inputAmount
        (ByteString -> m ()) -> WitnessStack -> m ()
forall (m :: * -> *) a. MonadPut m => (a -> m ()) -> [a] -> m ()
putList ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putLengthBytes WitnessStack
inputWitness
        (Address -> m ()) -> Maybe Address -> m ()
forall (m :: * -> *) a.
MonadPut m =>
(a -> m ()) -> Maybe a -> m ()
putMaybe Address -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Maybe Address
inputAddress

    deserialize :: m StoreInput
deserialize =
        m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8 m Word8 -> (Word8 -> m StoreInput) -> m StoreInput
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        0x00 -> do
            OutPoint
inputPoint <- m OutPoint
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
            Word32
inputSequence <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
            ByteString
inputSigScript <- m ByteString
forall (m :: * -> *). MonadGet m => m ByteString
getLengthBytes
            WitnessStack
inputWitness <- m ByteString -> m WitnessStack
forall (m :: * -> *) a. MonadGet m => m a -> m [a]
getList m ByteString
forall (m :: * -> *). MonadGet m => m ByteString
getLengthBytes
            StoreInput -> m StoreInput
forall (m :: * -> *) a. Monad m => a -> m a
return $WStoreCoinbase :: OutPoint -> Word32 -> ByteString -> WitnessStack -> StoreInput
StoreCoinbase{..}
        0x01 -> do
            OutPoint
inputPoint <- m OutPoint
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
            Word32
inputSequence <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
            ByteString
inputSigScript <- m ByteString
forall (m :: * -> *). MonadGet m => m ByteString
getLengthBytes
            ByteString
inputPkScript <- m ByteString
forall (m :: * -> *). MonadGet m => m ByteString
getLengthBytes
            Word64
inputAmount <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
            WitnessStack
inputWitness <- m ByteString -> m WitnessStack
forall (m :: * -> *) a. MonadGet m => m a -> m [a]
getList m ByteString
forall (m :: * -> *). MonadGet m => m ByteString
getLengthBytes
            Maybe Address
inputAddress <- m Address -> m (Maybe Address)
forall (m :: * -> *) a. MonadGet m => m a -> m (Maybe a)
getMaybe m Address
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
            StoreInput -> m StoreInput
forall (m :: * -> *) a. Monad m => a -> m a
return $WStoreInput :: OutPoint
-> Word32
-> ByteString
-> ByteString
-> Word64
-> WitnessStack
-> Maybe Address
-> StoreInput
StoreInput{..}
        x :: Word8
x -> String -> m StoreInput
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> m StoreInput) -> String -> m StoreInput
forall a b. (a -> b) -> a -> b
$ "Unknown input id: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ShowS
forall a b. ConvertibleStrings a b => a -> b
cs (Word8 -> String
forall a. Show a => a -> String
show Word8
x)

instance Serialize StoreInput where
    put :: Putter StoreInput
put = Putter StoreInput
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get StoreInput
get = Get StoreInput
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary StoreInput where
    put :: StoreInput -> Put
put = StoreInput -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get StoreInput
get = Get StoreInput
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

isCoinbase :: StoreInput -> Bool
isCoinbase :: StoreInput -> Bool
isCoinbase StoreCoinbase{} = Bool
True
isCoinbase StoreInput{}    = Bool
False

storeInputToJSON :: Network -> StoreInput -> Value
storeInputToJSON :: Network -> StoreInput -> Value
storeInputToJSON
    net :: Network
net
    StoreInput
    {
        inputPoint :: StoreInput -> OutPoint
inputPoint = OutPoint oph :: TxHash
oph opi :: Word32
opi,
        inputSequence :: StoreInput -> Word32
inputSequence = Word32
sq,
        inputSigScript :: StoreInput -> ByteString
inputSigScript = ByteString
ss,
        inputPkScript :: StoreInput -> ByteString
inputPkScript = ByteString
ps,
        inputAmount :: StoreInput -> Word64
inputAmount = Word64
val,
        inputWitness :: StoreInput -> WitnessStack
inputWitness = WitnessStack
wit,
        inputAddress :: StoreInput -> Maybe Address
inputAddress = Maybe Address
a
    } =
    [Pair] -> Value
A.object
    [ "coinbase" Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Bool
False
    , "txid" Text -> TxHash -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TxHash
oph
    , "output" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
opi
    , "sigscript" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Text -> Value
String (ByteString -> Text
encodeHex ByteString
ss)
    , "sequence" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
sq
    , "pkscript" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Text -> Value
String (ByteString -> Text
encodeHex ByteString
ps)
    , "value" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
val
    , "address" Text -> Maybe Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Network -> Address -> Value
addrToJSON Network
net (Address -> Value) -> Maybe Address -> Maybe Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Address
a)
    , "witness" Text -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (ByteString -> Text) -> WitnessStack -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map ByteString -> Text
encodeHex WitnessStack
wit
    ]

storeInputToJSON
    _
    StoreCoinbase
    {
        inputPoint :: StoreInput -> OutPoint
inputPoint = OutPoint oph :: TxHash
oph opi :: Word32
opi,
        inputSequence :: StoreInput -> Word32
inputSequence = Word32
sq,
        inputSigScript :: StoreInput -> ByteString
inputSigScript = ByteString
ss,
        inputWitness :: StoreInput -> WitnessStack
inputWitness = WitnessStack
wit
    } =
    [Pair] -> Value
A.object
    [ "coinbase" Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Bool
True
    , "txid" Text -> TxHash -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TxHash
oph
    , "output" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
opi
    , "sigscript" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Text -> Value
String (ByteString -> Text
encodeHex ByteString
ss)
    , "sequence" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
sq
    , "pkscript" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null
    , "value" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null
    , "address" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null
    , "witness" Text -> [Text] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (ByteString -> Text) -> WitnessStack -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map ByteString -> Text
encodeHex WitnessStack
wit
    ]

storeInputToEncoding :: Network -> StoreInput -> Encoding
storeInputToEncoding :: Network -> StoreInput -> Encoding
storeInputToEncoding
    net :: Network
net
    StoreInput
    {
        inputPoint :: StoreInput -> OutPoint
inputPoint = OutPoint oph :: TxHash
oph opi :: Word32
opi,
        inputSequence :: StoreInput -> Word32
inputSequence = Word32
sq,
        inputSigScript :: StoreInput -> ByteString
inputSigScript = ByteString
ss,
        inputPkScript :: StoreInput -> ByteString
inputPkScript = ByteString
ps,
        inputAmount :: StoreInput -> Word64
inputAmount = Word64
val,
        inputWitness :: StoreInput -> WitnessStack
inputWitness = WitnessStack
wit,
        inputAddress :: StoreInput -> Maybe Address
inputAddress = Maybe Address
a
    } =
    Series -> Encoding
AE.pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
    "coinbase" Text -> Bool -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Bool
False Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "txid" Text -> TxHash -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TxHash
oph Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "output" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
opi Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "sigscript" Text -> Encoding -> Series
`AE.pair` Text -> Encoding
forall a. Text -> Encoding' a
AE.text (ByteString -> Text
encodeHex ByteString
ss) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "sequence" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
sq Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "pkscript" Text -> Encoding -> Series
`AE.pair` Text -> Encoding
forall a. Text -> Encoding' a
AE.text (ByteString -> Text
encodeHex ByteString
ps) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "value" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
val Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "address" Text -> Encoding -> Series
`AE.pair` Encoding -> (Address -> Encoding) -> Maybe Address -> Encoding
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Encoding
AE.null_ (Network -> Address -> Encoding
addrToEncoding Network
net) Maybe Address
a Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "witness" Text -> [Text] -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (ByteString -> Text) -> WitnessStack -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map ByteString -> Text
encodeHex WitnessStack
wit

storeInputToEncoding
    _
    StoreCoinbase
    {
        inputPoint :: StoreInput -> OutPoint
inputPoint = OutPoint oph :: TxHash
oph opi :: Word32
opi,
        inputSequence :: StoreInput -> Word32
inputSequence = Word32
sq,
        inputSigScript :: StoreInput -> ByteString
inputSigScript = ByteString
ss,
        inputWitness :: StoreInput -> WitnessStack
inputWitness = WitnessStack
wit
    } =
    Series -> Encoding
AE.pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
    "coinbase" Text -> Bool -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Bool
True Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "txid" Text -> Encoding -> Series
`AE.pair` Text -> Encoding
forall a. Text -> Encoding' a
AE.text (TxHash -> Text
txHashToHex TxHash
oph) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "output" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
opi Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "sigscript" Text -> Encoding -> Series
`AE.pair` Text -> Encoding
forall a. Text -> Encoding' a
AE.text (ByteString -> Text
encodeHex ByteString
ss) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "sequence" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
sq Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "pkscript" Text -> Encoding -> Series
`AE.pair` Encoding
AE.null_ Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "value" Text -> Encoding -> Series
`AE.pair` Encoding
AE.null_ Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "address" Text -> Encoding -> Series
`AE.pair` Encoding
AE.null_ Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "witness" Text -> [Text] -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (ByteString -> Text) -> WitnessStack -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map ByteString -> Text
encodeHex WitnessStack
wit

storeInputParseJSON :: Network -> Value -> Parser StoreInput
storeInputParseJSON :: Network -> Value -> Parser StoreInput
storeInputParseJSON net :: Network
net =
    String
-> (Object -> Parser StoreInput) -> Value -> Parser StoreInput
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "storeinput" ((Object -> Parser StoreInput) -> Value -> Parser StoreInput)
-> (Object -> Parser StoreInput) -> Value -> Parser StoreInput
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
    Bool
coinbase <- Object
o Object -> Text -> Parser Bool
forall a. FromJSON a => Object -> Text -> Parser a
.: "coinbase"
    OutPoint
outpoint <- TxHash -> Word32 -> OutPoint
OutPoint (TxHash -> Word32 -> OutPoint)
-> Parser TxHash -> Parser (Word32 -> OutPoint)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser TxHash
forall a. FromJSON a => Object -> Text -> Parser a
.: "txid" Parser (Word32 -> OutPoint) -> Parser Word32 -> Parser OutPoint
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "output"
    Word32
sequ <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "sequence"
    WitnessStack
witness <- (Text -> Parser ByteString) -> [Text] -> Parser WitnessStack
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Text -> Parser ByteString
jsonHex ([Text] -> Parser WitnessStack)
-> Parser [Text] -> Parser WitnessStack
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Object
o Object -> Text -> Parser (Maybe [Text])
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? "witness" Parser (Maybe [Text]) -> [Text] -> Parser [Text]
forall a. Parser (Maybe a) -> a -> Parser a
.!= []
    ByteString
sigscript <- Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: "sigscript" Parser Text -> (Text -> Parser ByteString) -> Parser ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Parser ByteString
jsonHex
    if Bool
coinbase
        then StoreInput -> Parser StoreInput
forall (m :: * -> *) a. Monad m => a -> m a
return
                $WStoreCoinbase :: OutPoint -> Word32 -> ByteString -> WitnessStack -> StoreInput
StoreCoinbase
                    { inputPoint :: OutPoint
inputPoint = OutPoint
outpoint
                    , inputSequence :: Word32
inputSequence = Word32
sequ
                    , inputSigScript :: ByteString
inputSigScript = ByteString
sigscript
                    , inputWitness :: WitnessStack
inputWitness = WitnessStack
witness
                    }
        else do
            ByteString
pkscript <- Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: "pkscript" Parser Text -> (Text -> Parser ByteString) -> Parser ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Parser ByteString
jsonHex
            Word64
value <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "value"
            Maybe Address
addr <- Object
o Object -> Text -> Parser (Maybe Value)
forall a. FromJSON a => Object -> Text -> Parser a
.: "address" Parser (Maybe Value)
-> (Maybe Value -> Parser (Maybe Address))
-> Parser (Maybe Address)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
                Nothing -> Maybe Address -> Parser (Maybe Address)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Address
forall a. Maybe a
Nothing
                Just a :: Value
a  -> Address -> Maybe Address
forall a. a -> Maybe a
Just (Address -> Maybe Address)
-> Parser Address -> Parser (Maybe Address)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Network -> Value -> Parser Address
addrFromJSON Network
net Value
a Parser (Maybe Address)
-> Parser (Maybe Address) -> Parser (Maybe Address)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Address -> Parser (Maybe Address)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Address
forall a. Maybe a
Nothing
            StoreInput -> Parser StoreInput
forall (m :: * -> *) a. Monad m => a -> m a
return
                $WStoreInput :: OutPoint
-> Word32
-> ByteString
-> ByteString
-> Word64
-> WitnessStack
-> Maybe Address
-> StoreInput
StoreInput
                    { inputPoint :: OutPoint
inputPoint = OutPoint
outpoint
                    , inputSequence :: Word32
inputSequence = Word32
sequ
                    , inputSigScript :: ByteString
inputSigScript = ByteString
sigscript
                    , inputPkScript :: ByteString
inputPkScript = ByteString
pkscript
                    , inputAmount :: Word64
inputAmount = Word64
value
                    , inputWitness :: WitnessStack
inputWitness = WitnessStack
witness
                    , inputAddress :: Maybe Address
inputAddress = Maybe Address
addr
                    }

jsonHex :: Text -> Parser ByteString
jsonHex :: Text -> Parser ByteString
jsonHex s :: Text
s =
    case Text -> Maybe ByteString
decodeHex Text
s of
        Nothing -> String -> Parser ByteString
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "Could not decode hex"
        Just b :: ByteString
b  -> ByteString -> Parser ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
b

-- | Information about input spending output.
data Spender =
    Spender
        { Spender -> TxHash
spenderHash  :: !TxHash
        -- ^ input transaction hash
        , Spender -> Word32
spenderIndex :: !Word32
        -- ^ input position in transaction
        }
    deriving (Int -> Spender -> ShowS
[Spender] -> ShowS
Spender -> String
(Int -> Spender -> ShowS)
-> (Spender -> String) -> ([Spender] -> ShowS) -> Show Spender
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Spender] -> ShowS
$cshowList :: [Spender] -> ShowS
show :: Spender -> String
$cshow :: Spender -> String
showsPrec :: Int -> Spender -> ShowS
$cshowsPrec :: Int -> Spender -> ShowS
Show, ReadPrec [Spender]
ReadPrec Spender
Int -> ReadS Spender
ReadS [Spender]
(Int -> ReadS Spender)
-> ReadS [Spender]
-> ReadPrec Spender
-> ReadPrec [Spender]
-> Read Spender
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Spender]
$creadListPrec :: ReadPrec [Spender]
readPrec :: ReadPrec Spender
$creadPrec :: ReadPrec Spender
readList :: ReadS [Spender]
$creadList :: ReadS [Spender]
readsPrec :: Int -> ReadS Spender
$creadsPrec :: Int -> ReadS Spender
Read, Spender -> Spender -> Bool
(Spender -> Spender -> Bool)
-> (Spender -> Spender -> Bool) -> Eq Spender
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Spender -> Spender -> Bool
$c/= :: Spender -> Spender -> Bool
== :: Spender -> Spender -> Bool
$c== :: Spender -> Spender -> Bool
Eq, Eq Spender
Eq Spender =>
(Spender -> Spender -> Ordering)
-> (Spender -> Spender -> Bool)
-> (Spender -> Spender -> Bool)
-> (Spender -> Spender -> Bool)
-> (Spender -> Spender -> Bool)
-> (Spender -> Spender -> Spender)
-> (Spender -> Spender -> Spender)
-> Ord Spender
Spender -> Spender -> Bool
Spender -> Spender -> Ordering
Spender -> Spender -> Spender
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 :: Spender -> Spender -> Spender
$cmin :: Spender -> Spender -> Spender
max :: Spender -> Spender -> Spender
$cmax :: Spender -> Spender -> Spender
>= :: Spender -> Spender -> Bool
$c>= :: Spender -> Spender -> Bool
> :: Spender -> Spender -> Bool
$c> :: Spender -> Spender -> Bool
<= :: Spender -> Spender -> Bool
$c<= :: Spender -> Spender -> Bool
< :: Spender -> Spender -> Bool
$c< :: Spender -> Spender -> Bool
compare :: Spender -> Spender -> Ordering
$ccompare :: Spender -> Spender -> Ordering
$cp1Ord :: Eq Spender
Ord, (forall x. Spender -> Rep Spender x)
-> (forall x. Rep Spender x -> Spender) -> Generic Spender
forall x. Rep Spender x -> Spender
forall x. Spender -> Rep Spender x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Spender x -> Spender
$cfrom :: forall x. Spender -> Rep Spender x
Generic, Int -> Spender -> Int
Spender -> Int
(Int -> Spender -> Int) -> (Spender -> Int) -> Hashable Spender
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Spender -> Int
$chash :: Spender -> Int
hashWithSalt :: Int -> Spender -> Int
$chashWithSalt :: Int -> Spender -> Int
Hashable, Spender -> ()
(Spender -> ()) -> NFData Spender
forall a. (a -> ()) -> NFData a
rnf :: Spender -> ()
$crnf :: Spender -> ()
NFData)

instance Serial Spender where
    serialize :: Spender -> m ()
serialize Spender{..} = do
        TxHash -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize TxHash
spenderHash
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
spenderIndex
    deserialize :: m Spender
deserialize = TxHash -> Word32 -> Spender
Spender (TxHash -> Word32 -> Spender) -> m TxHash -> m (Word32 -> Spender)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m TxHash
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize m (Word32 -> Spender) -> m Word32 -> m Spender
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be

instance Serialize Spender where
    put :: Putter Spender
put = Putter Spender
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get Spender
get = Get Spender
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary Spender where
    put :: Spender -> Put
put = Spender -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get Spender
get = Get Spender
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance ToJSON Spender where
    toJSON :: Spender -> Value
toJSON n :: Spender
n =
        [Pair] -> Value
A.object
        [ "txid" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TxHash -> Text
txHashToHex (Spender -> TxHash
spenderHash Spender
n)
        , "input" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Spender -> Word32
spenderIndex Spender
n
        ]
    toEncoding :: Spender -> Encoding
toEncoding n :: Spender
n =
        Series -> Encoding
AE.pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
          "txid" Text -> Text -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TxHash -> Text
txHashToHex (Spender -> TxHash
spenderHash Spender
n) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
          "input" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Spender -> Word32
spenderIndex Spender
n

instance FromJSON Spender where
    parseJSON :: Value -> Parser Spender
parseJSON =
        String -> (Object -> Parser Spender) -> Value -> Parser Spender
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "spender" ((Object -> Parser Spender) -> Value -> Parser Spender)
-> (Object -> Parser Spender) -> Value -> Parser Spender
forall a b. (a -> b) -> a -> b
$ \o :: Object
o ->
        TxHash -> Word32 -> Spender
Spender (TxHash -> Word32 -> Spender)
-> Parser TxHash -> Parser (Word32 -> Spender)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser TxHash
forall a. FromJSON a => Object -> Text -> Parser a
.: "txid" Parser (Word32 -> Spender) -> Parser Word32 -> Parser Spender
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "input"

-- | Output information.
data StoreOutput =
    StoreOutput
        { StoreOutput -> Word64
outputAmount  :: !Word64
        , StoreOutput -> ByteString
outputScript  :: !ByteString
        , StoreOutput -> Maybe Spender
outputSpender :: !(Maybe Spender)
        , StoreOutput -> Maybe Address
outputAddr    :: !(Maybe Address)
        }
    deriving (Int -> StoreOutput -> ShowS
[StoreOutput] -> ShowS
StoreOutput -> String
(Int -> StoreOutput -> ShowS)
-> (StoreOutput -> String)
-> ([StoreOutput] -> ShowS)
-> Show StoreOutput
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StoreOutput] -> ShowS
$cshowList :: [StoreOutput] -> ShowS
show :: StoreOutput -> String
$cshow :: StoreOutput -> String
showsPrec :: Int -> StoreOutput -> ShowS
$cshowsPrec :: Int -> StoreOutput -> ShowS
Show, ReadPrec [StoreOutput]
ReadPrec StoreOutput
Int -> ReadS StoreOutput
ReadS [StoreOutput]
(Int -> ReadS StoreOutput)
-> ReadS [StoreOutput]
-> ReadPrec StoreOutput
-> ReadPrec [StoreOutput]
-> Read StoreOutput
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [StoreOutput]
$creadListPrec :: ReadPrec [StoreOutput]
readPrec :: ReadPrec StoreOutput
$creadPrec :: ReadPrec StoreOutput
readList :: ReadS [StoreOutput]
$creadList :: ReadS [StoreOutput]
readsPrec :: Int -> ReadS StoreOutput
$creadsPrec :: Int -> ReadS StoreOutput
Read, StoreOutput -> StoreOutput -> Bool
(StoreOutput -> StoreOutput -> Bool)
-> (StoreOutput -> StoreOutput -> Bool) -> Eq StoreOutput
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StoreOutput -> StoreOutput -> Bool
$c/= :: StoreOutput -> StoreOutput -> Bool
== :: StoreOutput -> StoreOutput -> Bool
$c== :: StoreOutput -> StoreOutput -> Bool
Eq, Eq StoreOutput
Eq StoreOutput =>
(StoreOutput -> StoreOutput -> Ordering)
-> (StoreOutput -> StoreOutput -> Bool)
-> (StoreOutput -> StoreOutput -> Bool)
-> (StoreOutput -> StoreOutput -> Bool)
-> (StoreOutput -> StoreOutput -> Bool)
-> (StoreOutput -> StoreOutput -> StoreOutput)
-> (StoreOutput -> StoreOutput -> StoreOutput)
-> Ord StoreOutput
StoreOutput -> StoreOutput -> Bool
StoreOutput -> StoreOutput -> Ordering
StoreOutput -> StoreOutput -> StoreOutput
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 :: StoreOutput -> StoreOutput -> StoreOutput
$cmin :: StoreOutput -> StoreOutput -> StoreOutput
max :: StoreOutput -> StoreOutput -> StoreOutput
$cmax :: StoreOutput -> StoreOutput -> StoreOutput
>= :: StoreOutput -> StoreOutput -> Bool
$c>= :: StoreOutput -> StoreOutput -> Bool
> :: StoreOutput -> StoreOutput -> Bool
$c> :: StoreOutput -> StoreOutput -> Bool
<= :: StoreOutput -> StoreOutput -> Bool
$c<= :: StoreOutput -> StoreOutput -> Bool
< :: StoreOutput -> StoreOutput -> Bool
$c< :: StoreOutput -> StoreOutput -> Bool
compare :: StoreOutput -> StoreOutput -> Ordering
$ccompare :: StoreOutput -> StoreOutput -> Ordering
$cp1Ord :: Eq StoreOutput
Ord, (forall x. StoreOutput -> Rep StoreOutput x)
-> (forall x. Rep StoreOutput x -> StoreOutput)
-> Generic StoreOutput
forall x. Rep StoreOutput x -> StoreOutput
forall x. StoreOutput -> Rep StoreOutput x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep StoreOutput x -> StoreOutput
$cfrom :: forall x. StoreOutput -> Rep StoreOutput x
Generic, Int -> StoreOutput -> Int
StoreOutput -> Int
(Int -> StoreOutput -> Int)
-> (StoreOutput -> Int) -> Hashable StoreOutput
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: StoreOutput -> Int
$chash :: StoreOutput -> Int
hashWithSalt :: Int -> StoreOutput -> Int
$chashWithSalt :: Int -> StoreOutput -> Int
Hashable, StoreOutput -> ()
(StoreOutput -> ()) -> NFData StoreOutput
forall a. (a -> ()) -> NFData a
rnf :: StoreOutput -> ()
$crnf :: StoreOutput -> ()
NFData)

instance Serial StoreOutput where
    serialize :: StoreOutput -> m ()
serialize StoreOutput{..} = do
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
outputAmount
        ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putLengthBytes ByteString
outputScript
        (Spender -> m ()) -> Maybe Spender -> m ()
forall (m :: * -> *) a.
MonadPut m =>
(a -> m ()) -> Maybe a -> m ()
putMaybe Spender -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Maybe Spender
outputSpender
        (Address -> m ()) -> Maybe Address -> m ()
forall (m :: * -> *) a.
MonadPut m =>
(a -> m ()) -> Maybe a -> m ()
putMaybe Address -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Maybe Address
outputAddr
    deserialize :: m StoreOutput
deserialize = do
        Word64
outputAmount <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        ByteString
outputScript <- m ByteString
forall (m :: * -> *). MonadGet m => m ByteString
getLengthBytes
        Maybe Spender
outputSpender <- m Spender -> m (Maybe Spender)
forall (m :: * -> *) a. MonadGet m => m a -> m (Maybe a)
getMaybe m Spender
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Maybe Address
outputAddr <- m Address -> m (Maybe Address)
forall (m :: * -> *) a. MonadGet m => m a -> m (Maybe a)
getMaybe m Address
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        StoreOutput -> m StoreOutput
forall (m :: * -> *) a. Monad m => a -> m a
return $WStoreOutput :: Word64
-> ByteString -> Maybe Spender -> Maybe Address -> StoreOutput
StoreOutput{..}

instance Serialize StoreOutput where
    put :: Putter StoreOutput
put = Putter StoreOutput
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get StoreOutput
get = Get StoreOutput
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary StoreOutput where
    put :: StoreOutput -> Put
put = StoreOutput -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get StoreOutput
get = Get StoreOutput
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

storeOutputToJSON :: Network -> StoreOutput -> Value
storeOutputToJSON :: Network -> StoreOutput -> Value
storeOutputToJSON net :: Network
net d :: StoreOutput
d =
    [Pair] -> Value
A.object
    [ "address" Text -> Maybe Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Network -> Address -> Value
addrToJSON Network
net (Address -> Value) -> Maybe Address -> Maybe Value
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StoreOutput -> Maybe Address
outputAddr StoreOutput
d)
    , "pkscript" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ByteString -> Text
encodeHex (StoreOutput -> ByteString
outputScript StoreOutput
d)
    , "value" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= StoreOutput -> Word64
outputAmount StoreOutput
d
    , "spent" Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Maybe Spender -> Bool
forall a. Maybe a -> Bool
isJust (StoreOutput -> Maybe Spender
outputSpender StoreOutput
d)
    , "spender" Text -> Maybe Spender -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= StoreOutput -> Maybe Spender
outputSpender StoreOutput
d
    ]

storeOutputToEncoding :: Network -> StoreOutput -> Encoding
storeOutputToEncoding :: Network -> StoreOutput -> Encoding
storeOutputToEncoding net :: Network
net d :: StoreOutput
d =
    Series -> Encoding
AE.pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
    "address" Text -> Encoding -> Series
`AE.pair` Encoding -> (Address -> Encoding) -> Maybe Address -> Encoding
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Encoding
AE.null_ (Network -> Address -> Encoding
addrToEncoding Network
net) (StoreOutput -> Maybe Address
outputAddr StoreOutput
d) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "pkscript" Text -> Encoding -> Series
`AE.pair` Text -> Encoding
forall a. Text -> Encoding' a
AE.text (ByteString -> Text
encodeHex (StoreOutput -> ByteString
outputScript StoreOutput
d)) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "value" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= StoreOutput -> Word64
outputAmount StoreOutput
d Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "spent" Text -> Bool -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Maybe Spender -> Bool
forall a. Maybe a -> Bool
isJust (StoreOutput -> Maybe Spender
outputSpender StoreOutput
d) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "spender" Text -> Maybe Spender -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= StoreOutput -> Maybe Spender
outputSpender StoreOutput
d

storeOutputParseJSON :: Network -> Value -> Parser StoreOutput
storeOutputParseJSON :: Network -> Value -> Parser StoreOutput
storeOutputParseJSON net :: Network
net =
    String
-> (Object -> Parser StoreOutput) -> Value -> Parser StoreOutput
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "storeoutput" ((Object -> Parser StoreOutput) -> Value -> Parser StoreOutput)
-> (Object -> Parser StoreOutput) -> Value -> Parser StoreOutput
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
    Word64
value <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "value"
    ByteString
pkscript <- Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: "pkscript" Parser Text -> (Text -> Parser ByteString) -> Parser ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Parser ByteString
jsonHex
    Maybe Spender
spender <- Object
o Object -> Text -> Parser (Maybe Spender)
forall a. FromJSON a => Object -> Text -> Parser a
.: "spender"
    Maybe Address
addr <- Object
o Object -> Text -> Parser (Maybe Value)
forall a. FromJSON a => Object -> Text -> Parser a
.: "address" Parser (Maybe Value)
-> (Maybe Value -> Parser (Maybe Address))
-> Parser (Maybe Address)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Nothing -> Maybe Address -> Parser (Maybe Address)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Address
forall a. Maybe a
Nothing
        Just a :: Value
a  -> Address -> Maybe Address
forall a. a -> Maybe a
Just (Address -> Maybe Address)
-> Parser Address -> Parser (Maybe Address)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Network -> Value -> Parser Address
addrFromJSON Network
net Value
a Parser (Maybe Address)
-> Parser (Maybe Address) -> Parser (Maybe Address)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Address -> Parser (Maybe Address)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Address
forall a. Maybe a
Nothing
    StoreOutput -> Parser StoreOutput
forall (m :: * -> *) a. Monad m => a -> m a
return
        $WStoreOutput :: Word64
-> ByteString -> Maybe Spender -> Maybe Address -> StoreOutput
StoreOutput
            { outputAmount :: Word64
outputAmount = Word64
value
            , outputScript :: ByteString
outputScript = ByteString
pkscript
            , outputSpender :: Maybe Spender
outputSpender = Maybe Spender
spender
            , outputAddr :: Maybe Address
outputAddr = Maybe Address
addr
            }

data Prev =
    Prev
        { Prev -> ByteString
prevScript :: !ByteString
        , Prev -> Word64
prevAmount :: !Word64
        }
    deriving (Int -> Prev -> ShowS
[Prev] -> ShowS
Prev -> String
(Int -> Prev -> ShowS)
-> (Prev -> String) -> ([Prev] -> ShowS) -> Show Prev
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Prev] -> ShowS
$cshowList :: [Prev] -> ShowS
show :: Prev -> String
$cshow :: Prev -> String
showsPrec :: Int -> Prev -> ShowS
$cshowsPrec :: Int -> Prev -> ShowS
Show, Prev -> Prev -> Bool
(Prev -> Prev -> Bool) -> (Prev -> Prev -> Bool) -> Eq Prev
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Prev -> Prev -> Bool
$c/= :: Prev -> Prev -> Bool
== :: Prev -> Prev -> Bool
$c== :: Prev -> Prev -> Bool
Eq, Eq Prev
Eq Prev =>
(Prev -> Prev -> Ordering)
-> (Prev -> Prev -> Bool)
-> (Prev -> Prev -> Bool)
-> (Prev -> Prev -> Bool)
-> (Prev -> Prev -> Bool)
-> (Prev -> Prev -> Prev)
-> (Prev -> Prev -> Prev)
-> Ord Prev
Prev -> Prev -> Bool
Prev -> Prev -> Ordering
Prev -> Prev -> Prev
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 :: Prev -> Prev -> Prev
$cmin :: Prev -> Prev -> Prev
max :: Prev -> Prev -> Prev
$cmax :: Prev -> Prev -> Prev
>= :: Prev -> Prev -> Bool
$c>= :: Prev -> Prev -> Bool
> :: Prev -> Prev -> Bool
$c> :: Prev -> Prev -> Bool
<= :: Prev -> Prev -> Bool
$c<= :: Prev -> Prev -> Bool
< :: Prev -> Prev -> Bool
$c< :: Prev -> Prev -> Bool
compare :: Prev -> Prev -> Ordering
$ccompare :: Prev -> Prev -> Ordering
$cp1Ord :: Eq Prev
Ord, (forall x. Prev -> Rep Prev x)
-> (forall x. Rep Prev x -> Prev) -> Generic Prev
forall x. Rep Prev x -> Prev
forall x. Prev -> Rep Prev x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Prev x -> Prev
$cfrom :: forall x. Prev -> Rep Prev x
Generic, Int -> Prev -> Int
Prev -> Int
(Int -> Prev -> Int) -> (Prev -> Int) -> Hashable Prev
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Prev -> Int
$chash :: Prev -> Int
hashWithSalt :: Int -> Prev -> Int
$chashWithSalt :: Int -> Prev -> Int
Hashable, Prev -> ()
(Prev -> ()) -> NFData Prev
forall a. (a -> ()) -> NFData a
rnf :: Prev -> ()
$crnf :: Prev -> ()
NFData)

instance Serial Prev where
    serialize :: Prev -> m ()
serialize Prev{..} = do
        ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putLengthBytes ByteString
prevScript
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
prevAmount
    deserialize :: m Prev
deserialize = do
        ByteString
prevScript <- m ByteString
forall (m :: * -> *). MonadGet m => m ByteString
getLengthBytes
        Word64
prevAmount <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Prev -> m Prev
forall (m :: * -> *) a. Monad m => a -> m a
return $WPrev :: ByteString -> Word64 -> Prev
Prev{..}

instance Binary Prev where
    put :: Prev -> Put
put = Prev -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get Prev
get = Get Prev
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Serialize Prev where
    put :: Putter Prev
put = Putter Prev
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get Prev
get = Get Prev
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

toInput :: TxIn -> Maybe Prev -> WitnessStack -> StoreInput
toInput :: TxIn -> Maybe Prev -> WitnessStack -> StoreInput
toInput i :: TxIn
i Nothing w :: WitnessStack
w =
    $WStoreCoinbase :: OutPoint -> Word32 -> ByteString -> WitnessStack -> StoreInput
StoreCoinbase
        { inputPoint :: OutPoint
inputPoint = TxIn -> OutPoint
prevOutput TxIn
i
        , inputSequence :: Word32
inputSequence = TxIn -> Word32
txInSequence TxIn
i
        , inputSigScript :: ByteString
inputSigScript = TxIn -> ByteString
scriptInput TxIn
i
        , inputWitness :: WitnessStack
inputWitness = WitnessStack
w
        }
toInput i :: TxIn
i (Just p :: Prev
p) w :: WitnessStack
w =
    $WStoreInput :: OutPoint
-> Word32
-> ByteString
-> ByteString
-> Word64
-> WitnessStack
-> Maybe Address
-> StoreInput
StoreInput
        { inputPoint :: OutPoint
inputPoint = TxIn -> OutPoint
prevOutput TxIn
i
        , inputSequence :: Word32
inputSequence = TxIn -> Word32
txInSequence TxIn
i
        , inputSigScript :: ByteString
inputSigScript = TxIn -> ByteString
scriptInput TxIn
i
        , inputPkScript :: ByteString
inputPkScript = Prev -> ByteString
prevScript Prev
p
        , inputAmount :: Word64
inputAmount = Prev -> Word64
prevAmount Prev
p
        , inputWitness :: WitnessStack
inputWitness = WitnessStack
w
        , inputAddress :: Maybe Address
inputAddress = Either String Address -> Maybe Address
forall a b. Either a b -> Maybe b
eitherToMaybe (ByteString -> Either String Address
scriptToAddressBS (Prev -> ByteString
prevScript Prev
p))
        }

toOutput :: TxOut -> Maybe Spender -> StoreOutput
toOutput :: TxOut -> Maybe Spender -> StoreOutput
toOutput o :: TxOut
o s :: Maybe Spender
s =
    $WStoreOutput :: Word64
-> ByteString -> Maybe Spender -> Maybe Address -> StoreOutput
StoreOutput
        { outputAmount :: Word64
outputAmount = TxOut -> Word64
outValue TxOut
o
        , outputScript :: ByteString
outputScript = TxOut -> ByteString
scriptOutput TxOut
o
        , outputSpender :: Maybe Spender
outputSpender = Maybe Spender
s
        , outputAddr :: Maybe Address
outputAddr = Either String Address -> Maybe Address
forall a b. Either a b -> Maybe b
eitherToMaybe (ByteString -> Either String Address
scriptToAddressBS (TxOut -> ByteString
scriptOutput TxOut
o))
        }

data TxData =
    TxData
        { TxData -> BlockRef
txDataBlock   :: !BlockRef
        , TxData -> Tx
txData        :: !Tx
        , TxData -> IntMap Prev
txDataPrevs   :: !(IntMap Prev)
        , TxData -> Bool
txDataDeleted :: !Bool
        , TxData -> Bool
txDataRBF     :: !Bool
        , TxData -> Word64
txDataTime    :: !Word64
        }
    deriving (Int -> TxData -> ShowS
[TxData] -> ShowS
TxData -> String
(Int -> TxData -> ShowS)
-> (TxData -> String) -> ([TxData] -> ShowS) -> Show TxData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TxData] -> ShowS
$cshowList :: [TxData] -> ShowS
show :: TxData -> String
$cshow :: TxData -> String
showsPrec :: Int -> TxData -> ShowS
$cshowsPrec :: Int -> TxData -> ShowS
Show, TxData -> TxData -> Bool
(TxData -> TxData -> Bool)
-> (TxData -> TxData -> Bool) -> Eq TxData
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TxData -> TxData -> Bool
$c/= :: TxData -> TxData -> Bool
== :: TxData -> TxData -> Bool
$c== :: TxData -> TxData -> Bool
Eq, Eq TxData
Eq TxData =>
(TxData -> TxData -> Ordering)
-> (TxData -> TxData -> Bool)
-> (TxData -> TxData -> Bool)
-> (TxData -> TxData -> Bool)
-> (TxData -> TxData -> Bool)
-> (TxData -> TxData -> TxData)
-> (TxData -> TxData -> TxData)
-> Ord TxData
TxData -> TxData -> Bool
TxData -> TxData -> Ordering
TxData -> TxData -> TxData
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 :: TxData -> TxData -> TxData
$cmin :: TxData -> TxData -> TxData
max :: TxData -> TxData -> TxData
$cmax :: TxData -> TxData -> TxData
>= :: TxData -> TxData -> Bool
$c>= :: TxData -> TxData -> Bool
> :: TxData -> TxData -> Bool
$c> :: TxData -> TxData -> Bool
<= :: TxData -> TxData -> Bool
$c<= :: TxData -> TxData -> Bool
< :: TxData -> TxData -> Bool
$c< :: TxData -> TxData -> Bool
compare :: TxData -> TxData -> Ordering
$ccompare :: TxData -> TxData -> Ordering
$cp1Ord :: Eq TxData
Ord, (forall x. TxData -> Rep TxData x)
-> (forall x. Rep TxData x -> TxData) -> Generic TxData
forall x. Rep TxData x -> TxData
forall x. TxData -> Rep TxData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TxData x -> TxData
$cfrom :: forall x. TxData -> Rep TxData x
Generic, TxData -> ()
(TxData -> ()) -> NFData TxData
forall a. (a -> ()) -> NFData a
rnf :: TxData -> ()
$crnf :: TxData -> ()
NFData)

instance Serial TxData where
    serialize :: TxData -> m ()
serialize TxData{..} = do
        BlockRef -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize BlockRef
txDataBlock
        Tx -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Tx
txData
        (Int -> m ()) -> (Prev -> m ()) -> IntMap Prev -> m ()
forall (m :: * -> *) a.
MonadPut m =>
(Int -> m ()) -> (a -> m ()) -> IntMap a -> m ()
putIntMap (Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be (Word64 -> m ()) -> (Int -> Word64) -> Int -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral) Prev -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize IntMap Prev
txDataPrevs
        Bool -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Bool
txDataDeleted
        Bool -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Bool
txDataRBF
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
txDataTime
    deserialize :: m TxData
deserialize = do
        BlockRef
txDataBlock <- m BlockRef
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Tx
txData <- m Tx
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        IntMap Prev
txDataPrevs <- m Int -> m Prev -> m (IntMap Prev)
forall (m :: * -> *) a. MonadGet m => m Int -> m a -> m (IntMap a)
getIntMap (Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Int) -> m Word64 -> m Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be) m Prev
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Bool
txDataDeleted <- m Bool
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Bool
txDataRBF <- m Bool
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Word64
txDataTime <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        TxData -> m TxData
forall (m :: * -> *) a. Monad m => a -> m a
return $WTxData :: BlockRef -> Tx -> IntMap Prev -> Bool -> Bool -> Word64 -> TxData
TxData{..}

instance Serialize TxData where
    put :: Putter TxData
put = Putter TxData
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get TxData
get = Get TxData
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary TxData where
    put :: TxData -> Put
put = TxData -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get TxData
get = Get TxData
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

toTransaction :: TxData -> IntMap Spender -> Transaction
toTransaction :: TxData -> IntMap Spender -> Transaction
toTransaction t :: TxData
t sm :: IntMap Spender
sm =
    $WTransaction :: BlockRef
-> Word32
-> Word32
-> [StoreInput]
-> [StoreOutput]
-> Bool
-> Bool
-> Word64
-> TxHash
-> Word32
-> Word32
-> Word64
-> Transaction
Transaction
        { transactionBlock :: BlockRef
transactionBlock = TxData -> BlockRef
txDataBlock TxData
t
        , transactionVersion :: Word32
transactionVersion = Tx -> Word32
txVersion (TxData -> Tx
txData TxData
t)
        , transactionLockTime :: Word32
transactionLockTime = Tx -> Word32
txLockTime (TxData -> Tx
txData TxData
t)
        , transactionInputs :: [StoreInput]
transactionInputs = [StoreInput]
ins
        , transactionOutputs :: [StoreOutput]
transactionOutputs = [StoreOutput]
outs
        , transactionDeleted :: Bool
transactionDeleted = TxData -> Bool
txDataDeleted TxData
t
        , transactionRBF :: Bool
transactionRBF = TxData -> Bool
txDataRBF TxData
t
        , transactionTime :: Word64
transactionTime = TxData -> Word64
txDataTime TxData
t
        , transactionId :: TxHash
transactionId = TxHash
txid
        , transactionSize :: Word32
transactionSize = Word32
txsize
        , transactionWeight :: Word32
transactionWeight = Word32
txweight
        , transactionFees :: Word64
transactionFees = Word64
fees
        }
  where
    txid :: TxHash
txid = Tx -> TxHash
txHash (TxData -> Tx
txData TxData
t)
    txsize :: Word32
txsize = Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word32) -> Int -> Word32
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
BS.length (Put -> ByteString
runPutS (Tx -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (TxData -> Tx
txData TxData
t)))
    txweight :: Word32
txweight =
        let b :: Int
b = ByteString -> Int
BS.length (ByteString -> Int) -> ByteString -> Int
forall a b. (a -> b) -> a -> b
$ Put -> ByteString
runPutS (Put -> ByteString) -> Put -> ByteString
forall a b. (a -> b) -> a -> b
$ Tx -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (TxData -> Tx
txData TxData
t) {txWitness :: WitnessData
txWitness = []}
            x :: Int
x = ByteString -> Int
BS.length (ByteString -> Int) -> ByteString -> Int
forall a b. (a -> b) -> a -> b
$ Put -> ByteString
runPutS (Put -> ByteString) -> Put -> ByteString
forall a b. (a -> b) -> a -> b
$ Tx -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (TxData -> Tx
txData TxData
t)
         in Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word32) -> Int -> Word32
forall a b. (a -> b) -> a -> b
$ Int
b Int -> Int -> Int
forall a. Num a => a -> a -> a
* 3 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x
    inv :: Word64
inv = [Word64] -> Word64
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ((StoreInput -> Word64) -> [StoreInput] -> [Word64]
forall a b. (a -> b) -> [a] -> [b]
map StoreInput -> Word64
inputAmount [StoreInput]
ins)
    outv :: Word64
outv = [Word64] -> Word64
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ((StoreOutput -> Word64) -> [StoreOutput] -> [Word64]
forall a b. (a -> b) -> [a] -> [b]
map StoreOutput -> Word64
outputAmount [StoreOutput]
outs)
    fees :: Word64
fees = if (StoreInput -> Bool) -> [StoreInput] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any StoreInput -> Bool
isCoinbase [StoreInput]
ins then 0 else Word64
inv Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
outv
    ws :: WitnessData
ws = Int -> WitnessData -> WitnessData
forall a. Int -> [a] -> [a]
take ([TxIn] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Tx -> [TxIn]
txIn (TxData -> Tx
txData TxData
t))) (WitnessData -> WitnessData) -> WitnessData -> WitnessData
forall a b. (a -> b) -> a -> b
$ Tx -> WitnessData
txWitness (TxData -> Tx
txData TxData
t) WitnessData -> WitnessData -> WitnessData
forall a. Semigroup a => a -> a -> a
<> WitnessStack -> WitnessData
forall a. a -> [a]
repeat []
    f :: Int -> TxIn -> StoreInput
f n :: Int
n i :: TxIn
i = TxIn -> Maybe Prev -> WitnessStack -> StoreInput
toInput TxIn
i (Int -> IntMap Prev -> Maybe Prev
forall a. Int -> IntMap a -> Maybe a
IntMap.lookup Int
n (TxData -> IntMap Prev
txDataPrevs TxData
t)) (WitnessData
ws WitnessData -> Int -> WitnessStack
forall a. [a] -> Int -> a
!! Int
n)
    ins :: [StoreInput]
ins = (Int -> TxIn -> StoreInput) -> [Int] -> [TxIn] -> [StoreInput]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> TxIn -> StoreInput
f [0 ..] (Tx -> [TxIn]
txIn (TxData -> Tx
txData TxData
t))
    g :: Int -> TxOut -> StoreOutput
g n :: Int
n o :: TxOut
o = TxOut -> Maybe Spender -> StoreOutput
toOutput TxOut
o (Int -> IntMap Spender -> Maybe Spender
forall a. Int -> IntMap a -> Maybe a
IntMap.lookup Int
n IntMap Spender
sm)
    outs :: [StoreOutput]
outs = (Int -> TxOut -> StoreOutput) -> [Int] -> [TxOut] -> [StoreOutput]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> TxOut -> StoreOutput
g [0 ..] (Tx -> [TxOut]
txOut (TxData -> Tx
txData TxData
t))

fromTransaction :: Transaction -> (TxData, IntMap Spender)
fromTransaction :: Transaction -> (TxData, IntMap Spender)
fromTransaction t :: Transaction
t = (TxData
d, IntMap Spender
sm)
  where
    d :: TxData
d =
        $WTxData :: BlockRef -> Tx -> IntMap Prev -> Bool -> Bool -> Word64 -> TxData
TxData
            { txDataBlock :: BlockRef
txDataBlock = Transaction -> BlockRef
transactionBlock Transaction
t
            , txData :: Tx
txData = Transaction -> Tx
transactionData Transaction
t
            , txDataPrevs :: IntMap Prev
txDataPrevs = IntMap Prev
ps
            , txDataDeleted :: Bool
txDataDeleted = Transaction -> Bool
transactionDeleted Transaction
t
            , txDataRBF :: Bool
txDataRBF = Transaction -> Bool
transactionRBF Transaction
t
            , txDataTime :: Word64
txDataTime = Transaction -> Word64
transactionTime Transaction
t
            }
    f :: a -> StoreInput -> Maybe (a, Prev)
f _ StoreCoinbase {} = Maybe (a, Prev)
forall a. Maybe a
Nothing
    f n :: a
n StoreInput {inputPkScript :: StoreInput -> ByteString
inputPkScript = ByteString
s, inputAmount :: StoreInput -> Word64
inputAmount = Word64
v} =
        (a, Prev) -> Maybe (a, Prev)
forall a. a -> Maybe a
Just (a
n, $WPrev :: ByteString -> Word64 -> Prev
Prev {prevScript :: ByteString
prevScript = ByteString
s, prevAmount :: Word64
prevAmount = Word64
v})
    ps :: IntMap Prev
ps = [(Int, Prev)] -> IntMap Prev
forall a. [(Int, a)] -> IntMap a
IntMap.fromList ([(Int, Prev)] -> IntMap Prev)
-> ([Maybe (Int, Prev)] -> [(Int, Prev)])
-> [Maybe (Int, Prev)]
-> IntMap Prev
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe (Int, Prev)] -> [(Int, Prev)]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe (Int, Prev)] -> IntMap Prev)
-> [Maybe (Int, Prev)] -> IntMap Prev
forall a b. (a -> b) -> a -> b
$ (Int -> StoreInput -> Maybe (Int, Prev))
-> [Int] -> [StoreInput] -> [Maybe (Int, Prev)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> StoreInput -> Maybe (Int, Prev)
forall a. a -> StoreInput -> Maybe (a, Prev)
f [0 ..] (Transaction -> [StoreInput]
transactionInputs Transaction
t)
    g :: a -> StoreOutput -> Maybe (a, Spender)
g _ StoreOutput {outputSpender :: StoreOutput -> Maybe Spender
outputSpender = Maybe Spender
Nothing} = Maybe (a, Spender)
forall a. Maybe a
Nothing
    g n :: a
n StoreOutput {outputSpender :: StoreOutput -> Maybe Spender
outputSpender = Just s :: Spender
s}  = (a, Spender) -> Maybe (a, Spender)
forall a. a -> Maybe a
Just (a
n, Spender
s)
    sm :: IntMap Spender
sm = [(Int, Spender)] -> IntMap Spender
forall a. [(Int, a)] -> IntMap a
IntMap.fromList ([(Int, Spender)] -> IntMap Spender)
-> ([Maybe (Int, Spender)] -> [(Int, Spender)])
-> [Maybe (Int, Spender)]
-> IntMap Spender
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe (Int, Spender)] -> [(Int, Spender)]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe (Int, Spender)] -> IntMap Spender)
-> [Maybe (Int, Spender)] -> IntMap Spender
forall a b. (a -> b) -> a -> b
$ (Int -> StoreOutput -> Maybe (Int, Spender))
-> [Int] -> [StoreOutput] -> [Maybe (Int, Spender)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> StoreOutput -> Maybe (Int, Spender)
forall a. a -> StoreOutput -> Maybe (a, Spender)
g [0 ..] (Transaction -> [StoreOutput]
transactionOutputs Transaction
t)

-- | Detailed transaction information.
data Transaction =
    Transaction
        { Transaction -> BlockRef
transactionBlock    :: !BlockRef
        -- ^ block information for this transaction
        , Transaction -> Word32
transactionVersion  :: !Word32
        -- ^ transaction version
        , Transaction -> Word32
transactionLockTime :: !Word32
        -- ^ lock time
        , Transaction -> [StoreInput]
transactionInputs   :: ![StoreInput]
        -- ^ transaction inputs
        , Transaction -> [StoreOutput]
transactionOutputs  :: ![StoreOutput]
        -- ^ transaction outputs
        , Transaction -> Bool
transactionDeleted  :: !Bool
        -- ^ this transaction has been deleted and is no longer valid
        , Transaction -> Bool
transactionRBF      :: !Bool
        -- ^ this transaction can be replaced in the mempool
        , Transaction -> Word64
transactionTime     :: !Word64
        -- ^ time the transaction was first seen or time of block
        , Transaction -> TxHash
transactionId       :: !TxHash
        -- ^ transaction id
        , Transaction -> Word32
transactionSize     :: !Word32
        -- ^ serialized transaction size (includes witness data)
        , Transaction -> Word32
transactionWeight   :: !Word32
        -- ^ transaction weight
        , Transaction -> Word64
transactionFees     :: !Word64
        -- ^ fees that this transaction pays (0 for coinbase)
        }
    deriving (Int -> Transaction -> ShowS
[Transaction] -> ShowS
Transaction -> String
(Int -> Transaction -> ShowS)
-> (Transaction -> String)
-> ([Transaction] -> ShowS)
-> Show Transaction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Transaction] -> ShowS
$cshowList :: [Transaction] -> ShowS
show :: Transaction -> String
$cshow :: Transaction -> String
showsPrec :: Int -> Transaction -> ShowS
$cshowsPrec :: Int -> Transaction -> ShowS
Show, Transaction -> Transaction -> Bool
(Transaction -> Transaction -> Bool)
-> (Transaction -> Transaction -> Bool) -> Eq Transaction
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Transaction -> Transaction -> Bool
$c/= :: Transaction -> Transaction -> Bool
== :: Transaction -> Transaction -> Bool
$c== :: Transaction -> Transaction -> Bool
Eq, Eq Transaction
Eq Transaction =>
(Transaction -> Transaction -> Ordering)
-> (Transaction -> Transaction -> Bool)
-> (Transaction -> Transaction -> Bool)
-> (Transaction -> Transaction -> Bool)
-> (Transaction -> Transaction -> Bool)
-> (Transaction -> Transaction -> Transaction)
-> (Transaction -> Transaction -> Transaction)
-> Ord Transaction
Transaction -> Transaction -> Bool
Transaction -> Transaction -> Ordering
Transaction -> Transaction -> Transaction
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 :: Transaction -> Transaction -> Transaction
$cmin :: Transaction -> Transaction -> Transaction
max :: Transaction -> Transaction -> Transaction
$cmax :: Transaction -> Transaction -> Transaction
>= :: Transaction -> Transaction -> Bool
$c>= :: Transaction -> Transaction -> Bool
> :: Transaction -> Transaction -> Bool
$c> :: Transaction -> Transaction -> Bool
<= :: Transaction -> Transaction -> Bool
$c<= :: Transaction -> Transaction -> Bool
< :: Transaction -> Transaction -> Bool
$c< :: Transaction -> Transaction -> Bool
compare :: Transaction -> Transaction -> Ordering
$ccompare :: Transaction -> Transaction -> Ordering
$cp1Ord :: Eq Transaction
Ord, (forall x. Transaction -> Rep Transaction x)
-> (forall x. Rep Transaction x -> Transaction)
-> Generic Transaction
forall x. Rep Transaction x -> Transaction
forall x. Transaction -> Rep Transaction x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Transaction x -> Transaction
$cfrom :: forall x. Transaction -> Rep Transaction x
Generic, Int -> Transaction -> Int
Transaction -> Int
(Int -> Transaction -> Int)
-> (Transaction -> Int) -> Hashable Transaction
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Transaction -> Int
$chash :: Transaction -> Int
hashWithSalt :: Int -> Transaction -> Int
$chashWithSalt :: Int -> Transaction -> Int
Hashable, Transaction -> ()
(Transaction -> ()) -> NFData Transaction
forall a. (a -> ()) -> NFData a
rnf :: Transaction -> ()
$crnf :: Transaction -> ()
NFData)

instance Serial Transaction where
    serialize :: Transaction -> m ()
serialize Transaction{..} = do
        BlockRef -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize BlockRef
transactionBlock
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
transactionVersion
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
transactionLockTime
        (StoreInput -> m ()) -> [StoreInput] -> m ()
forall (m :: * -> *) a. MonadPut m => (a -> m ()) -> [a] -> m ()
putList StoreInput -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize [StoreInput]
transactionInputs
        (StoreOutput -> m ()) -> [StoreOutput] -> m ()
forall (m :: * -> *) a. MonadPut m => (a -> m ()) -> [a] -> m ()
putList StoreOutput -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize [StoreOutput]
transactionOutputs
        Bool -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Bool
transactionDeleted
        Bool -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Bool
transactionRBF
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
transactionTime
        TxHash -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize TxHash
transactionId
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
transactionSize
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
transactionWeight
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
transactionFees
    deserialize :: m Transaction
deserialize = do
        BlockRef
transactionBlock <- m BlockRef
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Word32
transactionVersion <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        Word32
transactionLockTime <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        [StoreInput]
transactionInputs <- m StoreInput -> m [StoreInput]
forall (m :: * -> *) a. MonadGet m => m a -> m [a]
getList m StoreInput
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        [StoreOutput]
transactionOutputs <- m StoreOutput -> m [StoreOutput]
forall (m :: * -> *) a. MonadGet m => m a -> m [a]
getList m StoreOutput
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Bool
transactionDeleted <- m Bool
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Bool
transactionRBF <- m Bool
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Word64
transactionTime <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        TxHash
transactionId <- m TxHash
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Word32
transactionSize <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        Word32
transactionWeight <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        Word64
transactionFees <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Transaction -> m Transaction
forall (m :: * -> *) a. Monad m => a -> m a
return $WTransaction :: BlockRef
-> Word32
-> Word32
-> [StoreInput]
-> [StoreOutput]
-> Bool
-> Bool
-> Word64
-> TxHash
-> Word32
-> Word32
-> Word64
-> Transaction
Transaction{..}

instance Serialize Transaction where
    put :: Putter Transaction
put = Putter Transaction
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get Transaction
get = Get Transaction
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary Transaction where
    put :: Transaction -> Put
put = Transaction -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get Transaction
get = Get Transaction
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

transactionData :: Transaction -> Tx
transactionData :: Transaction -> Tx
transactionData t :: Transaction
t =
    $WTx :: Word32 -> [TxIn] -> [TxOut] -> WitnessData -> Word32 -> Tx
Tx { txVersion :: Word32
txVersion = Transaction -> Word32
transactionVersion Transaction
t
       , txIn :: [TxIn]
txIn = (StoreInput -> TxIn) -> [StoreInput] -> [TxIn]
forall a b. (a -> b) -> [a] -> [b]
map StoreInput -> TxIn
i (Transaction -> [StoreInput]
transactionInputs Transaction
t)
       , txOut :: [TxOut]
txOut = (StoreOutput -> TxOut) -> [StoreOutput] -> [TxOut]
forall a b. (a -> b) -> [a] -> [b]
map StoreOutput -> TxOut
o (Transaction -> [StoreOutput]
transactionOutputs Transaction
t)
       , txWitness :: WitnessData
txWitness = WitnessData -> WitnessData
forall (t :: * -> *) a. Foldable t => [t a] -> [t a]
w (WitnessData -> WitnessData) -> WitnessData -> WitnessData
forall a b. (a -> b) -> a -> b
$ (StoreInput -> WitnessStack) -> [StoreInput] -> WitnessData
forall a b. (a -> b) -> [a] -> [b]
map StoreInput -> WitnessStack
inputWitness (Transaction -> [StoreInput]
transactionInputs Transaction
t)
       , txLockTime :: Word32
txLockTime = Transaction -> Word32
transactionLockTime Transaction
t
       }
  where
    i :: StoreInput -> TxIn
i StoreCoinbase {inputPoint :: StoreInput -> OutPoint
inputPoint = OutPoint
p, inputSequence :: StoreInput -> Word32
inputSequence = Word32
q, inputSigScript :: StoreInput -> ByteString
inputSigScript = ByteString
s} =
        $WTxIn :: OutPoint -> ByteString -> Word32 -> TxIn
TxIn {prevOutput :: OutPoint
prevOutput = OutPoint
p, scriptInput :: ByteString
scriptInput = ByteString
s, txInSequence :: Word32
txInSequence = Word32
q}
    i StoreInput {inputPoint :: StoreInput -> OutPoint
inputPoint = OutPoint
p, inputSequence :: StoreInput -> Word32
inputSequence = Word32
q, inputSigScript :: StoreInput -> ByteString
inputSigScript = ByteString
s} =
        $WTxIn :: OutPoint -> ByteString -> Word32 -> TxIn
TxIn {prevOutput :: OutPoint
prevOutput = OutPoint
p, scriptInput :: ByteString
scriptInput = ByteString
s, txInSequence :: Word32
txInSequence = Word32
q}
    o :: StoreOutput -> TxOut
o StoreOutput {outputAmount :: StoreOutput -> Word64
outputAmount = Word64
v, outputScript :: StoreOutput -> ByteString
outputScript = ByteString
s} =
        $WTxOut :: Word64 -> ByteString -> TxOut
TxOut {outValue :: Word64
outValue = Word64
v, scriptOutput :: ByteString
scriptOutput = ByteString
s}
    w :: [t a] -> [t a]
w xs :: [t a]
xs | (t a -> Bool) -> [t a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all t a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [t a]
xs = []
         | Bool
otherwise = [t a]
xs

transactionToJSON :: Network -> Transaction -> Value
transactionToJSON :: Network -> Transaction -> Value
transactionToJSON net :: Network
net dtx :: Transaction
dtx =
    [Pair] -> Value
A.object
    [ "txid" Text -> TxHash -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> TxHash
transactionId Transaction
dtx
    , "size" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Word32
transactionSize Transaction
dtx
    , "version" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Word32
transactionVersion Transaction
dtx
    , "locktime" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Word32
transactionLockTime Transaction
dtx
    , "fee" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Word64
transactionFees Transaction
dtx
    , "inputs" Text -> [Value] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (StoreInput -> Value) -> [StoreInput] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map (Network -> StoreInput -> Value
storeInputToJSON Network
net) (Transaction -> [StoreInput]
transactionInputs Transaction
dtx)
    , "outputs" Text -> [Value] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (StoreOutput -> Value) -> [StoreOutput] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map (Network -> StoreOutput -> Value
storeOutputToJSON Network
net) (Transaction -> [StoreOutput]
transactionOutputs Transaction
dtx)
    , "block" Text -> BlockRef -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> BlockRef
transactionBlock Transaction
dtx
    , "deleted" Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Bool
transactionDeleted Transaction
dtx
    , "time" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Word64
transactionTime Transaction
dtx
    , "rbf" Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Bool
transactionRBF Transaction
dtx
    , "weight" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Word32
transactionWeight Transaction
dtx
    ]

transactionToEncoding :: Network -> Transaction -> Encoding
transactionToEncoding :: Network -> Transaction -> Encoding
transactionToEncoding net :: Network
net dtx :: Transaction
dtx =
    Series -> Encoding
AE.pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
    "txid" Text -> TxHash -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> TxHash
transactionId Transaction
dtx Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "size" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Word32
transactionSize Transaction
dtx Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "version" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Word32
transactionVersion Transaction
dtx Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "locktime" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Word32
transactionLockTime Transaction
dtx Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "fee" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Word64
transactionFees Transaction
dtx Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "inputs" Text -> Encoding -> Series
`AE.pair` (StoreInput -> Encoding) -> [StoreInput] -> Encoding
forall a. (a -> Encoding) -> [a] -> Encoding
AE.list
    (Network -> StoreInput -> Encoding
storeInputToEncoding Network
net) (Transaction -> [StoreInput]
transactionInputs Transaction
dtx) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "outputs" Text -> Encoding -> Series
`AE.pair` (StoreOutput -> Encoding) -> [StoreOutput] -> Encoding
forall a. (a -> Encoding) -> [a] -> Encoding
AE.list
    (Network -> StoreOutput -> Encoding
storeOutputToEncoding Network
net) (Transaction -> [StoreOutput]
transactionOutputs Transaction
dtx) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "block" Text -> BlockRef -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> BlockRef
transactionBlock Transaction
dtx Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "deleted" Text -> Bool -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Bool
transactionDeleted Transaction
dtx Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "time" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Word64
transactionTime Transaction
dtx Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "rbf" Text -> Bool -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Bool
transactionRBF Transaction
dtx Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
    "weight" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Transaction -> Word32
transactionWeight Transaction
dtx

transactionParseJSON :: Network -> Value -> Parser Transaction
transactionParseJSON :: Network -> Value -> Parser Transaction
transactionParseJSON net :: Network
net = String
-> (Object -> Parser Transaction) -> Value -> Parser Transaction
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "transaction" ((Object -> Parser Transaction) -> Value -> Parser Transaction)
-> (Object -> Parser Transaction) -> Value -> Parser Transaction
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
    Word32
version <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "version"
    Word32
locktime <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "locktime"
    [StoreInput]
inputs <- Object
o Object -> Text -> Parser [Value]
forall a. FromJSON a => Object -> Text -> Parser a
.: "inputs" Parser [Value]
-> ([Value] -> Parser [StoreInput]) -> Parser [StoreInput]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Value -> Parser StoreInput) -> [Value] -> Parser [StoreInput]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Network -> Value -> Parser StoreInput
storeInputParseJSON Network
net)
    [StoreOutput]
outputs <- Object
o Object -> Text -> Parser [Value]
forall a. FromJSON a => Object -> Text -> Parser a
.: "outputs" Parser [Value]
-> ([Value] -> Parser [StoreOutput]) -> Parser [StoreOutput]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Value -> Parser StoreOutput) -> [Value] -> Parser [StoreOutput]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Network -> Value -> Parser StoreOutput
storeOutputParseJSON Network
net)
    BlockRef
block <- Object
o Object -> Text -> Parser BlockRef
forall a. FromJSON a => Object -> Text -> Parser a
.: "block"
    Bool
deleted <- Object
o Object -> Text -> Parser Bool
forall a. FromJSON a => Object -> Text -> Parser a
.: "deleted"
    Word64
time <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "time"
    Bool
rbf <- Object
o Object -> Text -> Parser (Maybe Bool)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? "rbf" Parser (Maybe Bool) -> Bool -> Parser Bool
forall a. Parser (Maybe a) -> a -> Parser a
.!= Bool
False
    Word32
weight <- Object
o Object -> Text -> Parser (Maybe Word32)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? "weight" Parser (Maybe Word32) -> Word32 -> Parser Word32
forall a. Parser (Maybe a) -> a -> Parser a
.!= 0
    Word32
size <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "size"
    TxHash
txid <- Object
o Object -> Text -> Parser TxHash
forall a. FromJSON a => Object -> Text -> Parser a
.: "txid"
    Word64
fees <- Object
o Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "fee"
    Transaction -> Parser Transaction
forall (m :: * -> *) a. Monad m => a -> m a
return
        $WTransaction :: BlockRef
-> Word32
-> Word32
-> [StoreInput]
-> [StoreOutput]
-> Bool
-> Bool
-> Word64
-> TxHash
-> Word32
-> Word32
-> Word64
-> Transaction
Transaction
            { transactionBlock :: BlockRef
transactionBlock = BlockRef
block
            , transactionVersion :: Word32
transactionVersion = Word32
version
            , transactionLockTime :: Word32
transactionLockTime = Word32
locktime
            , transactionInputs :: [StoreInput]
transactionInputs = [StoreInput]
inputs
            , transactionOutputs :: [StoreOutput]
transactionOutputs = [StoreOutput]
outputs
            , transactionDeleted :: Bool
transactionDeleted = Bool
deleted
            , transactionTime :: Word64
transactionTime = Word64
time
            , transactionRBF :: Bool
transactionRBF = Bool
rbf
            , transactionWeight :: Word32
transactionWeight = Word32
weight
            , transactionSize :: Word32
transactionSize = Word32
size
            , transactionId :: TxHash
transactionId = TxHash
txid
            , transactionFees :: Word64
transactionFees = Word64
fees
            }

-- | Information about a connected peer.
data PeerInformation =
    PeerInformation
        { PeerInformation -> ByteString
peerUserAgent :: !ByteString
                        -- ^ user agent string
        , PeerInformation -> String
peerAddress   :: !String
                        -- ^ network address
        , PeerInformation -> Word32
peerVersion   :: !Word32
                        -- ^ version number
        , PeerInformation -> Word64
peerServices  :: !Word64
                        -- ^ services field
        , PeerInformation -> Bool
peerRelay     :: !Bool
                        -- ^ will relay transactions
        }
    deriving (Int -> PeerInformation -> ShowS
[PeerInformation] -> ShowS
PeerInformation -> String
(Int -> PeerInformation -> ShowS)
-> (PeerInformation -> String)
-> ([PeerInformation] -> ShowS)
-> Show PeerInformation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PeerInformation] -> ShowS
$cshowList :: [PeerInformation] -> ShowS
show :: PeerInformation -> String
$cshow :: PeerInformation -> String
showsPrec :: Int -> PeerInformation -> ShowS
$cshowsPrec :: Int -> PeerInformation -> ShowS
Show, PeerInformation -> PeerInformation -> Bool
(PeerInformation -> PeerInformation -> Bool)
-> (PeerInformation -> PeerInformation -> Bool)
-> Eq PeerInformation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PeerInformation -> PeerInformation -> Bool
$c/= :: PeerInformation -> PeerInformation -> Bool
== :: PeerInformation -> PeerInformation -> Bool
$c== :: PeerInformation -> PeerInformation -> Bool
Eq, Eq PeerInformation
Eq PeerInformation =>
(PeerInformation -> PeerInformation -> Ordering)
-> (PeerInformation -> PeerInformation -> Bool)
-> (PeerInformation -> PeerInformation -> Bool)
-> (PeerInformation -> PeerInformation -> Bool)
-> (PeerInformation -> PeerInformation -> Bool)
-> (PeerInformation -> PeerInformation -> PeerInformation)
-> (PeerInformation -> PeerInformation -> PeerInformation)
-> Ord PeerInformation
PeerInformation -> PeerInformation -> Bool
PeerInformation -> PeerInformation -> Ordering
PeerInformation -> PeerInformation -> PeerInformation
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 :: PeerInformation -> PeerInformation -> PeerInformation
$cmin :: PeerInformation -> PeerInformation -> PeerInformation
max :: PeerInformation -> PeerInformation -> PeerInformation
$cmax :: PeerInformation -> PeerInformation -> PeerInformation
>= :: PeerInformation -> PeerInformation -> Bool
$c>= :: PeerInformation -> PeerInformation -> Bool
> :: PeerInformation -> PeerInformation -> Bool
$c> :: PeerInformation -> PeerInformation -> Bool
<= :: PeerInformation -> PeerInformation -> Bool
$c<= :: PeerInformation -> PeerInformation -> Bool
< :: PeerInformation -> PeerInformation -> Bool
$c< :: PeerInformation -> PeerInformation -> Bool
compare :: PeerInformation -> PeerInformation -> Ordering
$ccompare :: PeerInformation -> PeerInformation -> Ordering
$cp1Ord :: Eq PeerInformation
Ord, (forall x. PeerInformation -> Rep PeerInformation x)
-> (forall x. Rep PeerInformation x -> PeerInformation)
-> Generic PeerInformation
forall x. Rep PeerInformation x -> PeerInformation
forall x. PeerInformation -> Rep PeerInformation x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PeerInformation x -> PeerInformation
$cfrom :: forall x. PeerInformation -> Rep PeerInformation x
Generic, PeerInformation -> ()
(PeerInformation -> ()) -> NFData PeerInformation
forall a. (a -> ()) -> NFData a
rnf :: PeerInformation -> ()
$crnf :: PeerInformation -> ()
NFData)

instance Serial PeerInformation where
    serialize :: PeerInformation -> m ()
serialize PeerInformation{..} = do
        ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putLengthBytes ByteString
peerUserAgent
        ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putLengthBytes (Text -> ByteString
TE.encodeUtf8 (String -> Text
T.pack String
peerAddress))
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
peerVersion
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
peerServices
        Bool -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Bool
peerRelay
    deserialize :: m PeerInformation
deserialize = do
        ByteString
peerUserAgent <- m ByteString
forall (m :: * -> *). MonadGet m => m ByteString
getLengthBytes
        String
peerAddress <- Text -> String
T.unpack (Text -> String) -> (ByteString -> Text) -> ByteString -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
TE.decodeUtf8 (ByteString -> String) -> m ByteString -> m String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m ByteString
forall (m :: * -> *). MonadGet m => m ByteString
getLengthBytes
        Word32
peerVersion <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        Word64
peerServices <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Bool
peerRelay <- m Bool
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        PeerInformation -> m PeerInformation
forall (m :: * -> *) a. Monad m => a -> m a
return $WPeerInformation :: ByteString -> String -> Word32 -> Word64 -> Bool -> PeerInformation
PeerInformation{..}

instance Serialize PeerInformation where
    put :: Putter PeerInformation
put = Putter PeerInformation
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get PeerInformation
get = Get PeerInformation
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary PeerInformation where
    put :: PeerInformation -> Put
put = PeerInformation -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get PeerInformation
get = Get PeerInformation
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance ToJSON PeerInformation where
    toJSON :: PeerInformation -> Value
toJSON p :: PeerInformation
p =
        [Pair] -> Value
A.object
        [ "useragent"   Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Text -> Value
String (ByteString -> Text
forall a b. ConvertibleStrings a b => a -> b
cs (PeerInformation -> ByteString
peerUserAgent PeerInformation
p))
        , "address"     Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= PeerInformation -> String
peerAddress PeerInformation
p
        , "version"     Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= PeerInformation -> Word32
peerVersion PeerInformation
p
        , "services"    Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.=
            Text -> Value
String (ByteString -> Text
encodeHex (Put -> ByteString
runPutS (Word64 -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (PeerInformation -> Word64
peerServices PeerInformation
p))))
        , "relay"       Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= PeerInformation -> Bool
peerRelay PeerInformation
p
        ]
    toEncoding :: PeerInformation -> Encoding
toEncoding p :: PeerInformation
p =
        Series -> Encoding
AE.pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
        "useragent" Text -> Encoding -> Series
`AE.pair` Text -> Encoding
forall a. Text -> Encoding' a
AE.text (ByteString -> Text
forall a b. ConvertibleStrings a b => a -> b
cs (PeerInformation -> ByteString
peerUserAgent PeerInformation
p)) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
        "address"   Text -> String -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= PeerInformation -> String
peerAddress PeerInformation
p Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
        "version"   Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= PeerInformation -> Word32
peerVersion PeerInformation
p Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
        "services"  Text -> Encoding -> Series
`AE.pair` Text -> Encoding
forall a. Text -> Encoding' a
AE.text
        (ByteString -> Text
encodeHex (Put -> ByteString
runPutS (Word64 -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (PeerInformation -> Word64
peerServices PeerInformation
p)))) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
        "relay"     Text -> Bool -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= PeerInformation -> Bool
peerRelay PeerInformation
p

instance FromJSON PeerInformation where
    parseJSON :: Value -> Parser PeerInformation
parseJSON =
        String
-> (Object -> Parser PeerInformation)
-> Value
-> Parser PeerInformation
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "peerinformation" ((Object -> Parser PeerInformation)
 -> Value -> Parser PeerInformation)
-> (Object -> Parser PeerInformation)
-> Value
-> Parser PeerInformation
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
        String useragent :: Text
useragent <- Object
o Object -> Text -> Parser Value
forall a. FromJSON a => Object -> Text -> Parser a
.: "useragent"
        String
address <- Object
o Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.: "address"
        Word32
version <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "version"
        Word64
services <-
            Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: "services" Parser Text -> (Text -> Parser ByteString) -> Parser ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Parser ByteString
jsonHex Parser ByteString -> (ByteString -> Parser Word64) -> Parser Word64
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \b :: ByteString
b ->
                case Get Word64 -> ByteString -> Either String Word64
forall a. Get a -> ByteString -> Either String a
runGetS Get Word64
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize ByteString
b of
                    Left e :: String
e  -> String -> Parser Word64
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser Word64) -> String -> Parser Word64
forall a b. (a -> b) -> a -> b
$ "Could not decode services: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
e
                    Right s :: Word64
s -> Word64 -> Parser Word64
forall (m :: * -> *) a. Monad m => a -> m a
return Word64
s
        Bool
relay <- Object
o Object -> Text -> Parser Bool
forall a. FromJSON a => Object -> Text -> Parser a
.: "relay"
        PeerInformation -> Parser PeerInformation
forall (m :: * -> *) a. Monad m => a -> m a
return
            $WPeerInformation :: ByteString -> String -> Word32 -> Word64 -> Bool -> PeerInformation
PeerInformation
                { peerUserAgent :: ByteString
peerUserAgent = Text -> ByteString
forall a b. ConvertibleStrings a b => a -> b
cs Text
useragent
                , peerAddress :: String
peerAddress = String
address
                , peerVersion :: Word32
peerVersion = Word32
version
                , peerServices :: Word64
peerServices = Word64
services
                , peerRelay :: Bool
peerRelay = Bool
relay
                }

-- | Address balances for an extended public key.
data XPubBal =
    XPubBal
        { XPubBal -> [Word32]
xPubBalPath :: ![KeyIndex]
        , XPubBal -> Balance
xPubBal     :: !Balance
        }
    deriving (Int -> XPubBal -> ShowS
[XPubBal] -> ShowS
XPubBal -> String
(Int -> XPubBal -> ShowS)
-> (XPubBal -> String) -> ([XPubBal] -> ShowS) -> Show XPubBal
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [XPubBal] -> ShowS
$cshowList :: [XPubBal] -> ShowS
show :: XPubBal -> String
$cshow :: XPubBal -> String
showsPrec :: Int -> XPubBal -> ShowS
$cshowsPrec :: Int -> XPubBal -> ShowS
Show, Eq XPubBal
Eq XPubBal =>
(XPubBal -> XPubBal -> Ordering)
-> (XPubBal -> XPubBal -> Bool)
-> (XPubBal -> XPubBal -> Bool)
-> (XPubBal -> XPubBal -> Bool)
-> (XPubBal -> XPubBal -> Bool)
-> (XPubBal -> XPubBal -> XPubBal)
-> (XPubBal -> XPubBal -> XPubBal)
-> Ord XPubBal
XPubBal -> XPubBal -> Bool
XPubBal -> XPubBal -> Ordering
XPubBal -> XPubBal -> XPubBal
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 :: XPubBal -> XPubBal -> XPubBal
$cmin :: XPubBal -> XPubBal -> XPubBal
max :: XPubBal -> XPubBal -> XPubBal
$cmax :: XPubBal -> XPubBal -> XPubBal
>= :: XPubBal -> XPubBal -> Bool
$c>= :: XPubBal -> XPubBal -> Bool
> :: XPubBal -> XPubBal -> Bool
$c> :: XPubBal -> XPubBal -> Bool
<= :: XPubBal -> XPubBal -> Bool
$c<= :: XPubBal -> XPubBal -> Bool
< :: XPubBal -> XPubBal -> Bool
$c< :: XPubBal -> XPubBal -> Bool
compare :: XPubBal -> XPubBal -> Ordering
$ccompare :: XPubBal -> XPubBal -> Ordering
$cp1Ord :: Eq XPubBal
Ord, XPubBal -> XPubBal -> Bool
(XPubBal -> XPubBal -> Bool)
-> (XPubBal -> XPubBal -> Bool) -> Eq XPubBal
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: XPubBal -> XPubBal -> Bool
$c/= :: XPubBal -> XPubBal -> Bool
== :: XPubBal -> XPubBal -> Bool
$c== :: XPubBal -> XPubBal -> Bool
Eq, (forall x. XPubBal -> Rep XPubBal x)
-> (forall x. Rep XPubBal x -> XPubBal) -> Generic XPubBal
forall x. Rep XPubBal x -> XPubBal
forall x. XPubBal -> Rep XPubBal x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep XPubBal x -> XPubBal
$cfrom :: forall x. XPubBal -> Rep XPubBal x
Generic, XPubBal -> ()
(XPubBal -> ()) -> NFData XPubBal
forall a. (a -> ()) -> NFData a
rnf :: XPubBal -> ()
$crnf :: XPubBal -> ()
NFData)

instance Serial XPubBal where
    serialize :: XPubBal -> m ()
serialize XPubBal{..} = do
        (Word32 -> m ()) -> [Word32] -> m ()
forall (m :: * -> *) a. MonadPut m => (a -> m ()) -> [a] -> m ()
putList Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be [Word32]
xPubBalPath
        Balance -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Balance
xPubBal
    deserialize :: m XPubBal
deserialize = do
        [Word32]
xPubBalPath <- m Word32 -> m [Word32]
forall (m :: * -> *) a. MonadGet m => m a -> m [a]
getList m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        Balance
xPubBal <- m Balance
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        XPubBal -> m XPubBal
forall (m :: * -> *) a. Monad m => a -> m a
return $WXPubBal :: [Word32] -> Balance -> XPubBal
XPubBal{..}

instance Serialize XPubBal where
    put :: Putter XPubBal
put = Putter XPubBal
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get XPubBal
get = Get XPubBal
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary XPubBal where
    put :: XPubBal -> Put
put = XPubBal -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get XPubBal
get = Get XPubBal
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

xPubBalToJSON :: Network -> XPubBal -> Value
xPubBalToJSON :: Network -> XPubBal -> Value
xPubBalToJSON net :: Network
net XPubBal {xPubBalPath :: XPubBal -> [Word32]
xPubBalPath = [Word32]
p, xPubBal :: XPubBal -> Balance
xPubBal = Balance
b} =
    [Pair] -> Value
A.object ["path" Text -> [Word32] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= [Word32]
p, "balance" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Network -> Balance -> Value
balanceToJSON Network
net Balance
b]

xPubBalToEncoding :: Network -> XPubBal -> Encoding
xPubBalToEncoding :: Network -> XPubBal -> Encoding
xPubBalToEncoding net :: Network
net XPubBal {xPubBalPath :: XPubBal -> [Word32]
xPubBalPath = [Word32]
p, xPubBal :: XPubBal -> Balance
xPubBal = Balance
b} =
    Series -> Encoding
AE.pairs ("path" Text -> [Word32] -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= [Word32]
p Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<> "balance" Text -> Encoding -> Series
`AE.pair` Network -> Balance -> Encoding
balanceToEncoding Network
net Balance
b)

xPubBalParseJSON :: Network -> Value -> Parser XPubBal
xPubBalParseJSON :: Network -> Value -> Parser XPubBal
xPubBalParseJSON net :: Network
net =
    String -> (Object -> Parser XPubBal) -> Value -> Parser XPubBal
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "xpubbal" ((Object -> Parser XPubBal) -> Value -> Parser XPubBal)
-> (Object -> Parser XPubBal) -> Value -> Parser XPubBal
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
        [Word32]
path <- Object
o Object -> Text -> Parser [Word32]
forall a. FromJSON a => Object -> Text -> Parser a
.: "path"
        Balance
balance <- Network -> Value -> Parser Balance
balanceParseJSON Network
net (Value -> Parser Balance) -> Parser Value -> Parser Balance
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Object
o Object -> Text -> Parser Value
forall a. FromJSON a => Object -> Text -> Parser a
.: "balance"
        XPubBal -> Parser XPubBal
forall (m :: * -> *) a. Monad m => a -> m a
return $WXPubBal :: [Word32] -> Balance -> XPubBal
XPubBal {xPubBalPath :: [Word32]
xPubBalPath = [Word32]
path, xPubBal :: Balance
xPubBal = Balance
balance}

-- | Unspent transaction for extended public key.
data XPubUnspent =
    XPubUnspent
        { XPubUnspent -> Unspent
xPubUnspent     :: !Unspent
        , XPubUnspent -> [Word32]
xPubUnspentPath :: ![KeyIndex]
        }
    deriving (Int -> XPubUnspent -> ShowS
[XPubUnspent] -> ShowS
XPubUnspent -> String
(Int -> XPubUnspent -> ShowS)
-> (XPubUnspent -> String)
-> ([XPubUnspent] -> ShowS)
-> Show XPubUnspent
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [XPubUnspent] -> ShowS
$cshowList :: [XPubUnspent] -> ShowS
show :: XPubUnspent -> String
$cshow :: XPubUnspent -> String
showsPrec :: Int -> XPubUnspent -> ShowS
$cshowsPrec :: Int -> XPubUnspent -> ShowS
Show, XPubUnspent -> XPubUnspent -> Bool
(XPubUnspent -> XPubUnspent -> Bool)
-> (XPubUnspent -> XPubUnspent -> Bool) -> Eq XPubUnspent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: XPubUnspent -> XPubUnspent -> Bool
$c/= :: XPubUnspent -> XPubUnspent -> Bool
== :: XPubUnspent -> XPubUnspent -> Bool
$c== :: XPubUnspent -> XPubUnspent -> Bool
Eq, Eq XPubUnspent
Eq XPubUnspent =>
(XPubUnspent -> XPubUnspent -> Ordering)
-> (XPubUnspent -> XPubUnspent -> Bool)
-> (XPubUnspent -> XPubUnspent -> Bool)
-> (XPubUnspent -> XPubUnspent -> Bool)
-> (XPubUnspent -> XPubUnspent -> Bool)
-> (XPubUnspent -> XPubUnspent -> XPubUnspent)
-> (XPubUnspent -> XPubUnspent -> XPubUnspent)
-> Ord XPubUnspent
XPubUnspent -> XPubUnspent -> Bool
XPubUnspent -> XPubUnspent -> Ordering
XPubUnspent -> XPubUnspent -> XPubUnspent
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 :: XPubUnspent -> XPubUnspent -> XPubUnspent
$cmin :: XPubUnspent -> XPubUnspent -> XPubUnspent
max :: XPubUnspent -> XPubUnspent -> XPubUnspent
$cmax :: XPubUnspent -> XPubUnspent -> XPubUnspent
>= :: XPubUnspent -> XPubUnspent -> Bool
$c>= :: XPubUnspent -> XPubUnspent -> Bool
> :: XPubUnspent -> XPubUnspent -> Bool
$c> :: XPubUnspent -> XPubUnspent -> Bool
<= :: XPubUnspent -> XPubUnspent -> Bool
$c<= :: XPubUnspent -> XPubUnspent -> Bool
< :: XPubUnspent -> XPubUnspent -> Bool
$c< :: XPubUnspent -> XPubUnspent -> Bool
compare :: XPubUnspent -> XPubUnspent -> Ordering
$ccompare :: XPubUnspent -> XPubUnspent -> Ordering
$cp1Ord :: Eq XPubUnspent
Ord, (forall x. XPubUnspent -> Rep XPubUnspent x)
-> (forall x. Rep XPubUnspent x -> XPubUnspent)
-> Generic XPubUnspent
forall x. Rep XPubUnspent x -> XPubUnspent
forall x. XPubUnspent -> Rep XPubUnspent x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep XPubUnspent x -> XPubUnspent
$cfrom :: forall x. XPubUnspent -> Rep XPubUnspent x
Generic, XPubUnspent -> ()
(XPubUnspent -> ()) -> NFData XPubUnspent
forall a. (a -> ()) -> NFData a
rnf :: XPubUnspent -> ()
$crnf :: XPubUnspent -> ()
NFData)

instance Serial XPubUnspent where
    serialize :: XPubUnspent -> m ()
serialize XPubUnspent{..} = do
        (Word32 -> m ()) -> [Word32] -> m ()
forall (m :: * -> *) a. MonadPut m => (a -> m ()) -> [a] -> m ()
putList Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be [Word32]
xPubUnspentPath
        Unspent -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Unspent
xPubUnspent
    deserialize :: m XPubUnspent
deserialize = do
        [Word32]
xPubUnspentPath <- m Word32 -> m [Word32]
forall (m :: * -> *) a. MonadGet m => m a -> m [a]
getList m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        Unspent
xPubUnspent <- m Unspent
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        XPubUnspent -> m XPubUnspent
forall (m :: * -> *) a. Monad m => a -> m a
return $WXPubUnspent :: Unspent -> [Word32] -> XPubUnspent
XPubUnspent{..}

instance Serialize XPubUnspent where
    put :: Putter XPubUnspent
put = Putter XPubUnspent
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get XPubUnspent
get = Get XPubUnspent
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary XPubUnspent where
    put :: XPubUnspent -> Put
put = XPubUnspent -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get XPubUnspent
get = Get XPubUnspent
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

xPubUnspentToJSON :: Network -> XPubUnspent -> Value
xPubUnspentToJSON :: Network -> XPubUnspent -> Value
xPubUnspentToJSON net :: Network
net XPubUnspent{xPubUnspentPath :: XPubUnspent -> [Word32]
xPubUnspentPath = [Word32]
p, xPubUnspent :: XPubUnspent -> Unspent
xPubUnspent = Unspent
u} =
    [Pair] -> Value
A.object ["unspent" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Network -> Unspent -> Value
unspentToJSON Network
net Unspent
u, "path" Text -> [Word32] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= [Word32]
p]

xPubUnspentToEncoding :: Network -> XPubUnspent -> Encoding
xPubUnspentToEncoding :: Network -> XPubUnspent -> Encoding
xPubUnspentToEncoding net :: Network
net XPubUnspent{xPubUnspentPath :: XPubUnspent -> [Word32]
xPubUnspentPath = [Word32]
p, xPubUnspent :: XPubUnspent -> Unspent
xPubUnspent = Unspent
u} =
    Series -> Encoding
AE.pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$ "unspent" Text -> Encoding -> Series
`AE.pair` Network -> Unspent -> Encoding
unspentToEncoding Network
net Unspent
u Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<> "path" Text -> [Word32] -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= [Word32]
p

xPubUnspentParseJSON :: Network -> Value -> Parser XPubUnspent
xPubUnspentParseJSON :: Network -> Value -> Parser XPubUnspent
xPubUnspentParseJSON net :: Network
net =
    String
-> (Object -> Parser XPubUnspent) -> Value -> Parser XPubUnspent
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "xpubunspent" ((Object -> Parser XPubUnspent) -> Value -> Parser XPubUnspent)
-> (Object -> Parser XPubUnspent) -> Value -> Parser XPubUnspent
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
        Unspent
u <- Object
o Object -> Text -> Parser Value
forall a. FromJSON a => Object -> Text -> Parser a
.: "unspent" Parser Value -> (Value -> Parser Unspent) -> Parser Unspent
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Network -> Value -> Parser Unspent
unspentParseJSON Network
net
        [Word32]
p <- Object
o Object -> Text -> Parser [Word32]
forall a. FromJSON a => Object -> Text -> Parser a
.: "path"
        XPubUnspent -> Parser XPubUnspent
forall (m :: * -> *) a. Monad m => a -> m a
return $WXPubUnspent :: Unspent -> [Word32] -> XPubUnspent
XPubUnspent {xPubUnspentPath :: [Word32]
xPubUnspentPath = [Word32]
p, xPubUnspent :: Unspent
xPubUnspent = Unspent
u}

data XPubSummary =
    XPubSummary
        { XPubSummary -> Word64
xPubSummaryConfirmed :: !Word64
        , XPubSummary -> Word64
xPubSummaryZero      :: !Word64
        , XPubSummary -> Word64
xPubSummaryReceived  :: !Word64
        , XPubSummary -> Word64
xPubUnspentCount     :: !Word64
        , XPubSummary -> Word32
xPubExternalIndex    :: !Word32
        , XPubSummary -> Word32
xPubChangeIndex      :: !Word32
        }
    deriving (XPubSummary -> XPubSummary -> Bool
(XPubSummary -> XPubSummary -> Bool)
-> (XPubSummary -> XPubSummary -> Bool) -> Eq XPubSummary
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: XPubSummary -> XPubSummary -> Bool
$c/= :: XPubSummary -> XPubSummary -> Bool
== :: XPubSummary -> XPubSummary -> Bool
$c== :: XPubSummary -> XPubSummary -> Bool
Eq, Int -> XPubSummary -> ShowS
[XPubSummary] -> ShowS
XPubSummary -> String
(Int -> XPubSummary -> ShowS)
-> (XPubSummary -> String)
-> ([XPubSummary] -> ShowS)
-> Show XPubSummary
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [XPubSummary] -> ShowS
$cshowList :: [XPubSummary] -> ShowS
show :: XPubSummary -> String
$cshow :: XPubSummary -> String
showsPrec :: Int -> XPubSummary -> ShowS
$cshowsPrec :: Int -> XPubSummary -> ShowS
Show, (forall x. XPubSummary -> Rep XPubSummary x)
-> (forall x. Rep XPubSummary x -> XPubSummary)
-> Generic XPubSummary
forall x. Rep XPubSummary x -> XPubSummary
forall x. XPubSummary -> Rep XPubSummary x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep XPubSummary x -> XPubSummary
$cfrom :: forall x. XPubSummary -> Rep XPubSummary x
Generic, XPubSummary -> ()
(XPubSummary -> ()) -> NFData XPubSummary
forall a. (a -> ()) -> NFData a
rnf :: XPubSummary -> ()
$crnf :: XPubSummary -> ()
NFData)

instance Serial XPubSummary where
    serialize :: XPubSummary -> m ()
serialize XPubSummary{..} = do
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
xPubSummaryConfirmed
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
xPubSummaryZero
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
xPubSummaryReceived
        Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be Word64
xPubUnspentCount
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
xPubExternalIndex
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
xPubChangeIndex
    deserialize :: m XPubSummary
deserialize = do
        Word64
xPubSummaryConfirmed <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Word64
xPubSummaryZero      <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Word64
xPubSummaryReceived  <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Word64
xPubUnspentCount     <- m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be
        Word32
xPubExternalIndex    <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        Word32
xPubChangeIndex      <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        XPubSummary -> m XPubSummary
forall (m :: * -> *) a. Monad m => a -> m a
return $WXPubSummary :: Word64
-> Word64 -> Word64 -> Word64 -> Word32 -> Word32 -> XPubSummary
XPubSummary{..}

instance Binary XPubSummary where
    put :: XPubSummary -> Put
put = XPubSummary -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get XPubSummary
get = Get XPubSummary
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Serialize XPubSummary where
    put :: Putter XPubSummary
put = Putter XPubSummary
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get XPubSummary
get = Get XPubSummary
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance ToJSON XPubSummary where
    toJSON :: XPubSummary -> Value
toJSON
        XPubSummary
        {
            xPubSummaryConfirmed :: XPubSummary -> Word64
xPubSummaryConfirmed = Word64
c,
            xPubSummaryZero :: XPubSummary -> Word64
xPubSummaryZero = Word64
z,
            xPubSummaryReceived :: XPubSummary -> Word64
xPubSummaryReceived = Word64
r,
            xPubUnspentCount :: XPubSummary -> Word64
xPubUnspentCount = Word64
u,
            xPubExternalIndex :: XPubSummary -> Word32
xPubExternalIndex = Word32
ext,
            xPubChangeIndex :: XPubSummary -> Word32
xPubChangeIndex = Word32
ch
        } =
        [Pair] -> Value
A.object
        [ "balance" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.=
            [Pair] -> Value
A.object
            [ "confirmed" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
c
            , "unconfirmed" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
z
            , "received" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
r
            , "utxo" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
u
            ]
        , "indices" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.=
            [Pair] -> Value
A.object
            [ "change" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
ch
            , "external" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
ext
            ]
        ]
    toEncoding :: XPubSummary -> Encoding
toEncoding
        XPubSummary
        {
            xPubSummaryConfirmed :: XPubSummary -> Word64
xPubSummaryConfirmed = Word64
c,
            xPubSummaryZero :: XPubSummary -> Word64
xPubSummaryZero = Word64
z,
            xPubSummaryReceived :: XPubSummary -> Word64
xPubSummaryReceived = Word64
r,
            xPubUnspentCount :: XPubSummary -> Word64
xPubUnspentCount = Word64
u,
            xPubExternalIndex :: XPubSummary -> Word32
xPubExternalIndex = Word32
ext,
            xPubChangeIndex :: XPubSummary -> Word32
xPubChangeIndex = Word32
ch
        } =
        Series -> Encoding
AE.pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$
            "balance" Text -> Encoding -> Series
`AE.pair` Series -> Encoding
AE.pairs
            (
                "confirmed" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
c Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
                "unconfirmed" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
z Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
                "received" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
r Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
                "utxo" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
u
            ) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
            "indices" Text -> Encoding -> Series
`AE.pair` Series -> Encoding
AE.pairs
            (
                "change" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
ch Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<>
                "external" Text -> Word32 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
ext
            )

instance FromJSON XPubSummary where
    parseJSON :: Value -> Parser XPubSummary
parseJSON =
        String
-> (Object -> Parser XPubSummary) -> Value -> Parser XPubSummary
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "xpubsummary" ((Object -> Parser XPubSummary) -> Value -> Parser XPubSummary)
-> (Object -> Parser XPubSummary) -> Value -> Parser XPubSummary
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
            Object
b <- Object
o Object -> Text -> Parser Object
forall a. FromJSON a => Object -> Text -> Parser a
.: "balance"
            Object
i <- Object
o Object -> Text -> Parser Object
forall a. FromJSON a => Object -> Text -> Parser a
.: "indices"
            Word64
conf <- Object
b Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "confirmed"
            Word64
unconfirmed <- Object
b Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "unconfirmed"
            Word64
received <- Object
b Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "received"
            Word64
utxo <- Object
b Object -> Text -> Parser Word64
forall a. FromJSON a => Object -> Text -> Parser a
.: "utxo"
            Word32
change <- Object
i Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "change"
            Word32
external <- Object
i Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "external"
            XPubSummary -> Parser XPubSummary
forall (m :: * -> *) a. Monad m => a -> m a
return
                $WXPubSummary :: Word64
-> Word64 -> Word64 -> Word64 -> Word32 -> Word32 -> XPubSummary
XPubSummary
                    { xPubSummaryConfirmed :: Word64
xPubSummaryConfirmed = Word64
conf
                    , xPubSummaryZero :: Word64
xPubSummaryZero = Word64
unconfirmed
                    , xPubSummaryReceived :: Word64
xPubSummaryReceived = Word64
received
                    , xPubUnspentCount :: Word64
xPubUnspentCount = Word64
utxo
                    , xPubExternalIndex :: Word32
xPubExternalIndex = Word32
external
                    , xPubChangeIndex :: Word32
xPubChangeIndex = Word32
change
                    }

class Healthy a where
    isOK :: a -> Bool

data BlockHealth =
    BlockHealth
        { BlockHealth -> Word32
blockHealthHeaders :: !BlockHeight
        , BlockHealth -> Word32
blockHealthBlocks  :: !BlockHeight
        , BlockHealth -> Int32
blockHealthMaxDiff :: !Int32
        }
    deriving (Int -> BlockHealth -> ShowS
[BlockHealth] -> ShowS
BlockHealth -> String
(Int -> BlockHealth -> ShowS)
-> (BlockHealth -> String)
-> ([BlockHealth] -> ShowS)
-> Show BlockHealth
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BlockHealth] -> ShowS
$cshowList :: [BlockHealth] -> ShowS
show :: BlockHealth -> String
$cshow :: BlockHealth -> String
showsPrec :: Int -> BlockHealth -> ShowS
$cshowsPrec :: Int -> BlockHealth -> ShowS
Show, BlockHealth -> BlockHealth -> Bool
(BlockHealth -> BlockHealth -> Bool)
-> (BlockHealth -> BlockHealth -> Bool) -> Eq BlockHealth
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BlockHealth -> BlockHealth -> Bool
$c/= :: BlockHealth -> BlockHealth -> Bool
== :: BlockHealth -> BlockHealth -> Bool
$c== :: BlockHealth -> BlockHealth -> Bool
Eq, (forall x. BlockHealth -> Rep BlockHealth x)
-> (forall x. Rep BlockHealth x -> BlockHealth)
-> Generic BlockHealth
forall x. Rep BlockHealth x -> BlockHealth
forall x. BlockHealth -> Rep BlockHealth x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BlockHealth x -> BlockHealth
$cfrom :: forall x. BlockHealth -> Rep BlockHealth x
Generic, BlockHealth -> ()
(BlockHealth -> ()) -> NFData BlockHealth
forall a. (a -> ()) -> NFData a
rnf :: BlockHealth -> ()
$crnf :: BlockHealth -> ()
NFData)

instance Serial BlockHealth where
    serialize :: BlockHealth -> m ()
serialize h :: BlockHealth
h@BlockHealth{..} = do
        Bool -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (BlockHealth -> Bool
forall a. Healthy a => a -> Bool
isOK BlockHealth
h)
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
blockHealthHeaders
        Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32be Word32
blockHealthBlocks
        Int32 -> m ()
forall (m :: * -> *). MonadPut m => Int32 -> m ()
putInt32be Int32
blockHealthMaxDiff
    deserialize :: m BlockHealth
deserialize = do
        Bool
k                  <- m Bool
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Word32
blockHealthHeaders <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        Word32
blockHealthBlocks  <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32be
        Int32
blockHealthMaxDiff <- m Int32
forall (m :: * -> *). MonadGet m => m Int32
getInt32be
        let h :: BlockHealth
h = $WBlockHealth :: Word32 -> Word32 -> Int32 -> BlockHealth
BlockHealth{..}
        Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Bool
k Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== BlockHealth -> Bool
forall a. Healthy a => a -> Bool
isOK BlockHealth
h) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ String -> m ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "Inconsistent health check"
        BlockHealth -> m BlockHealth
forall (m :: * -> *) a. Monad m => a -> m a
return BlockHealth
h

instance Serialize BlockHealth where
    put :: Putter BlockHealth
put = Putter BlockHealth
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get BlockHealth
get = Get BlockHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary BlockHealth where
    put :: BlockHealth -> Put
put = BlockHealth -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get BlockHealth
get = Get BlockHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Healthy BlockHealth where
    isOK :: BlockHealth -> Bool
isOK BlockHealth{..} =
        Int32
h Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
- Int32
b Int32 -> Int32 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int32
blockHealthMaxDiff
      where
        h :: Int32
h = Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
blockHealthHeaders
        b :: Int32
b = Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
blockHealthBlocks

instance ToJSON BlockHealth where
    toJSON :: BlockHealth -> Value
toJSON h :: BlockHealth
h@BlockHealth{..} =
        [Pair] -> Value
A.object
            [ "headers"  Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
blockHealthHeaders
            , "blocks"   Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
blockHealthBlocks
            , "diff"     Text -> Integer -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Integer
diff
            , "max"      Text -> Int32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int32
blockHealthMaxDiff
            , "ok"       Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHealth -> Bool
forall a. Healthy a => a -> Bool
isOK BlockHealth
h
            ]
      where
        diff :: Integer
diff = Word32 -> Integer
forall a. Integral a => a -> Integer
toInteger Word32
blockHealthHeaders Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Word32 -> Integer
forall a. Integral a => a -> Integer
toInteger Word32
blockHealthBlocks

instance FromJSON BlockHealth where
    parseJSON :: Value -> Parser BlockHealth
parseJSON =
        String
-> (Object -> Parser BlockHealth) -> Value -> Parser BlockHealth
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "BlockHealth" ((Object -> Parser BlockHealth) -> Value -> Parser BlockHealth)
-> (Object -> Parser BlockHealth) -> Value -> Parser BlockHealth
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
            Word32
blockHealthHeaders  <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "headers"
            Word32
blockHealthBlocks   <- Object
o Object -> Text -> Parser Word32
forall a. FromJSON a => Object -> Text -> Parser a
.: "blocks"
            Int32
blockHealthMaxDiff  <- Object
o Object -> Text -> Parser Int32
forall a. FromJSON a => Object -> Text -> Parser a
.: "max"
            BlockHealth -> Parser BlockHealth
forall (m :: * -> *) a. Monad m => a -> m a
return $WBlockHealth :: Word32 -> Word32 -> Int32 -> BlockHealth
BlockHealth {..}

data TimeHealth =
    TimeHealth
        { TimeHealth -> Int64
timeHealthAge :: !Int64
        , TimeHealth -> Int64
timeHealthMax :: !Int64
        }
    deriving (Int -> TimeHealth -> ShowS
[TimeHealth] -> ShowS
TimeHealth -> String
(Int -> TimeHealth -> ShowS)
-> (TimeHealth -> String)
-> ([TimeHealth] -> ShowS)
-> Show TimeHealth
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TimeHealth] -> ShowS
$cshowList :: [TimeHealth] -> ShowS
show :: TimeHealth -> String
$cshow :: TimeHealth -> String
showsPrec :: Int -> TimeHealth -> ShowS
$cshowsPrec :: Int -> TimeHealth -> ShowS
Show, TimeHealth -> TimeHealth -> Bool
(TimeHealth -> TimeHealth -> Bool)
-> (TimeHealth -> TimeHealth -> Bool) -> Eq TimeHealth
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TimeHealth -> TimeHealth -> Bool
$c/= :: TimeHealth -> TimeHealth -> Bool
== :: TimeHealth -> TimeHealth -> Bool
$c== :: TimeHealth -> TimeHealth -> Bool
Eq, (forall x. TimeHealth -> Rep TimeHealth x)
-> (forall x. Rep TimeHealth x -> TimeHealth) -> Generic TimeHealth
forall x. Rep TimeHealth x -> TimeHealth
forall x. TimeHealth -> Rep TimeHealth x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TimeHealth x -> TimeHealth
$cfrom :: forall x. TimeHealth -> Rep TimeHealth x
Generic, TimeHealth -> ()
(TimeHealth -> ()) -> NFData TimeHealth
forall a. (a -> ()) -> NFData a
rnf :: TimeHealth -> ()
$crnf :: TimeHealth -> ()
NFData)

instance Serial TimeHealth where
    serialize :: TimeHealth -> m ()
serialize h :: TimeHealth
h@TimeHealth{..} = do
        Bool -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (TimeHealth -> Bool
forall a. Healthy a => a -> Bool
isOK TimeHealth
h)
        Int64 -> m ()
forall (m :: * -> *). MonadPut m => Int64 -> m ()
putInt64be Int64
timeHealthAge
        Int64 -> m ()
forall (m :: * -> *). MonadPut m => Int64 -> m ()
putInt64be Int64
timeHealthMax
    deserialize :: m TimeHealth
deserialize = do
        Bool
k             <- m Bool
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Int64
timeHealthAge <- m Int64
forall (m :: * -> *). MonadGet m => m Int64
getInt64be
        Int64
timeHealthMax <- m Int64
forall (m :: * -> *). MonadGet m => m Int64
getInt64be
        let t :: TimeHealth
t = $WTimeHealth :: Int64 -> Int64 -> TimeHealth
TimeHealth{..}
        Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Bool
k Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== TimeHealth -> Bool
forall a. Healthy a => a -> Bool
isOK TimeHealth
t) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ String -> m ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "Inconsistent health check"
        TimeHealth -> m TimeHealth
forall (m :: * -> *) a. Monad m => a -> m a
return TimeHealth
t

instance Binary TimeHealth where
    put :: TimeHealth -> Put
put = TimeHealth -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get TimeHealth
get = Get TimeHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Serialize TimeHealth where
    put :: Putter TimeHealth
put = Putter TimeHealth
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get TimeHealth
get = Get TimeHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Healthy TimeHealth where
    isOK :: TimeHealth -> Bool
isOK TimeHealth{..} =
        Int64
timeHealthAge Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
timeHealthMax

instance ToJSON TimeHealth where
    toJSON :: TimeHealth -> Value
toJSON h :: TimeHealth
h@TimeHealth{..} =
        [Pair] -> Value
A.object
            [ "age"  Text -> Int64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int64
timeHealthAge
            , "max"  Text -> Int64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int64
timeHealthMax
            , "ok"   Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TimeHealth -> Bool
forall a. Healthy a => a -> Bool
isOK TimeHealth
h
            ]

instance FromJSON TimeHealth where
    parseJSON :: Value -> Parser TimeHealth
parseJSON =
        String
-> (Object -> Parser TimeHealth) -> Value -> Parser TimeHealth
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "TimeHealth" ((Object -> Parser TimeHealth) -> Value -> Parser TimeHealth)
-> (Object -> Parser TimeHealth) -> Value -> Parser TimeHealth
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
            Int64
timeHealthAge <- Object
o Object -> Text -> Parser Int64
forall a. FromJSON a => Object -> Text -> Parser a
.: "age"
            Int64
timeHealthMax <- Object
o Object -> Text -> Parser Int64
forall a. FromJSON a => Object -> Text -> Parser a
.: "max"
            TimeHealth -> Parser TimeHealth
forall (m :: * -> *) a. Monad m => a -> m a
return $WTimeHealth :: Int64 -> Int64 -> TimeHealth
TimeHealth {..}

data CountHealth =
    CountHealth
        { CountHealth -> Int64
countHealthNum :: !Int64
        , CountHealth -> Int64
countHealthMin :: !Int64
        }
    deriving (Int -> CountHealth -> ShowS
[CountHealth] -> ShowS
CountHealth -> String
(Int -> CountHealth -> ShowS)
-> (CountHealth -> String)
-> ([CountHealth] -> ShowS)
-> Show CountHealth
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CountHealth] -> ShowS
$cshowList :: [CountHealth] -> ShowS
show :: CountHealth -> String
$cshow :: CountHealth -> String
showsPrec :: Int -> CountHealth -> ShowS
$cshowsPrec :: Int -> CountHealth -> ShowS
Show, CountHealth -> CountHealth -> Bool
(CountHealth -> CountHealth -> Bool)
-> (CountHealth -> CountHealth -> Bool) -> Eq CountHealth
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CountHealth -> CountHealth -> Bool
$c/= :: CountHealth -> CountHealth -> Bool
== :: CountHealth -> CountHealth -> Bool
$c== :: CountHealth -> CountHealth -> Bool
Eq, (forall x. CountHealth -> Rep CountHealth x)
-> (forall x. Rep CountHealth x -> CountHealth)
-> Generic CountHealth
forall x. Rep CountHealth x -> CountHealth
forall x. CountHealth -> Rep CountHealth x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CountHealth x -> CountHealth
$cfrom :: forall x. CountHealth -> Rep CountHealth x
Generic, CountHealth -> ()
(CountHealth -> ()) -> NFData CountHealth
forall a. (a -> ()) -> NFData a
rnf :: CountHealth -> ()
$crnf :: CountHealth -> ()
NFData)

instance Serial CountHealth where
    serialize :: CountHealth -> m ()
serialize h :: CountHealth
h@CountHealth{..} = do
        Bool -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (CountHealth -> Bool
forall a. Healthy a => a -> Bool
isOK CountHealth
h)
        Int64 -> m ()
forall (m :: * -> *). MonadPut m => Int64 -> m ()
putInt64be Int64
countHealthNum
        Int64 -> m ()
forall (m :: * -> *). MonadPut m => Int64 -> m ()
putInt64be Int64
countHealthMin
    deserialize :: m CountHealth
deserialize = do
        Bool
k              <- m Bool
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Int64
countHealthNum <- m Int64
forall (m :: * -> *). MonadGet m => m Int64
getInt64be
        Int64
countHealthMin <- m Int64
forall (m :: * -> *). MonadGet m => m Int64
getInt64be
        let c :: CountHealth
c = $WCountHealth :: Int64 -> Int64 -> CountHealth
CountHealth{..}
        Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Bool
k Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== CountHealth -> Bool
forall a. Healthy a => a -> Bool
isOK CountHealth
c) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ String -> m ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "Inconsistent health check"
        CountHealth -> m CountHealth
forall (m :: * -> *) a. Monad m => a -> m a
return CountHealth
c

instance Serialize CountHealth where
    put :: Putter CountHealth
put = Putter CountHealth
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get CountHealth
get = Get CountHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Binary CountHealth where
    put :: CountHealth -> Put
put = CountHealth -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get CountHealth
get = Get CountHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Healthy CountHealth where
    isOK :: CountHealth -> Bool
isOK CountHealth {..} =
        Int64
countHealthMin Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
countHealthNum

instance ToJSON CountHealth where
    toJSON :: CountHealth -> Value
toJSON h :: CountHealth
h@CountHealth {..} =
        [Pair] -> Value
A.object
            [ "count"  Text -> Int64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int64
countHealthNum
            , "min"    Text -> Int64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int64
countHealthMin
            , "ok"     Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= CountHealth -> Bool
forall a. Healthy a => a -> Bool
isOK CountHealth
h
            ]

instance FromJSON CountHealth where
    parseJSON :: Value -> Parser CountHealth
parseJSON =
        String
-> (Object -> Parser CountHealth) -> Value -> Parser CountHealth
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "CountHealth" ((Object -> Parser CountHealth) -> Value -> Parser CountHealth)
-> (Object -> Parser CountHealth) -> Value -> Parser CountHealth
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
            Int64
countHealthNum <- Object
o Object -> Text -> Parser Int64
forall a. FromJSON a => Object -> Text -> Parser a
.: "count"
            Int64
countHealthMin <- Object
o Object -> Text -> Parser Int64
forall a. FromJSON a => Object -> Text -> Parser a
.: "min"
            CountHealth -> Parser CountHealth
forall (m :: * -> *) a. Monad m => a -> m a
return $WCountHealth :: Int64 -> Int64 -> CountHealth
CountHealth {..}

data MaxHealth =
    MaxHealth
        { MaxHealth -> Int64
maxHealthNum :: !Int64
        , MaxHealth -> Int64
maxHealthMax :: !Int64
        }
    deriving (Int -> MaxHealth -> ShowS
[MaxHealth] -> ShowS
MaxHealth -> String
(Int -> MaxHealth -> ShowS)
-> (MaxHealth -> String)
-> ([MaxHealth] -> ShowS)
-> Show MaxHealth
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MaxHealth] -> ShowS
$cshowList :: [MaxHealth] -> ShowS
show :: MaxHealth -> String
$cshow :: MaxHealth -> String
showsPrec :: Int -> MaxHealth -> ShowS
$cshowsPrec :: Int -> MaxHealth -> ShowS
Show, MaxHealth -> MaxHealth -> Bool
(MaxHealth -> MaxHealth -> Bool)
-> (MaxHealth -> MaxHealth -> Bool) -> Eq MaxHealth
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MaxHealth -> MaxHealth -> Bool
$c/= :: MaxHealth -> MaxHealth -> Bool
== :: MaxHealth -> MaxHealth -> Bool
$c== :: MaxHealth -> MaxHealth -> Bool
Eq, (forall x. MaxHealth -> Rep MaxHealth x)
-> (forall x. Rep MaxHealth x -> MaxHealth) -> Generic MaxHealth
forall x. Rep MaxHealth x -> MaxHealth
forall x. MaxHealth -> Rep MaxHealth x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep MaxHealth x -> MaxHealth
$cfrom :: forall x. MaxHealth -> Rep MaxHealth x
Generic, MaxHealth -> ()
(MaxHealth -> ()) -> NFData MaxHealth
forall a. (a -> ()) -> NFData a
rnf :: MaxHealth -> ()
$crnf :: MaxHealth -> ()
NFData)

instance Serial MaxHealth where
    serialize :: MaxHealth -> m ()
serialize h :: MaxHealth
h@MaxHealth {..} = do
        Bool -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (Bool -> m ()) -> Bool -> m ()
forall a b. (a -> b) -> a -> b
$ MaxHealth -> Bool
forall a. Healthy a => a -> Bool
isOK MaxHealth
h
        Int64 -> m ()
forall (m :: * -> *). MonadPut m => Int64 -> m ()
putInt64be Int64
maxHealthNum
        Int64 -> m ()
forall (m :: * -> *). MonadPut m => Int64 -> m ()
putInt64be Int64
maxHealthMax
    deserialize :: m MaxHealth
deserialize = do
        Bool
k            <- m Bool
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        Int64
maxHealthNum <- m Int64
forall (m :: * -> *). MonadGet m => m Int64
getInt64be
        Int64
maxHealthMax <- m Int64
forall (m :: * -> *). MonadGet m => m Int64
getInt64be
        let h :: MaxHealth
h = $WMaxHealth :: Int64 -> Int64 -> MaxHealth
MaxHealth{..}
        Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Bool
k Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== MaxHealth -> Bool
forall a. Healthy a => a -> Bool
isOK MaxHealth
h) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ String -> m ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "Inconsistent health check"
        MaxHealth -> m MaxHealth
forall (m :: * -> *) a. Monad m => a -> m a
return MaxHealth
h

instance Binary MaxHealth where
    put :: MaxHealth -> Put
put = MaxHealth -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get MaxHealth
get = Get MaxHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Serialize MaxHealth where
    put :: Putter MaxHealth
put = Putter MaxHealth
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get MaxHealth
get = Get MaxHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Healthy MaxHealth where
    isOK :: MaxHealth -> Bool
isOK MaxHealth {..} = Int64
maxHealthNum Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
maxHealthMax

instance ToJSON MaxHealth where
    toJSON :: MaxHealth -> Value
toJSON h :: MaxHealth
h@MaxHealth {..} =
        [Pair] -> Value
A.object
            [ "count" Text -> Int64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int64
maxHealthNum
            , "max"   Text -> Int64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int64
maxHealthMax
            , "ok"    Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= MaxHealth -> Bool
forall a. Healthy a => a -> Bool
isOK MaxHealth
h
            ]

instance FromJSON MaxHealth where
    parseJSON :: Value -> Parser MaxHealth
parseJSON =
        String -> (Object -> Parser MaxHealth) -> Value -> Parser MaxHealth
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject "MaxHealth" ((Object -> Parser MaxHealth) -> Value -> Parser MaxHealth)
-> (Object -> Parser MaxHealth) -> Value -> Parser MaxHealth
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
            Int64
maxHealthNum <- Object
o Object -> Text -> Parser Int64
forall a. FromJSON a => Object -> Text -> Parser a
.: "count"
            Int64
maxHealthMax <- Object
o Object -> Text -> Parser Int64
forall a. FromJSON a => Object -> Text -> Parser a
.: "max"
            MaxHealth -> Parser MaxHealth
forall (m :: * -> *) a. Monad m => a -> m a
return $WMaxHealth :: Int64 -> Int64 -> MaxHealth
MaxHealth {..}

data HealthCheck =
    HealthCheck
        { HealthCheck -> BlockHealth
healthBlocks     :: !BlockHealth
        , HealthCheck -> TimeHealth
healthLastBlock  :: !TimeHealth
        , HealthCheck -> TimeHealth
healthLastTx     :: !TimeHealth
        , HealthCheck -> MaxHealth
healthPendingTxs :: !MaxHealth
        , HealthCheck -> CountHealth
healthPeers      :: !CountHealth
        , HealthCheck -> String
healthNetwork    :: !String
        , HealthCheck -> String
healthVersion    :: !String
        }
    deriving (Int -> HealthCheck -> ShowS
[HealthCheck] -> ShowS
HealthCheck -> String
(Int -> HealthCheck -> ShowS)
-> (HealthCheck -> String)
-> ([HealthCheck] -> ShowS)
-> Show HealthCheck
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HealthCheck] -> ShowS
$cshowList :: [HealthCheck] -> ShowS
show :: HealthCheck -> String
$cshow :: HealthCheck -> String
showsPrec :: Int -> HealthCheck -> ShowS
$cshowsPrec :: Int -> HealthCheck -> ShowS
Show, HealthCheck -> HealthCheck -> Bool
(HealthCheck -> HealthCheck -> Bool)
-> (HealthCheck -> HealthCheck -> Bool) -> Eq HealthCheck
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HealthCheck -> HealthCheck -> Bool
$c/= :: HealthCheck -> HealthCheck -> Bool
== :: HealthCheck -> HealthCheck -> Bool
$c== :: HealthCheck -> HealthCheck -> Bool
Eq, (forall x. HealthCheck -> Rep HealthCheck x)
-> (forall x. Rep HealthCheck x -> HealthCheck)
-> Generic HealthCheck
forall x. Rep HealthCheck x -> HealthCheck
forall x. HealthCheck -> Rep HealthCheck x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep HealthCheck x -> HealthCheck
$cfrom :: forall x. HealthCheck -> Rep HealthCheck x
Generic, HealthCheck -> ()
(HealthCheck -> ()) -> NFData HealthCheck
forall a. (a -> ()) -> NFData a
rnf :: HealthCheck -> ()
$crnf :: HealthCheck -> ()
NFData)

instance Serial HealthCheck where
    serialize :: HealthCheck -> m ()
serialize h :: HealthCheck
h@HealthCheck {..} = do
        Bool -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (HealthCheck -> Bool
forall a. Healthy a => a -> Bool
isOK HealthCheck
h)
        BlockHealth -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize BlockHealth
healthBlocks
        TimeHealth -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize TimeHealth
healthLastBlock
        TimeHealth -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize TimeHealth
healthLastTx
        MaxHealth -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize MaxHealth
healthPendingTxs
        CountHealth -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize CountHealth
healthPeers
        ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putLengthBytes ((Text -> ByteString
TE.encodeUtf8 (Text -> ByteString) -> (String -> Text) -> String -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack) String
healthNetwork)
        ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putLengthBytes ((Text -> ByteString
TE.encodeUtf8 (Text -> ByteString) -> (String -> Text) -> String -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack) String
healthVersion)
    deserialize :: m HealthCheck
deserialize = do
        Bool
k                   <- m Bool
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        BlockHealth
healthBlocks        <- m BlockHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        TimeHealth
healthLastBlock     <- m TimeHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        TimeHealth
healthLastTx        <- m TimeHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        MaxHealth
healthPendingTxs    <- m MaxHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        CountHealth
healthPeers         <- m CountHealth
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
        String
healthNetwork       <- Text -> String
T.unpack (Text -> String) -> (ByteString -> Text) -> ByteString -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
TE.decodeUtf8 (ByteString -> String) -> m ByteString -> m String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m ByteString
forall (m :: * -> *). MonadGet m => m ByteString
getLengthBytes
        String
healthVersion       <- Text -> String
T.unpack (Text -> String) -> (ByteString -> Text) -> ByteString -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
TE.decodeUtf8 (ByteString -> String) -> m ByteString -> m String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m ByteString
forall (m :: * -> *). MonadGet m => m ByteString
getLengthBytes
        let h :: HealthCheck
h = $WHealthCheck :: BlockHealth
-> TimeHealth
-> TimeHealth
-> MaxHealth
-> CountHealth
-> String
-> String
-> HealthCheck
HealthCheck {..}
        Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Bool
k Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== HealthCheck -> Bool
forall a. Healthy a => a -> Bool
isOK HealthCheck
h) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ String -> m ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "Inconsistent health check"
        HealthCheck -> m HealthCheck
forall (m :: * -> *) a. Monad m => a -> m a
return HealthCheck
h

instance Binary HealthCheck where
    put :: HealthCheck -> Put
put = HealthCheck -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get HealthCheck
get = Get HealthCheck
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Serialize HealthCheck where
    put :: Putter HealthCheck
put = Putter HealthCheck
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
    get :: Get HealthCheck
get = Get HealthCheck
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize

instance Healthy HealthCheck where
    isOK :: HealthCheck -> Bool
isOK HealthCheck {..} =
        BlockHealth -> Bool
forall a. Healthy a => a -> Bool
isOK BlockHealth
healthBlocks Bool -> Bool -> Bool
&&
        TimeHealth -> Bool
forall a. Healthy a => a -> Bool
isOK TimeHealth
healthLastBlock Bool -> Bool -> Bool
&&
        TimeHealth -> Bool
forall a. Healthy a => a -> Bool
isOK TimeHealth
healthLastTx Bool -> Bool -> Bool
&&
        MaxHealth -> Bool
forall a. Healthy a => a -> Bool
isOK MaxHealth
healthPendingTxs Bool -> Bool -> Bool
&&
        CountHealth -> Bool
forall a. Healthy a => a -> Bool
isOK CountHealth
healthPeers

instance ToJSON HealthCheck where
    toJSON :: HealthCheck -> Value
toJSON h :: HealthCheck
h@HealthCheck {..} =
        [Pair] -> Value
A.object
            [ "blocks"      Text -> BlockHealth -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockHealth
healthBlocks
            , "last-block"  Text -> TimeHealth -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TimeHealth
healthLastBlock
            , "last-tx"     Text -> TimeHealth -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TimeHealth
healthLastTx
            , "pending-txs" Text -> MaxHealth -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= MaxHealth
healthPendingTxs
            , "peers"       Text -> CountHealth -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= CountHealth
healthPeers
            , "net"         Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= String
healthNetwork
            , "version"     Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= String
healthVersion