How to serialize a type variable which is a template name

I’d like this assert to include the serialized template name in the message. How is it possible?

assertPartyCanQuery : (Template t, Eq t) => Party -> ContractId t -> Script ()
assertPartyCanQuery party contractId = do
  let serializedT = ...???...
  contract <- queryContractId party contractId
  assertMsg
    ((show party) <> " cannot query contract of template " <> serializedT)
    (isSome contract)

e.g. “Alice cannot query contract of template Iou”

2 Likes

You cannot extract a value representation of the Template instance at the moment. What you can do is to require an additional constraint and use that for this. Of course this means you have to implement the instance but that’s mostly something you do once and then stop worrying about so it’s not that big of an issue even if it’s a bit of boilerplate.

To provide a concrete example:

template MyTemplate
  with
    p : Party
  where
    signatory p

class Template t => NamedTemplate t  where
  templateName : Text

instance NamedTemplate MyTemplate where
  templateName = "MyTemplate"

assertPartyCanQuery : forall t. (NamedTemplate t, Eq t) => Party -> ContractId t -> Script ()
assertPartyCanQuery party contractId = do
  let serializedT = templateName @t
  contract <- queryContractId party contractId
  assertMsg
    ((show party) <> " cannot query contract of template " <> serializedT)
    (isSome contract)

You need to enable the AllowAmbiguousTypes extension for that since the instance for the call to templateName can only be resolved via a type application but that extension is perfectly reasonable despite the slightly scary name.

1 Like