diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -2,6 +2,9 @@
 
 ## Unreleased changes
 
+- Change `waitStream` so that it automatically credits the connection. This
+  is a breaking change due to function signature change.
+
 ## v0.10.0.0
 
 - Export frameHttp2RawConnection to convert an RawHttp2Connection into an Http2FrameConnection.
diff --git a/http2-client.cabal b/http2-client.cabal
--- a/http2-client.cabal
+++ b/http2-client.cabal
@@ -1,5 +1,5 @@
 name:                http2-client
-version:             0.10.0.0
+version:             0.10.0.1
 synopsis:            A native HTTP2 client library.
 description:         Please read the README.md at the homepage.
 homepage:            https://github.com/lucasdicioccio/http2-client
@@ -22,19 +22,19 @@
                      , Network.HTTP2.Client.RawConnection
   other-modules:       Network.HTTP2.Client.Channels
                      , Network.HTTP2.Client.Dispatch
-  build-depends:       base >= 4.7 && < 5
-                     , async >= 2.1 && < 3
-                     , bytestring >= 0.10 && < 1
-                     , containers >= 0.5 && < 1
-                     , deepseq >= 1.4 && < 2
-                     , http2 >= 1.6 && < 2.1
+  build-depends:       base >= 4.7 && < 4.20
+                     , async >= 2.1 && < 2.3
+                     , bytestring >= 0.11 && < 0.13
+                     , containers >= 0.5 && < 0.8
+                     , deepseq >= 1.4 && < 1.6
+                     , http2 >= 4.1 && < 5
                      , lifted-async >= 0.10 && < 0.11
                      , lifted-base >= 0.2 && < 0.3
-                     , mtl >= 2.2 && < 3
-                     , network >= 2.6 && < 4
-                     , stm >= 2.4 && < 3
-                     , time >= 1.8 && < 2
-                     , tls >= 1.4 && < 2
+                     , mtl >= 2.2 && < 2.4
+                     , network >= 2.6 && < 3.2
+                     , stm >= 2.4 && < 2.8
+                     , time >= 1.8 && < 1.15
+                     , tls >= 2 && < 2.0.3
                      , transformers-base >= 0.4 && < 0.5
   default-language:    Haskell2010
 
diff --git a/src/Network/HTTP2/Client.hs b/src/Network/HTTP2/Client.hs
--- a/src/Network/HTTP2/Client.hs
+++ b/src/Network/HTTP2/Client.hs
@@ -57,7 +57,7 @@
 import           Data.IORef.Lifted (newIORef, atomicModifyIORef', readIORef)
 import           Data.Maybe (fromMaybe)
 import           Network.HPACK as HPACK
-import           Network.HTTP2 as HTTP2
+import           Network.HTTP2.Frame as HTTP2
 import           Network.Socket (HostName, PortNumber)
 import           Network.TLS (ClientParams)
 
@@ -166,7 +166,7 @@
   -- is provided. Only the first call to this IO will return if a reply is
   -- received. Hence we recommend wrapping this IO in an Async (e.g., with
   -- @race (threadDelay timeout)@.)
-  , _goaway           :: ErrorCodeId -> ByteString -> ClientIO ()
+  , _goaway           :: ErrorCode -> ByteString -> ClientIO ()
   -- ^ Sends a GOAWAY.
   , _startStream      :: forall a. StreamStarter a
   -- ^ Spawns new streams. See 'StreamStarter'.
@@ -188,7 +188,7 @@
 data InitHttp2Client = InitHttp2Client {
     _initPing                :: ByteString -> ClientIO (ClientIO (FrameHeader, FramePayload))
   , _initSettings            :: SettingsList -> ClientIO (ClientIO (FrameHeader, FramePayload))
-  , _initGoaway              :: ErrorCodeId -> ByteString -> ClientIO ()
+  , _initGoaway              :: ErrorCode -> ByteString -> ClientIO ()
   , _initStartStream         :: forall a. StreamStarter a
   , _initIncomingFlowControl :: IncomingFlowControl
   , _initOutgoingFlowControl :: OutgoingFlowControl
@@ -224,7 +224,7 @@
 -- | Synonym of '_goaway'.
 --
 -- https://github.com/http2/http2-spec/pull/366
-_gtfo :: Http2Client -> ErrorCodeId -> ByteString -> ClientIO ()
+_gtfo :: Http2Client -> ErrorCode -> ByteString -> ClientIO ()
 _gtfo = _goaway
 
 -- | Opaque proof that a client stream was initialized.
@@ -243,7 +243,7 @@
   -- Usually, this is the only call needed to build an '_initStream'.
   , _prio         :: Priority -> ClientIO ()
   -- ^ Changes the PRIORITY of this stream.
-  , _rst          :: ErrorCodeId -> ClientIO ()
+  , _rst          :: ErrorCode -> ClientIO ()
   -- ^ Resets this stream with a RST frame. You should not use this stream past this call.
   , _waitEvent    :: ClientIO StreamEvent
   -- ^ Waits for the next event on the stream.
@@ -283,7 +283,7 @@
 --
 -- Please refer to 'StreamStarter' and 'StreamDefinition' for more.
 withHttp2Stream :: Http2Client -> StreamStarter a
-withHttp2Stream = _startStream
+withHttp2Stream client = _startStream client
 
 -- | Type synonym for functions that modify flags.
 --
@@ -599,14 +599,14 @@
     case payload of
         (RSTStreamFrame err) -> lift $ do
             chan <- fmap _streamStateEvents <$> lookupStreamState d sid
-            let msg = StreamErrorEvent fh (HTTP2.fromErrorCodeId err)
+            let msg = StreamErrorEvent fh err
             maybe (return ()) (flip writeChan msg) chan
             closeReleaseStream d sid
         _ ->
             error $ "expecting RSTFrame but got " ++ show payload
 
 dispatchFramesStep
-  :: (FrameHeader, Either HTTP2Error FramePayload)
+  :: (FrameHeader, Either FrameDecodeError FramePayload)
   -> Dispatch
   -> ClientIO ()
 dispatchFramesStep (fh,_) d = do
@@ -615,7 +615,7 @@
     atomicModifyIORef' (_dispatchMaxStreamId d) (\n -> (max n sid, ()))
 
 finalizeFramesStep
-  :: (FrameHeader, Either HTTP2Error FramePayload)
+  :: (FrameHeader, Either FrameDecodeError FramePayload)
   -> Dispatch
   -> ClientIO ()
 finalizeFramesStep (fh,_) d = do
@@ -697,7 +697,7 @@
   | OpenPushPromise !StreamId !StreamId
 
 data HPACKStepResult =
-    WaitContinuation !((FrameHeader, Either HTTP2Error FramePayload) -> ClientIO HPACKStepResult)
+    WaitContinuation !((FrameHeader, Either FrameDecodeError FramePayload) -> ClientIO HPACKStepResult)
   | FailedHeaders !FrameHeader !StreamId ErrorCode
   | FinishedWithHeaders !FrameHeader !StreamId (IO HeaderList)
   | FinishedWithPushPromise !FrameHeader !StreamId !StreamId (IO HeaderList)
@@ -721,7 +721,7 @@
     sid :: StreamId
     sid = HTTP2.streamId fh
 
-    go :: FrameHeader -> HPACKLoopDecision -> Either ErrorCodeId ByteString -> HPACKStepResult
+    go :: FrameHeader -> HPACKLoopDecision -> Either ErrorCode ByteString -> HPACKStepResult
     go curFh decision (Right buffer) =
         if not $ HTTP2.testEndHeader (HTTP2.flags curFh)
         then WaitContinuation $ \frame -> do
@@ -743,7 +743,7 @@
             OpenPushPromise parentSid newSid ->
                 FinishedWithPushPromise curFh parentSid newSid (decodeHeader _dispatchHPACKDynamicTable buffer)
     go curFh _ (Left err) =
-        FailedHeaders curFh sid (HTTP2.fromErrorCodeId err)
+        FailedHeaders curFh sid err
 
 
 newIncomingFlowControl
@@ -892,13 +892,13 @@
 sendDataFrame s flagmod dat = do
     sendOne s flagmod (DataFrame dat)
 
-sendResetFrame :: Http2FrameClientStream -> ErrorCodeId -> ClientIO ()
+sendResetFrame :: Http2FrameClientStream -> ErrorCode -> ClientIO ()
 sendResetFrame s err = do
     sendOne s id (RSTStreamFrame err)
 
 sendGTFOFrame
   :: Http2FrameClientStream
-     -> StreamId -> ErrorCodeId -> ByteString -> ClientIO ()
+     -> StreamId -> ErrorCode -> ByteString -> ClientIO ()
 sendGTFOFrame s lastStreamId err errStr = do
     sendOne s id (GoAwayFrame lastStreamId err errStr)
 
diff --git a/src/Network/HTTP2/Client/Channels.hs b/src/Network/HTTP2/Client/Channels.hs
--- a/src/Network/HTTP2/Client/Channels.hs
+++ b/src/Network/HTTP2/Client/Channels.hs
@@ -11,10 +11,12 @@
 
 import           Control.Concurrent.Chan.Lifted (Chan, readChan, newChan, writeChan)
 import           Control.Exception.Lifted (Exception, throwIO)
-import           Network.HTTP2 (StreamId, FrameHeader, FramePayload, FrameTypeId, framePayloadToFrameTypeId, streamId)
+import           Network.HTTP2.Frame (StreamId, FrameHeader, FramePayload, FrameType, FrameDecodeError, framePayloadToFrameType, streamId)
 
 import           Network.HTTP2.Client.Exceptions
 
+instance Exception FrameDecodeError
+
 type FramesChan e = Chan (FrameHeader, Either e FramePayload)
 
 whenFrame
@@ -42,5 +44,5 @@
 hasStreamId :: StreamId -> FrameHeader -> FramePayload -> Bool
 hasStreamId sid h _ = streamId h == sid
 
-hasTypeId :: [FrameTypeId] -> FrameHeader -> FramePayload -> Bool
-hasTypeId tids _ p = framePayloadToFrameTypeId p `elem` tids
+hasTypeId :: [FrameType] -> FrameHeader -> FramePayload -> Bool
+hasTypeId tids _ p = framePayloadToFrameType p `elem` tids
diff --git a/src/Network/HTTP2/Client/Dispatch.hs b/src/Network/HTTP2/Client/Dispatch.hs
--- a/src/Network/HTTP2/Client/Dispatch.hs
+++ b/src/Network/HTTP2/Client/Dispatch.hs
@@ -14,12 +14,12 @@
 import           GHC.Exception (Exception)
 import           Network.HPACK as HPACK
 import qualified Network.HPACK.Token as HPACK
-import           Network.HTTP2 as HTTP2
+import           Network.HTTP2.Frame as HTTP2
 
 import           Network.HTTP2.Client.Channels
 import           Network.HTTP2.Client.Exceptions
 
-type DispatchChan = FramesChan HTTP2Error
+type DispatchChan = FramesChan FrameDecodeError
 
 -- | A fallback handler for frames.
 type FallBackFrameHandler = (FrameHeader, FramePayload) -> ClientIO ()
@@ -29,7 +29,7 @@
 ignoreFallbackHandler = const $ pure ()
 
 -- | An exception thrown when the server sends a GoAwayFrame.
-data RemoteSentGoAwayFrame = RemoteSentGoAwayFrame !StreamId !ErrorCodeId !ByteString
+data RemoteSentGoAwayFrame = RemoteSentGoAwayFrame !StreamId !ErrorCode !ByteString
   deriving Show
 instance Exception RemoteSentGoAwayFrame
 
diff --git a/src/Network/HTTP2/Client/Exceptions.hs b/src/Network/HTTP2/Client/Exceptions.hs
--- a/src/Network/HTTP2/Client/Exceptions.hs
+++ b/src/Network/HTTP2/Client/Exceptions.hs
@@ -4,10 +4,12 @@
   , ClientError(..)
   , runClientIO
   , module Control.Monad.Except
+  , module Control.Monad.Trans
   ) where
 
+import           Control.Monad.Trans (lift)
 import           Control.Exception (Exception)
-import           Control.Monad.Except (ExceptT, runExceptT, throwError, lift)
+import           Control.Monad.Except (ExceptT, runExceptT, throwError)
 
 type ClientIO = ExceptT ClientError IO
 
diff --git a/src/Network/HTTP2/Client/FrameConnection.hs b/src/Network/HTTP2/Client/FrameConnection.hs
--- a/src/Network/HTTP2/Client/FrameConnection.hs
+++ b/src/Network/HTTP2/Client/FrameConnection.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE RecordWildCards  #-}
-{-# LANGUAGE RankNTypes  #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE RankNTypes #-}
 
 module Network.HTTP2.Client.FrameConnection (
       Http2FrameConnection(..)
@@ -22,8 +22,8 @@
 import           Control.Concurrent.MVar.Lifted (newMVar, takeMVar, putMVar)
 import           Control.Monad ((>=>), void, when)
 import qualified Data.ByteString as ByteString
-import           Network.HTTP2 (FrameHeader(..), FrameFlags, FramePayload, HTTP2Error, encodeInfo, decodeFramePayload)
-import qualified Network.HTTP2 as HTTP2
+import           Network.HTTP2.Frame (FrameHeader(..), FrameFlags, FramePayload, FrameDecodeError, encodeInfo, decodeFramePayload)
+import qualified Network.HTTP2.Frame as HTTP2
 import           Network.Socket (HostName, PortNumber)
 import qualified Network.TLS as TLS
 
@@ -66,11 +66,11 @@
 sendBackToBack client payloads = _sendFrames client (pure payloads)
 
 data Http2ServerStream = Http2ServerStream {
-    _nextHeaderAndFrame :: ClientIO (FrameHeader, Either HTTP2Error FramePayload)
+    _nextHeaderAndFrame :: ClientIO (FrameHeader, Either FrameDecodeError FramePayload)
   }
 
 -- | Waits for the next frame from the server.
-next :: Http2FrameConnection -> ClientIO (FrameHeader, Either HTTP2Error FramePayload)
+next :: Http2FrameConnection -> ClientIO (FrameHeader, Either FrameDecodeError FramePayload)
 next = _nextHeaderAndFrame . _serverStream
 
 -- | Adds framing around a 'RawHttp2Connection'.
diff --git a/src/Network/HTTP2/Client/Helpers.hs b/src/Network/HTTP2/Client/Helpers.hs
--- a/src/Network/HTTP2/Client/Helpers.hs
+++ b/src/Network/HTTP2/Client/Helpers.hs
@@ -21,7 +21,7 @@
   ) where
 
 import           Data.Time.Clock (UTCTime, getCurrentTime)
-import qualified Network.HTTP2 as HTTP2
+import qualified Network.HTTP2.Frame as HTTP2
 import qualified Network.HPACK as HPACK
 import           Data.ByteString (ByteString)
 import qualified Data.ByteString as ByteString
@@ -115,12 +115,16 @@
 --
 -- This function is fine if you don't want to consume results in chunks.  See
 -- 'fromStreamResult' to collect the complicated 'StreamResult' into a simpler
--- 'StramResponse'.
-waitStream :: Http2Stream
+-- 'StreamResponse'.
+waitStream :: Http2Client
+           -- ^The connection.
+           -> Http2Stream
+           -- ^The stream to wait on. This stream must be part of the connection.
            -> IncomingFlowControl
+           -- ^Incoming flow control for the __stream__.
            -> PushPromiseHandler
            -> ClientIO StreamResult
-waitStream stream streamFlowControl ppHandler = do
+waitStream conn stream streamFlowControl ppHandler = do
     ev <- _waitEvent stream
     case ev of
         StreamHeadersEvent fH hdrs
@@ -131,10 +135,11 @@
                 return (Right hdrs, reverse dfrms, trls)
         StreamPushPromiseEvent _ ppSid ppHdrs -> do
             _handlePushPromise stream ppSid ppHdrs ppHandler
-            waitStream stream streamFlowControl ppHandler
+            waitStream conn stream streamFlowControl ppHandler
         _ ->
             error $ "expecting StreamHeadersEvent but got " ++ show ev
   where
+    connFlowControl = _incomingFlowControl conn
     waitDataFrames xs = do
         ev <- _waitEvent stream
         case ev of
@@ -142,9 +147,19 @@
                 | HTTP2.testEndStream (HTTP2.flags fh) ->
                     return ((Right x):xs, Nothing)
                 | otherwise                            -> do
-                    _ <- lift $ _consumeCredit streamFlowControl (HTTP2.payloadLength fh)
-                    lift $ _addCredit streamFlowControl (HTTP2.payloadLength fh)
+                    let size = HTTP2.payloadLength fh
+                    _ <- lift $ _consumeCredit streamFlowControl size
+                    lift $ _addCredit streamFlowControl size
                     _ <- _updateWindow $ streamFlowControl
+                    -- We also send a WINDOW_UPDATE for the connection in order
+                    -- to not rely on external updateWindow calls. This reduces
+                    -- latency and makes the function less error-prone to use.
+                    -- Note that the main loop (dispatchLoop) already credits
+                    -- the connection for received data frames, but it does not
+                    -- send the WINDOW_UPDATE frames.. That is why we only send
+                    -- those frames here, and we do not credit the connection
+                    --  as we do the stream in the preceding lines.
+                    _ <- _updateWindow $ connFlowControl
                     waitDataFrames ((Right x):xs)
             StreamPushPromiseEvent _ ppSid ppHdrs -> do
                 _handlePushPromise stream ppSid ppHdrs ppHandler
diff --git a/src/Network/HTTP2/Client/RawConnection.hs b/src/Network/HTTP2/Client/RawConnection.hs
--- a/src/Network/HTTP2/Client/RawConnection.hs
+++ b/src/Network/HTTP2/Client/RawConnection.hs
@@ -17,7 +17,7 @@
 import qualified Data.ByteString as ByteString
 import           Data.ByteString.Lazy (fromChunks)
 import           Data.Monoid ((<>))
-import qualified Network.HTTP2 as HTTP2
+import qualified Network.HTTP2.Frame as HTTP2
 import           Network.Socket hiding (recv)
 import           Network.Socket.ByteString
 import qualified Network.TLS as TLS
