content: {-# LANGUAGE TemplateHaskell #-}
  
  -- | Wallet with incremental balance updates and prefiltering
  module Wallet.Prefiltered (
      -- * State (re-exported from "Wallet.Incremental")
      Incr.State
    , Incr.stateUtxo
    , Incr.statePending
    , Incr.stateUtxoBalance
    , Incr.initState
      -- Construction
    , mkWallet
    , walletEmpty
    ) where
  
  import           Universum
  
  import qualified Data.Set as Set
  
  import           UTxO.DSL
  import           Wallet.Abstract
  import qualified Wallet.Incremental as Incr
  
  {-------------------------------------------------------------------------------
    Construction
  -------------------------------------------------------------------------------}
  
  mkWallet :: (Hash h a, Buildable st)
           => Ours a -> Lens' st (Incr.State h a) -> WalletConstr h a st
  mkWallet ours l self st = (Incr.mkWallet ours l self st) {
        applyBlock = \b ->
          let utxoPlus   = utxoRestrictToOurs ours (txOuts b)
              filterUtxo = utxo this `utxoUnion` utxoPlus
              filtered   = txIns b `Set.intersection` utxoDomain filterUtxo
          in self (st & l %~ Incr.applyBlock' (filtered, utxoPlus))
      }
    where
      this = self st
  
  walletEmpty :: (Hash h a, Buildable a) => Ours a -> Wallet h a
  walletEmpty ours = fix (mkWallet ours identity) Incr.initState
  