{-# 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