Can someone make some order about the interface conversion functions and the way we use them?

G-d willing

Hi everyone,
I am a bit confused with all the functions that convert contracts between interfaces and templates.
Especially, the way we use them in Script is not the same compared to Update.
Currently, since the documentation lacks examples, I never know which function is doing what, and how it is being done.
I am embarrassed to say that I mostly guess before really getting to the desired result.
Can someone please explain these functions with examples, one for Script and the second for Update

1 Like

There are two main groups, one for converting between contract ids, the other for converting between contract payloads.

For payloads:

-- Conversion from template payload to interface value
toInterface : forall i t.HasToInterface t i => t -> i
-- Conversion from interface value to template payload. Returns None if the value was of a different template
fromInterface : HasFromInterface t i => i -> Optional t

For contract ids:

-- Convert from template contract id to interface contract id. Won't compile if template does not implement interface.
toInterfaceContractId : forall i t. HasToInterface t i => ContractId t -> ContractId i
-- Convert from interface contracd id to template id. DANGER: Will not check that the contract is of the specific template. Only when fetching/exercising the contract will you see a failure.
fromInterfaceContractId : forall t i. HasFromInterface t i => ContractId i -> ContractId t
-- Convert from interface contract id to template contract id + payload. This is similar to `fromInterfaceContractId` but it checks that the contract actually is of the given template by fetching it. This is really just a wrapper around `fetch` + `fromInterface`
fetchFromInterface : forall t i. (HasFromInterface t i, HasFetch i) => ContractId i -> Update (Optional (ContractId t, t))

Lastly there is a conversion for converting between contract ids of different interfaces rather than between interfaces & templates:

-- DANGER: Does not check that contract id implements given interface.
coerceInterfaceContractId : forall j i. (HasInterfaceTypeRep i, HasInterfaceTypeRep j) => ContractId i -> ContractId j

I think this is one of the cases where the types + docs are actually far more useful than examples. Reference: Interfaces — Daml SDK 2.5.0 documentation has a good overview of those functions.

2 Likes