{-# LANGUAGE TemplateHaskell #-}

module Plutarch.Extra.ExtendedAssetClass (
  -- * Types

  -- ** Haskell
  ExtendedAssetClass (..),

  -- ** Plutarch
  PExtendedAssetClass (..),

  -- * Constants

  -- ** Haskell
  extendedAdaClass,

  -- ** Plutarch
  pextendedAdaClass,

  -- * Functions

  -- ** Haskell
  isExtendedAdaClass,
  eqClasses,
  unsafeToAssetClass,

  -- ** Plutarch
  pisExtendedAdaClass,
  pextendedAssetClassValueOf,
  pextendedAssetClassValueOf',
  peqClasses,
  punsafeToAssetClass,
  punsafeToAssetClassData,
) where

import Data.Aeson (
  FromJSON (parseJSON),
  ToJSON (toEncoding, toJSON),
  object,
  pairs,
  withObject,
  (.:),
 )
import Data.Aeson.Encoding (pair)
import Data.Tagged (unTagged)
import Data.Text (Text, unpack)
import Optics.AffineTraversal (An_AffineTraversal, atraversal)
import Optics.Getter (A_Getter, to, view)
import Optics.Label (LabelOptic (labelOptic))
import Optics.Setter (set)
import Plutarch.Api.V1 (
  AmountGuarantees,
  KeyGuarantees,
  PCurrencySymbol,
  PValue,
 )
import Plutarch.DataRepr (DerivePConstantViaData (DerivePConstantViaData))
import Plutarch.Extra.AssetClass (
  AssetClass (AssetClass),
  PAssetClass (PAssetClass),
  PAssetClassData (PAssetClassData),
  adaClass,
  ptoScottEncoding,
 )
import Plutarch.Extra.Value (
  passetClassValueOf,
  passetClassValueOf',
  psymbolValueOf,
 )
import Plutarch.Lift (
  PConstantDecl,
  PUnsafeLiftDecl (PLifted),
 )
import PlutusLedgerApi.V2 (
  CurrencySymbol,
  Data,
  TokenName,
  toData,
 )
import PlutusTx.IsData (makeIsDataIndexed)
import Ply.Core.Class (PlyArg (UPLCRep, toBuiltinArg, toBuiltinArgData))
import Ply.Plutarch.Class (PlyArgOf)

{- | An 'AssetClass' whose 'TokenName' may or may not be relevant.

 @since 3.14.2
-}
data ExtendedAssetClass
  = -- | 'TokenName' is irrelevant
    AnyToken CurrencySymbol
  | -- | 'TokenName' is relevant
    FixedToken AssetClass
  deriving stock
    ( -- | @since 3.14.2
      forall (x :: OpticKind).
Rep ExtendedAssetClass x -> ExtendedAssetClass
forall (x :: OpticKind).
ExtendedAssetClass -> Rep ExtendedAssetClass x
forall (a :: OpticKind).
(forall (x :: OpticKind). a -> Rep a x)
-> (forall (x :: OpticKind). Rep a x -> a) -> Generic a
$cto :: forall (x :: OpticKind).
Rep ExtendedAssetClass x -> ExtendedAssetClass
$cfrom :: forall (x :: OpticKind).
ExtendedAssetClass -> Rep ExtendedAssetClass x
Generic
    , -- | @since 3.14.2
      Int -> ExtendedAssetClass -> ShowS
[ExtendedAssetClass] -> ShowS
ExtendedAssetClass -> String
forall (a :: OpticKind).
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ExtendedAssetClass] -> ShowS
$cshowList :: [ExtendedAssetClass] -> ShowS
show :: ExtendedAssetClass -> String
$cshow :: ExtendedAssetClass -> String
showsPrec :: Int -> ExtendedAssetClass -> ShowS
$cshowsPrec :: Int -> ExtendedAssetClass -> ShowS
Show
    , -- | @since 3.14.2
      ExtendedAssetClass -> ExtendedAssetClass -> Bool
forall (a :: OpticKind).
(a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtendedAssetClass -> ExtendedAssetClass -> Bool
$c/= :: ExtendedAssetClass -> ExtendedAssetClass -> Bool
== :: ExtendedAssetClass -> ExtendedAssetClass -> Bool
$c== :: ExtendedAssetClass -> ExtendedAssetClass -> Bool
Eq
    , -- | @since 3.14.2
      Eq ExtendedAssetClass
ExtendedAssetClass -> ExtendedAssetClass -> Bool
ExtendedAssetClass -> ExtendedAssetClass -> Ordering
ExtendedAssetClass -> ExtendedAssetClass -> ExtendedAssetClass
forall (a :: OpticKind).
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ExtendedAssetClass -> ExtendedAssetClass -> ExtendedAssetClass
$cmin :: ExtendedAssetClass -> ExtendedAssetClass -> ExtendedAssetClass
max :: ExtendedAssetClass -> ExtendedAssetClass -> ExtendedAssetClass
$cmax :: ExtendedAssetClass -> ExtendedAssetClass -> ExtendedAssetClass
>= :: ExtendedAssetClass -> ExtendedAssetClass -> Bool
$c>= :: ExtendedAssetClass -> ExtendedAssetClass -> Bool
> :: ExtendedAssetClass -> ExtendedAssetClass -> Bool
$c> :: ExtendedAssetClass -> ExtendedAssetClass -> Bool
<= :: ExtendedAssetClass -> ExtendedAssetClass -> Bool
$c<= :: ExtendedAssetClass -> ExtendedAssetClass -> Bool
< :: ExtendedAssetClass -> ExtendedAssetClass -> Bool
$c< :: ExtendedAssetClass -> ExtendedAssetClass -> Bool
compare :: ExtendedAssetClass -> ExtendedAssetClass -> Ordering
$ccompare :: ExtendedAssetClass -> ExtendedAssetClass -> Ordering
Ord
    )

-- | @since 3.14.2
makeIsDataIndexed
  ''ExtendedAssetClass
  [ ('AnyToken, 0)
  , ('FixedToken, 1)
  ]

-- | @since 3.14.5
instance PlyArg ExtendedAssetClass where
  type UPLCRep ExtendedAssetClass = Data
  toBuiltinArg :: ExtendedAssetClass -> UPLCRep ExtendedAssetClass
toBuiltinArg = forall (a :: OpticKind). ToData a => a -> Data
toData
  toBuiltinArgData :: ToDataConstraint ExtendedAssetClass => ExtendedAssetClass -> Data
toBuiltinArgData = forall (a :: OpticKind). ToData a => a -> Data
toData

-- | @since 3.14.2
deriving via
  (DerivePConstantViaData ExtendedAssetClass PExtendedAssetClass)
  instance
    PConstantDecl ExtendedAssetClass

-- | @since 3.14.2
instance ToJSON ExtendedAssetClass where
  {-# INLINEABLE toJSON #-}
  toJSON :: ExtendedAssetClass -> Value
toJSON = \case
    AnyToken CurrencySymbol
x ->
      [Pair] -> Value
object
        [ (Key
"tag", forall (a :: OpticKind). ToJSON a => a -> Value
toJSON @Text Text
"anyToken")
        , (Key
"symbol", forall (a :: OpticKind). ToJSON a => a -> Value
toJSON CurrencySymbol
x)
        ]
    FixedToken AssetClass
x ->
      [Pair] -> Value
object
        [ (Key
"tag", forall (a :: OpticKind). ToJSON a => a -> Value
toJSON @Text Text
"fixedToken")
        , (Key
"symbol", forall (a :: OpticKind). ToJSON a => a -> Value
toJSON forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall (a :: OpticKind). IsLabel "symbol" a => a
#symbol forall (a :: OpticKind) b. (a -> b) -> a -> b
$ AssetClass
x)
        , (Key
"name", forall (a :: OpticKind). ToJSON a => a -> Value
toJSON forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall (a :: OpticKind). IsLabel "name" a => a
#name forall (a :: OpticKind) b. (a -> b) -> a -> b
$ AssetClass
x)
        ]
  {-# INLINEABLE toEncoding #-}
  toEncoding :: ExtendedAssetClass -> Encoding
toEncoding = \case
    AnyToken CurrencySymbol
x ->
      Series -> Encoding
pairs forall (a :: OpticKind) b. (a -> b) -> a -> b
$
        Key -> Encoding -> Series
pair Key
"tag" (forall (a :: OpticKind). ToJSON a => a -> Encoding
toEncoding @Text Text
"anyToken")
          forall (a :: OpticKind). Semigroup a => a -> a -> a
<> Key -> Encoding -> Series
pair Key
"symbol" (forall (a :: OpticKind). ToJSON a => a -> Encoding
toEncoding CurrencySymbol
x)
    FixedToken AssetClass
x ->
      Series -> Encoding
pairs forall (a :: OpticKind) b. (a -> b) -> a -> b
$
        Key -> Encoding -> Series
pair Key
"tag" (forall (a :: OpticKind). ToJSON a => a -> Encoding
toEncoding @Text Text
"fixedToken")
          forall (a :: OpticKind). Semigroup a => a -> a -> a
<> Key -> Encoding -> Series
pair Key
"symbol" (forall (a :: OpticKind). ToJSON a => a -> Encoding
toEncoding forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall (a :: OpticKind). IsLabel "symbol" a => a
#symbol forall (a :: OpticKind) b. (a -> b) -> a -> b
$ AssetClass
x)
          forall (a :: OpticKind). Semigroup a => a -> a -> a
<> Key -> Encoding -> Series
pair Key
"name" (forall (a :: OpticKind). ToJSON a => a -> Encoding
toEncoding forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall (a :: OpticKind). IsLabel "name" a => a
#name forall (a :: OpticKind) b. (a -> b) -> a -> b
$ AssetClass
x)

-- | @since 3.14.2
instance FromJSON ExtendedAssetClass where
  {-# INLINEABLE parseJSON #-}
  parseJSON :: Value -> Parser ExtendedAssetClass
parseJSON = forall (a :: OpticKind).
String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"ExtendedAssetClass" forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \Object
obj -> do
    Text
tag :: Text <- Object
obj forall (a :: OpticKind). FromJSON a => Object -> Key -> Parser a
.: Key
"tag"
    CurrencySymbol
cs <- Object
obj forall (a :: OpticKind). FromJSON a => Object -> Key -> Parser a
.: Key
"symbol"
    case Text
tag of
      Text
"anyToken" -> do
        forall (f :: OpticKind -> OpticKind) (a :: OpticKind).
Applicative f =>
a -> f a
pure forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. CurrencySymbol -> ExtendedAssetClass
AnyToken forall (a :: OpticKind) b. (a -> b) -> a -> b
$ CurrencySymbol
cs
      Text
"fixedToken" -> do
        TokenName
tn <- Object
obj forall (a :: OpticKind). FromJSON a => Object -> Key -> Parser a
.: Key
"name"
        forall (f :: OpticKind -> OpticKind) (a :: OpticKind).
Applicative f =>
a -> f a
pure forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. AssetClass -> ExtendedAssetClass
FixedToken forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. CurrencySymbol -> TokenName -> AssetClass
AssetClass CurrencySymbol
cs forall (a :: OpticKind) b. (a -> b) -> a -> b
$ TokenName
tn
      Text
_ -> forall (m :: OpticKind -> OpticKind) (a :: OpticKind).
MonadFail m =>
String -> m a
fail forall (a :: OpticKind) b. (a -> b) -> a -> b
$ String
"Not a valid tag: " forall (a :: OpticKind). Semigroup a => a -> a -> a
<> Text -> String
unpack Text
tag

{- | We can always retrieve a 'CurrencySymbol', but depending on what we have,
 we may be unable to change it.

 @since 3.14.2
-}
instance
  (k ~ A_Getter, a ~ CurrencySymbol, b ~ CurrencySymbol) =>
  LabelOptic "symbol" k ExtendedAssetClass ExtendedAssetClass a b
  where
  labelOptic :: Optic k NoIx ExtendedAssetClass ExtendedAssetClass a b
labelOptic = forall (s :: OpticKind) (a :: OpticKind). (s -> a) -> Getter s a
to forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \case
    AnyToken CurrencySymbol
x -> CurrencySymbol
x
    FixedToken AssetClass
x -> forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall (a :: OpticKind). IsLabel "symbol" a => a
#symbol AssetClass
x

{- | We may not necessarily have a 'TokenName' that matters; if we do, then
 changing it is fine.

 @since 3.14.2
-}
instance
  (k ~ An_AffineTraversal, a ~ TokenName, b ~ TokenName) =>
  LabelOptic "name" k ExtendedAssetClass ExtendedAssetClass a b
  where
  labelOptic :: Optic k NoIx ExtendedAssetClass ExtendedAssetClass a b
labelOptic = forall (s :: OpticKind) (t :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(s -> Either t a) -> (s -> b -> t) -> AffineTraversal s t a b
atraversal ExtendedAssetClass -> Either ExtendedAssetClass TokenName
out forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \ExtendedAssetClass
eac b
tn -> case ExtendedAssetClass
eac of
    AnyToken CurrencySymbol
_ -> ExtendedAssetClass
eac
    FixedToken AssetClass
x -> AssetClass -> ExtendedAssetClass
FixedToken forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (t :: OpticKind) (a :: OpticKind) (b :: OpticKind).
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set forall (a :: OpticKind). IsLabel "name" a => a
#name b
tn forall (a :: OpticKind) b. (a -> b) -> a -> b
$ AssetClass
x
    where
      out :: ExtendedAssetClass -> Either ExtendedAssetClass TokenName
      out :: ExtendedAssetClass -> Either ExtendedAssetClass TokenName
out = \case
        eac :: ExtendedAssetClass
eac@(AnyToken CurrencySymbol
_) -> forall (a :: OpticKind) (b :: OpticKind). a -> Either a b
Left ExtendedAssetClass
eac
        FixedToken AssetClass
x -> forall (a :: OpticKind) (b :: OpticKind). b -> Either a b
Right forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall (a :: OpticKind). IsLabel "name" a => a
#name forall (a :: OpticKind) b. (a -> b) -> a -> b
$ AssetClass
x

{- | We can always \'pull out\' an 'AssetClass', by essentially \'forgetting\'
 the significance of our \'TokenName\'. In cases where it's not significant,
 we stub it with the empty name.

 @since 3.14.2
-}
instance
  (k ~ A_Getter, a ~ AssetClass, b ~ AssetClass) =>
  LabelOptic "assetClass" k ExtendedAssetClass ExtendedAssetClass a b
  where
  labelOptic :: Optic k NoIx ExtendedAssetClass ExtendedAssetClass a b
labelOptic = forall (s :: OpticKind) (a :: OpticKind). (s -> a) -> Getter s a
to forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \case
    AnyToken CurrencySymbol
x -> CurrencySymbol -> TokenName -> AssetClass
AssetClass CurrencySymbol
x TokenName
""
    FixedToken AssetClass
x -> AssetClass
x

{- | A 'FixedToken' wrapper around 'adaClass'. Provided mostly for convenience.

 @since 3.15.1
-}
extendedAdaClass :: ExtendedAssetClass
extendedAdaClass :: ExtendedAssetClass
extendedAdaClass = AssetClass -> ExtendedAssetClass
FixedToken forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall {k :: OpticKind} (s :: k) (b :: OpticKind). Tagged s b -> b
unTagged forall (a :: OpticKind) b. (a -> b) -> a -> b
$ Tagged "Ada" AssetClass
adaClass

{- | Compare an 'ExtendedAssetClass' to an 'AssetClass'.

 @since 3.15.3
-}
eqClasses :: ExtendedAssetClass -> AssetClass -> Bool
eqClasses :: ExtendedAssetClass -> AssetClass -> Bool
eqClasses ExtendedAssetClass
eac AssetClass
ac = case ExtendedAssetClass
eac of
  AnyToken CurrencySymbol
cs -> CurrencySymbol
cs forall (a :: OpticKind). Eq a => a -> a -> Bool
== forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall (a :: OpticKind). IsLabel "symbol" a => a
#symbol AssetClass
ac
  FixedToken AssetClass
ac' -> AssetClass
ac forall (a :: OpticKind). Eq a => a -> a -> Bool
== AssetClass
ac'

{- | Convert to an 'AssetClass'. We do this by either \'unwrapping\' a
 'FixedToken', or \'stubbing in\' an empty 'TokenName' for an 'AnyToken'.

 = Note

 This is /not/ a safe conversion in general (hence its name). For example:

 > cls = AnyTokenType sym
 >
 > v = assetClassValueOf (unsafeToAssetClass cls)
 >                       (singleton x "" 1 <> singleton x "a" 1)

 Then @v@ would equal @1@, when it's supposed to be @2@.

 There are some legitimate uses for this conversion, which is why it exists,
 but it should be used with care.

 @since 3.15.3
-}
unsafeToAssetClass :: ExtendedAssetClass -> AssetClass
unsafeToAssetClass :: ExtendedAssetClass -> AssetClass
unsafeToAssetClass = \case
  AnyToken CurrencySymbol
cs -> CurrencySymbol -> TokenName -> AssetClass
AssetClass CurrencySymbol
cs TokenName
""
  FixedToken AssetClass
ac -> AssetClass
ac

{- | Plutarch equivalent to 'ExtendedAssetClass'.

 @since 3.14.2
-}
data PExtendedAssetClass (s :: S)
  = PAnyToken (Term s (PDataRecord '["_0" ':= PCurrencySymbol]))
  | PFixedToken (Term s (PDataRecord '["_0" ':= PAssetClassData]))
  deriving stock
    ( -- | @since 3.14.2
      forall (a :: OpticKind).
(forall (x :: OpticKind). a -> Rep a x)
-> (forall (x :: OpticKind). Rep a x -> a) -> Generic a
forall (s :: S) (x :: OpticKind).
Rep (PExtendedAssetClass s) x -> PExtendedAssetClass s
forall (s :: S) (x :: OpticKind).
PExtendedAssetClass s -> Rep (PExtendedAssetClass s) x
$cto :: forall (s :: S) (x :: OpticKind).
Rep (PExtendedAssetClass s) x -> PExtendedAssetClass s
$cfrom :: forall (s :: S) (x :: OpticKind).
PExtendedAssetClass s -> Rep (PExtendedAssetClass s) x
Generic
    )
  deriving anyclass
    ( -- | @since 3.14.2
      forall (s :: S).
Term s PExtendedAssetClass
-> Term s PExtendedAssetClass -> Term s PBool
forall (t :: PType).
(forall (s :: S). Term s t -> Term s t -> Term s PBool) -> PEq t
#== :: forall (s :: S).
Term s PExtendedAssetClass
-> Term s PExtendedAssetClass -> Term s PBool
$c#== :: forall (s :: S).
Term s PExtendedAssetClass
-> Term s PExtendedAssetClass -> Term s PBool
PEq
    , -- | @since 3.14.2
      forall (s :: S).
PExtendedAssetClass s -> Term s (PInner PExtendedAssetClass)
forall (s :: S) (b :: PType).
Term s (PInner PExtendedAssetClass)
-> (PExtendedAssetClass s -> Term s b) -> Term s b
forall (a :: PType).
(forall (s :: S). a s -> Term s (PInner a))
-> (forall (s :: S) (b :: PType).
    Term s (PInner a) -> (a s -> Term s b) -> Term s b)
-> PlutusType a
pmatch' :: forall (s :: S) (b :: PType).
Term s (PInner PExtendedAssetClass)
-> (PExtendedAssetClass s -> Term s b) -> Term s b
$cpmatch' :: forall (s :: S) (b :: PType).
Term s (PInner PExtendedAssetClass)
-> (PExtendedAssetClass s -> Term s b) -> Term s b
pcon' :: forall (s :: S).
PExtendedAssetClass s -> Term s (PInner PExtendedAssetClass)
$cpcon' :: forall (s :: S).
PExtendedAssetClass s -> Term s (PInner PExtendedAssetClass)
PlutusType
    , -- | @since 3.14.2
      forall (s :: S).
Bool -> Term s PExtendedAssetClass -> Term s PString
forall (t :: PType).
(forall (s :: S). Bool -> Term s t -> Term s PString) -> PShow t
pshow' :: forall (s :: S).
Bool -> Term s PExtendedAssetClass -> Term s PString
$cpshow' :: forall (s :: S).
Bool -> Term s PExtendedAssetClass -> Term s PString
PShow
    , -- | @since 3.14.2
      forall (s :: S).
Term s (PAsData PExtendedAssetClass) -> Term s PExtendedAssetClass
forall (s :: S). Term s PExtendedAssetClass -> Term s PData
forall (a :: PType).
(forall (s :: S). Term s (PAsData a) -> Term s a)
-> (forall (s :: S). Term s a -> Term s PData) -> PIsData a
pdataImpl :: forall (s :: S). Term s PExtendedAssetClass -> Term s PData
$cpdataImpl :: forall (s :: S). Term s PExtendedAssetClass -> Term s PData
pfromDataImpl :: forall (s :: S).
Term s (PAsData PExtendedAssetClass) -> Term s PExtendedAssetClass
$cpfromDataImpl :: forall (s :: S).
Term s (PAsData PExtendedAssetClass) -> Term s PExtendedAssetClass
PIsData
    )

-- | @since 3.14.2
instance DerivePlutusType PExtendedAssetClass where
  type DPTStrat _ = PlutusTypeData

-- | @since 3.14.2
instance PUnsafeLiftDecl PExtendedAssetClass where
  type PLifted PExtendedAssetClass = ExtendedAssetClass

-- | @since 3.14.5
type instance PlyArgOf PExtendedAssetClass = ExtendedAssetClass

{- | As 'passetClassValueOf', but for 'PExtendedAssetClass'.

 @since 3.14.2
-}
pextendedAssetClassValueOf ::
  forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees) (s :: S).
  Term s (PExtendedAssetClass :--> PValue keys amounts :--> PInteger)
pextendedAssetClassValueOf :: forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees)
       (s :: S).
Term
  s (PExtendedAssetClass :--> (PValue keys amounts :--> PInteger))
pextendedAssetClassValueOf = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall (a :: OpticKind) b. (a -> b) -> a -> b
$ forall (a :: OpticKind) (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \Term s PExtendedAssetClass
eac Term s (PValue keys amounts)
value ->
  forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s PExtendedAssetClass
eac forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \case
    PAnyToken Term s (PDataRecord '[ "_0" ':= PCurrencySymbol])
t -> forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees)
       (s :: S).
Term s (PCurrencySymbol :--> (PValue keys amounts :--> PInteger))
psymbolValueOf forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (a :: PType) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData (forall (name :: Symbol) (b :: PType) (p :: PType) (s :: S)
       (a :: PType) (as :: [PLabeledType]) (n :: Nat).
(PDataFields p, as ~ PFields p, n ~ PLabelIndex name as,
 KnownNat n, a ~ PUnLabel (IndexList n as), PFromDataable a b) =>
Term s (p :--> b)
pfield @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PDataRecord '[ "_0" ':= PCurrencySymbol])
t) forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PValue keys amounts)
value
    PFixedToken Term s (PDataRecord '[ "_0" ':= PAssetClassData])
t ->
      let t' :: Term s PAssetClass
t' = forall (s :: S). Term s (PAssetClassData :--> PAssetClass)
ptoScottEncoding forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (name :: Symbol) (b :: PType) (p :: PType) (s :: S)
       (a :: PType) (as :: [PLabeledType]) (n :: Nat).
(PDataFields p, as ~ PFields p, n ~ PLabelIndex name as,
 KnownNat n, a ~ PUnLabel (IndexList n as), PFromDataable a b) =>
Term s (p :--> b)
pfield @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PDataRecord '[ "_0" ':= PAssetClassData])
t
       in forall (key :: KeyGuarantees) (amount :: AmountGuarantees)
       (s :: S).
Term s (PAssetClass :--> (PValue key amount :--> PInteger))
passetClassValueOf forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s PAssetClass
t' forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PValue keys amounts)
value

{- | As 'pextendedAssetClassValueOf', but using a Haskell-level
 'ExtendedAssetClass'.

 @since 3.14.6
-}
pextendedAssetClassValueOf' ::
  forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees) (s :: S).
  ExtendedAssetClass ->
  Term s (PValue keys amounts :--> PInteger)
pextendedAssetClassValueOf' :: forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees)
       (s :: S).
ExtendedAssetClass -> Term s (PValue keys amounts :--> PInteger)
pextendedAssetClassValueOf' ExtendedAssetClass
eac = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall (a :: OpticKind) b. (a -> b) -> a -> b
$ forall (a :: OpticKind) (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \Term s (PValue keys amounts)
value ->
  case ExtendedAssetClass
eac of
    AnyToken CurrencySymbol
cs -> forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees)
       (s :: S).
Term s (PCurrencySymbol :--> (PValue keys amounts :--> PInteger))
psymbolValueOf forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant CurrencySymbol
cs forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PValue keys amounts)
value
    FixedToken AssetClass
ac -> forall (keys :: KeyGuarantees) (amounts :: AmountGuarantees)
       (a :: OpticKind) (k :: OpticKind) (s :: S).
(Is k A_Getter, LabelOptic' "symbol" k a CurrencySymbol,
 LabelOptic' "name" k a TokenName) =>
a -> Term s (PValue keys amounts :--> PInteger)
passetClassValueOf' AssetClass
ac forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PValue keys amounts)
value

{- | Compare a 'PExtendedAssetClass' to a 'PAssetClass'.

 @since 3.14.2
-}
peqClasses ::
  forall (s :: S).
  Term s (PExtendedAssetClass :--> PAssetClassData :--> PBool)
peqClasses :: forall (s :: S).
Term s (PExtendedAssetClass :--> (PAssetClassData :--> PBool))
peqClasses = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall (a :: OpticKind) b. (a -> b) -> a -> b
$ forall (a :: OpticKind) (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \Term s PExtendedAssetClass
eac Term s PAssetClassData
acd ->
  forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s PExtendedAssetClass
eac forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \case
    PAnyToken Term s (PDataRecord '[ "_0" ':= PCurrencySymbol])
t ->
      forall (a :: PType) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData (forall (name :: Symbol) (b :: PType) (p :: PType) (s :: S)
       (a :: PType) (as :: [PLabeledType]) (n :: Nat).
(PDataFields p, as ~ PFields p, n ~ PLabelIndex name as,
 KnownNat n, a ~ PUnLabel (IndexList n as), PFromDataable a b) =>
Term s (p :--> b)
pfield @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PDataRecord '[ "_0" ':= PCurrencySymbol])
t) forall (t :: PType) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== forall (a :: PType) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData (forall (name :: Symbol) (b :: PType) (p :: PType) (s :: S)
       (a :: PType) (as :: [PLabeledType]) (n :: Nat).
(PDataFields p, as ~ PFields p, n ~ PLabelIndex name as,
 KnownNat n, a ~ PUnLabel (IndexList n as), PFromDataable a b) =>
Term s (p :--> b)
pfield @"symbol" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s PAssetClassData
acd)
    PFixedToken Term s (PDataRecord '[ "_0" ':= PAssetClassData])
t -> forall (a :: PType) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData (forall (name :: Symbol) (b :: PType) (p :: PType) (s :: S)
       (a :: PType) (as :: [PLabeledType]) (n :: Nat).
(PDataFields p, as ~ PFields p, n ~ PLabelIndex name as,
 KnownNat n, a ~ PUnLabel (IndexList n as), PFromDataable a b) =>
Term s (p :--> b)
pfield @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PDataRecord '[ "_0" ':= PAssetClassData])
t) forall (t :: PType) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== Term s PAssetClassData
acd

{- | Convert to a 'PAssetClass'. We do this by either \'unwrapping\' a
 'PFixedToken', or \'stubbing in\' an empty 'PTokenName' for 'PAnyToken'.

 = Note

 This is /not/ a safe conversion in general (hence its name). For example:

 > cls = pcon $ PAnyTokenType sym
 >
 > v = passetClassValueOf # (punsafeToAssetClass cls) #
 >  pconstant (singleton x "" 1 <> singleton x "a" 1)

 Then @v@ would equal @1@, when it's supposed to be @2@.

 There are some legitimate uses for this conversion (specifically for creating
 'Value's), which is why it exists, but it should be used with care.

 @since 3.15.0
-}
punsafeToAssetClass ::
  forall (s :: S).
  Term s (PExtendedAssetClass :--> PAssetClass)
punsafeToAssetClass :: forall (s :: S). Term s (PExtendedAssetClass :--> PAssetClass)
punsafeToAssetClass = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall (a :: OpticKind) b. (a -> b) -> a -> b
$ forall (a :: OpticKind) (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \Term s PExtendedAssetClass
eac ->
  forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s PExtendedAssetClass
eac forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \case
    PAnyToken Term s (PDataRecord '[ "_0" ':= PCurrencySymbol])
t ->
      forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (s :: S).
Term s (PAsData PCurrencySymbol)
-> Term s (PAsData PTokenName) -> PAssetClass s
PAssetClass (forall (name :: Symbol) (b :: PType) (p :: PType) (s :: S)
       (a :: PType) (as :: [PLabeledType]) (n :: Nat).
(PDataFields p, as ~ PFields p, n ~ PLabelIndex name as,
 KnownNat n, a ~ PUnLabel (IndexList n as), PFromDataable a b) =>
Term s (p :--> b)
pfield @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PDataRecord '[ "_0" ':= PCurrencySymbol])
t) forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant forall (a :: OpticKind) b. (a -> b) -> a -> b
$ TokenName
""
    PFixedToken Term s (PDataRecord '[ "_0" ':= PAssetClassData])
t -> forall (s :: S). Term s (PAssetClassData :--> PAssetClass)
ptoScottEncoding forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (name :: Symbol) (b :: PType) (p :: PType) (s :: S)
       (a :: PType) (as :: [PLabeledType]) (n :: Nat).
(PDataFields p, as ~ PFields p, n ~ PLabelIndex name as,
 KnownNat n, a ~ PUnLabel (IndexList n as), PFromDataable a b) =>
Term s (p :--> b)
pfield @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PDataRecord '[ "_0" ':= PAssetClassData])
t

{- | Convert to a 'PAssetClassData'.

 = Note

 This is not a safe conversion in general, for the same reasons as
 'punsafeToAssetClass'. All caveats on the use of 'punsafeToAssetClass' also
 apply to this function.

 @since 3.15.0
-}
punsafeToAssetClassData ::
  forall (s :: S).
  Term s (PExtendedAssetClass :--> PAssetClassData)
punsafeToAssetClassData :: forall (s :: S). Term s (PExtendedAssetClass :--> PAssetClassData)
punsafeToAssetClassData = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall (a :: OpticKind) b. (a -> b) -> a -> b
$ forall (a :: OpticKind) (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \Term s PExtendedAssetClass
eac ->
  forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s PExtendedAssetClass
eac forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \case
    PAnyToken Term s (PDataRecord '[ "_0" ':= PCurrencySymbol])
t ->
      forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon
        forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (s :: S).
Term
  s
  (PDataRecord
     '[ "symbol" ':= PCurrencySymbol, "name" ':= PTokenName])
-> PAssetClassData s
PAssetClassData
        forall (a :: OpticKind) b. (a -> b) -> a -> b
$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# (forall (name :: Symbol) (b :: PType) (p :: PType) (s :: S)
       (a :: PType) (as :: [PLabeledType]) (n :: Nat).
(PDataFields p, as ~ PFields p, n ~ PLabelIndex name as,
 KnownNat n, a ~ PUnLabel (IndexList n as), PFromDataable a b) =>
Term s (p :--> b)
pfield @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PDataRecord '[ "_0" ':= PCurrencySymbol])
t) forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (label :: Symbol) (a :: PType) (l :: [PLabeledType])
       (s :: S).
Term
  s
  (PAsData a
   :--> (PDataRecord l :--> PDataRecord ((label ':= a) : l)))
pdcons forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# (forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant forall (a :: OpticKind) b. (a -> b) -> a -> b
$ TokenName
"") forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# forall (s :: S). Term s (PDataRecord '[])
pdnil
    PFixedToken Term s (PDataRecord '[ "_0" ':= PAssetClassData])
t -> forall (name :: Symbol) (b :: PType) (p :: PType) (s :: S)
       (a :: PType) (as :: [PLabeledType]) (n :: Nat).
(PDataFields p, as ~ PFields p, n ~ PLabelIndex name as,
 KnownNat n, a ~ PUnLabel (IndexList n as), PFromDataable a b) =>
Term s (p :--> b)
pfield @"_0" forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PDataRecord '[ "_0" ':= PAssetClassData])
t

{- | Plutarch equivalent to 'extendedAdaClass'.

 @since 3.15.1
-}
pextendedAdaClass :: forall (s :: S). Term s PExtendedAssetClass
pextendedAdaClass :: forall (s :: S). Term s PExtendedAssetClass
pextendedAdaClass = forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant ExtendedAssetClass
extendedAdaClass

{- | Verify whether an 'ExtendedAssetClass' is the ADA extended asset class.

 @since 3.15.1
-}
isExtendedAdaClass :: ExtendedAssetClass -> Bool
isExtendedAdaClass :: ExtendedAssetClass -> Bool
isExtendedAdaClass = (ExtendedAssetClass
extendedAdaClass forall (a :: OpticKind). Eq a => a -> a -> Bool
==)

{- | As 'isExtendedAdaClass', but for Plutarch.

 @since 3.15.1
-}
pisExtendedAdaClass ::
  forall (s :: S).
  Term s (PExtendedAssetClass :--> PBool)
pisExtendedAdaClass :: forall (s :: S). Term s (PExtendedAssetClass :--> PBool)
pisExtendedAdaClass = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall (a :: OpticKind) b. (a -> b) -> a -> b
$ forall (a :: OpticKind) (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall (a :: OpticKind) b. (a -> b) -> a -> b
$ \Term s PExtendedAssetClass
eac ->
  Term s PExtendedAssetClass
eac forall (t :: PType) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== forall (s :: S). Term s PExtendedAssetClass
pextendedAdaClass