{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE Rank2Types #-}

-- |
-- Copyright: © 2022 IOHK
-- License: Apache-2.0
--
-- Module containing extra 'Cardano.Api' functionality needed by the wallet.
module Cardano.Api.Extra
    ( withShelleyBasedTx
    , inAnyCardanoEra
    , asAnyShelleyBasedEra
    ) where

import Prelude

import Cardano.Api
    ( CardanoEra (..)
    , InAnyCardanoEra (..)
    , InAnyShelleyBasedEra (..)
    , IsCardanoEra (cardanoEra)
    , IsShelleyBasedEra
    , ShelleyBasedEra (..)
    , Tx
    )

-- | Apply an era-parameterized function to an existentially-wrapped
-- tx.
withShelleyBasedTx
    :: InAnyShelleyBasedEra Tx
    -> (forall era. IsShelleyBasedEra era => Tx era -> a)
    -> a
withShelleyBasedTx :: InAnyShelleyBasedEra Tx
-> (forall era. IsShelleyBasedEra era => Tx era -> a) -> a
withShelleyBasedTx (InAnyShelleyBasedEra ShelleyBasedEra era
_era Tx era
tx) forall era. IsShelleyBasedEra era => Tx era -> a
f
    = Tx era -> a
forall era. IsShelleyBasedEra era => Tx era -> a
f Tx era
tx

-- | Helper function for more easily creating an existential
-- @InAnyCardanoEra Tx@.
inAnyCardanoEra :: IsCardanoEra era => Tx era -> InAnyCardanoEra Tx
inAnyCardanoEra :: Tx era -> InAnyCardanoEra Tx
inAnyCardanoEra = CardanoEra era -> Tx era -> InAnyCardanoEra Tx
forall era (thing :: * -> *).
IsCardanoEra era =>
CardanoEra era -> thing era -> InAnyCardanoEra thing
InAnyCardanoEra CardanoEra era
forall era. IsCardanoEra era => CardanoEra era
cardanoEra

-- | "Downcast" an existentially wrapped tx.
asAnyShelleyBasedEra
    :: InAnyCardanoEra a
    -> Maybe (InAnyShelleyBasedEra a)
asAnyShelleyBasedEra :: InAnyCardanoEra a -> Maybe (InAnyShelleyBasedEra a)
asAnyShelleyBasedEra = \case
    InAnyCardanoEra CardanoEra era
ByronEra a era
_ ->
        Maybe (InAnyShelleyBasedEra a)
forall a. Maybe a
Nothing
    InAnyCardanoEra CardanoEra era
ShelleyEra a era
a ->
        InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a)
forall a. a -> Maybe a
Just (InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a))
-> InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a)
forall a b. (a -> b) -> a -> b
$ ShelleyBasedEra ShelleyEra
-> a ShelleyEra -> InAnyShelleyBasedEra a
forall era (thing :: * -> *).
IsShelleyBasedEra era =>
ShelleyBasedEra era -> thing era -> InAnyShelleyBasedEra thing
InAnyShelleyBasedEra ShelleyBasedEra ShelleyEra
ShelleyBasedEraShelley a era
a ShelleyEra
a
    InAnyCardanoEra CardanoEra era
AllegraEra a era
a ->
        InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a)
forall a. a -> Maybe a
Just (InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a))
-> InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a)
forall a b. (a -> b) -> a -> b
$ ShelleyBasedEra AllegraEra
-> a AllegraEra -> InAnyShelleyBasedEra a
forall era (thing :: * -> *).
IsShelleyBasedEra era =>
ShelleyBasedEra era -> thing era -> InAnyShelleyBasedEra thing
InAnyShelleyBasedEra ShelleyBasedEra AllegraEra
ShelleyBasedEraAllegra a era
a AllegraEra
a
    InAnyCardanoEra CardanoEra era
MaryEra a era
a ->
        InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a)
forall a. a -> Maybe a
Just (InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a))
-> InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a)
forall a b. (a -> b) -> a -> b
$ ShelleyBasedEra MaryEra -> a MaryEra -> InAnyShelleyBasedEra a
forall era (thing :: * -> *).
IsShelleyBasedEra era =>
ShelleyBasedEra era -> thing era -> InAnyShelleyBasedEra thing
InAnyShelleyBasedEra ShelleyBasedEra MaryEra
ShelleyBasedEraMary a era
a MaryEra
a
    InAnyCardanoEra CardanoEra era
AlonzoEra a era
a ->
        InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a)
forall a. a -> Maybe a
Just (InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a))
-> InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a)
forall a b. (a -> b) -> a -> b
$ ShelleyBasedEra AlonzoEra -> a AlonzoEra -> InAnyShelleyBasedEra a
forall era (thing :: * -> *).
IsShelleyBasedEra era =>
ShelleyBasedEra era -> thing era -> InAnyShelleyBasedEra thing
InAnyShelleyBasedEra ShelleyBasedEra AlonzoEra
ShelleyBasedEraAlonzo a era
a AlonzoEra
a
    InAnyCardanoEra CardanoEra era
BabbageEra a era
a ->
        InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a)
forall a. a -> Maybe a
Just (InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a))
-> InAnyShelleyBasedEra a -> Maybe (InAnyShelleyBasedEra a)
forall a b. (a -> b) -> a -> b
$ ShelleyBasedEra BabbageEra
-> a BabbageEra -> InAnyShelleyBasedEra a
forall era (thing :: * -> *).
IsShelleyBasedEra era =>
ShelleyBasedEra era -> thing era -> InAnyShelleyBasedEra thing
InAnyShelleyBasedEra ShelleyBasedEra BabbageEra
ShelleyBasedEraBabbage a era
a BabbageEra
a