signTx :: Tx               -- ^ Transaction to sign
          -> [SigInput]       -- ^ SigInput signing parameters
          -> [PrvKey]         -- ^ List of private keys to use for signing
          -> Either String Tx -- ^ Signed transaction
signTx otx@(Tx _ ti _ _) sigis allKeys
    | null ti   = Left "signTx: Transaction has no inputs"
    | otherwise = foldM go otx $ findSigInput sigis ti
  where
    go tx (sigi@(SigInput so _ _ rdmM), i) = do
        keys <- sigKeys so rdmM allKeys
        foldM (\t k -> signInput t i sigi k) tx keys

-- | Sign a single input in a transaction deterministically (RFC-6979).
signTx :: Tx               -- ^ Transaction to sign
          -> [SigInput]       -- ^ SigInput signing parameters
          -> [PrvKey]         -- ^ List of private keys to use for signing
          -> Either String Tx
signTx otx@(Tx _ ti _ _) sigis allKeys
    | null ti   = Left "signTx: Transaction has no inputs"
    | otherwise = foldM go otx $ findSigInput sigis ti
  where
    go tx (sigi@(SigInput so _ _ rdmM), i) = do
        keys <- sigKeys so rdmM allKeys
        foldM (\t k -> signInput t i sigi k) tx keys

-- | Sign a single input in a transaction deterministically (RFC-6979).
signTx otx@(Tx _ ti _ _) sigis allKeys
    | null ti   = Left "signTx: Transaction has no inputs"
    | otherwise = foldM go otx $ findSigInput sigis ti
  where
    go tx (sigi@(SigInput so _ _ rdmM), i) = do
        keys <- sigKeys so rdmM allKeys
        foldM (\t k -> signInput t i sigi k) tx keys

-- | Sign a single input in a transaction deterministically (RFC-6979).