diff --git a/bitcoin-payment-channel.cabal b/bitcoin-payment-channel.cabal
--- a/bitcoin-payment-channel.cabal
+++ b/bitcoin-payment-channel.cabal
@@ -1,5 +1,5 @@
 name:                 bitcoin-payment-channel
-version:              0.2.1.0
+version:              0.2.2.0
 synopsis:             Library for working with Bitcoin payment channels
 description:
     A Bitcoin payment channel allows secure and instant transfer of bitcoins from one
@@ -37,6 +37,7 @@
 
   other-modules:
                         Data.Bitcoin.PaymentChannel.Internal.Error
+                        Data.Bitcoin.PaymentChannel.Internal.BitcoinAmount,
                         Data.Bitcoin.PaymentChannel.Internal.Payment,
                         Data.Bitcoin.PaymentChannel.Internal.Refund,
                         Data.Bitcoin.PaymentChannel.Internal.Script,
@@ -46,6 +47,7 @@
                         Data.Bitcoin.PaymentChannel.Internal.Serialization,
                         Data.Bitcoin.PaymentChannel.Internal.Util,
                         Data.Bitcoin.PaymentChannel.Internal.Version
+
 
   ghc-options:          -W
 
diff --git a/src/Data/Bitcoin/PaymentChannel/Internal/BitcoinAmount.hs b/src/Data/Bitcoin/PaymentChannel/Internal/BitcoinAmount.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bitcoin/PaymentChannel/Internal/BitcoinAmount.hs
@@ -0,0 +1,60 @@
+module Data.Bitcoin.PaymentChannel.Internal.BitcoinAmount where
+
+import qualified Data.Serialize     as Ser
+import qualified Data.Serialize.Put as SerPut
+import qualified Data.Serialize.Get as SerGet
+import qualified Data.Binary        as Bin
+import qualified Data.Binary.Put    as BinPut
+import qualified Data.Binary.Get    as BinGet
+import           Data.Word
+
+
+-- |Represents a bitcoin amount as number of satoshis.
+--  1 satoshi = 1e-8 bitcoin.
+--  Only natural numbers (>= 0) can be represented ('fromInteger' caps to a 'Word64').
+--  It is thus not possible to construct a negative BitcoinAmount which, when added to
+--  another BitcoinAmount, subtracts from its value. So we avoid the problem of being
+--  able to invert subtraction/addition by supplying a negative value as one of the
+--  arguments.
+newtype BitcoinAmount = BitcoinAmount Integer
+    deriving (Eq, Ord)
+instance Show BitcoinAmount where
+    show amount = show (toInteger amount) ++ " satoshi"
+
+instance Num BitcoinAmount where
+    -- We leave multiplication of two money amounts as undefined
+    (BitcoinAmount _)  * (BitcoinAmount _)  = undefined
+    (BitcoinAmount a1) + (BitcoinAmount a2) = BitcoinAmount (fromIntegral . capToWord64 $ a1+a2)
+    (BitcoinAmount a1) - (BitcoinAmount a2) = BitcoinAmount (fromIntegral . capToWord64 $ a1-a2)
+    abs = id    -- Always positive
+    signum (BitcoinAmount 0) = BitcoinAmount 0
+    signum (BitcoinAmount _) = BitcoinAmount 1
+    fromInteger = BitcoinAmount . fromIntegral . capToWord64
+
+instance Enum BitcoinAmount where
+    toEnum = BitcoinAmount . fromIntegral . capToWord64 . fromIntegral
+    fromEnum (BitcoinAmount amount) = fromIntegral amount
+
+instance Real BitcoinAmount where
+    toRational (BitcoinAmount amount) = toRational amount
+
+instance Integral BitcoinAmount where
+    toInteger (BitcoinAmount int) = int
+    -- Dividing one money amounts by another doesn't make sense either
+    quotRem (BitcoinAmount _) (BitcoinAmount _) = undefined
+
+-- | Convert to 'Word64', with zero as floor, (maxBound :: Word64) as ceiling
+capToWord64 :: Integer -> Word64
+capToWord64 i = fromIntegral $
+    max 0 cappedValue
+        where
+            cappedValue = min i $ fromIntegral (maxBound :: Word64)
+
+instance Bin.Binary BitcoinAmount where
+    put = BinPut.putWord64le . fromIntegral . toInteger
+    get = BitcoinAmount . fromIntegral <$> BinGet.getWord64le
+
+instance Ser.Serialize BitcoinAmount where
+    put = SerPut.putWord64le . fromIntegral . toInteger
+    get = BitcoinAmount . fromIntegral <$> SerGet.getWord64le
+
diff --git a/src/Data/Bitcoin/PaymentChannel/Internal/Error.hs b/src/Data/Bitcoin/PaymentChannel/Internal/Error.hs
--- a/src/Data/Bitcoin/PaymentChannel/Internal/Error.hs
+++ b/src/Data/Bitcoin/PaymentChannel/Internal/Error.hs
@@ -1,6 +1,6 @@
 module Data.Bitcoin.PaymentChannel.Internal.Error where
 
-import Data.Bitcoin.PaymentChannel.Internal.Util (BitcoinAmount)
+import Data.Bitcoin.PaymentChannel.Internal.Types (BitcoinAmount)
 
 data PayChanError =
     BadSignature |
diff --git a/src/Data/Bitcoin/PaymentChannel/Internal/Payment.hs b/src/Data/Bitcoin/PaymentChannel/Internal/Payment.hs
--- a/src/Data/Bitcoin/PaymentChannel/Internal/Payment.hs
+++ b/src/Data/Bitcoin/PaymentChannel/Internal/Payment.hs
@@ -43,7 +43,7 @@
 getPaymentTxForSigning st@(CPaymentChannelState _ fti
     (CPaymentTxConfig sendAddr) chanValLeft _) newValueLeft =
         paymentTxAddOutput senderOut $ buildEmptyPaymentTx fti
-            where senderOut = HT.TxOut (toWord64 newValueLeft) (addressToScriptPubKeyBS sendAddr)
+            where senderOut = HT.TxOut (fromIntegral . toInteger $ newValueLeft) (addressToScriptPubKeyBS sendAddr)
 
 getPaymentTxHashForSigning ::
     PaymentChannelState
diff --git a/src/Data/Bitcoin/PaymentChannel/Internal/Refund.hs b/src/Data/Bitcoin/PaymentChannel/Internal/Refund.hs
--- a/src/Data/Bitcoin/PaymentChannel/Internal/Refund.hs
+++ b/src/Data/Bitcoin/PaymentChannel/Internal/Refund.hs
@@ -14,13 +14,15 @@
 getUnsignedRefundTx st txFee = -- @CPaymentChannelState =
     let
         (baseTx,_) = getPaymentTxForSigning st 0 --create empty payment tx, which redeems funding tx
-        refundOut = HT.TxOut (toWord64 $ pcsChannelTotalValue st - txFee) (pcsClientChange st)
+        refundOut = HT.TxOut
+                (fromIntegral . toInteger $ pcsChannelTotalValue st - txFee)
+                (pcsClientChangeScriptPubKey st)
         txInput0 = head $ HT.txIn baseTx
     in
         baseTx {
             HT.txOut = [refundOut],
-            -- lockTime of refund tx must be equal to or greater than lockTime
-            -- in channel redeemScript
+            -- lockTime of refund tx must be greater than or equal to the lockTime
+            -- in the channel redeemScript
             HT.txLockTime = toWord32 (pcsLockTime st),
             -- if the sequence field equals maxBound (0xffffffff),
             -- lockTime features are disabled, so we set it to that minus one
diff --git a/src/Data/Bitcoin/PaymentChannel/Internal/Serialization.hs b/src/Data/Bitcoin/PaymentChannel/Internal/Serialization.hs
--- a/src/Data/Bitcoin/PaymentChannel/Internal/Serialization.hs
+++ b/src/Data/Bitcoin/PaymentChannel/Internal/Serialization.hs
@@ -6,7 +6,7 @@
 
 import           Data.Bitcoin.PaymentChannel.Internal.Types
 import           Data.Bitcoin.PaymentChannel.Internal.Util
-                            (BitcoinAmount(..), toWord64, deserEither, toHexString,
+                            (deserEither, toHexString,
                              parseBitcoinLocktime, BitcoinLockTime(..), toWord32)
 
 import           Data.Aeson (Value(Number), FromJSON(..), ToJSON(..),
@@ -50,7 +50,7 @@
 
 instance ToJSON BitcoinAmount where
     toJSON amt = Number $ scientific
-        (fromIntegral $ toWord64 amt) 0
+        (fromIntegral $ toInteger amt) 0
 
 instance FromJSON BitcoinAmount where
     parseJSON = withScientific "BitcoinAmount" $
@@ -113,8 +113,8 @@
 
     -- Needed to convert from Scientific
 instance Bounded BitcoinAmount where
-    minBound = CMoneyAmount 0
-    maxBound = CMoneyAmount $ round $ 21e6 * 1e8
+    minBound = BitcoinAmount 0
+    maxBound = BitcoinAmount $ round $ 21e6 * 1e8
 
 
 --- Util
@@ -138,7 +138,7 @@
 parseJSONInt :: Scientific -> Parser Integer
 parseJSONInt s =
     case toBoundedInteger s of
-        Just (CMoneyAmount i) -> return i
+        Just (BitcoinAmount i) -> return i
         Nothing -> fail $ "failed to decode JSON number to integer. data: " ++ show s
 
 parseJSONWord :: Scientific -> Parser Word64
diff --git a/src/Data/Bitcoin/PaymentChannel/Internal/Settlement.hs b/src/Data/Bitcoin/PaymentChannel/Internal/Settlement.hs
--- a/src/Data/Bitcoin/PaymentChannel/Internal/Settlement.hs
+++ b/src/Data/Bitcoin/PaymentChannel/Internal/Settlement.hs
@@ -24,7 +24,7 @@
             (baseTx,_) = getPaymentTxForSigning st senderVal
             adjTx = if sigHash == HS.SigNone True then removeOutputs baseTx else baseTx
             receiverAmount = channelTotalValue - senderVal - txFee -- may be less than zero
-            recvOut = HT.TxOut (toWord64 receiverAmount) (addressToScriptPubKeyBS recvAddr)
+            recvOut = HT.TxOut (fromIntegral . toInteger $ receiverAmount) (addressToScriptPubKeyBS recvAddr)
         in
             paymentTxAddOutput recvOut adjTx
 getSettlementTxForSigning _ _ _ = error "no payment sig available"
diff --git a/src/Data/Bitcoin/PaymentChannel/Internal/State.hs b/src/Data/Bitcoin/PaymentChannel/Internal/State.hs
--- a/src/Data/Bitcoin/PaymentChannel/Internal/State.hs
+++ b/src/Data/Bitcoin/PaymentChannel/Internal/State.hs
@@ -4,7 +4,7 @@
 
 import Data.Bitcoin.PaymentChannel.Internal.Types
 import Data.Bitcoin.PaymentChannel.Internal.Error
-import Data.Bitcoin.PaymentChannel.Internal.Util  (addressToScriptPubKeyBS, BitcoinAmount)
+import Data.Bitcoin.PaymentChannel.Internal.Util  (addressToScriptPubKeyBS)
 
 import qualified Network.Haskoin.Transaction as HT
 import qualified Network.Haskoin.Crypto as HC
@@ -17,7 +17,7 @@
 pcsServerPubKey = cpReceiverPubKey . pcsParameters
 pcsExpirationDate = cpLockTime . pcsParameters
 pcsClientChangeAddress = ptcSenderChangeAddress . pcsPaymentConfig
-pcsClientChange = addressToScriptPubKeyBS . pcsClientChangeAddress
+pcsClientChangeScriptPubKey = addressToScriptPubKeyBS . pcsClientChangeAddress
 pcsLockTime = cpLockTime . pcsParameters
 
 pcsChannelID :: PaymentChannelState -> HT.OutPoint
diff --git a/src/Data/Bitcoin/PaymentChannel/Internal/Types.hs b/src/Data/Bitcoin/PaymentChannel/Internal/Types.hs
--- a/src/Data/Bitcoin/PaymentChannel/Internal/Types.hs
+++ b/src/Data/Bitcoin/PaymentChannel/Internal/Types.hs
@@ -1,19 +1,23 @@
 -- {-# LANGUAGE DeriveDataTypeable #-}
 
-module Data.Bitcoin.PaymentChannel.Internal.Types where
+module Data.Bitcoin.PaymentChannel.Internal.Types
+(
+    module Data.Bitcoin.PaymentChannel.Internal.Types
+  , module Data.Bitcoin.PaymentChannel.Internal.BitcoinAmount
+)
 
+where
+
 import Data.Bitcoin.PaymentChannel.Internal.Util
 import Data.Bitcoin.PaymentChannel.Internal.Version
+import Data.Bitcoin.PaymentChannel.Internal.BitcoinAmount
 
 import qualified  Network.Haskoin.Transaction as HT
 import qualified  Network.Haskoin.Crypto as HC
 import qualified  Network.Haskoin.Script as HS
-import qualified Data.ByteString as B
-import Data.Word (Word32, Word64, Word8)
-import qualified  Data.Binary as Bin
-import qualified  Data.Binary.Put as BinPut
-import qualified  Data.Binary.Get as BinGet
 import            Data.Typeable
+import            Data.Word
+
 
 dUST_LIMIT = 700 :: BitcoinAmount
 mIN_CHANNEL_SIZE = dUST_LIMIT * 2
diff --git a/src/Data/Bitcoin/PaymentChannel/Internal/Util.hs b/src/Data/Bitcoin/PaymentChannel/Internal/Util.hs
--- a/src/Data/Bitcoin/PaymentChannel/Internal/Util.hs
+++ b/src/Data/Bitcoin/PaymentChannel/Internal/Util.hs
@@ -4,7 +4,7 @@
 module Data.Bitcoin.PaymentChannel.Internal.Util where
 
 import Data.String (fromString)
-import qualified Data.Serialize as Ser (Serialize, encode, get, put)
+import qualified Data.Serialize as Ser
 import qualified Data.Serialize.Put as SerPut
 import qualified Data.Serialize.Get as SerGet
 import qualified Data.Binary as Bin
@@ -44,32 +44,6 @@
         (bs,e) ->
             if B.length e /= 0 then B.empty else bs
 
-
--- |Represents a bitcoin amount as number of satoshis.
---  1 satoshi = 1e-8 bitcoins.
---  Integer operations will never over- or underflow with this type.
---  Convert to a Word64 using 'toWord64', which caps the final amount.
-newtype BitcoinAmount = CMoneyAmount Integer
-    deriving (Eq, Ord, Num, Enum, Real, Integral)
-instance Show BitcoinAmount where
-    show ma = show (fromIntegral $ toWord64 ma) ++ " satoshi"
-
--- | Convert to 'Word64', with zero as floor, UINT64_MAX as ceiling
-toWord64 :: BitcoinAmount -> Word64
-toWord64 (CMoneyAmount i) = fromIntegral $
-    max 0 cappedValue
-        where
-            cappedValue = min i $ fromIntegral (maxBound :: Word64)
-
-instance Bin.Binary BitcoinAmount where
-    put = BinPut.putWord64le . toWord64
-    get = CMoneyAmount . fromIntegral <$> BinGet.getWord64le
-
-instance Ser.Serialize BitcoinAmount where
-    put = SerPut.putWord64le . toWord64
-    get = CMoneyAmount . fromIntegral <$> SerGet.getWord64le
-
-
 -- | Converts a pay-to-pubkey-hash address string to Script.
 -- | Eg. \"1PDGytNA7EJ5XrJdTGKv11VAUFxKnsfwke\" into
 -- | \"Script [OP_DUP, OP_HASH160, OP_PUSHDATA f3a5194fbf4b3556838e0f773b613a876737a2c6,
@@ -122,7 +96,7 @@
 replaceScriptInput scriptIn (HT.Tx v (txIn:_) txOut lt)  =
     HT.Tx v [newTxIn] txOut lt
         where newTxIn = txIn { HT.scriptInput = scriptIn }
-replaceScriptInput scriptIn (HT.Tx _ [] _ _) =
+replaceScriptInput _ (HT.Tx _ [] _ _) =
     error "cannot replace scriptInput without any inputs"
 
 removeOutputs :: HT.Tx -> HT.Tx
diff --git a/src/Data/Bitcoin/PaymentChannel/Types.hs b/src/Data/Bitcoin/PaymentChannel/Types.hs
--- a/src/Data/Bitcoin/PaymentChannel/Types.hs
+++ b/src/Data/Bitcoin/PaymentChannel/Types.hs
@@ -21,7 +21,7 @@
 PayChanError(..),
 PaymentChannelState,
 SendPubKey(..),RecvPubKey(..),IsPubKey(..),
-BitcoinAmount, toWord64,
+BitcoinAmount,
 BitcoinLockTime(..), fromDate,
 usesBlockHeight,
 
@@ -34,15 +34,15 @@
 where
 
 import Data.Bitcoin.PaymentChannel.Internal.Types
-    (PaymentChannelState(..), Payment(..)
+    (BitcoinAmount(..),
+     PaymentChannelState(..), Payment(..)
     ,FundingTxInfo(..), ChannelParameters(..),
     PaymentSignature(..), SendPubKey(..), RecvPubKey(..), IsPubKey(..),
     dUST_LIMIT, mIN_CHANNEL_SIZE)
 import Data.Bitcoin.PaymentChannel.Internal.Serialization
 --     ()
 import Data.Bitcoin.PaymentChannel.Internal.Util
-    (BitcoinAmount(..), toWord64,
-    BitcoinLockTime(..), fromDate, usesBlockHeight)
+    (BitcoinLockTime(..), fromDate, usesBlockHeight)
 import qualified Data.Bitcoin.PaymentChannel.Internal.State as S
 import Data.Bitcoin.PaymentChannel.Internal.Error (PayChanError(..))
 -- import Data.Bitcoin.PaymentChannel.Internal.Types ()
