chooseMSCoinsSink :: (Monad m, Coin c)
                  => Word64     -- ^ Target price to pay.
                  -> Word64     -- ^ Fee price per 1000 bytes.
                  -> (Int, Int) -- ^ Multisig parameters m of n (m,n).
                  -> Bool -- ^ Try to find better solution when one is found
                  -> Sink c m (Either String ([c], Word64))
                     -- ^ Coin selection result and change amount.
chooseMSCoinsSink target kbfee ms continue
    | target > 0 =
        maybeToEither err <$> greedyAddSink target (getMSFee kbfee ms) continue
    | otherwise = return $ Left "chooseMSCoins: Target must be > 0"
  where
    err = "chooseMSCoins: No solution found"

-- Select coins greedily by starting from an empty solution. If the continue
-- value is set to True, the algorithm will try to find a better solution in
-- the stream once a solution is found. If the next solution found is not
-- strictly better than the previously found solution, the algorithm stops and
-- returns the previous solution. If the continue value is set to False, the
-- algorithm will return the first solution it finds in the stream.
chooseMSCoinsSink :: (Monad m, Coin c)
                  => Word64     -- ^ Target price to pay.
                  -> Word64     -- ^ Fee price per 1000 bytes.
                  -> (Int, Int) -- ^ Multisig parameters m of n (m,n).
                  -> Bool -- ^ Try to find better solution when one is found
                  -> Sink c m (Either String ([c], Word64))
chooseMSCoinsSink target kbfee ms continue
    | target > 0 =
        maybeToEither err <$> greedyAddSink target (getMSFee kbfee ms) continue
    | otherwise = return $ Left "chooseMSCoins: Target must be > 0"
  where
    err = "chooseMSCoins: No solution found"

-- Select coins greedily by starting from an empty solution. If the continue
-- value is set to True, the algorithm will try to find a better solution in
-- the stream once a solution is found. If the next solution found is not
-- strictly better than the previously found solution, the algorithm stops and
-- returns the previous solution. If the continue value is set to False, the
-- algorithm will return the first solution it finds in the stream.
chooseMSCoinsSink target kbfee ms continue
    | target > 0 =
        maybeToEither err <$> greedyAddSink target (getMSFee kbfee ms) continue
    | otherwise = return $ Left "chooseMSCoins: Target must be > 0"
  where
    err = "chooseMSCoins: No solution found"

-- Select coins greedily by starting from an empty solution. If the continue
-- value is set to True, the algorithm will try to find a better solution in
-- the stream once a solution is found. If the next solution found is not
-- strictly better than the previously found solution, the algorithm stops and
-- returns the previous solution. If the continue value is set to False, the
-- algorithm will return the first solution it finds in the stream.