{-------------------------------------------------------------------------------
  Top-level coin selection
-------------------------------------------------------------------------------}

runCoinSelT :: forall utxo e h a m.
               (GenHash m, Dom utxo ~ DSL h a, CoinSelDom (DSL h a))
            => a      -- ^ Change address
            -> CoinSelT utxo e m [CoinSelResult (Dom utxo)]
            -> utxo   -- ^ Available UTxO
            -> m (Either e (DSL.Transaction h a, TxStats, utxo))
runCoinSelT changeAddr policy utxo = do
    mSelection <- unwrapCoinSelT policy utxo
    case mSelection of
      Left err -> return (Left err)
      Right (cssWithDust, utxo') -> do
          let css = map (coinSelRemoveDust valueZero) cssWithDust
          tx <- mkTx changeAddr css
          return $ Right (tx, deriveTxStats css, utxo')
runCoinSelT :: forall utxo e h a m.
               (GenHash m, Dom utxo ~ DSL h a, CoinSelDom (DSL h a))
            => a      -- ^ Change address
            -> CoinSelT utxo e m [CoinSelResult (Dom utxo)]
            -> utxo   -- ^ Available UTxO
            -> m (Either e (DSL.Transaction h a, TxStats, utxo))
runCoinSelT changeAddr policy utxo = do
    mSelection <- unwrapCoinSelT policy utxo
    case mSelection of
      Left err -> return (Left err)
      Right (cssWithDust, utxo') -> do
          let css = map (coinSelRemoveDust valueZero) cssWithDust
          tx <- mkTx changeAddr css
          return $ Right (tx, deriveTxStats css, utxo')
runCoinSelT changeAddr policy utxo = do
    mSelection <- unwrapCoinSelT policy utxo
    case mSelection of
      Left err -> return (Left err)
      Right (cssWithDust, utxo') -> do
          let css = map (coinSelRemoveDust valueZero) cssWithDust
          tx <- mkTx changeAddr css
          return $ Right (tx, deriveTxStats css, utxo')