Skip to content
CCPEDIAby Unity Nodes
VideosHow to automate ledger actions using Daml Triggers - Daml Webinar

How to automate ledger actions using Daml Triggers - Daml Webinar

Nothing is loaded from YouTube until you press play, and then without tracking cookies.

About this video

๐Ÿ“– Get started with Daml: bit.ly/tryDaml ๐Ÿ“š Learn more about Daml Smart Contracts: bit.ly/learn_daml ๐Ÿ“ฎCheck out our blogs: bit.ly/daml-blog-engineering ๐Ÿ“‹ Become a Daml certified expert: bit.ly/daml-certification

In this session, we will discuss what DAML Triggers are and how to write them.

Daml applications often need to automate certain interactions with the ledger.

For example, when an expense request is created on the ledger, you might want to auto-approve it so long as it is less than a certain amount.

Although it is possible to write such automations in a language of your choice using the JSON API or the ledger bindings, it introduces an additional layer of friction.

DAML triggers address this problem by allowing you to write automations directly in DAML reusing all the DAML types that you have already defined in your model.

Speakers: 1. Dimitri Liakakos, Digital Asset 2. Moritz Kiefer, DAML Language team

๐Ÿ”Ž Please create a free account on project: DABL and deploy this smart contracts based chat application on your ledger. You get your own URL to share with everyone, and now have your own collaboration system for your projects!

๐Ÿ“– Here are two other end-to-end samples here and here that will help you get started when you are ready to host your own business app.

โฉ What better way than to create your roadmaps and important to-dos on DAML smart contracts based, project:DABL hosted, OpenWork Board! Board is a Kanban-style card tracking app.

๐Ÿ‘ For any questions or assistance please feel free to write to us. Stay safeโ—๏ธ

#HyperledgerFabric #dlt #smartcontract #blockchain #damlsmartcontract #digitalasset #ledger #technicalskills #DLT #skillset

Transcript

4,980 words

Captions as YouTube publishes them, usually machine-generated, so names such as Daml and Canton can be misheard.

  1. 0:01

    okay so good morning everyone thank you very much for joining um and uh this is manish and i've got uh my colleagues from digital asset uh dimitri and moritz who are going to be taking you through the concept of demo triggers uh so damil triggers as you may have heard or you've seen in the description of the webinar is about automating um automating events uh on a diamond ledger so very simply put

  2. 0:25

    if you have a contract that is created take some action automatically based on that so if there's a new invoice proposal that has come in uh then take some action maybe send it to verification notify the party that is uh responsible for verifying the invoice etc automatically using demo and and the beauty is of course you can do that in tamil now using tamil now instead of trying to use a use another general purpose language and

  3. 0:49

    which sits on top of the ledger so uh without further ado then uh and uh i'm going to be recording the session obviously so we'll send out the recording after the webinar we'll also put it on youtube and on the discuss forum as well so for those of you who are unable to stay for the full session or if any of your colleagues wanted to attend but they couldn't feel free to send them the link and let them know

  4. 1:14

    okay all right then so uh dimitri over to you thank you manish if you can unshare so i can share my screen okay so uh i guess you uh manish you did uh already make an intro so i'm not gonna bore uh the audience with uh more slides so as you mentioned uh demo triggers uh they are off-ledger automation uh they're written in demo so the usual uh strict typing and um power of demo that we're used to in our smart contracts uh and they interact only with their

  5. 1:51

    ledger so uh this is not you would not use every trigger to uh to call it saying an external api uh so you would you use it for uh simple uh automation and syncing uh tasks uh that are that are triggered off ledger uh so why uh what's the motivation behind them uh we feel that there's a lot less friction uh when things are in demo uh both the models are endangered and the automation is in demo

  6. 2:17

    uh given that you don't have to translate all these data payloads you know to json back and forth or to whatever other binding you have chosen uh and there's less code duplication as well in terms of checking things right so you could leverage the insurers and the um and the assertion that demo uh provides you uh straight out of the model instead of uh instead of having to write some of that logic on your on your client uh and last but not least there's a

  7. 2:41

    fairly straightforward interface with a few functions that you can uh define uh that let you uh keep a user-defined state updated uh some rules on on you know if this then uh that uh signal um uh set up your hook up your triggers to specific uh template events and then also the ability to fire things uh on a timer which is that heartbeat that you see here at the uh last line so without further ado let's uh let's uh see like a hands-on example basically

  8. 3:13

    all this and again uh if you have a question feel free to post it on the q a section or just raise your hand and we'll answer a few at the end of this um okay so to start what we'll do is we'll uh draw inspiration actually pretty much uh take a newer version of of what uh of this blog post uh which demonstrates demo triggers and the um the setup would be in terms of uh a vacation tracker within a company so we

  9. 3:45

    we would have acme a corporation being a company and two parties alice and bob where alice is bob's uh boss and bob basically signs their employee contract with a company that gives them some sort of a vacation allocation and then bob is requesting vacation days from his boss alice now alice because she's in a good mood she'll have a trigger uh to auto accept uh any vacation request that bob makes as long as uh that vacation is not uh is

  10. 4:22

    um below the allocated days uh you can we'll have this link on this blog post which describes this thing in more detail uh for everyone who's interested then we'll share the link at the end of this uh webinar as well uh so let's jump into the uh to the code i'll launch uh vs code here and i'll resize it so what we have is uh we have this model uh simple model there are three templates there's this agreement between the employee and the company that

  11. 4:56

    defines how many uh vacation days are remaining for this employee at this company with this boss uh this contract is created through a proposal contract so this is the contract the proposal contract that essentially creates this uh agreement uh and then uh the employee can issue vacation requests that are uh then accepted uh from the boss and turned into uh uh vacation contracts uh and to drive this uh i

  12. 5:20

    think this just to see what uh what it looks like we do have a vacation allocation that employee bob has he has 29 remaining days because he requested a vacation from alice which was approved manually in this case in the scenario by alice for uh august uh 12th so for tomorrow uh now what we want to do is we want to write this auto accept trigger so that alice doesn't have to manually uh see each vacation request and um and accept it so if i just want

  13. 5:54

    to show you this vacation request which was archived and it's here and it was translated into this vacation contract um so to do that we'll write a trigger and to write a trigger what we need is a simple it's just a demo file um so just put it here uh and we need to implement uh this interface so this interface is nothing but a few set of functions the first one uh is a function that's called upon uh running the trigger once and this gives us a chance to

  14. 6:26

    read from the acs the acs is basically the active contract set that this party can can see and define uh and hydrate let's say prepare a user state which could be anything we denote this by s uh then each uh message that comes in whether it's a transaction or a command completion uh triggers this update state and gives us the opportunity to uh uh combine anything that's in the active contract state plus this message we received in our existing state to update our next

  15. 6:58

    user state uh then we have this rule which is the meat basically of this of the trigger which is um run by a specific party uh it has access to the acs it has access to the existing time in case we want to do anything time related and it gives us a set of in-flight uh commands so commands that we have already submitted on the ledger uh but we haven't heard the completion uh back yet and our user defines state obviously and combining all these

  16. 7:29

    what we do is we submit uh a set of commands uh wrapped around the trigger a this trigger a is nothing but uh you would you could think of uh of it as a scenario when you're writing scenarios so like a do block scenario do or like an update monad on which is um the equivalent on the demo models uh just a return type uh um and then uh register templates i hinted to this before in these slides is basically what we want as far as

  17. 7:58

    uh hooks for this trigger uh so when does this trigger actually um execute uh and we can you know there's a there's a convenience that we could say that this uh trigger should be uh executed uh on any dar or on any on any uh on any template of the dar or uh filter it down uh to more specific subset of templates that we're interested in the only reason we would do such a thing is if we wanted to uh to optimize the performance of this trigger if we let's say we had a

  18. 8:30

    bunch of templates that we didn't want uh our trigger to be spammed with we would just isolate the ones that made sense for this for these rules and last but not least there's a heartbeat which is we would implement this if we want this trigger to fire uh every specific time interval so that's why it accepts an optional of relative time here so let's go ahead and implement this interface i'll just comment it out

  19. 8:56

    and what i'll do is i'll i have a cheat sheet here so i'll bring i'll bring in some some code and i will do the proper inputs and implement the interface and basically the initialize function is uh is a no op which says that we don't really need we don't really need a user state that's why we've replaced s here with uh with unit i'm getting a linter um i'm getting a lender suggestion here that because i have a nav i could use const here which i'll actually do uh update state again uh this is uh getting the active

  20. 9:43

    contract set and a message and our user defined state and updating our user defined state but because our user-defined state is is a unit we don't need to do anything there either for register templates we could have we filtered it down just to vacation requests because this is what we would uh want to respond to but we could also uh remove this and just have something that's called olindar so that we uh our trigger response to everything uh this is the function that we're gonna implement which is the uh uh

  21. 10:15

    approval um and then we don't want this trigger to fire in an interval so we just have uh none for the heartbeat now for the approval rule itself um i'll just bring it in the picture uh what we have here is uh we uh run it on behalf of a party which is the boss uh this is our active contract that at the time we're not interested about the time uh any time events here uh nor do we care about any commands in flight so these are

  22. 10:46

    underscored and not not relevant and then our user state is also as i said at the unit so what we'll do in this trigger is we'll say uh we'll fetch any requests so we'll use this get contracts function which is imported by the demo trigger library and we'll say let's get all the vacation requests from our acs this gives us a list of top tuples of contract ids and payloads or vacation requests and then what we'll do next is we'll uh

  23. 11:17

    we'll take those requests and uh filter them down uh to uh the actual boss so we are we're running the party as the bus and we want to all the requests where we are the boss that we need to address because other ones we may be an observer at too and we don't really care for them and then last but not least what we're going to do is we're going to take this filtered list and we're going to loop

  24. 11:42

    over it and we're just gonna call uh an exercise uh on each of those contract ids which is the simple accept request so hence the uh the auto accept logic uh there's a little dedup uh here and the reason there is a hadoop and not just an exercise is that uh there could be some commands uh in flight uh suppose that we've already responded to a vacation request and our trigger crashes

  25. 12:07

    uh and we reestablish a connection and we no longer have uh the pending set and we try to send uh the same command this the dupe uh uh function will take care of not uh sending the uh the same command uh twice so that uh that's all uh actually we need uh for the trigger and what we should do next is we should uh uh actually execute it and see see how it works so for this i'm gonna first

  26. 12:36

    save let me make sure i save everything and i will uh perform a demo start to start the local stack that does not start the trigger that just basically builds the dar starts the sandbox and starts the the demo navigator and let's give it a couple moments okay uh so we have this thing uh running and in a different tab uh what we'll do is we'll start the uh the demo trigger that we just built so uh we do this by issuing a command which is

  27. 13:21

    referencing the uh vacation trigger dar that we just compiled uh we have a trigger name which is called autoproof trigger which is basically uh this uh trigger here and it lives under the demo trigger directory uh it's connecting to our local host and port which is where the sandbox is running and it's running as alice which is the boss of bob and the manager in the acme company

  28. 13:46

    so i will run this and we see the message trigger running as alice and what we'll do next is we'll try to exercise the same workflow we saw in the scenarios so first of all i'll log in as acme corporation i'll go to my templates and i'll create a proposal uh for bob who's in the employees employees bob company's acme corporation and the boss is alice and let's allocate 30 vacation days for bob so we hit on submit we see that this thing succeeded and we should expect a contract

  29. 14:30

    uh here to appear which is the employee proposal that we'll go ahead and accept as well so log in as bob accept this proposal great and now if i go back to the active contract set of bob i see that there's an employee vacation allocation which if i click on it i see that uh i do have 30 days remaining as well so what i'll do is i'll request a vacation and i'll uh request the vacation let's say for tomorrow set and submit and i see this succeeded if i go to contracts i'm not

  30. 15:03

    actually i don't actually have a vacation request but i do have an uh approved vacation right away and which is what i would expect uh it's the vacation that i requested for um august the 12th uh and just to see that the the the bot uh the the trigger um did its job uh if i say click uh include archive i see that indeed i did create a vacation request which was automatically um accepted by uh the trigger we wrote uh and that's

  31. 15:35

    uh as easy uh as as a few lines of code in demo uh now there is a little um like a little gotcha basically here and the reason is that if we want to uh expand the logic of this trigger uh we end up uh writing uh more more logic here and this in this file and then once we recompile this dar uh the dar changes the hash which the hash is basically this uh string after the add sign which means that if we have a long

  32. 16:08

    uh running ledger of a demo model and we just change the automation logic the automation logic won't be able to talk uh to our demo model so a good practice for running a trigger is actually keeping decoupling the model and the trigger on separate bars and that's what we'll uh demonstrate uh next so uh suppose i wanted to uh change uh the the body of this choice of this uh sorry the body of this trigger here and i'd like to use instead of the dupe exercise i want to use a new uh newer

  33. 16:42

    function which is called emit commands uh i could do the change here but i'll prefer to do it in a separate bar and just import this dar here so what i'll do is i'll quit my trigger i'll switch tabs and i'll just issue a new command which i'll call a new project which i'll call a stand-alone trigger and this just creates a new um a new project which i'll go and i'll launch my id for and uh i'll just need to do some cleanup work before i

  34. 17:24

    add my uh the trigger file here so uh what i'll do first is i don't really need any sort of setup i'll delete this file uh on my main i also don't need any of that logic and on my demo.yaml uh what i'll need to do is uh i will need to add the demo trigger dependency so i'll remove the script that i don't need to change it to demo trigger so then i'll uh trigger here uh and uh i'll also import uh the the dar

  35. 17:54

    that contains my model so by doing this uh they happen to be in the same director so this is like a relative path my vacation tracker or my vacation uh trigger so this is what i will need to do on my demo.yaml file and then on my main uh what i'll do is i'll uh paste uh this uh um pretty much the same trigger logic that i had uh that i had before and i'll give it a refresh just because

  36. 18:24

    i didn't import and i want this um vs code to understand what i'm importing uh here uh and again i have this linter suggestion that i can get rid of uh and as you can see here i've uh slightly changed the uh logic of the uh the body of the trigger the logic remains the same it's just the implementation is different so what i'm doing here instead is i'm saying that from the uh from the requests that are filtered for this boss let's go ahead and just keep the contract ids so this is just a list of

  37. 19:06

    contract ids or vacation requests then i'm going to create a list of commands so for each of those contract ids i'm going to call i'm going to exercise the accept request so i have a list of commands and then unless my commands are void so unless i don't have any empty uh any commands to send uh i'll uh call this thing called emit commands which will accept my commands and will also um

  38. 19:30

    accept the list of uh contract ids and the reason for this argument here it may be a bit confusing to begin with but this is what i am marking as in flight so this is a a convenience a convenient way of saying that because i'm sending this set of commands uh the next time that i'm going to do a get uh here uh these commands are going to be these contracts are going to be filtered out uh from the get so i will never submit um

  39. 19:59

    a set of commands that are doing the same uh operating on the same uh contract id so this is also handled uh on the demo trigger library itself um so i've changed my logic i've imported my demo model and what i'll do next is just build this thing and run it against the long running sandbox that i haven't uh i still have running here um so i'll save and i'll go to my uh to my trigger code i'll do a demo build

  40. 20:35

    my trigger built and what i'll do next is i'll issue a very similar command uh to the one i used to run the previous trigger uh but instead now i'm referencing the actual standalone trigger dar dars i'm not referencing i'm not referencing the model dar i'm referencing my trigger dar my trigger name is under main now auto proof trigger which is this main uh auto proof trigger and

  41. 21:00

    uh again i'm connecting to the same sandbox and i'm doing this as alex so i'm i'll run this trigger is running uh and i'll just repeat this uh workflow uh we're still logged in as bob we already have a vacation approved uh what i'll do is i'll try again and ask for a new vacation day so i'll say request location we've already taken the 12th so let's take 13.

  42. 21:38

    hit submit and as i can see here i have another vacation and indeed another uh two uh vacation requests as well and just to show that this is uh it's a trigger actually doing the work what i could do is i could uh cancel uh the execution of this uh and retry this and request another date i'll request the 14th hit submit i still get this success uh but uh this is now a vacation request

  43. 22:10

    it's not auto approved because i'm not running the trigger uh that's pretty much in terms of uh in terms of the uh how triggers work and what is the best practice on decoupling the model and the trigger uh there's a more complicated example uh like a deeper dive if you will which we have on our documentation page so if you go to our docs.demo.com there is an early access features section and under that there's the demo triggers uh automation and this talks about uh a trigger which basically syncs

  44. 22:44

    uh uh instances of the original uh template uh to um different subscribers of that original template it's slightly more involved in logic but gives you a better understanding of the power that triggers offer and then last but not least there's this library for triggers which does have all the get contracts and the dupe functions that i uh demonstrated as well as this submit commands uh function that we uh that we used on our uh

  45. 23:16

    the kabul the example uh and uh i've also have uh these links here i'll just make them full screen so they get recorded uh and for anyone to go and explore uh later and we also have this uh ready to go example um which is straight off the uh democli so instead of just doing demo new my example i just could do download my example and add this copy trigger and this will instantiate a skeleton project based off of the copy trigger logic so it will give me a uh this copy trigger that's on the documentation

  46. 23:50

    which i could just go ahead and run or modify according to my uh to my needs uh and that should uh sum up the um the webinar for today if you guys have questions uh we'd love to hear them and as many said this is going to be recorded so uh we will share the link so you guys can take your time and uh follow along this example uh on the recorded version yeah thank you so much dimitri also uh just so everybody knows uh we'll probably be covering in the next coming weeks we'll be

  47. 24:25

    covering how to use demo triggers on project devil um which is you know which many of you may be using uh so we'll do a session on that and we may also be doing a we'll also probably be doing a session on um on using triggers uh on a on a dlt you know such as a when on a sawtooth instance or or how do you do it when it's on when it's your own instance of damal on postgres uh on

  48. 24:49

    maybe on the cloud so we'll cover some of those topics they should be straightforward but it helps to you know just go through a tutorial like this okay any questions from the audience let me check the q a um i don't think we've got any open questions um let me tell you but i did have one so it was so when you run the trigger you specify the party id right not not the security token or the jot

  49. 25:20

    token of the user yes in this case we we did a local run against localhost and our parties are uh human readable strings yeah but i guess if this were running on uh on a production setup and no not localhost these would be uh ledger party ids okay and another question is an sd5 access token so there's an access token file flag which is the same that all our other sdk tools like demoscript and navigator and so on except so if you're running against an authenticated ledger you can specify that and it

  50. 25:51

    supports it okay perfect and you also mentioned there is a time interval right uh like triggers can run um against a predetermined time interval what is the difference between that option and the other which the one that we just executed is it that it's constantly pulling or what is the what is the difference between the two options so the time interval is useful if your rule depends on the time so let's say you

  51. 26:15

    you have some proposal contracts and those proposals can only be executed until a certain time like you just have some some deadline and afterwards they cannot be accepted anymore so then what you could do is have a trigger that auto archives three uh proposals that have been that have expired so in that case you want to make sure that your trigger runs i don't know every five minutes or so even if there have been no changes to the contract so

  52. 26:40

    you can archive those those expired proposals at a time professionally don't have to wait until some some arbitrary ledger event happens that triggers you your role okay guarded marriage thank you so much and i think there's a question now from peter peter white to um dimitri can you see the question uh did the original did you represent the possibility of a half completed transaction taking place

  53. 27:04

    assuming the code crashed at some point no so as everything in demo this is transactional so there's no there's no chance of this being half complete either it happens or it doesn't happen okay good so hopefully peter that answers your question and then there's a que a question from yuri in a recent sdk update you talked about a trigger service uh could you elaborate on that what is the trigger service so if you looked at how this works as db3 just told the demo trigger

  54. 27:35

    command accepts a single trigger and a single party so let's say you have like a thousand parties on your trigger and each of them wants to run the the auto accept bot so you have a very large company well i don't know something else where each party wants to run and trigger so you have a lot of these triggers and potentially also different triggers then spinning up thousands of these processes and each of them is currently a java virtual machine so they're fairly

  55. 27:58

    expensive it doesn't really scale right it's annoying to manage and just very resource intensive you need a very large machine for that so the trigger service basically wraps this all in in a service where you start your service once and then you can dynamically say start this trigger as this person and the single trigger process will take care of managing all of these triggers and we'll do that with significantly

  56. 28:21

    less resources in a more nicer and more dynamic fashion than just starting up all these processes manually okay get it so yuri hopefully that answered your question and then we'll probably cover this in a subsequent session as well any other questions from the audience nope um so that's great uh thank you so much and uh dimitri moritz any closing remarks well just check it out if you have any

  57. 28:52

    feedback we're always happy to hear it just ping us on the forum that's a good way to get us in touch with us we're happy to hear any feedback or see triggers that you've built and learn from it yep and and i also want to hint something uh for any user of project dabble as well uh we are in the process of uh supporting uh triggers and running them uh and we're harding those um the ux around it as well so uh stay

  58. 29:18

    tuned because these are gonna be working uh very nicely on uh project level as well awesome okay thank you so much dimitri thank you maureen thank you everyone for joining and um of course i'll post the recording on youtube uh as well as on on the on discuss so if you have any questions just get in touch with us thank you so much bye