<p>This is to do with the use of Template Haskell. You can do this to prevent the error:</p>
<pre class="lang-haskell prettyprint-override"><code>policy :: TxOutRef -&gt; MintingPolicy
policy oref = mkMintingPolicyScript $
  $$(PlutusTx.compile [|| wrap ||])
  `PlutusTx.applyCode`
  PlutusTx.liftCode oref
  where
    wrap = mkUntypedMintingPolicy . emurgoMintingPolicyT
</code></pre>

CC BY-SA 4.0
2023-04-22T08:45:37.977Z
2023-04-22T08:45:37.977Z
james
<p>I could not make the typed redeemer in the following minting policy work.  The redeemer was supposed to be <code>data MintAction = Mint | Burn</code>.  (I settled with the workaround <code>type MintAction = Bool</code>, with <code>False</code> representing <code>Mint</code> and <code>True</code> representing <code>Burn</code>.)</p>
<p>I get the error:</p>
<pre class="lang-shell prettyprint-override"><code>    * GHC stage restriction:
        instance for `UnsafeFromData
                        MintAction' is used in a top-level splice, quasi-quote, or annotation,
        and must be imported, not defined locally
    * In the first argument of `(.)', namely `mkUntypedMintingPolicy'
      In the Template Haskell quotation
        [|| mkUntypedMintingPolicy . emurgoMintingPolicyT ||]
      In the first argument of `PlutusTx.compile', namely
        `[|| mkUntypedMintingPolicy . emurgoMintingPolicyT ||]'
</code></pre>
<p>How to fix my minting policy?</p>
<pre class="lang-haskell prettyprint-override"><code>{-# LANGUAGE DataKinds             #-}
{-# LANGUAGE DeriveAnyClass        #-}
{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoImplicitPrelude     #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE TypeApplications      #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE TypeOperators         #-}
{-# LANGUAGE NumericUnderscores    #-}

module Minting where

-- import           Data.Aeson          (ToJSON, FromJSON)
-- import           GHC.Generics        (Generic)
import qualified PlutusTx
import qualified PlutusTx.AssocMap as M
import           PlutusTx.Prelude       as TxPrelude hiding (unless)
import           Plutus.Script.Utils.Typed (mkUntypedMintingPolicy)
import           Plutus.V1.Ledger.Value
import           Plutus.V2.Ledger.Api
import           Plutus.V2.Ledger.Contexts as V2LC

-- data MintAction = Mint | Burn
--   deriving (Generic, FromJSON, ToJSON)
-- PlutusTx.unstableMakeIsData ''MintAction

-- | A workaround since I could not make 'data MintAction = Mint | Burn' work
type MintAction = Bool

treasuryValHash :: ValidatorHash
treasuryValHash = ValidatorHash &quot;deadbeef&quot;

mintingCost :: Integer
mintingCost = 75_000_000

symbolValueOf' :: CurrencySymbol -&gt; Value -&gt; (Integer, Integer)
symbolValueOf' cs v = case M.lookup cs (getValue v) of
  Nothing        -&gt; (0, 0)
  Just csTokens -&gt; (minted, burned)
    where
      minted = foldr sum' 0 . M.toList $ M.filter (&gt;0) csTokens
      burned = foldr sum' 0 . M.toList $ M.filter (&lt;0) csTokens
      sum' = \(_, a) b -&gt; a + b

{-# INLINABLE emurgoMintingPolicyT #-}
-- | Typed minting policy
emurgoMintingPolicyT :: TxOutRef -&gt; MintAction -&gt; V2LC.ScriptContext -&gt; Bool
emurgoMintingPolicyT oref redeemer ctx =
  let
    info             = scriptContextTxInfo ctx
    (minted, burned) = symbolValueOf' (ownCurrencySymbol ctx) (txInfoMint info)
  in
    case redeemer of
      -- 'False' stands for 'Mint'
      False -&gt;   minted == 1
              &amp;&amp; burned == 0
              &amp;&amp; (any (\txo -&gt; case addressCredential . txOutAddress $ txo of
                          PubKeyCredential _  -&gt; False
                          ScriptCredential vh -&gt; vh == treasuryValHash &amp;&amp;
                            valueOf (txOutValue txo) adaSymbol adaToken &gt;= mintingCost) $
                      txInfoOutputs info)
              &amp;&amp; (any (\txIn -&gt; txInInfoOutRef txIn == oref) $ txInfoInputs info)
      -- 'True' stands for 'Burn'
      True  -&gt; minted == 0 &amp;&amp; burned &lt; 0

-- | Minting policy compiled to Plutus Core
policy :: TxOutRef -&gt; MintingPolicy
policy oref = mkMintingPolicyScript $
  $$(PlutusTx.compile [|| mkUntypedMintingPolicy . emurgoMintingPolicyT ||])
  `PlutusTx.applyCode`
  PlutusTx.liftCode oref
</code></pre>

CC BY-SA 4.0
2023-04-11T21:16:06.883Z
It compiles. So, in what way does this policy not work and what are you doing to produce that result?
james
CC BY-SA 4.0
2023-04-21T00:11:13.147Z
Thanks for the reply.  It does not seem to compile.  I edited my post adding the error message.
a_juggler
<plutus-pioneer-program>
Typed redeemer in a minting policy
# Typed redeemer in a minting policy

(Asked by: username_0 on 2023-04-11)

I could not make the typed redeemer in the following minting policy work.  The redeemer was supposed to be data MintAction = Mint | Burn.  (I settled with the workaround type MintAction = Bool, with False representing Mint and True representing Burn.)
I get the error:
    * GHC stage restriction:
        instance for `UnsafeFromData
                        MintAction' is used in a top-level splice, quasi-quote, or annotation,
        and must be imported, not defined locally
    * In the first argument of `(.)', namely `mkUntypedMintingPolicy'
      In the Template Haskell quotation
        [|| mkUntypedMintingPolicy . emurgoMintingPolicyT ||]
      In the first argument of `PlutusTx.compile', namely
        `[|| mkUntypedMintingPolicy . emurgoMintingPolicyT ||]'

How to fix my minting policy?
{-# LANGUAGE DataKinds             #-}
{-# LANGUAGE DeriveAnyClass        #-}
{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoImplicitPrelude     #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE TypeApplications      #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE TypeOperators         #-}
{-# LANGUAGE NumericUnderscores    #-}

module Minting where

-- import           Data.Aeson          (ToJSON, FromJSON)
-- import           GHC.Generics        (Generic)
import qualified PlutusTx
import qualified PlutusTx.AssocMap as M
import           PlutusTx.Prelude       as TxPrelude hiding (unless)
import           Plutus.Script.Utils.Typed (mkUntypedMintingPolicy)
import           Plutus.V1.Ledger.Value
import           Plutus.V2.Ledger.Api
import           Plutus.V2.Ledger.Contexts as V2LC

-- data MintAction = Mint | Burn
--   deriving (Generic, FromJSON, ToJSON)
-- PlutusTx.unstableMakeIsData ''MintAction

-- | A workaround since I could not make 'data MintAction = Mint | Burn' work
type MintAction = Bool

treasuryValHash :: ValidatorHash
treasuryValHash = ValidatorHash "deadbeef"

mintingCost :: Integer
mintingCost = 75_000_000

symbolValueOf' :: CurrencySymbol -> Value -> (Integer, Integer)
symbolValueOf' cs v = case M.lookup cs (getValue v) of
  Nothing        -> (0, 0)
  Just csTokens -> (minted, burned)
    where
      minted = foldr sum' 0 . M.toList $ M.filter (>0) csTokens
      burned = foldr sum' 0 . M.toList $ M.filter (<0) csTokens
      sum' = \(_, a) b -> a + b

{-# INLINABLE emurgoMintingPolicyT #-}
-- | Typed minting policy
emurgoMintingPolicyT :: TxOutRef -> MintAction -> V2LC.ScriptContext -> Bool
emurgoMintingPolicyT oref redeemer ctx =
  let
    info             = scriptContextTxInfo ctx
    (minted, burned) = symbolValueOf' (ownCurrencySymbol ctx) (txInfoMint info)
  in
    case redeemer of
      -- 'False' stands for 'Mint'
      False ->   minted == 1
              && burned == 0
              && (any (\txo -> case addressCredential . txOutAddress $ txo of
                          PubKeyCredential _  -> False
                          ScriptCredential vh -> vh == treasuryValHash &&
                            valueOf (txOutValue txo) adaSymbol adaToken >= mintingCost) $
                      txInfoOutputs info)
              && (any (\txIn -> txInInfoOutRef txIn == oref) $ txInfoInputs info)
      -- 'True' stands for 'Burn'
      True  -> minted == 0 && burned < 0

-- | Minting policy compiled to Plutus Core
policy :: TxOutRef -> MintingPolicy
policy oref = mkMintingPolicyScript $
  $$(PlutusTx.compile [|| mkUntypedMintingPolicy . emurgoMintingPolicyT ||])
  `PlutusTx.applyCode`
  PlutusTx.liftCode oref

**Tags:** plutus-pioneer-program
> **Comments:**
> **username_1**: It compiles. So, in what way does this policy not work and what are you doing to produce that result?  
> **username_0**: Thanks for the reply.  It does not seem to compile.  I edited my post adding the error message.  

---

## 1 answers

### Answer by username_1 on 2023-04-22. Score: 0

This is to do with the use of Template Haskell. You can do this to prevent the error:
policy :: TxOutRef -> MintingPolicy
policy oref = mkMintingPolicyScript $
  $$(PlutusTx.compile [|| wrap ||])
  `PlutusTx.applyCode`
  PlutusTx.liftCode oref
  where
    wrap = mkUntypedMintingPolicy . emurgoMintingPolicyT


---

