diff --git a/CHANGELOG b/CHANGELOG
deleted file mode 100644
--- a/CHANGELOG
+++ /dev/null
@@ -1,8 +0,0 @@
-0.3
----
-* Hotfix for `0.2` was wrong making it a brownbag release. This version should
-  now work correctly.
-
-0.2
----
-* Make sure specified number of bytes are retrieved from socket.
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,28 @@
+# Change Log
+All notable changes to this project will be documented in this file. This file
+follows the formatting recommendations from [Keep a
+CHANGELOG](http://keepachangelog.com/).
+
+## [0.4][0.4] - 2015-4-13
+### Changed
+- Upgrade to `exceptions-0.6`.
+- Upgrade to `pipes-concurrency-2.0.3`.
+- Increase upper bounds for `base`.
+### Added
+- Include example from `pipes-p2p-example` package.
+
+## [0.3][0.3] - 2014-3-6
+### Fixed
+- Hotfix for `0.2` was wrong making it a brownbag release. This version should
+  now work correctly.
+
+## [0.2][0.2] - 2014-3-6
+### Fixed
+- Make sure specified number of bytes are retrieved from socket.
+
+## 0.1 - 2014-3-4
+-Initial release
+
+[0.4]: https://github.com/jdnavarro/pipes-p2p/compare/v0.3...v0.4
+[0.3]: https://github.com/jdnavarro/pipes-p2p/compare/v0.2...v0.3
+[0.2]: https://github.com/jdnavarro/pipes-p2p/compare/v0.1...v0.2
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2014, Danny Navarro
+Copyright (c) 2014-2015, J. Daniel Navarro
 
 All rights reserved.
 
@@ -13,7 +13,7 @@
       disclaimer in the documentation and/or other materials provided
       with the distribution.
 
-    * Neither the name of Danny Navarro nor the names of other
+    * Neither the name of J. Daniel Navarro nor the names of other
       contributors may be used to endorse or promote products derived
       from this software without specific prior written permission.
 
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# Pipes P2P
+
+Toy library to facilitate the creation of custom P2P networks using `pipes`.
+
+[![Hackage Version](https://img.shields.io/hackage/v/pipes-p2p.svg)](https://hackage.haskell.org/package/pipes-p2p) [![Build Status](https://img.shields.io/travis/jdnavarro/pipes-p2p.svg)](https://travis-ci.org/jdnavarro/pipes-p2p)
diff --git a/pipes-p2p.cabal b/pipes-p2p.cabal
--- a/pipes-p2p.cabal
+++ b/pipes-p2p.cabal
@@ -1,38 +1,38 @@
 name:                pipes-p2p
-version:             0.3
+version:             0.4
 cabal-version:       >=1.10
-tested-with:         GHC == 7.6.3
+tested-with:         GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.1
 build-type:          Simple
 homepage:            https://github.com/jdnavarro/pipes-p2p
 license:             BSD3
 license-file:        LICENSE
 author:              Danny Navarro
-maintainer:          j@dannynavarro.net
+maintainer:          Danny Navarro <j@dannynavarro.net>
 category:            Network, Pipes
 synopsis:            P2P network nodes with pipes
 description:
   Toy library to facilitate the creation of custom P2P networks using `pipes`.
 
-extra-source-files: CHANGELOG
+extra-source-files: CHANGELOG.md README.md
 
 source-repository head
     type: git
-    location: git@github.com:jdnavarro/pipes-p2p.git
+    location: git://github.com/jdnavarro/pipes-p2p.git
 
 library
   exposed-modules:     Pipes.Network.P2P
   hs-source-dirs:      src
   default-language:    Haskell2010
   ghc-options:         -Wall
-  build-depends:       base >=4.6 && <4.8,
+  build-depends:       base >=4.6 && <4.9,
                        async >=2,
                        binary >=0.7,
                        mtl >=2,
                        bytestring >=0.10,
                        errors >=1.4,
-                       exceptions >=0.3,
+                       exceptions >=0.6,
                        pipes >=0.4,
-                       pipes-concurrency >=2.0,
+                       pipes-concurrency >=2.0.3,
                        pipes-network >=0.6,
                        network >=2.4,
-                       network-simple-sockaddr
+                       network-simple-sockaddr >= 0.2
diff --git a/src/Pipes/Network/P2P.hs b/src/Pipes/Network/P2P.hs
--- a/src/Pipes/Network/P2P.hs
+++ b/src/Pipes/Network/P2P.hs
@@ -30,7 +30,6 @@
   -- * Re-exports
   , MonadIO
   , liftIO
-  , MonadCatch
   ) where
 
 import Control.Applicative (Applicative, (<$>))
@@ -47,7 +46,7 @@
 import qualified Data.Binary as Binary(encode,decodeOrFail)
 import Control.Monad.Reader (ReaderT(..), MonadReader, runReaderT, ask)
 import Control.Error (MaybeT, hoistMaybe, hush)
-import Control.Monad.Catch (MonadCatch, bracket_)
+import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask, bracket_)
 import Pipes
   ( Pipe
   , Producer
@@ -64,9 +63,9 @@
 import Pipes.Network.TCP (fromSocketN)
 import qualified Pipes.Concurrent
 import Pipes.Concurrent
-  ( Buffer(Unbounded)
-  , Output
+  ( Output
   , Input
+  , unbounded
   , spawn
   , toOutput
   , fromInput
@@ -110,7 +109,7 @@
      -- ^ Functions to define the behavior of the 'Node'.
      -> m (Node a)
 node magic addr handlers =
-    Node magic addr handlers <$> liftIO (spawn Unbounded)
+    Node magic addr handlers <$> liftIO (spawn unbounded)
 {-# INLINABLE node #-}
 
 -- | Functions to define the behavior of a 'Node'.
@@ -123,7 +122,7 @@
     -- ^ Action to perform after a connection has been established.
     , onDisconnect :: Handler a
     -- ^ Action to perform after a connection has ended.
-    , msgConsumer  :: forall m . (MonadIO m, MonadCatch m)
+    , msgConsumer  :: forall m . (MonadIO m, MonadMask m)
                    => a -> Consumer (Either (Relay a) a) (NodeConnT a m) ()
     -- ^ This consumes incoming messages either from other connections in the
     --   node, as @'Left' ('Relay' a)@, or from the current connected socket,
@@ -146,12 +145,14 @@
                , Applicative
                , Monad
                , MonadIO
+               , MonadThrow
                , MonadCatch
+               , MonadMask
                , MonadReader (NodeConn a)
                )
 
 -- | Launch a 'Node'.
-launch :: (Functor m, Applicative m, MonadIO m, MonadCatch m, Binary a)
+launch :: (Functor m, Applicative m, MonadIO m, MonadMask m, Binary a)
        => Node a
        -- ^
        -> [SockAddr]
@@ -163,7 +164,7 @@
 {-# INLINABLE launch #-}
 
 -- | Connect a 'Node' to the given pair of 'SockAddr', 'Socket'.
-runNodeConn :: (Functor m, MonadIO m, MonadCatch m, Binary a)
+runNodeConn :: (Functor m, MonadIO m, MonadMask m, Binary a)
             => Node a
             -- ^
             -> Bool
@@ -245,19 +246,19 @@
 -- * Internal
 
 type Mailbox a = (Output (Relay a), Input (Relay a))
-type HandShaker a = forall m . (Functor m, MonadIO m, MonadCatch m)
+type HandShaker a = forall m . (Functor m, MonadIO m, MonadMask m)
                  => NodeConnT a m (Maybe a)
 type Handler a = forall m . MonadIO m => a -> m ()
 
 
 -- | Coordinates the handlers in the 'Node'.
-handle :: forall a m . (MonadIO m, MonadCatch m, Binary a)
+handle :: forall a m . (MonadIO m, MonadMask m, Binary a)
        => a -> NodeConnT a m ()
 handle msg = do
     NodeConn Node{magic, handlers, broadcaster} (Connection _ sock) <- ask
     let Handlers{onConnect, onDisconnect, msgConsumer} = handlers
     bracket_ (onConnect msg) (onDisconnect msg) $ do
-        (ol, il) <- liftIO $ spawn Unbounded
+        (ol, il) <- liftIO $ spawn unbounded
         liftIO $ do
             let (obc, ibc) = broadcaster
             tid <- myThreadId
