Reference: Interfaces

Warning

This feature is under active development and not officially supported in production environments.

In Daml, an interface defines an abstract type which specifies the behavior that a template must implement. This allows decoupling such behavior from its implementation, so other developers can write applications in terms of the interface instead of the concrete template.

Interface declaration

An interface declaration is somewhat similar to a template declaration.

Interface name

interface MyInterface where
  • This is the name of the interface.
  • It’s preceded by the keyword interface and followed by the keyword where.
  • It must begin with a capital letter, like any other type name.

Interface methods

  method1 : Party
  method2 : Int
  method3 : Bool -> Int -> Int -> Int
  • An interface may define any number of methods.

  • Methods are in scope as functions at the top level, in the ensure clause, and in interface choices. These functions always take an unstated first argument corresponding to a contract that implements the interface:

    func1 : Implements t MyInterface => t -> Party
    func1 = method1
    
    func2 : Implements t MyInterface => t -> Int
    func2 = method2
    
    func3 : Implements t MyInterface => t -> Bool -> Int -> Int -> Int
    func3 = method3
    
  • Methods are also in scope in interface choices (see Interface choices below).

Interface precondition

  ensure myGuard (method1 this)
  • A precondition is introduced with the keyword ensure and must be a boolean expression.
  • It is possible to define interfaces without an ensure clause, but writing more than one is a compilation error.
  • this is in scope in the method with the type of the interface. self, however, is not.
  • The interface methods can be used as part of the expression (e.g. method1).
  • It is evaluated and checked right after the implementing template’s precondition upon contract creation

Interface choices

  choice MyChoice : (ContractId MyInterface, Int)
    with
      argument1 : Bool
      argument2 : Int
    controller method1 this
    do
      let n0 = method2 this
      let n1 = method3 this argument1 argument2 n0
      pure (self, n1)

  nonconsuming choice MyNonConsumingChoice : Int
    controller method1 this
    do
      pure $ method2 this
  • Interface choices work in a very similar way to template choices. Any contract of an implementing interface will grant the choice to the controlling party.
  • Interface methods can be used to define the controller of a choice (e.g. method1) as well as the actions that run when the choice is exercised (e.g. method2 and method3).
  • As for template choices, the choice keyword can be optionally prefixed with the nonconsuming keyword to specify that the contract will not be consumed when the choice is exercised. If not specified, the choice will be consuming. Note that the preconsuming and postconsuming qualifiers are not supported on interface choices.
  • See Reference: choices for full reference information, but note that controller-first syntax is not supported for interface choices.

Empty interfaces

interface YourInterface
  • It is possible (though not necessarily useful) to define an interface without methods, precondition or choices. In such a case, the where keyword can be dropped.

Required interfaces

interface OurInterface requires MyInterface, YourInterface where
  • An interface can depend on other interfaces. These are specified with the requires keyword after the interface name but before the where keyword, separated by commas.

  • For a template’s implementation of an interface to be valid, all its required interfaces must also be implemented by the template.

  • If the interface doesn’t have any methods, precondition or choices, the where keyword after the last required interface can be dropped:

    interface TheirInterface requires MyInterface, YourInterface
    

Interface implementation

For context, a simple template definition:

template MyTemplate
  with
    field1 : Party
    field2 : Int
  where
    signatory field1

Implements clause

    implements MyInterface where
      method1 = field1
      method2 = field2
      method3 False _ _ = 0
      method3 True x y
        | x > 0 = x + y
        | otherwise = y
  • To make a template implement an interface, an implements clause is added to the body of the template.
  • The clause must start with the keyword implements, followed by the name of the interface, followed by the keyword where, which introduces a block where all the methods of the interface must be implemented.
  • Methods can be defined using the same syntax as for top level functions, including pattern matches and guards (e.g. method3).

Empty implements clause

    implements YourInterface
  • If the interface being implemented has no methods, the where keyword can be dropped.

Interface functions

Function Type Instantiated type Notes
interfaceTypeRep HasInterfaceTypeRep i => i -> TemplateTypeRep MyInterface -> TemplateTypeRep The value of the resulting TemplateTypeRep indicates what template was used to construct the interface value.
toInterface forall i t. HasToInterface t i => t -> i MyTemplate -> MyInterface Converts a template value into an interface value. Can also be used to convert an interface value to one of its required interfaces.
fromInterface HasFromInterface t i => i -> Optional t MyInterface -> Optional MyTemplate Attempts to convert an interface value back into a template value. The result is None if the expected template type doesn’t match the underlying template type used to construct the contract. Can also be used to convert a value of an interface type to one of its requiring interfaces.
toInterfaceContractId forall i t. HasToInterface t i => ContractId t -> ContractId i ContractId MyTemplate -> ContractId MyInterface Convert a template contract id into an interface contract id. Can also be used to convert an interface contract id into a contract id of one of its required interfaces.
fromInterfaceContractId forall t i. (HasFromInterface t i, HasFetch i) => ContractId i -> Update (Optional (ContractId t)) ContractId MyInterface -> Update (Optional (ContractId MyTemplate)) Attempts to convert an interface contract id into a template contract id. In order to verify that the underlying contract has the expected template type, this needs to perform a fetch. Can also be used to convert a contract id of an interface type to a contract id of one of its requiring interfaces.