packages feed

bitcoin-payment-channel-1.0.0.0: src/Bitcoin/Fee.hs

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Bitcoin.Fee where

-- import Bitcoin.Types
import Bitcoin.Amount
import Bitcoin.Util (calcTxSize)
import qualified Network.Haskoin.Transaction as HT
import qualified Data.Serialize     as Bin
import qualified Data.Aeson.Types   as JSON

-- |Objects from which a Bitcoin fee can be calculated,
--   given a transaction (yeah you need to create a tx twice).
class HasFee a where
    absoluteFee :: TxByteSize -> a -> BtcAmount

-- |For compatibility
instance HasFee BtcAmount where
    absoluteFee _ = id    -- Same as constant fee

data Constant = Constant BtcAmount
instance HasFee Constant where
    absoluteFee _ (Constant amt) = amt

type TxByteSize = Word
-- |Specify a fee as satoshis per byte
newtype SatoshisPerByte = SatoshisPerByte BtcAmount -- ^Fee in satoshis per byte
    deriving (Eq, Show, Ord, Num, Enum, Real, Integral, Bin.Serialize, JSON.ToJSON, JSON.FromJSON)
instance HasFee SatoshisPerByte where
    absoluteFee txByteSize (SatoshisPerByte satoshisPerByte) =
        fromIntegral txByteSize * satoshisPerByte

mkRelativeFeeTx
    :: HasFee fee
    => fee                          -- ^Desired (per-byte) transaction fee
    -> (BtcAmount -> HT.Tx)     -- ^Produces desired Bitcoin tx with given fee
    -> HT.Tx
mkRelativeFeeTx fee mkTxFunc =
    mkTxSizeFee pass2Tx
    where
        pass2Tx = mkTxSizeFee pass1Tx
        pass1Tx = mkTxFunc (0 :: BtcAmount)
        mkTxSizeFee tx = mkTxFunc $ absoluteFee (calcTxSize tx) fee