{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

-- | Helpers shared by the transaction and sub-transaction body builders.
module Cardano.CLI.EraBased.Transaction.Internal.Common
  ( toTxOutInEra
  , toTxOutInShelleyBasedEra
  , getAllReferenceInputs
  , createTxMintValue
  , convertWithdrawals
  , convertVotingProcedures
  , scriptInEraToSimpleScript
  , partitionSomeWitnesses
  )
where

import Cardano.Api
import Cardano.Api.Experimental (obtainCommonConstraints)
import Cardano.Api.Experimental qualified as Exp
import Cardano.Api.Experimental.AnyScriptWitness qualified as Exp
import Cardano.Api.Experimental.Tx qualified as Exp
import Cardano.Api.Ledger qualified as L

import Cardano.CLI.Compatible.Exception
import Cardano.CLI.Compatible.Transaction.TxOut
import Cardano.CLI.Read
import Cardano.CLI.Type.Common
import Cardano.CLI.Type.Error.TxCmdError
import Cardano.Ledger.Hashes (DataHash)

import RIO hiding (toList)

import Data.Foldable qualified as Foldable
import Data.List qualified as List
import Data.Map.Strict qualified as Map
import Data.Set qualified as Set
import GHC.Exts (IsList (..))

toTxOutInEra
  :: forall era e
   . Exp.IsEra era
  => TxOutAnyEra
  -> CIO e (Exp.TxOut (Exp.LedgerEra era), Map.Map DataHash (L.Data (Exp.LedgerEra era)))
toTxOutInEra :: forall era e.
IsEra era =>
TxOutAnyEra
-> CIO
     e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era)))
toTxOutInEra (TxOutAnyEra AddressAny
addr' Value
val' TxOutDatumAnyEra
mDatumHash ReferenceScriptAnyEra
refScriptFp) = do
  let sbe :: ShelleyBasedEra era
sbe = Era era -> ShelleyBasedEra era
forall era. Era era -> ShelleyBasedEra era
forall a (f :: a -> *) (g :: a -> *) (era :: a).
Convert f g =>
f era -> g era
convert (forall era. IsEra era => Era era
Exp.useEra @era)
      addr :: AddressInEra era
addr = ShelleyBasedEra era -> AddressAny -> AddressInEra era
forall era. ShelleyBasedEra era -> AddressAny -> AddressInEra era
anyAddressInShelleyBasedEra ShelleyBasedEra era
sbe AddressAny
addr'
  Era era
-> (EraCommonConstraints era =>
    RIO e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era))))
-> RIO
     e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era)))
forall era a. Era era -> (EraCommonConstraints era => a) -> a
obtainCommonConstraints (forall era. IsEra era => Era era
Exp.useEra @era) ((EraCommonConstraints era =>
  RIO e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era))))
 -> RIO
      e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era))))
-> (EraCommonConstraints era =>
    RIO e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era))))
-> RIO
     e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era)))
forall a b. (a -> b) -> a -> b
$
    ShelleyBasedEra era
-> AddressInEra era
-> Value
-> TxOutDatumAnyEra
-> ReferenceScriptAnyEra
-> CIO
     e
     (TxOut (ShelleyLedgerEra era),
      Map DataHash (Data (ShelleyLedgerEra era)))
forall era e.
ShelleyBasedEra era
-> AddressInEra era
-> Value
-> TxOutDatumAnyEra
-> ReferenceScriptAnyEra
-> CIO
     e
     (TxOut (ShelleyLedgerEra era),
      Map DataHash (Data (ShelleyLedgerEra era)))
mkTxOut ShelleyBasedEra era
sbe AddressInEra era
addr Value
val' TxOutDatumAnyEra
mDatumHash ReferenceScriptAnyEra
refScriptFp

toTxOutInShelleyBasedEra
  :: forall era e
   . Exp.IsEra era
  => TxOutShelleyBasedEra
  -> CIO e (Exp.TxOut (Exp.LedgerEra era), Map.Map DataHash (L.Data (Exp.LedgerEra era)))
toTxOutInShelleyBasedEra :: forall era e.
IsEra era =>
TxOutShelleyBasedEra
-> CIO
     e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era)))
toTxOutInShelleyBasedEra (TxOutShelleyBasedEra Address ShelleyAddr
addr' Value
val' TxOutDatumAnyEra
mDatumHash ReferenceScriptAnyEra
refScriptFp) = do
  let sbe :: ShelleyBasedEra era
sbe = Era era -> ShelleyBasedEra era
forall era. Era era -> ShelleyBasedEra era
forall a (f :: a -> *) (g :: a -> *) (era :: a).
Convert f g =>
f era -> g era
convert (forall era. IsEra era => Era era
Exp.useEra @era)
      addr :: AddressInEra era
addr = ShelleyBasedEra era -> Address ShelleyAddr -> AddressInEra era
forall era.
ShelleyBasedEra era -> Address ShelleyAddr -> AddressInEra era
shelleyAddressInEra ShelleyBasedEra era
sbe Address ShelleyAddr
addr'
  Era era
-> (EraCommonConstraints era =>
    RIO e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era))))
-> RIO
     e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era)))
forall era a. Era era -> (EraCommonConstraints era => a) -> a
obtainCommonConstraints (forall era. IsEra era => Era era
Exp.useEra @era) ((EraCommonConstraints era =>
  RIO e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era))))
 -> RIO
      e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era))))
-> (EraCommonConstraints era =>
    RIO e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era))))
-> RIO
     e (TxOut (LedgerEra era), Map DataHash (Data (LedgerEra era)))
forall a b. (a -> b) -> a -> b
$
    ShelleyBasedEra era
-> AddressInEra era
-> Value
-> TxOutDatumAnyEra
-> ReferenceScriptAnyEra
-> CIO
     e
     (TxOut (ShelleyLedgerEra era),
      Map DataHash (Data (ShelleyLedgerEra era)))
forall era e.
ShelleyBasedEra era
-> AddressInEra era
-> Value
-> TxOutDatumAnyEra
-> ReferenceScriptAnyEra
-> CIO
     e
     (TxOut (ShelleyLedgerEra era),
      Map DataHash (Data (ShelleyLedgerEra era)))
mkTxOut ShelleyBasedEra era
sbe AddressInEra era
addr Value
val' TxOutDatumAnyEra
mDatumHash ReferenceScriptAnyEra
refScriptFp

getAllReferenceInputs
  :: [Exp.AnyWitness (Exp.LedgerEra era)]
  -> [Exp.AnyScriptWitness (Exp.LedgerEra era)]
  -> [Exp.AnyWitness (Exp.LedgerEra era)]
  -- ^ Certificate witnesses
  -> [Exp.AnyWitness (Exp.LedgerEra era)]
  -> [Exp.AnyWitness (Exp.LedgerEra era)]
  -> [Exp.AnyWitness (Exp.LedgerEra era)]
  -> [TxIn]
  -- ^ Read only reference inputs
  -> [TxIn]
getAllReferenceInputs :: forall era.
[AnyWitness (LedgerEra era)]
-> [AnyScriptWitness (LedgerEra era)]
-> [AnyWitness (LedgerEra era)]
-> [AnyWitness (LedgerEra era)]
-> [AnyWitness (LedgerEra era)]
-> [AnyWitness (LedgerEra era)]
-> [TxIn]
-> [TxIn]
getAllReferenceInputs
  [AnyWitness (LedgerEra era)]
spendingWitnesses
  [AnyScriptWitness (LedgerEra era)]
mintWitnesses
  [AnyWitness (LedgerEra era)]
certScriptWitnesses
  [AnyWitness (LedgerEra era)]
withdrawals
  [AnyWitness (LedgerEra era)]
votingProceduresAndMaybeScriptWits
  [AnyWitness (LedgerEra era)]
propProceduresAnMaybeScriptWits
  [TxIn]
readOnlyRefIns = do
    let txinsWitByRefInputs :: [TxIn]
txinsWitByRefInputs = (AnyWitness (LedgerEra era) -> Maybe TxIn)
-> [AnyWitness (LedgerEra era)] -> [TxIn]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe AnyWitness (LedgerEra era) -> Maybe TxIn
forall era. AnyWitness era -> Maybe TxIn
Exp.getAnyWitnessReferenceInput [AnyWitness (LedgerEra era)]
spendingWitnesses
        mintingRefInputs :: [TxIn]
mintingRefInputs = (AnyScriptWitness (LedgerEra era) -> Maybe TxIn)
-> [AnyScriptWitness (LedgerEra era)] -> [TxIn]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe AnyScriptWitness (LedgerEra era) -> Maybe TxIn
forall era. AnyScriptWitness era -> Maybe TxIn
Exp.getAnyScriptWitnessReferenceInput [AnyScriptWitness (LedgerEra era)]
mintWitnesses
        certsWitByRefInputs :: [TxIn]
certsWitByRefInputs = (AnyWitness (LedgerEra era) -> Maybe TxIn)
-> [AnyWitness (LedgerEra era)] -> [TxIn]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe AnyWitness (LedgerEra era) -> Maybe TxIn
forall era. AnyWitness era -> Maybe TxIn
Exp.getAnyWitnessReferenceInput [AnyWitness (LedgerEra era)]
certScriptWitnesses
        withdrawalsWitByRefInputs :: [TxIn]
withdrawalsWitByRefInputs = (AnyWitness (LedgerEra era) -> Maybe TxIn)
-> [AnyWitness (LedgerEra era)] -> [TxIn]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe AnyWitness (LedgerEra era) -> Maybe TxIn
forall era. AnyWitness era -> Maybe TxIn
Exp.getAnyWitnessReferenceInput [AnyWitness (LedgerEra era)]
withdrawals
        votesWitByRefInputs :: [TxIn]
votesWitByRefInputs = (AnyWitness (LedgerEra era) -> Maybe TxIn)
-> [AnyWitness (LedgerEra era)] -> [TxIn]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe AnyWitness (LedgerEra era) -> Maybe TxIn
forall era. AnyWitness era -> Maybe TxIn
Exp.getAnyWitnessReferenceInput [AnyWitness (LedgerEra era)]
votingProceduresAndMaybeScriptWits
        propsWitByRefInputs :: [TxIn]
propsWitByRefInputs = (AnyWitness (LedgerEra era) -> Maybe TxIn)
-> [AnyWitness (LedgerEra era)] -> [TxIn]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe AnyWitness (LedgerEra era) -> Maybe TxIn
forall era. AnyWitness era -> Maybe TxIn
Exp.getAnyWitnessReferenceInput [AnyWitness (LedgerEra era)]
propProceduresAnMaybeScriptWits

    [[TxIn]] -> [TxIn]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
      [ [TxIn]
txinsWitByRefInputs
      , [TxIn]
mintingRefInputs
      , [TxIn]
certsWitByRefInputs
      , [TxIn]
withdrawalsWitByRefInputs
      , [TxIn]
votesWitByRefInputs
      , [TxIn]
propsWitByRefInputs
      , (TxIn -> Maybe TxIn) -> [TxIn] -> [TxIn]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe TxIn -> Maybe TxIn
forall a. a -> Maybe a
Just [TxIn]
readOnlyRefIns
      ]

-- TODO: Currently we specify the policyId with the '--mint' option on the cli
-- and we added a separate '--policy-id' parser that parses the policy id for the
-- given reference input (since we don't have the script in this case). To avoid asking
-- for the policy id twice (in the build command) we can potentially query the UTxO and
-- access the script (and therefore the policy id).
createTxMintValue
  :: (L.MultiAsset, [(PolicyId, Exp.AnyScriptWitness (Exp.LedgerEra era))])
  -> Either TxCmdError (Exp.TxMintValue (Exp.LedgerEra era))
createTxMintValue :: forall era.
(MultiAsset, [(PolicyId, AnyScriptWitness (LedgerEra era))])
-> Either TxCmdError (TxMintValue (LedgerEra era))
createTxMintValue (MultiAsset
val, [(PolicyId, AnyScriptWitness (LedgerEra era))]
scriptWitnesses) =
  if MultiAsset
forall a. Monoid a => a
mempty MultiAsset -> MultiAsset -> Bool
forall a. Eq a => a -> a -> Bool
== MultiAsset
val Bool -> Bool -> Bool
&& [(PolicyId, AnyScriptWitness (LedgerEra era))] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
List.null [(PolicyId, AnyScriptWitness (LedgerEra era))]
scriptWitnesses
    then TxMintValue (LedgerEra era)
-> Either TxCmdError (TxMintValue (LedgerEra era))
forall a. a -> Either TxCmdError a
forall (m :: * -> *) a. Monad m => a -> m a
return (TxMintValue (LedgerEra era)
 -> Either TxCmdError (TxMintValue (LedgerEra era)))
-> TxMintValue (LedgerEra era)
-> Either TxCmdError (TxMintValue (LedgerEra era))
forall a b. (a -> b) -> a -> b
$ Map PolicyId (PolicyAssets, AnyScriptWitness (LedgerEra era))
-> TxMintValue (LedgerEra era)
forall era.
Map PolicyId (PolicyAssets, AnyScriptWitness era)
-> TxMintValue era
Exp.TxMintValue Map PolicyId (PolicyAssets, AnyScriptWitness (LedgerEra era))
forall k a. Map k a
Map.empty
    else do
      let policiesWithAssets :: Map PolicyId PolicyAssets
          policiesWithAssets :: Map PolicyId PolicyAssets
policiesWithAssets = MultiAsset -> Map PolicyId PolicyAssets
multiAssetToPolicyAssets MultiAsset
val
          -- The set of policy ids for which we need witnesses:
          witnessesNeededSet :: Set PolicyId
          witnessesNeededSet :: Set PolicyId
witnessesNeededSet = Map PolicyId PolicyAssets -> Set PolicyId
forall k a. Map k a -> Set k
Map.keysSet Map PolicyId PolicyAssets
policiesWithAssets

      let witnessesProvidedMap :: Map PolicyId (AnyScriptWitness (LedgerEra era))
witnessesProvidedMap = [Item (Map PolicyId (AnyScriptWitness (LedgerEra era)))]
-> Map PolicyId (AnyScriptWitness (LedgerEra era))
forall l. IsList l => [Item l] -> l
fromList [(PolicyId, AnyScriptWitness (LedgerEra era))]
[Item (Map PolicyId (AnyScriptWitness (LedgerEra era)))]
scriptWitnesses
          witnessesProvidedSet :: Set PolicyId
          witnessesProvidedSet :: Set PolicyId
witnessesProvidedSet = Map PolicyId (AnyScriptWitness (LedgerEra era)) -> Set PolicyId
forall k a. Map k a -> Set k
Map.keysSet Map PolicyId (AnyScriptWitness (LedgerEra era))
witnessesProvidedMap

      -- Check not too many, nor too few:
      Set PolicyId -> Set PolicyId -> Either TxCmdError ()
validateAllWitnessesProvided Set PolicyId
witnessesNeededSet Set PolicyId
witnessesProvidedSet
      Set PolicyId -> Set PolicyId -> Either TxCmdError ()
validateNoUnnecessaryWitnesses Set PolicyId
witnessesNeededSet Set PolicyId
witnessesProvidedSet
      TxMintValue (LedgerEra era)
-> Either TxCmdError (TxMintValue (LedgerEra era))
forall a. a -> Either TxCmdError a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TxMintValue (LedgerEra era)
 -> Either TxCmdError (TxMintValue (LedgerEra era)))
-> TxMintValue (LedgerEra era)
-> Either TxCmdError (TxMintValue (LedgerEra era))
forall a b. (a -> b) -> a -> b
$
        Map PolicyId (PolicyAssets, AnyScriptWitness (LedgerEra era))
-> TxMintValue (LedgerEra era)
forall era.
Map PolicyId (PolicyAssets, AnyScriptWitness era)
-> TxMintValue era
Exp.TxMintValue (Map PolicyId (PolicyAssets, AnyScriptWitness (LedgerEra era))
 -> TxMintValue (LedgerEra era))
-> Map PolicyId (PolicyAssets, AnyScriptWitness (LedgerEra era))
-> TxMintValue (LedgerEra era)
forall a b. (a -> b) -> a -> b
$
          (PolicyAssets
 -> AnyScriptWitness (LedgerEra era)
 -> (PolicyAssets, AnyScriptWitness (LedgerEra era)))
-> Map PolicyId PolicyAssets
-> Map PolicyId (AnyScriptWitness (LedgerEra era))
-> Map PolicyId (PolicyAssets, AnyScriptWitness (LedgerEra era))
forall k a b c.
Ord k =>
(a -> b -> c) -> Map k a -> Map k b -> Map k c
Map.intersectionWith
            (,)
            Map PolicyId PolicyAssets
policiesWithAssets
            Map PolicyId (AnyScriptWitness (LedgerEra era))
witnessesProvidedMap
 where
  validateAllWitnessesProvided :: Set PolicyId -> Set PolicyId -> Either TxCmdError ()
validateAllWitnessesProvided Set PolicyId
witnessesNeeded Set PolicyId
witnessesProvided
    | [PolicyId] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [PolicyId]
witnessesMissing = () -> Either TxCmdError ()
forall a. a -> Either TxCmdError a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    | Bool
otherwise = TxCmdError -> Either TxCmdError ()
forall a b. a -> Either a b
Left ([PolicyId] -> [PolicyId] -> TxCmdError
TxCmdPolicyIdsMissing [PolicyId]
witnessesMissing (Set PolicyId -> [Item (Set PolicyId)]
forall l. IsList l => l -> [Item l]
toList Set PolicyId
witnessesProvided))
   where
    witnessesMissing :: [PolicyId]
witnessesMissing = Set PolicyId -> [PolicyId]
forall a. Set a -> [a]
Set.elems (Set PolicyId
witnessesNeeded Set PolicyId -> Set PolicyId -> Set PolicyId
forall a. Ord a => Set a -> Set a -> Set a
Set.\\ Set PolicyId
witnessesProvided)

  validateNoUnnecessaryWitnesses :: Set PolicyId -> Set PolicyId -> Either TxCmdError ()
validateNoUnnecessaryWitnesses Set PolicyId
witnessesNeeded Set PolicyId
witnessesProvided
    | [PolicyId] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [PolicyId]
witnessesExtra = () -> Either TxCmdError ()
forall a. a -> Either TxCmdError a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    | Bool
otherwise = TxCmdError -> Either TxCmdError ()
forall a b. a -> Either a b
Left ([PolicyId] -> TxCmdError
TxCmdPolicyIdsExcess [PolicyId]
witnessesExtra)
   where
    witnessesExtra :: [PolicyId]
witnessesExtra = Set PolicyId -> [PolicyId]
forall a. Set a -> [a]
Set.elems (Set PolicyId
witnessesProvided Set PolicyId -> Set PolicyId -> Set PolicyId
forall a. Ord a => Set a -> Set a -> Set a
Set.\\ Set PolicyId
witnessesNeeded)

convertWithdrawals
  :: [(StakeAddress, L.Coin, Exp.AnyWitness (Exp.LedgerEra era))]
  -> Exp.TxWithdrawals (Exp.LedgerEra era)
convertWithdrawals :: forall era.
[(StakeAddress, Coin, AnyWitness (LedgerEra era))]
-> TxWithdrawals (LedgerEra era)
convertWithdrawals = [(StakeAddress, Coin, AnyWitness (LedgerEra era))]
-> TxWithdrawals (LedgerEra era)
forall era.
[(StakeAddress, Coin, AnyWitness era)] -> TxWithdrawals era
Exp.TxWithdrawals

convertVotingProcedures
  :: forall era
   . Exp.IsEra era
  => [(VotingProcedures era, Exp.AnyWitness (Exp.LedgerEra era))]
  -> [(L.VotingProcedures (Exp.LedgerEra era), Exp.AnyWitness (Exp.LedgerEra era))]
convertVotingProcedures :: forall era.
IsEra era =>
[(VotingProcedures era, AnyWitness (LedgerEra era))]
-> [(VotingProcedures (LedgerEra era), AnyWitness (LedgerEra era))]
convertVotingProcedures =
  ((VotingProcedures era, AnyWitness (LedgerEra era))
 -> (VotingProcedures (LedgerEra era), AnyWitness (LedgerEra era)))
-> [(VotingProcedures era, AnyWitness (LedgerEra era))]
-> [(VotingProcedures (LedgerEra era), AnyWitness (LedgerEra era))]
forall a b. (a -> b) -> [a] -> [b]
map
    ( \(VotingProcedures VotingProcedures (ShelleyLedgerEra era)
vp, AnyWitness (LedgerEra era)
wit) ->
        (Era era
-> (EraCommonConstraints era => VotingProcedures (LedgerEra era))
-> VotingProcedures (LedgerEra era)
forall era a. Era era -> (EraCommonConstraints era => a) -> a
obtainCommonConstraints (forall era. IsEra era => Era era
Exp.useEra @era) VotingProcedures (ShelleyLedgerEra era)
VotingProcedures (LedgerEra era)
EraCommonConstraints era => VotingProcedures (LedgerEra era)
vp, AnyWitness (LedgerEra era)
wit)
    )

scriptInEraToSimpleScript
  :: forall era. Exp.IsEra era => ScriptInEra era -> Maybe (Exp.SimpleScript (Exp.LedgerEra era))
scriptInEraToSimpleScript :: forall era.
IsEra era =>
ScriptInEra era -> Maybe (SimpleScript (LedgerEra era))
scriptInEraToSimpleScript ScriptInEra era
s =
  Era era
-> (EraCommonConstraints era =>
    Maybe (SimpleScript (LedgerEra era)))
-> Maybe (SimpleScript (LedgerEra era))
forall era a. Era era -> (EraCommonConstraints era => a) -> a
obtainCommonConstraints (forall era. IsEra era => Era era
Exp.useEra @era) ((EraCommonConstraints era => Maybe (SimpleScript (LedgerEra era)))
 -> Maybe (SimpleScript (LedgerEra era)))
-> (EraCommonConstraints era =>
    Maybe (SimpleScript (LedgerEra era)))
-> Maybe (SimpleScript (LedgerEra era))
forall a b. (a -> b) -> a -> b
$
    NativeScript (LedgerEra era) -> SimpleScript (LedgerEra era)
forall era. EraScript era => NativeScript era -> SimpleScript era
Exp.SimpleScript
      (NativeScript (LedgerEra era) -> SimpleScript (LedgerEra era))
-> Maybe (NativeScript (LedgerEra era))
-> Maybe (SimpleScript (LedgerEra era))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Script (LedgerEra era) -> Maybe (NativeScript (LedgerEra era))
forall era. EraScript era => Script era -> Maybe (NativeScript era)
L.getNativeScript (Era era
-> (EraCommonConstraints era => Script (LedgerEra era))
-> Script (LedgerEra era)
forall era a. Era era -> (EraCommonConstraints era => a) -> a
obtainCommonConstraints (forall era. IsEra era => Era era
Exp.useEra @era) ((EraCommonConstraints era => Script (LedgerEra era))
 -> Script (LedgerEra era))
-> (EraCommonConstraints era => Script (LedgerEra era))
-> Script (LedgerEra era)
forall a b. (a -> b) -> a -> b
$ ScriptInEra era -> Script (ShelleyLedgerEra era)
forall era. ScriptInEra era -> Script (ShelleyLedgerEra era)
toShelleyScript ScriptInEra era
s)

partitionSomeWitnesses
  :: [ByronOrShelleyWitness]
  -> ( [ShelleyBootstrapWitnessSigningKeyData]
     , [ShelleyWitnessSigningKey]
     )
partitionSomeWitnesses :: [ByronOrShelleyWitness]
-> ([ShelleyBootstrapWitnessSigningKeyData],
    [ShelleyWitnessSigningKey])
partitionSomeWitnesses = ([ShelleyBootstrapWitnessSigningKeyData],
 [ShelleyWitnessSigningKey])
-> ([ShelleyBootstrapWitnessSigningKeyData],
    [ShelleyWitnessSigningKey])
forall {a} {a}. ([a], [a]) -> ([a], [a])
reversePartitionedWits (([ShelleyBootstrapWitnessSigningKeyData],
  [ShelleyWitnessSigningKey])
 -> ([ShelleyBootstrapWitnessSigningKeyData],
     [ShelleyWitnessSigningKey]))
-> ([ByronOrShelleyWitness]
    -> ([ShelleyBootstrapWitnessSigningKeyData],
        [ShelleyWitnessSigningKey]))
-> [ByronOrShelleyWitness]
-> ([ShelleyBootstrapWitnessSigningKeyData],
    [ShelleyWitnessSigningKey])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([ShelleyBootstrapWitnessSigningKeyData],
  [ShelleyWitnessSigningKey])
 -> ByronOrShelleyWitness
 -> ([ShelleyBootstrapWitnessSigningKeyData],
     [ShelleyWitnessSigningKey]))
-> ([ShelleyBootstrapWitnessSigningKeyData],
    [ShelleyWitnessSigningKey])
-> [ByronOrShelleyWitness]
-> ([ShelleyBootstrapWitnessSigningKeyData],
    [ShelleyWitnessSigningKey])
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Foldable.foldl' ([ShelleyBootstrapWitnessSigningKeyData],
 [ShelleyWitnessSigningKey])
-> ByronOrShelleyWitness
-> ([ShelleyBootstrapWitnessSigningKeyData],
    [ShelleyWitnessSigningKey])
go ([ShelleyBootstrapWitnessSigningKeyData],
 [ShelleyWitnessSigningKey])
forall a. Monoid a => a
mempty
 where
  reversePartitionedWits :: ([a], [a]) -> ([a], [a])
reversePartitionedWits ([a]
bw, [a]
skw) =
    ([a] -> [a]
forall a. [a] -> [a]
reverse [a]
bw, [a] -> [a]
forall a. [a] -> [a]
reverse [a]
skw)

  go :: ([ShelleyBootstrapWitnessSigningKeyData],
 [ShelleyWitnessSigningKey])
-> ByronOrShelleyWitness
-> ([ShelleyBootstrapWitnessSigningKeyData],
    [ShelleyWitnessSigningKey])
go ([ShelleyBootstrapWitnessSigningKeyData]
byronAcc, [ShelleyWitnessSigningKey]
shelleyKeyAcc) ByronOrShelleyWitness
byronOrShelleyWit =
    case ByronOrShelleyWitness
byronOrShelleyWit of
      AByronWitness ShelleyBootstrapWitnessSigningKeyData
byronWit ->
        (ShelleyBootstrapWitnessSigningKeyData
byronWit ShelleyBootstrapWitnessSigningKeyData
-> [ShelleyBootstrapWitnessSigningKeyData]
-> [ShelleyBootstrapWitnessSigningKeyData]
forall a. a -> [a] -> [a]
: [ShelleyBootstrapWitnessSigningKeyData]
byronAcc, [ShelleyWitnessSigningKey]
shelleyKeyAcc)
      AShelleyKeyWitness ShelleyWitnessSigningKey
shelleyKeyWit ->
        ([ShelleyBootstrapWitnessSigningKeyData]
byronAcc, ShelleyWitnessSigningKey
shelleyKeyWit ShelleyWitnessSigningKey
-> [ShelleyWitnessSigningKey] -> [ShelleyWitnessSigningKey]
forall a. a -> [a] -> [a]
: [ShelleyWitnessSigningKey]
shelleyKeyAcc)