E2E Property Rentals Written in Daml

author by Fabio Tudone February 16, 2021

In this article

Improving renting

Renting a property is still quite a manual and cumbersome process because different actors have different views of it and can’t fully trust each other, so paperwork is put in place to mitigate risks.

If we were able to solve these paperwork issues, we could apply the same approach to not only rentals but also many other multi-party processes.

Defining the shared rental process

Suppose we’ve been hired by rental market players to improve their business.

The first thing we’d do is to sit together and to define a shared process and, after several iterations, we might agree on the following one:

Business actors

  1. Authority: registers properties to their landlords and grants licenses to rental agencies.
  2. Landlord: owns a property and can delegate its rental to an agency.
  3. Agency: governs the whole process on behalf of the landlord.
  4. Tenant: the current tenant of a property, runs property visits.
  5. Renter(s): prospective tenants that can be invited to visits by the agency and can apply.

Successful rental

A successful process runs as follows, with stages represented as Daml contracts:


The Daml Rental process

  1. The authority registers a Property to a landlord and offers an AgencyLicenseOffer to a rental agency.
  2. The agency accepts the AgencyLicense.
  3. The landlord turns the Property into a Rental and delegates the rental to an agency through RentalDelegateOffer. From now on, the agency manages the property’s rental.
  4. The agency accepts and updates the Rental, inviting one or more prospective tenants for a visit through VisitOffer.
  5. A prospective tenant creates a VisitScheduleRequest.
  6. The current tenant schedules and runs the visit(s), whose completion is audited by a Visited stage.
  7. The prospective renter(s) may create a RentalApplication.
  8. The agency may accept at most one application and emits a RentalContractOffer while locking the Rental by transforming it into a RentalPendingContract, preventing other applications from being accepted.
  9. The selected applicant may accept it and RentalPendingContract becomes a RentalContract.

Unsuccessful rental

Of course any stage of the process is allowed to fail: the agency license can be withdrawn and any offer can be rejected; the actors, though, should still be free to engage in new agreements.

Renting in Daml

Translating a process into Daml is fairly straightforward, as Daml is built around the concepts of multi-party agreements, but it also means defining it more precisely and dealing with inconsistencies immediately. For this reason, it might be actually a good idea to use Daml as a design aid from the start.

In the following sections we’re going to analyze Rental.daml which can be obtained by cloning this. Alternatively you can check out a short video demo:

Short video demo of "E2E Property Rentals Written in Daml"

Modelling patterns

Some patterns are commonly used in Daml processes:

  • The state of the active processes are stored as contracts and the blueprints for contracts are templates. Templates can have parameters, signatories and observers (i.e. parties that resp. endorse or see contracts), as well as lookup keys.
  • Templates also define the process transitions as choices and restrict the parties that can perform them. Since choices can define many actions that can also be choices, exercising a choice can trigger a rather big set of actions.
  • Choices execute atomically, i.e. either all actions will be applied in the order specified or none of them will.

Let’s have a look at the AgencyLicenseOffer template that represents the initial state of a rental process for an agency:

This template employs Daml offer-accept pattern for rights delegation:

  1. A party submits a create AgencyLicenseOffer transaction, with herself as the authority and an agency party.
  2. authority is a signatory, i.e. it signs the contract, and also automatically an observer (but not vice-versa).
  3. agency is declared as a controller for two choices, i.e. it can exercise either AgencyLicenseOffer_Accept or AgencyLicenseOffer_Refuse with the endorsement of authority that created the contract.
  4. When agency exercises AgencyLicenseOffer_Accept, the AgencyLicenseOffer contract is archived (this is the default behavior) and a new AgencyLicense replaces it. Alternatively, exercising AgencyLicenseOffer_Refuse will only archive the offer.

A short tour of Rental.daml

Rental.daml follows the previously described process closely, so I’ll concentrate on portions that introduce new concepts.

Initially, when the authority offers a license to an agency, we maintain role separation and, with the following assertion, ensure that they are not the same party:

Similarly, when the authority registers a property to a landlord, specific clauses are in place to avoid conflicts of interest:

Also note that the authority can always revoke a license through an empty consuming choice on the license contract:

All offer-accept steps provide similar empty choices to refuse an offer:

Also note that the property registry ID is a key for the Rental:

This key is used to refer to Rental independently from its contract ID that changes because the Rental gets transformed into a RentalPendingContract when a rental application is accepted:

This mechanism effectively locks the Rental so that there is at most one contract offer. If it is refused, the RentalPendingContract becomes a Rental again:

Finally, non-consuming choices are used for non-exclusive steps like offering a visit, exercising these choices won’t archive the Rental contract:

Scenarios

Daml scenarios are scripted submissions similar to commands issued by a Daml application and are used for testing and documentation.

The repository includes a scenario that tests authorization and the happy path.

Triggers

Triggers simplify off-ledger automation, i.e. automatic submissions in reaction to ledger updates. They are effective for cleanup and bookkeeping tasks as they can be written in Daml (they are currently considered experimental).

In our Daml Rental model, we allow many visits and applications for a single property; this means that, when the property is rented, the pending visits and applications must be rejected.

It is possible to let our model track pending activities and archive them when a rental lease is signed but it is easier to write a cleanup trigger that will react to ledger events and perform the cleanup.

User Interface in Daml

Daml offers a sandbox with an UI that allows utilitarian interaction with the model during development.

A dedicated user interface is expected for a production-ready application though. For this we offer a React-Typescript scaffolding based on create-react-app that provides a starting point to modern, single-page web applications that interact with Daml. You can check it out here.

Since I already had my own React-TypeScript scaffold, I decided to reuse that one:


React-TypeScript scaffold

It currently includes all the tables but only two actions: creating and renting a property.

Invoking the Daml JSON API

Daml Rental invokes the Daml JSON API through Axios, for example here’s the implementation of loadContracts, which gets all contracts belonging to a specific template:

Authentication and Authorization

The Daml platform is agnostic w.r.t. Identity and Access Management (IAM) architectures.

The Ledger API Server offers a gRPC API and supports out-of-the-box requests that carry a JWT token signed by a well-known issuer; the token includes the capabilities of the submitter, i.e. on behalf of which parties it can read and write.

The Daml platform also includes a JSON API that translates between REST and gRPC requests/responses, forwarding the JWT token.

Daml Rental accesses the JSON API through Axios and authenticates by attaching the user token to every request:

Conclusion

This example covers the bulk of a real-world rental process and was written in one week by reusing an empty React-Redux-Typescript scaffold; a similar or better productivity gain can be achieved by using create-daml-app.

The most thought-intensive part was designing the rental process which is where Daml really shined. Daml allowed me to focus exclusively on the business logic and customer interactions in my Daml application. I didn’t have to worry about the JSON API, data persistence, or access management which greatly decreased my mental load.

On the frontend side writing a dedicated UI was mostly busywork and the API integration was extremely smooth.

If you want start building and learning, Daml has also a new learn section where you can begin to code online:

 

Learn DAML online