Implementing Bots in DAML Application

Reading Time: 4 minutes

In this blog, we will explore the Bots in DAML, we will start with basic introduction about Bots than we move to why do we need it and how we can implements Bots in our DAML Application. Before moving forward, I assume that you know basic of DAML if not then please read this blog.

What is a Bot?

A bot is a software application that is programmed to do certain tasks. Bots are automated, which means they run according to their instructions without a human user needing to start them up. Typically they do repetitive tasks, and they can do them much faster than human users could.

Why do we need Bots?

DAML is a great programming language to write a smart contract but is still new and under development. Sometimes, developers need to automate processes like the generation of action in response to a certain event (an incoming transaction, for instance). Let suppose, we want to automatically create a new contract in DAML after another contract is created or we want to archive a contract after a user performs a certain transaction. Right now, this is not possible to accomplish with just DAML itself as DAML Trigger is still under development. We need bots for this purpose which is basically an abstraction to create an automation for a DAML Ledger.

How do we Implement Bots in DAML Application?

For bot implementation, we use a python library called DAZL.

DAZL is an amazing Python library provided by Digital Asset. It provides a number of functions that enable the automation on the Ledger as it provides event listeners for the same. Suppose you want to run a certain piece of code after the execution of events related to contracts, like creation, archival, or exercise of choice, then it can easily be done using the DAZL Library.

Benefits of Bot

  1. Add support for third-party APIs simply by creating bots that listen to external activity.
  2. Works great with DABL Cloud Service.
  3. Portable and adjustable as per requirements.
  4. Quick response time.
For creating a Bot we need following files to be added in our project.
  • setup.py: for adding basic info about Bot. Like the name of bot, version name and for importing dazl library.
  • __init__.py:  It usually just be left empty—it’s just a marker file that tells Python that a directory is a module.
  • __main__.py: It contains your “main”—whatever is in there is run when you run your application.
  • bot.py:  It contains main function you need to perform after a particular transaction.
Directory structure

Let create a Demo Application

Now we will create a simple application where a user query for a car of selected company with limited budget. As a response company marketing team will send proposal to user. Once user select a proposal and create a Final Agreement we will use bot to archive the remaining proposal.

Application Flow

As you can see in above figure that user Accept only Maruti proposal so our bot will reject Honda request.

Main.daml
module Main where


-- MAIN_TEMPLATE_BEGIN
template CarRequest with
    userName: Party
    userBudget : Int
    interestedCompany : [Party]
  where
    signatory userName
    observer interestedCompany
-- MAIN_TEMPLATE_END

    
    -- FOLLOW_BEGIN
    nonconsuming choice Proposal: ContractId CarProposal with
        company : Party
        model : Text
        price  : Int
      controller company
      do
         assert(company `elem` interestedCompany)
         create CarProposal with companyName = company ,queryParty=userName, carModel = model, carPrice = price

    choice NotInterested :  () with

        company : Party
        
      controller company
        do
          assert(company `elem` interestedCompany)
          return ()


template CarProposal with
   companyName : Party
   queryParty : Party
   carModel : Text
   carPrice : Int
   
  where
    signatory companyName
    observer queryParty    


    controller queryParty can
      AcceptOffer : ContractId FinalAgreement
       do
         create FinalAgreement with 
           company = companyName
           user = queryParty
           model = carModel
    
    controller queryParty can
      RejectOffer : ()
       do
         return ()
    

template  FinalAgreement with
   company :Party
   user : Party
   model : Text
  
  where
    signatory user
    observer company
    
setup.py
from setuptools import setup

setup(name='bot',
      version='1.0.0',
      description='Car-Info Bot',
      author='Knoldus Inc.',
      license='Apache2',
      install_requires=['dazl'],
      packages=['bot'],
      include_package_data=True)
bot.py
import logging
import uuid
import datetime
import time
import dazl

dazl.setup_default_logger(logging.INFO)
EPOCH = datetime.datetime.utcfromtimestamp(0)

def main():
        
        #configure bot environment so it can connect to ledger 
  
 	network = dazl.Network()
	network.set_config(url='http://localhost:6865')
	client = network.simple_party('Alice')

	contractIdProposals = []
         
        #creating decorator which will log as soon as client make any 
        #transaction

	@client.ledger_ready()
	def bot_ready(event): 
		logging.info(f'user_bot for party {client} is ready')

	
        #decorator for storing CarProposal Id 

        @client.ledger_created('Main.CarProposal')
	def on_message(event):
		contractIdProposals.append(event.cid)
		logging.info(contractIdProposals)
        
        #decorator for rejecting remaining offer aftr user accept a 
        #proposal
 
	@client.ledger_exercised('Main.CarProposal','AcceptOffer')
	def final_agreement_created(event):
		contractIdProposals.remove(event.cid)
		for contractId in contractIdProposals:
			client.submit_exercise(contractId, 'RejectOffer')
        
        # for running bot forever 
	network.run_forever()

if __name__ == '__main__':
    main()
If you are deploying it over dabl change bot environment configuration to
	url = os.getenv('DAML_LEDGER_URL')
	party = os.getenv('DAML_LEDGER_PARTY')
	network = dazl.Network()
	network.set_config(url=url)
        client = network.aio_party(party)

you can get complete code here.

Now run application

daml start

open another terminal and move to bot folder to start our bot.

python3 bot.py

Now use navigator to test your application.

References
https://github.com/digital-asset/dazl-client
https://docs.daml.com/