diff --git a/haskoin-store.cabal b/haskoin-store.cabal
--- a/haskoin-store.cabal
+++ b/haskoin-store.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 63c2a0e85118148d88a0ddfbd79034b4a4a45715a820cf743c52d55ac164eb35
+-- hash: 05cb5cdade7814a9d00229d0a0ad2fb0c69fbde6a4b8660b01ebd6f5be7eed36
 
 name:           haskoin-store
-version:        0.26.6
+version:        0.27.0
 synopsis:       Storage and index for Bitcoin and Bitcoin Cash
 description:    Store and index Bitcoin or Bitcoin Cash blocks, transactions, balances and unspent outputs.
                 All data is available via REST API in JSON or binary format.
@@ -57,7 +57,7 @@
     , hashable >=1.3.0.0
     , haskoin-core >=0.13.3
     , haskoin-node >=0.13.0
-    , haskoin-store-data ==0.26.6
+    , haskoin-store-data ==0.27.0
     , hedis >=0.12.13
     , http-types >=0.12.3
     , monad-logger >=0.3.32
@@ -99,7 +99,7 @@
     , haskoin-core >=0.13.3
     , haskoin-node >=0.13.0
     , haskoin-store
-    , haskoin-store-data ==0.26.6
+    , haskoin-store-data ==0.27.0
     , monad-logger >=0.3.32
     , mtl >=2.2.2
     , nqe >=0.6.1
@@ -149,7 +149,7 @@
     , hashable >=1.3.0.0
     , haskoin-core >=0.13.3
     , haskoin-node >=0.13.0
-    , haskoin-store-data ==0.26.6
+    , haskoin-store-data ==0.27.0
     , hedis >=0.12.13
     , hspec >=2.7.1
     , http-types >=0.12.3
diff --git a/src/Haskoin/Store.hs b/src/Haskoin/Store.hs
--- a/src/Haskoin/Store.hs
+++ b/src/Haskoin/Store.hs
@@ -15,6 +15,8 @@
     , CacheError (..)
     , withCache
     , connectRedis
+    , isInCache
+    , evictFromCache
 
       -- * Store Reader
     , StoreRead (..)
diff --git a/src/Haskoin/Store/Cache.hs b/src/Haskoin/Store/Cache.hs
--- a/src/Haskoin/Store/Cache.hs
+++ b/src/Haskoin/Store/Cache.hs
@@ -21,15 +21,15 @@
     , cacheNewBlock
     , cacheNewTx
     , cacheWriter
-    , isXPubCached
-    , delXPubKeys
+    , isInCache
+    , evictFromCache
     ) where
 
 import           Control.DeepSeq           (NFData)
 import           Control.Monad             (forM, forM_, forever, unless, void)
 import           Control.Monad.Logger      (MonadLoggerIO, logDebugS, logErrorS,
                                             logInfoS, logWarnS)
-import           Control.Monad.Reader      (ReaderT (..), asks)
+import           Control.Monad.Reader      (ReaderT (..), ask, asks)
 import           Control.Monad.Trans       (lift)
 import           Control.Monad.Trans.Maybe (MaybeT (..), runMaybeT)
 import           Data.Bits                 (shift, (.&.), (.|.))
@@ -84,7 +84,7 @@
                                             bracket, liftIO, throwIO)
 import           UnliftIO.Concurrent       (threadDelay)
 
-runRedis :: MonadLoggerIO m => Redis (Either Reply a) -> CacheT m a
+runRedis :: MonadLoggerIO m => Redis (Either Reply a) -> CacheX m a
 runRedis action =
     asks cacheConn >>= \conn ->
         liftIO (Redis.runRedis conn action) >>= \case
@@ -101,7 +101,8 @@
         , cacheChain :: !Chain
         }
 
-type CacheT = ReaderT CacheConfig
+type CacheT = ReaderT (Maybe CacheConfig)
+type CacheX = ReaderT CacheConfig
 
 data CacheError
     = RedisError Reply
@@ -136,13 +137,22 @@
     getAddressUnspents addr start = lift . getAddressUnspents addr start
     getAddressesUnspents addrs start = lift . getAddressesUnspents addrs start
     getMempool = lift getMempool
-    xPubBals = getXPubBalances
-    xPubUnspents = getXPubUnspents
-    xPubTxs = getXPubTxs
+    xPubBals xpub =
+        ask >>= \case
+            Nothing -> lift (xPubBals xpub)
+            Just cfg -> lift (runReaderT (getXPubBalances xpub) cfg)
+    xPubUnspents xpub start offset limit =
+        ask >>= \case
+            Nothing -> lift (xPubUnspents xpub start offset limit)
+            Just cfg -> lift (runReaderT (getXPubUnspents xpub start offset limit) cfg)
+    xPubTxs xpub start offset limit =
+        ask >>= \case
+            Nothing -> lift (xPubTxs xpub start offset limit)
+            Just cfg -> lift (runReaderT (getXPubTxs xpub start offset limit) cfg)
     getMaxGap = lift getMaxGap
     getInitialGap = lift getInitialGap
 
-withCache :: StoreRead m => CacheConfig -> CacheT m a -> m a
+withCache :: StoreRead m => (Maybe CacheConfig) -> CacheT m a -> m a
 withCache s f = runReaderT f s
 
 balancesPfx :: ByteString
@@ -160,7 +170,7 @@
     -> Maybe BlockRef
     -> Offset
     -> Maybe Limit
-    -> CacheT m [BlockTx]
+    -> CacheX m [BlockTx]
 getXPubTxs xpub start offset limit = do
     xpubtxt <- xpubText xpub
     $(logDebugS) "Cache" $ "Getting xpub txs for " <> xpubtxt
@@ -183,7 +193,7 @@
                     else do
                         $(logDebugS) "Cache" $
                             "Using DB to return txs for xpub " <> xpubtxt
-                        xPubBalsTxs bals start offset limit
+                        lift $ xPubBalsTxs bals start offset limit
 
 getXPubUnspents ::
        (MonadUnliftIO m, MonadLoggerIO m, StoreRead m)
@@ -191,7 +201,7 @@
     -> Maybe BlockRef
     -> Offset
     -> Maybe Limit
-    -> CacheT m [XPubUnspent]
+    -> CacheX m [XPubUnspent]
 getXPubUnspents xpub start offset limit = do
     xpubtxt <- xpubText xpub
     $(logDebugS) "Cache" $ "Getting utxo for xpub " <> xpubtxt
@@ -209,11 +219,11 @@
                     else do
                         $(logDebugS) "Cache" $
                             "Using DB to return utxo for xpub " <> xpubtxt
-                        xPubBalsUnspents bals start offset limit
+                        lift $ xPubBalsUnspents bals start offset limit
   where
     process bals = do
         ops <- map snd <$> cacheGetXPubUnspents xpub start offset limit
-        uns <- catMaybes <$> mapM getUnspent ops
+        uns <- catMaybes <$> lift (mapM getUnspent ops)
         let addrmap =
                 Map.fromList $
                 map (\b -> (balanceAddress (xPubBal b), xPubBalPath b)) bals
@@ -240,7 +250,7 @@
 getXPubBalances ::
        (MonadUnliftIO m, MonadLoggerIO m, StoreRead m)
     => XPubSpec
-    -> CacheT m [XPubBal]
+    -> CacheX m [XPubBal]
 getXPubBalances xpub = do
     xpubtxt <- xpubText xpub
     $(logDebugS) "Cache" $ "Getting balances for xpub " <> xpubtxt
@@ -255,13 +265,19 @@
             $(logDebugS) "Cache" $ "Caching balances for xpub " <> xpubtxt
             fst <$> newXPubC xpub
 
-isXPubCached :: MonadLoggerIO m => XPubSpec -> CacheT m Bool
+isInCache :: MonadLoggerIO m => XPubSpec -> CacheT m Bool
+isInCache xpub =
+    ask >>= \case
+        Nothing -> return False
+        Just cfg -> runReaderT (isXPubCached xpub) cfg
+
+isXPubCached :: MonadLoggerIO m => XPubSpec -> CacheX m Bool
 isXPubCached = runRedis . redisIsXPubCached
 
 redisIsXPubCached :: RedisCtx m f => XPubSpec -> m (f Bool)
 redisIsXPubCached xpub = Redis.exists (balancesPfx <> encode xpub)
 
-cacheGetXPubBalances :: MonadLoggerIO m => XPubSpec -> CacheT m [XPubBal]
+cacheGetXPubBalances :: MonadLoggerIO m => XPubSpec -> CacheX m [XPubBal]
 cacheGetXPubBalances xpub = do
     bals <- runRedis $ redisGetXPubBalances xpub
     touchKeys [xpub]
@@ -273,7 +289,7 @@
     -> Maybe BlockRef
     -> Offset
     -> Maybe Limit
-    -> CacheT m [BlockTx]
+    -> CacheX m [BlockTx]
 cacheGetXPubTxs xpub start offset limit = do
     txs <- runRedis $ redisGetXPubTxs xpub start offset limit
     touchKeys [xpub]
@@ -285,7 +301,7 @@
     -> Maybe BlockRef
     -> Offset
     -> Maybe Limit
-    -> CacheT m [(BlockRef, OutPoint)]
+    -> CacheX m [(BlockRef, OutPoint)]
 cacheGetXPubUnspents xpub start offset limit = do
     uns <- runRedis $ redisGetXPubUnspents xpub start offset limit
     touchKeys [xpub]
@@ -442,7 +458,7 @@
 maxKey :: ByteString
 maxKey = "max"
 
-isAnythingCached :: MonadLoggerIO m => CacheT m Bool
+isAnythingCached :: MonadLoggerIO m => CacheX m Bool
 isAnythingCached = runRedis $ Redis.exists maxKey
 
 xPubAddrFunction :: DeriveType -> XPubKey -> Address
@@ -464,7 +480,7 @@
             x <- receive inbox
             cacheWriterReact x
 
-lockIt :: MonadLoggerIO m => ByteString -> CacheT m (Maybe Word32)
+lockIt :: MonadLoggerIO m => ByteString -> CacheX m (Maybe Word32)
 lockIt k = do
     rnd <- liftIO randomIO
     go rnd >>= \case
@@ -498,7 +514,7 @@
             Redis.setOpts k (cs (show rnd)) opts
 
 
-unlockIt :: MonadLoggerIO m => ByteString -> Maybe Word32 -> CacheT m ()
+unlockIt :: MonadLoggerIO m => ByteString -> Maybe Word32 -> CacheX m ()
 unlockIt _ Nothing = return ()
 unlockIt k (Just i) =
     runRedis (Redis.get k) >>= \case
@@ -521,8 +537,8 @@
 withLock ::
        (MonadLoggerIO m, MonadUnliftIO m)
     => ByteString
-    -> CacheT m a
-    -> CacheT m (Maybe a)
+    -> CacheX m a
+    -> CacheX m (Maybe a)
 withLock k f =
     bracket (lockIt k) (unlockIt k) $ \case
         Just _ -> Just <$> f
@@ -531,8 +547,8 @@
 withLockWait ::
        (MonadLoggerIO m, MonadUnliftIO m)
     => ByteString
-    -> CacheT m a
-    -> CacheT m a
+    -> CacheX m a
+    -> CacheX m a
 withLockWait k f = do
     $(logDebugS) "Cache" $ "Acquiring " <> cs k <> " lock…"
     go
@@ -545,7 +561,7 @@
                 threadDelay r
                 go
 
-pruneDB :: (MonadUnliftIO m, MonadLoggerIO m, StoreRead m) => CacheT m Integer
+pruneDB :: (MonadUnliftIO m, MonadLoggerIO m, StoreRead m) => CacheX m Integer
 pruneDB = do
     isAnythingCached >>= \case
         True -> do
@@ -568,7 +584,7 @@
                         "Pruning " <> cs (show (length ks)) <> " old xpubs"
                     delXPubKeys ks
 
-touchKeys :: MonadLoggerIO m => [XPubSpec] -> CacheT m ()
+touchKeys :: MonadLoggerIO m => [XPubSpec] -> CacheX m ()
 touchKeys xpubs = do
     now <- systemSeconds <$> liftIO getSystemTime
     runRedis $ redisTouchKeys now xpubs
@@ -581,7 +597,7 @@
 cacheWriterReact ::
        (MonadUnliftIO m, MonadLoggerIO m, StoreRead m)
     => CacheWriterMessage
-    -> CacheT m ()
+    -> CacheX m ()
 cacheWriterReact CacheNewBlock = newBlockC
 cacheWriterReact (CacheNewTx th) =
     withLockWait importLockKey $ do
@@ -604,7 +620,7 @@
 newXPubC ::
        (MonadUnliftIO m, MonadLoggerIO m, StoreRead m)
     => XPubSpec
-    -> CacheT m ([XPubBal], Bool)
+    -> CacheX m ([XPubBal], Bool)
 newXPubC xpub =
     cachePrime >> do
         bals <- lift $ xPubBals xpub
@@ -647,7 +663,7 @@
             e <- redisAddXPubTxs xpub xtxs
             return $ b >> c >> d >> e >> return ()
 
-newBlockC :: (MonadUnliftIO m, MonadLoggerIO m, StoreRead m) => CacheT m ()
+newBlockC :: (MonadUnliftIO m, MonadLoggerIO m, StoreRead m) => CacheX m ()
 newBlockC = withLockWait importLockKey f
   where
     f =
@@ -709,7 +725,7 @@
                 Just newcachenode ->
                     importBlockC (headerHash (nodeHeader newcachenode)) >> f
 
-importBlockC :: (MonadUnliftIO m, StoreRead m, MonadLoggerIO m) => BlockHash -> CacheT m ()
+importBlockC :: (MonadUnliftIO m, StoreRead m, MonadLoggerIO m) => BlockHash -> CacheX m ()
 importBlockC bh =
     lift (getBlock bh) >>= \case
         Nothing -> do
@@ -733,7 +749,7 @@
             blockHashToHex bh
         cacheSetHead bh
 
-removeHeadC :: (StoreRead m, MonadUnliftIO m, MonadLoggerIO m) => CacheT m ()
+removeHeadC :: (StoreRead m, MonadUnliftIO m, MonadLoggerIO m) => CacheX m ()
 removeHeadC =
     void . runMaybeT $ do
         bh <- MaybeT cacheGetHead
@@ -752,7 +768,7 @@
 importMultiTxC ::
        (MonadUnliftIO m, StoreRead m, MonadLoggerIO m)
     => [TxData]
-    -> CacheT m ()
+    -> CacheX m ()
 importMultiTxC txs = do
     $(logDebugS) "Cache" $ "Processing " <> cs (show (length txs)) <> " txs…"
     $(logDebugS) "Cache" $
@@ -767,7 +783,7 @@
     $(logDebugS) "Cache" $
         "Getting unspent data for " <> cs (show (length allops)) <> " outputs…"
     unspentmap <- getunspents
-    gap <- getMaxGap
+    gap <- lift getMaxGap
     now <- systemSeconds <$> liftIO getSystemTime
     let xpubs = allxpubsls addrmap
     forM_ (zip [(1 :: Int) ..] xpubs) $ \(i, xpub) -> do
@@ -894,7 +910,7 @@
 cacheAddAddresses ::
        (StoreRead m, MonadUnliftIO m, MonadLoggerIO m)
     => [(Address, AddressXPub)]
-    -> CacheT m ()
+    -> CacheX m ()
 cacheAddAddresses [] = $(logDebugS) "Cache" "No further addresses to add"
 cacheAddAddresses addrs = do
     $(logDebugS) "Cache" $
@@ -916,7 +932,7 @@
     let xpubs = HashSet.toList . HashSet.fromList . map addressXPubSpec $ Map.elems amap
     $(logDebugS) "Cache" $ "Getting xpub balances…"
     xmap <- getbals xpubs
-    gap <- getMaxGap
+    gap <- lift getMaxGap
     let notnulls = getnotnull balmap
         addrs' = getNewAddrs gap xmap notnulls
     cacheAddAddresses addrs'
@@ -964,7 +980,7 @@
             Nothing   -> []
             Just bals -> addrsToAdd gap bals a
 
-syncMempoolC :: (MonadUnliftIO m, MonadLoggerIO m, StoreRead m) => CacheT m ()
+syncMempoolC :: (MonadUnliftIO m, MonadLoggerIO m, StoreRead m) => CacheX m ()
 syncMempoolC = do
     nodepool <- (HashSet.fromList . map blockTxHash) <$> lift getMempool
     cachepool <- (HashSet.fromList . map blockTxHash) <$> cacheGetMempool
@@ -989,15 +1005,15 @@
             Nothing -> return (Left th)
             Just tx -> return (Right tx)
 
-cacheGetMempool :: MonadLoggerIO m => CacheT m [BlockTx]
+cacheGetMempool :: MonadLoggerIO m => CacheX m [BlockTx]
 cacheGetMempool = runRedis redisGetMempool
 
-cacheGetHead :: MonadLoggerIO m => CacheT m (Maybe BlockHash)
+cacheGetHead :: MonadLoggerIO m => CacheX m (Maybe BlockHash)
 cacheGetHead = runRedis redisGetHead
 
 cachePrime ::
        (StoreRead m, MonadUnliftIO m, MonadLoggerIO m)
-    => CacheT m (Maybe BlockHash)
+    => CacheX m (Maybe BlockHash)
 cachePrime =
     cacheGetHead >>= \case
         Nothing -> do
@@ -1014,13 +1030,13 @@
                         return $ a >> b >> return (Just newhead)
         Just cachehead -> return $ Just cachehead
 
-cacheSetHead :: (MonadLoggerIO m, StoreRead m) => BlockHash -> CacheT m ()
+cacheSetHead :: (MonadLoggerIO m, StoreRead m) => BlockHash -> CacheX m ()
 cacheSetHead bh = do
     $(logDebugS) "Cache" $ "Cache head set to: " <> blockHashToHex bh
     runRedis (redisSetHead bh) >> return ()
 
 cacheGetAddrsInfo ::
-       MonadLoggerIO m => [Address] -> CacheT m [Maybe AddressXPub]
+       MonadLoggerIO m => [Address] -> CacheX m [Maybe AddressXPub]
 cacheGetAddrsInfo as = runRedis (redisGetAddrsInfo as)
 
 redisAddToMempool :: (Applicative f, RedisCtx m f) => [BlockTx] -> m (f Integer)
@@ -1039,10 +1055,18 @@
        (Functor f, RedisCtx m f) => Address -> AddressXPub -> m (f ())
 redisSetAddrInfo a i = void <$> Redis.set (addrPfx <> encode a) (encode i)
 
+evictFromCache ::
+       (MonadUnliftIO m, MonadLoggerIO m, StoreRead m)
+    => [XPubSpec]
+    -> CacheT m ()
+evictFromCache xpubs = ask >>= \case
+    Nothing -> return ()
+    Just cfg -> void (runReaderT (delXPubKeys xpubs) cfg)
+
 delXPubKeys ::
        (MonadUnliftIO m, MonadLoggerIO m, StoreRead m)
     => [XPubSpec]
-    -> CacheT m Integer
+    -> CacheX m Integer
 delXPubKeys [] = return 0
 delXPubKeys xpubs = do
     forM_ xpubs $ \x -> do
@@ -1193,9 +1217,9 @@
   where
     f t s = BlockTx {blockTxBlock = scoreBlockRef s, blockTxHash = t}
 
-xpubText :: (MonadUnliftIO m, MonadLoggerIO m, StoreRead m) => XPubSpec -> CacheT m Text
+xpubText :: (MonadUnliftIO m, MonadLoggerIO m, StoreRead m) => XPubSpec -> CacheX m Text
 xpubText xpub = do
-    net <- getNetwork
+    net <- lift getNetwork
     return . cs $ xPubExport net (xPubSpecKey xpub)
 
 cacheNewBlock :: MonadIO m => CacheWriter -> m ()
diff --git a/src/Haskoin/Store/Web.hs b/src/Haskoin/Store/Web.hs
--- a/src/Haskoin/Store/Web.hs
+++ b/src/Haskoin/Store/Web.hs
@@ -18,7 +18,8 @@
 import           Control.Monad.Logger          (MonadLogger, MonadLoggerIO,
                                                 askLoggerIO, logInfoS,
                                                 monadLoggerLog)
-import           Control.Monad.Reader          (ReaderT, asks, runReaderT)
+import           Control.Monad.Reader          (ReaderT, asks, local,
+                                                runReaderT)
 import           Control.Monad.Trans           (lift)
 import           Control.Monad.Trans.Maybe     (MaybeT (..), runMaybeT)
 import           Data.Aeson                    (Encoding, ToJSON (..))
@@ -58,7 +59,8 @@
 import           Haskoin.Node                  (Chain, OnlinePeer (..),
                                                 PeerManager, chainGetBest,
                                                 managerGetPeers, sendMessage)
-import           Haskoin.Store.Cache           (CacheT, delXPubKeys, withCache)
+import           Haskoin.Store.Cache           (CacheT, evictFromCache,
+                                                withCache)
 import           Haskoin.Store.Common          (Limit, Offset, PubExcept (..),
                                                 StoreEvent (..), StoreRead (..),
                                                 applyOffset, blockAtOrBefore,
@@ -182,56 +184,43 @@
 
 runInWebReader ::
        MonadIO m
-    => DatabaseReaderT m a
-    -> CacheT (DatabaseReaderT m) a
+    => CacheT (DatabaseReaderT m) a
     -> ReaderT WebConfig m a
-runInWebReader bf cf = do
+runInWebReader f = do
     bdb <- asks (storeDB . webStore)
     mc <- asks (storeCache . webStore)
-    lift $ withDatabaseReader bdb $
-        case mc of
-            Nothing -> bf
-            Just c  -> withCache c cf
+    lift $ withDatabaseReader bdb (withCache mc f)
 
-runNoCache :: MonadIO m => DatabaseReaderT m a -> WebT m a
-runNoCache f = lift $ do
-    bdb <- asks (storeDB . webStore)
-    lift $ withDatabaseReader bdb f
+runNoCache :: MonadIO m => Bool -> ReaderT WebConfig m a -> ReaderT WebConfig m a
+runNoCache False f = f
+runNoCache True f =
+    local (\s -> s {webStore = (webStore s) {storeCache = Nothing}}) f
 
 instance (MonadUnliftIO m, MonadLoggerIO m) =>
          StoreRead (ReaderT WebConfig m) where
-    getMaxGap = runInWebReader getMaxGap getMaxGap
-    getInitialGap = runInWebReader getInitialGap getInitialGap
-    getNetwork = runInWebReader getNetwork getNetwork
-    getBestBlock = runInWebReader getBestBlock getBestBlock
-    getBlocksAtHeight height =
-        runInWebReader (getBlocksAtHeight height) (getBlocksAtHeight height)
-    getBlock bh = runInWebReader (getBlock bh) (getBlock bh)
-    getTxData th = runInWebReader (getTxData th) (getTxData th)
-    getSpender op = runInWebReader (getSpender op) (getSpender op)
-    getSpenders th = runInWebReader (getSpenders th) (getSpenders th)
-    getUnspent op = runInWebReader (getUnspent op) (getUnspent op)
-    getBalance a = runInWebReader (getBalance a) (getBalance a)
-    getBalances as = runInWebReader (getBalances as) (getBalances as)
-    getMempool = runInWebReader getMempool getMempool
+    getMaxGap = runInWebReader getMaxGap
+    getInitialGap = runInWebReader getInitialGap
+    getNetwork = runInWebReader getNetwork
+    getBestBlock = runInWebReader getBestBlock
+    getBlocksAtHeight height = runInWebReader (getBlocksAtHeight height)
+    getBlock bh = runInWebReader (getBlock bh)
+    getTxData th = runInWebReader (getTxData th)
+    getSpender op = runInWebReader (getSpender op)
+    getSpenders th = runInWebReader (getSpenders th)
+    getUnspent op = runInWebReader (getUnspent op)
+    getBalance a = runInWebReader (getBalance a)
+    getBalances as = runInWebReader (getBalances as)
+    getMempool = runInWebReader getMempool
     getAddressesTxs addrs start limit =
-        runInWebReader
-            (getAddressesTxs addrs start limit)
-            (getAddressesTxs addrs start limit)
+        runInWebReader (getAddressesTxs addrs start limit)
     getAddressesUnspents addrs start limit =
-        runInWebReader
-            (getAddressesUnspents addrs start limit)
-            (getAddressesUnspents addrs start limit)
-    xPubBals xpub = runInWebReader (xPubBals xpub) (xPubBals xpub)
-    xPubSummary xpub = runInWebReader (xPubSummary xpub) (xPubSummary xpub)
+        runInWebReader (getAddressesUnspents addrs start limit)
+    xPubBals xpub = runInWebReader (xPubBals xpub)
+    xPubSummary xpub = runInWebReader (xPubSummary xpub)
     xPubUnspents xpub start offset limit =
-        runInWebReader
-            (xPubUnspents xpub start offset limit)
-            (xPubUnspents xpub start offset limit)
+        runInWebReader (xPubUnspents xpub start offset limit)
     xPubTxs xpub start offset limit =
-        runInWebReader
-            (xPubTxs xpub start offset limit)
-            (xPubTxs xpub start offset limit)
+        runInWebReader (xPubTxs xpub start offset limit)
 
 instance (MonadUnliftIO m, MonadLoggerIO m) => StoreRead (WebT m) where
     getNetwork = lift getNetwork
@@ -583,9 +572,7 @@
     proto <- setupBin
     res <-
         filter (not . nullBalance . xPubBal) <$>
-        if nocache
-            then runNoCache (xPubBals xpub)
-            else xPubBals xpub
+        lift (runNoCache nocache (xPubBals xpub))
     protoSerialNet proto (list . xPubBalToEncoding) res
 
 scottyXpubTxs :: (MonadUnliftIO m, MonadLoggerIO m) => Bool -> WebT m ()
@@ -597,27 +584,23 @@
     limit <- getLimit full
     o <- getOffset
     proto <- setupBin
-    txs <- xPubTxs xpub start o limit
+    txs <- lift . runNoCache nocache $ xPubTxs xpub start o limit
     if full
         then do
             txs' <-
-                catMaybes <$>
-                if nocache
-                    then runNoCache (mapM (getTransaction . blockTxHash) txs)
-                    else mapM (getTransaction . blockTxHash) txs
+                fmap catMaybes . lift . runNoCache nocache $
+                mapM (getTransaction . blockTxHash) txs
             protoSerialNet proto (list . transactionToEncoding) txs'
         else protoSerial proto txs
 
 scottyXpubEvict :: (MonadUnliftIO m, MonadLoggerIO m) => WebT m ()
 scottyXpubEvict =
-    lift (asks (storeCache . webStore)) >>= \case
-        Nothing -> S.raise ThingNotFound
-        Just cache -> do
-            setHeaders
-            xpub <- parseXpub
-            proto <- setupBin
-            n <- lift $ withCache cache (delXPubKeys [xpub])
-            protoSerial proto (GenericResult (n > 0))
+    lift (asks (storeCache . webStore)) >>= \cache -> do
+        setHeaders
+        xpub <- parseXpub
+        proto <- setupBin
+        lift . withCache cache $ evictFromCache [xpub]
+        protoSerial proto (GenericResult True)
 
 
 scottyXpubUnspents :: (MonadUnliftIO m, MonadLoggerIO m) => WebT m ()
@@ -627,11 +610,9 @@
     xpub <- parseXpub
     proto <- setupBin
     start <- getStart
+    o <- getOffset
     limit <- getLimit False
-    uns <-
-        if nocache
-            then runNoCache (xPubUnspents xpub start 0 limit)
-            else xPubUnspents xpub start 0 limit
+    uns <- lift . runNoCache nocache $ xPubUnspents xpub start o limit
     protoSerialNet proto (list . xPubUnspentToEncoding) uns
 
 scottyXpubSummary :: (MonadUnliftIO m, MonadLoggerIO m) => WebT m ()
@@ -640,10 +621,7 @@
     nocache <- parseNoCache
     xpub <- parseXpub
     proto <- setupBin
-    res <-
-        if nocache
-            then runNoCache (xPubSummary xpub)
-            else xPubSummary xpub
+    res <- lift . runNoCache nocache $ xPubSummary xpub
     protoSerial proto res
 
 scottyPostTx ::
