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.
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:
Authority
: registers properties to their landlords and grants licenses to rental agencies.Landlord
: owns a property and can delegate its rental to an agency.Agency
: governs the whole process on behalf of the landlord.Tenant
: the current tenant of a property, runs property visits.Renter(s)
: prospective tenants that can be invited to visits by the agency and can apply.A successful process runs as follows, with stages represented as Daml contracts:
Property
to a landlord and offers an AgencyLicenseOffer
to a rental agency.AgencyLicense
.Property
into a Rental and delegates the rental to an agency through RentalDelegateOffer
. From now on, the agency manages the property’s rental.Rental
, inviting one or more prospective tenants for a visit through VisitOffer
.VisitScheduleRequest
.Visited
stage.RentalApplication
.RentalContractOffer
while locking the Rental
by transforming it into a RentalPendingContract
, preventing other applications from being accepted.RentalPendingContract
becomes a RentalContract
.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.
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"Some patterns are commonly used in Daml processes:
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:
create AgencyLicenseOffer
transaction, with herself as the authority
and an agency
party.authority
is a signatory, i.e. it signs the contract, and also automatically an observer (but not vice-versa).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.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.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:
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 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.
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:
It currently includes all the tables but only two actions: creating and renting a property.
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:
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:
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: