{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

module Cardano.Api.Experimental.Tx.Internal.Type
  ( UnsignedTx (..)
  )
where

import Cardano.Api.Experimental.Era
import Cardano.Api.HasTypeProxy (HasTypeProxy (..), Proxy, asType)
import Cardano.Api.Ledger.Internal.Reexport qualified as L
import Cardano.Api.ProtocolParameters
import Cardano.Api.Serialise.Raw
  ( SerialiseAsRawBytes (..)
  , SerialiseAsRawBytesError (SerialiseAsRawBytesError)
  )

import Cardano.Ledger.Binary qualified as Ledger
import Cardano.Ledger.Core qualified as Ledger

import Control.Exception (displayException)
import Data.Bifunctor (bimap)
import Data.ByteString.Lazy (fromStrict)

-- | A transaction that can contain everything
-- except key witnesses.
data UnsignedTx era
  = L.EraTx (LedgerEra era) => UnsignedTx (Ledger.Tx (LedgerEra era))

instance HasTypeProxy era => HasTypeProxy (UnsignedTx era) where
  data AsType (UnsignedTx era) = AsUnsignedTx (AsType era)
  proxyToAsType :: Proxy (UnsignedTx era) -> AsType (UnsignedTx era)
  proxyToAsType :: Proxy (UnsignedTx era) -> AsType (UnsignedTx era)
proxyToAsType Proxy (UnsignedTx era)
_ = AsType era -> AsType (UnsignedTx era)
forall era. AsType era -> AsType (UnsignedTx era)
AsUnsignedTx (forall t. HasTypeProxy t => AsType t
asType @era)

instance
  ( HasTypeProxy era
  , L.EraTx (LedgerEra era)
  )
  => SerialiseAsRawBytes (UnsignedTx era)
  where
  serialiseToRawBytes :: UnsignedTx era -> ByteString
serialiseToRawBytes (UnsignedTx Tx (LedgerEra era)
tx) =
    Version -> Tx (LedgerEra era) -> ByteString
forall a. EncCBOR a => Version -> a -> ByteString
Ledger.serialize' (forall era. Era era => Version
Ledger.eraProtVerHigh @(LedgerEra era)) Tx (LedgerEra era)
tx
  deserialiseFromRawBytes :: AsType (UnsignedTx era)
-> ByteString -> Either SerialiseAsRawBytesError (UnsignedTx era)
deserialiseFromRawBytes AsType (UnsignedTx era)
_ =
    (DecoderError -> SerialiseAsRawBytesError)
-> (Tx (LedgerEra era) -> UnsignedTx era)
-> Either DecoderError (Tx (LedgerEra era))
-> Either SerialiseAsRawBytesError (UnsignedTx era)
forall a b c d. (a -> b) -> (c -> d) -> Either a c -> Either b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap DecoderError -> SerialiseAsRawBytesError
wrapError Tx (LedgerEra era) -> UnsignedTx era
forall era.
EraTx (LedgerEra era) =>
Tx (LedgerEra era) -> UnsignedTx era
UnsignedTx
      (Either DecoderError (Tx (LedgerEra era))
 -> Either SerialiseAsRawBytesError (UnsignedTx era))
-> (ByteString -> Either DecoderError (Tx (LedgerEra era)))
-> ByteString
-> Either SerialiseAsRawBytesError (UnsignedTx era)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Version
-> Text
-> (forall s. Decoder s (Annotator (Tx (LedgerEra era))))
-> ByteString
-> Either DecoderError (Tx (LedgerEra era))
forall a.
Version
-> Text
-> (forall s. Decoder s (Annotator a))
-> ByteString
-> Either DecoderError a
Ledger.decodeFullAnnotator
        (forall era. Era era => Version
Ledger.eraProtVerHigh @(LedgerEra era))
        Text
"UnsignedTx"
        Decoder s (Annotator (Tx (LedgerEra era)))
forall s. Decoder s (Annotator (Tx (LedgerEra era)))
forall a s. DecCBOR a => Decoder s a
Ledger.decCBOR
      (ByteString -> Either DecoderError (Tx (LedgerEra era)))
-> (ByteString -> ByteString)
-> ByteString
-> Either DecoderError (Tx (LedgerEra era))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
fromStrict
   where
    wrapError
      :: Ledger.DecoderError -> SerialiseAsRawBytesError
    wrapError :: DecoderError -> SerialiseAsRawBytesError
wrapError = String -> SerialiseAsRawBytesError
SerialiseAsRawBytesError (String -> SerialiseAsRawBytesError)
-> (DecoderError -> String)
-> DecoderError
-> SerialiseAsRawBytesError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DecoderError -> String
forall e. Exception e => e -> String
displayException

deriving instance Eq (UnsignedTx era)

deriving instance Show (UnsignedTx era)