{"id":"oi1TPbVztAY","title":"Lesson 1: Introduction to Daml Triggers","description":"For a better learning experience, sign up and enroll in this free course at: https://daml.talentlms.com/plus/catalog/courses/154","channel_name":"Digital Asset Training","published_at":"2025-02-20T00:00:00.000Z","thumbnail_url":"https://i.ytimg.com/vi/oi1TPbVztAY/hqdefault.jpg","transcript_text":"a daml trigger is an optional component of a damel solution that can provide off lger Automation in this lesson we will explain what damel triggers are how daml triggers operate and what function they serve then we'll take a look at the code structure of a trigger and create a very simple noop trigger a trigger that does nothing a damel trigger is an off lger automation component it is a small application or process that runs outside of The Ledger and acts as a ledger client it communicates with The Ledger using The Ledger API over the grpc framework just like other Ledger clients for example those implemented using The Ledger API Java or python bindings anything done using triggers can also be done using The Ledger API over grpc or through Java or python bindings in this course we cover daml triggers but not the Ledger API the reason is that this course is focused on developing in daml and triggers are written in daml while Ledger clients developed using Ledger API would be written in Java python or some other language triggers react to changes in The Ledger State and execute a function that can send commands to The Ledger because of this it is tempting to think about triggers as event handlers in terms of objectoriented programming however this analogy is imperfect and can get you in trouble in some edge cases a better way to think about triggers is as an automation or application that restores The Ledger to a desired invariant state for example a desired Ledger State might be that there are no active contracts of a certain type on The Ledger whenever a contract of this type is created a trigger would exercise a consuming choice choice on this contract thus archiving the contract and restoring The Ledger to the desired invariance State suppose we build a loan servicing application where loans are processed and life cycled and each individual loan is represented as a damel contract on The Ledger the desired invariance State might be that there are no matured loans on The Ledger we could create a trigger that periodically queries The Ledger for loan contracts where the mat date is prior to today's date and when such contract is found exercise a consuming choice on this contract that executes the repayment of principal amount and any acred interest on the loan and archives the loan contract triggers are used for automation for example later on we'll see a trigger that implements a bot that automatically responds to messages in a messaging app the same automation can be implemented using The Ledger a API compared to The Ledger API triggers have only one advantage triggers are implemented using daml rather than another programming language as a developer writing templates and test scripts in daml you can use the same language to create triggers instead of having to switch to another language like Java or python to implement an automation using The Ledger API because they're written in daml triggers integrate seam l ly with your daml model reducing development cycle time for experimenting with different approaches to the workflow you're implementing because damel triggers are integrated with the daml models type system you can take advantage of automatic refactoring assistance when modifying the model one may think that another advantage of using triggers is better performance because triggers written in daml don't need to do type conversion in practice type conversion has negligible effect on performance and triggers do not have any performance advantage over java or python bindings using The Ledger API triggers cannot access any data sources other than the Ledger therefore if the automation application needs to react to off lger events or needs to utilize any data other than what's available on The Ledger then the application cannot be implemented as a daml trigger uction damel Solutions may have hundreds of millions of contracts in the active contract set or ACs on The Ledger damble triggers need to keep the entire ACS in memory which is a limiting factor for their scalability another factor is the lack of query indexes which means non-trivial trigger Expressions can run into algorithmic complexity issues long before the trigger runs out of memory as the size of the ACs grows at some point it becomes imperative for performance reasons that ledger client applications Implement an operational data store or ODS the ODS typically maintains a replica of a subset of data from The Ledger in the format optimized for a specific client application this way a client application can perform fast and efficient queries against the data stored in the ODS Ledger data in an ODS could be combined with data from other other sources to support the workflows in a client application since daml triggers cannot have access to any data sources other than the Ledger an automation application that requires an ODS cannot be implemented as a damel trigger to summarize daml triggers may be very useful for quick prototyping of automated workflows for developer testing or proof of concepts for scalable Production Solutions off lger automation should should be implemented using other tools like The Ledger API using an operational data store and possibly integrating with other off lger systems or data sources since triggers send commands to The Ledger and these commands must be authorized a trigger runs under the authority of a party or a set of parties mapped to a user like any other Ledger client application to create a daml trigger you need to define a value of type trigger s where the trigger is a data type imported from the dl. trigger module and S is the type of user defined State a daml application running on The Ledger is stateless a daml trigger on the other hand can have internal state which can be used in the code logic what you see in the lower part of the screen is the definition of the trigger type in the dl. trigger module the trigger type is a daml record with five fields let's look at these fields the initialize function is called on Startup and allows you to initialize your userdefined trigger state which can be based on querying the active contract set the update State function is called on new transactions and command completions and can be used to update your userdefined trigger State based on the active contract set in the transaction or completion the rule function is the core of a daml trigger it defines which commands need to be sent to The Ledger based on the party the trigger is executed on the current state of the active contract set and the user defined State the type trigger a allows you to emit commands that are then sent to The Ledger query the ACs update the user defined State and retrieve the commands in Flight with the get commands in Flight function do notation and the get time function can both be used in the rule function templates and interfaces that the trigger will operate on can be specified using the registered templates field this defines which templates and interfaces the trigger will receive events for you can list an explicit set of templates and interfaces here or you can set the value of registered templates field to All In which means that the trigger will receive events for all template and interface types defined in the DAR file the trigger will be compiled into while it is possible to use the all and dar value for the registered templates field in production applications it's almost always advisable to use an explicit list of templates or interfaces Instead This is mainly for performance reasons the DAR file will typically contain many templates and interfaces that are not relevant to the trigger note that providing an explicit list of templates and interfaces also filters the result results of querying the ACs using the trigger API also note that contracts of the excluded templates and interfaces cannot be queried finally you can specify an optional heartbeat interval at which the trigger will be sent a heartbeat message this is useful if you want to ensure that the trigger is executed at a certain rate to issue timed commands in this example we see the implementation of a trigger named noop the noop variable is declared with the type trigger imported from the dl. trigger module this is a trivial trigger that does not apply user defined state in the code logic hence the state is defined as a unit or an empty tupple since this trigger doesn't use state in the code Logic the initialized function doesn't do anything and just Returns the unit wrapped in the trigger context by calling a pure function with the unit as the value of the argument similarly the update State function is defined as a Lambda function that discards the value of the argument and just calls pure unit the rule function here is also defined as a Lambda function that discards the value of the argument and calls the debug function that prints the word triggered to standard out the registered templates field is set to all inar which means the trigger does not filter out trigger events based on the template and finally the heartbeat field is set to none which means that the trigger responds to the change in Ledger State rather than to the heartbeat messages the effect of running this trigger is that whenever The Ledger State changes the trigger will print the word triggered to standard out to summarize a daml trigger is an off lger automation component unlike Ledger clients implemented using The Ledger API daml triggers are written in daml triggers react to changes in The Ledger State and execute a function that sends commands to The Ledger and restores The Ledger to a desired invariance state to implement a trigger you need to import the dl. trigger module and create a variable of the type trigger s where s is the user defined trigger state","transcript_synced_at":"2026-10-26T03:59:46.072Z","segments":[{"start_seconds":0,"text":"a daml trigger is an optional component of a damel solution that can provide off lger Automation in this lesson we will","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=0s"},{"start_seconds":8,"text":"explain what damel triggers are how daml triggers operate and what function they serve then we'll take a look at the code","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=8s"},{"start_seconds":16,"text":"structure of a trigger and create a very simple noop trigger a trigger that does nothing a damel trigger is an off lger","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=16s"},{"start_seconds":26,"text":"automation component it is a small application or process that runs outside of The Ledger and acts as a ledger","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=26s"},{"start_seconds":34,"text":"client it communicates with The Ledger using The Ledger API over the grpc framework just like other Ledger clients","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=34s"},{"start_seconds":43,"text":"for example those implemented using The Ledger API Java or python bindings anything done using triggers","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=43s"},{"start_seconds":51,"text":"can also be done using The Ledger API over grpc or through Java or python","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=51s"},{"start_seconds":57,"text":"bindings in this course we cover daml triggers but not the Ledger API the reason is that this course is focused on","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=57s"},{"start_seconds":66,"text":"developing in daml and triggers are written in daml while Ledger clients developed using Ledger API would be","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=66s"},{"start_seconds":74,"text":"written in Java python or some other language triggers react to changes in The Ledger State and execute a function","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=74s"},{"start_seconds":82,"text":"that can send commands to The Ledger because of this it is tempting to think about triggers as event handlers in","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=82s"},{"start_seconds":90,"text":"terms of objectoriented programming however this analogy is imperfect and can get you in trouble in some edge","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=90s"},{"start_seconds":97,"text":"cases a better way to think about triggers is as an automation or application that restores The Ledger to","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=97s"},{"start_seconds":104,"text":"a desired invariant state for example a desired Ledger State might be that there are no active contracts of a certain","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=104s"},{"start_seconds":112,"text":"type on The Ledger whenever a contract of this type is created a trigger would exercise a consuming choice choice on","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=112s"},{"start_seconds":120,"text":"this contract thus archiving the contract and restoring The Ledger to the desired invariance State suppose we","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=120s"},{"start_seconds":128,"text":"build a loan servicing application where loans are processed and life cycled and each individual loan is represented as a","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=128s"},{"start_seconds":136,"text":"damel contract on The Ledger the desired invariance State might be that there are no matured loans on The Ledger we could","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=136s"},{"start_seconds":144,"text":"create a trigger that periodically queries The Ledger for loan contracts where the mat date is prior to today's","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=144s"},{"start_seconds":151,"text":"date and when such contract is found exercise a consuming choice on this contract that executes the repayment of","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=151s"},{"start_seconds":159,"text":"principal amount and any acred interest on the loan and archives the loan contract triggers are used for","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=159s"},{"start_seconds":166,"text":"automation for example later on we'll see a trigger that implements a bot that automatically responds to messages in a","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=166s"},{"start_seconds":174,"text":"messaging app the same automation can be implemented using The Ledger a API compared to The Ledger API triggers have","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=174s"},{"start_seconds":183,"text":"only one advantage triggers are implemented using daml rather than another programming language as a","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=183s"},{"start_seconds":191,"text":"developer writing templates and test scripts in daml you can use the same language to create triggers instead of","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=191s"},{"start_seconds":198,"text":"having to switch to another language like Java or python to implement an automation using The Ledger API because","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=198s"},{"start_seconds":206,"text":"they're written in daml triggers integrate seam l ly with your daml model reducing development cycle time for experimenting with different approaches","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=206s"},{"start_seconds":215,"text":"to the workflow you're implementing because damel triggers are integrated with the daml models type system you can","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=215s"},{"start_seconds":223,"text":"take advantage of automatic refactoring assistance when modifying the model one may think that another advantage of","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=223s"},{"start_seconds":230,"text":"using triggers is better performance because triggers written in daml don't need to do type conversion in practice","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=230s"},{"start_seconds":239,"text":"type conversion has negligible effect on performance and triggers do not have any performance advantage over java or","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=239s"},{"start_seconds":247,"text":"python bindings using The Ledger API triggers cannot access any data sources other than the Ledger therefore if the","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=247s"},{"start_seconds":256,"text":"automation application needs to react to off lger events or needs to utilize any data other than what's available on The","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=256s"},{"start_seconds":264,"text":"Ledger then the application cannot be implemented as a daml trigger uction damel Solutions may have hundreds of","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=264s"},{"start_seconds":272,"text":"millions of contracts in the active contract set or ACs on The Ledger damble triggers need to keep the entire ACS in","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=272s"},{"start_seconds":280,"text":"memory which is a limiting factor for their scalability another factor is the lack of query indexes which means non-trivial","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=280s"},{"start_seconds":289,"text":"trigger Expressions can run into algorithmic complexity issues long before the trigger runs out of memory as","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=289s"},{"start_seconds":297,"text":"the size of the ACs grows at some point it becomes imperative for performance reasons that ledger client applications","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=297s"},{"start_seconds":305,"text":"Implement an operational data store or ODS the ODS typically maintains a replica of a subset of data from The","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=305s"},{"start_seconds":313,"text":"Ledger in the format optimized for a specific client application this way a client application can perform fast and","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=313s"},{"start_seconds":321,"text":"efficient queries against the data stored in the ODS Ledger data in an ODS could be combined with data from other","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=321s"},{"start_seconds":329,"text":"other sources to support the workflows in a client application since daml triggers cannot have access to any data sources other","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=329s"},{"start_seconds":338,"text":"than the Ledger an automation application that requires an ODS cannot be implemented as a damel trigger to","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=338s"},{"start_seconds":346,"text":"summarize daml triggers may be very useful for quick prototyping of automated workflows for developer","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=346s"},{"start_seconds":352,"text":"testing or proof of concepts for scalable Production Solutions off lger automation should should be implemented","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=352s"},{"start_seconds":360,"text":"using other tools like The Ledger API using an operational data store and possibly integrating with other off lger","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=360s"},{"start_seconds":369,"text":"systems or data sources since triggers send commands to The Ledger and these commands must be","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=369s"},{"start_seconds":375,"text":"authorized a trigger runs under the authority of a party or a set of parties mapped to a user like any other Ledger client","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=375s"},{"start_seconds":384,"text":"application to create a daml trigger you need to define a value of type trigger s where the trigger is a data type","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=384s"},{"start_seconds":392,"text":"imported from the dl. trigger module and S is the type of user defined State a daml application running on The Ledger","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=392s"},{"start_seconds":400,"text":"is stateless a daml trigger on the other hand can have internal state which can be used in the code logic what you see","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=400s"},{"start_seconds":409,"text":"in the lower part of the screen is the definition of the trigger type in the dl. trigger module the trigger type is a","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=409s"},{"start_seconds":416,"text":"daml record with five fields let's look at these fields the initialize function is called on Startup and allows you to","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=416s"},{"start_seconds":425,"text":"initialize your userdefined trigger state which can be based on querying the active contract set the update State","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=425s"},{"start_seconds":433,"text":"function is called on new transactions and command completions and can be used to update your userdefined trigger State","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=433s"},{"start_seconds":441,"text":"based on the active contract set in the transaction or completion the rule function is the core of a daml trigger","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=441s"},{"start_seconds":449,"text":"it defines which commands need to be sent to The Ledger based on the party the trigger is executed on the current state of the active contract set and the","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=449s"},{"start_seconds":458,"text":"user defined State the type trigger a allows you to emit commands that are then sent to The Ledger query the ACs","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=458s"},{"start_seconds":467,"text":"update the user defined State and retrieve the commands in Flight with the get commands in Flight function do","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=467s"},{"start_seconds":475,"text":"notation and the get time function can both be used in the rule function templates and interfaces that the","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=475s"},{"start_seconds":482,"text":"trigger will operate on can be specified using the registered templates field this defines which templates and","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=482s"},{"start_seconds":490,"text":"interfaces the trigger will receive events for you can list an explicit set of templates and interfaces here or you","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=490s"},{"start_seconds":498,"text":"can set the value of registered templates field to All In which means that the trigger will receive events for","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=498s"},{"start_seconds":505,"text":"all template and interface types defined in the DAR file the trigger will be compiled into while it is possible to","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=505s"},{"start_seconds":513,"text":"use the all and dar value for the registered templates field in production applications it's almost always advisable to use an explicit list of","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=513s"},{"start_seconds":522,"text":"templates or interfaces Instead This is mainly for performance reasons the DAR file will typically contain many","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=522s"},{"start_seconds":529,"text":"templates and interfaces that are not relevant to the trigger note that providing an explicit list of templates","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=529s"},{"start_seconds":536,"text":"and interfaces also filters the result results of querying the ACs using the trigger API also note that contracts of","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=536s"},{"start_seconds":545,"text":"the excluded templates and interfaces cannot be queried finally you can specify an optional heartbeat interval at which the","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=545s"},{"start_seconds":554,"text":"trigger will be sent a heartbeat message this is useful if you want to ensure that the trigger is executed at a","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=554s"},{"start_seconds":561,"text":"certain rate to issue timed commands in this example we see the implementation of a trigger named noop","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=561s"},{"start_seconds":569,"text":"the noop variable is declared with the type trigger imported from the dl.","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=569s"},{"start_seconds":574,"text":"trigger module this is a trivial trigger that does not apply user defined state in the code logic hence the state is","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=574s"},{"start_seconds":582,"text":"defined as a unit or an empty tupple since this trigger doesn't use state in the code Logic the initialized function","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=582s"},{"start_seconds":590,"text":"doesn't do anything and just Returns the unit wrapped in the trigger context by calling a pure function with the unit as","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=590s"},{"start_seconds":598,"text":"the value of the argument similarly the update State function is defined as a Lambda function that","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=598s"},{"start_seconds":605,"text":"discards the value of the argument and just calls pure unit the rule function here is also defined as a Lambda","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=605s"},{"start_seconds":613,"text":"function that discards the value of the argument and calls the debug function that prints the word triggered to","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=613s"},{"start_seconds":620,"text":"standard out the registered templates field is set to all inar which means the trigger does not filter out trigger","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=620s"},{"start_seconds":628,"text":"events based on the template and finally the heartbeat field is set to none which means that the trigger responds to the","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=628s"},{"start_seconds":636,"text":"change in Ledger State rather than to the heartbeat messages the effect of running this trigger is that whenever The Ledger","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=636s"},{"start_seconds":644,"text":"State changes the trigger will print the word triggered to standard out to summarize a daml trigger is an off lger","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=644s"},{"start_seconds":652,"text":"automation component unlike Ledger clients implemented using The Ledger API daml triggers are written in daml","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=652s"},{"start_seconds":661,"text":"triggers react to changes in The Ledger State and execute a function that sends commands to The Ledger and restores The","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=661s"},{"start_seconds":669,"text":"Ledger to a desired invariance state to implement a trigger you need to import the dl. trigger module and create a","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=669s"},{"start_seconds":677,"text":"variable of the type trigger s where s is the user defined trigger","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=677s"},{"start_seconds":687,"text":"state","url":"https://www.youtube.com/watch?v=oi1TPbVztAY&t=687s"}],"youtube_url":"https://youtube.com/watch?v=oi1TPbVztAY","url":"https://ccpedia.xyz/videos/oi1TPbVztAY"}