11{-# LANGUAGE FlexibleContexts #-}
2+ {-# LANGUAGE FlexibleInstances #-}
23{-# LANGUAGE GADTs #-}
34{-# LANGUAGE KindSignatures #-}
45{-# LANGUAGE RankNTypes #-}
56{-# LANGUAGE ScopedTypeVariables #-}
67{-# LANGUAGE TypeApplications #-}
8+ {-# LANGUAGE TypeFamilies #-}
79
810module Cardano.Api.Experimental.AnyScript
911 ( AnyScript (.. )
12+ , AsType (.. )
1013 , deserialiseAnyPlutusScriptOfLanguage
1114 , deserialiseAnySimpleScript
1215 , hashAnyScript
@@ -18,16 +21,76 @@ import Cardano.Api.Experimental.Plutus.Internal.Script hiding (AnyPlutusScript)
1821import Cardano.Api.Experimental.Simple.Script
1922import Cardano.Api.HasTypeProxy
2023import Cardano.Api.Ledger.Internal.Reexport qualified as L
24+ import Cardano.Api.Serialise.Cbor
2125
22- import Cardano.Binary qualified as CBOR
26+ import Cardano.Ledger. Binary qualified as CBOR
2327import Cardano.Ledger.Core qualified as L
2428import Cardano.Ledger.Plutus.Language qualified as Plutus
2529
2630import Data.ByteString qualified as BS
31+ import Data.Either.Combinators (maybeToRight , rightToMaybe )
32+ import Data.Foldable (asum )
33+ import Data.Type.Equality ((:~:) (.. ))
34+ import Data.Typeable (Typeable , eqT )
2735
2836data AnyScript era where
2937 AnySimpleScript :: SimpleScript era -> AnyScript era
30- AnyPlutusScript :: Plutus. PlutusLanguage lang => PlutusScriptInEra lang era -> AnyScript era
38+ AnyPlutusScript
39+ :: (Plutus. PlutusLanguage lang , Typeable lang ) => PlutusScriptInEra lang era -> AnyScript era
40+
41+ instance L. Era era => HasTypeProxy (AnyScript era ) where
42+ data AsType (AnyScript era ) = AsAnyScript
43+ proxyToAsType _ = AsAnyScript
44+
45+ instance Show (AnyScript era ) where
46+ show (AnySimpleScript ss) = " AnySimpleScript " ++ show ss
47+ show (AnyPlutusScript ps) = " AnyPlutusScript " ++ show ps
48+
49+ instance Eq (AnyScript era ) where
50+ AnySimpleScript s1 == AnySimpleScript s2 = s1 == s2
51+ AnyPlutusScript (ps1 :: PlutusScriptInEra lang1 era ) == AnyPlutusScript (ps2 :: PlutusScriptInEra lang2 era ) =
52+ case eqT @ lang1 @ lang2 of
53+ Just Refl -> ps1 == ps2
54+ Nothing -> False
55+ _ == _ = False
56+
57+ instance
58+ L. AlonzoEraScript era
59+ => SerialiseAsCBOR (AnyScript era )
60+ where
61+ serialiseToCBOR (AnySimpleScript (SimpleScript ns)) =
62+ L. serialize' (L. eraProtVerHigh @ era ) (L. fromNativeScript ns :: L. Script era )
63+ serialiseToCBOR (AnyPlutusScript ps) =
64+ L. serialize' (L. eraProtVerHigh @ era ) (plutusScriptInEraToScript ps)
65+
66+ deserialiseFromCBOR _ bs = do
67+ script <- decodeScript
68+ maybeToRight noParseError $
69+ asum
70+ [ tryNativeScript script
71+ , tryPlutusScript script
72+ ]
73+ where
74+ decodeScript :: Either CBOR. DecoderError (L. Script era )
75+ decodeScript = do
76+ r <- CBOR. runAnnotator <$> CBOR. decodeFull' (L. eraProtVerHigh @ era ) bs
77+ return $ r $ CBOR. Full $ BS. fromStrict bs
78+
79+ tryNativeScript :: L. Script era -> Maybe (AnyScript era )
80+ tryNativeScript = fmap (AnySimpleScript . SimpleScript ) . L. getNativeScript
81+
82+ tryPlutusScript :: L. Script era -> Maybe (AnyScript era )
83+ tryPlutusScript script = do
84+ ps <- L. toPlutusScript script
85+ L. withPlutusScript ps $ \ (plutus :: Plutus. Plutus l ) ->
86+ AnyPlutusScript . PlutusScriptInEra
87+ <$> rightToMaybe (Plutus. decodePlutusRunnable (L. eraProtVerHigh @ era ) plutus)
88+
89+ noParseError :: CBOR. DecoderError
90+ noParseError =
91+ CBOR. DecoderErrorCustom
92+ " AnyScript"
93+ " Decoded Script era is neither a NativeScript nor a PlutusScript"
3194
3295hashAnyScript :: forall era . IsEra era => AnyScript (LedgerEra era ) -> L. ScriptHash
3396hashAnyScript (AnySimpleScript ss) =
0 commit comments