ACH Payments on Smart Contracts — A Daml & Dwolla Example

This is a guest post from Dimitri Liakakos . The original article was  posted on Medium  and is republished here with permission.
1_XlqlNKomDvMqxcILbGJtVw (1)

Smart contracts are great tools for storing value in digital form as well as defining the behavior of how that value can be transferred, split, locked or simply destroyed. However, describing smart contract state transitions without specifying who is allowed to perform them and when, is like playing a game of chess where each player can move any piece on the board regardless of their turn. In this regard Daml, the platform-agnostic smart contract programming language developed by Digital Asset, shines.

Daml provides a higher level abstraction of the business logic from the nitty-gritty details of the data persistence layer implementation, be it a relational database or a blockchain. Its smart contracts also offer fine-grained permissions that hide all of the public address and transaction signing cryptography (should there be any) under the concept of a Party, a primitive type of the Daml language.

In this post I’ll try to demonstrate how to use Daml and its permissions in order to transfer value between parties in the form of ACH Payments. For this we will use Drachma — a library of Daml modules with a Python app that wrap the powerful Dwolla APIs for interfacing with the ACH Network. To set the stage, let’s use a scenario similar to the one in Settling a Daml Payment Obligation on Ethereum.

This time, Alice is looking to mow the lawn of her freshly painted house. She gets an offer from (you guessed it..) Bob the Gardener in exchange for $59.99. Bob, being a Drachma user, can set up a Daml agreement with Alice and receive payment in the form of an ACH transfer that will deposit the funds directly to his savings bank account. Daml will handle all the workflow and permissions between the two parties and Dwolla will power the ACH transaction.

Bootstrapping Alice to the ledger

Alice would like to accept Bob’s offer but unfortunately is not a Drachma user yet. She decides to get onboard and asks the Drachma operator to extend her a UserInvitation. (In Drachma, the “operator” is a trusted third party responsible for on-boarding users and servicing their requests):

Alice accepting the Operator’s invitation

Now that Alice is a Drachma user and has a User role contract, she will need to register herself as a Dwolla personal verified customer and attach her checking bank account from which she will send the funds. To kick off the registration process she exercises the User_VerifiedCustomerRequest choice on her role contract and provides the necessary fields for the Dwolla API

Alice requesting from the Operator to become a verified customer

The operator forwards the request to Dwolla and a successful response leads to the creation of a personal verified customer resource for Alice as well as an equivalent Daml Customer contract for Alice.

Alice as a Dwolla personal verified customer

Adding Alice’s bank account

The next step for Alice is to attach her bank account as a Dwolla Customer funding source. To accomplish that, she will exercise the Customer_UnverifiedFundingSourceRequest choice on her Customer contract:

Alice requesting a new unverified funding source

The request is once again forwarded to Dwolla which creates a funding source resource for Alice and the corresponding Daml FundingSource contract.

Unverified Dwolla funding sources however may only receive funds. In order for Alice to be able to send funds, she will need to verify her bank account. Dwolla offers a number of options for verification of a funding source — among them is the Micro-deposit verification process.

In this workflow, Alice will instruct Dwolla through the operator to transfer two deposits of less than $0.10 to her bank account. After the two random amounts post, she can fetch them from her statement and use them to verify her account. Let’s see how this unfolds in Drachma:

Verifying Alice’s bank account

Alice navigates to her FundingSource contract and exercises the FundingSource_InitiateMicroDeposits choice. This initiates the two random micro deposits and creates a micro-deposits resource on Dwolla’s side and a MicroDeposits contract in Daml. According to Dwolla, it will take 1–2 business days until the status of the deposits changes from pending to processed.

Alice’s MicroDeposits contract

Thankfully we are on a sandboxed environment so we don’t have to wait! Alice’s micro deposits have already posted and she is ready to proceed with verification. She exercises the MicroDeposits_Verify choice on the MicroDeposits contract and passes the two amounts as arguments.

1_uIMIVQfPs5xL6eY3ModMug (1)
Alice verifying her checking account with micro-deposits

The amounts make their way to the Dwolla API and if they match the ones sent, the bank account gets verified! Alice is now a verified customer with a verified bank account and is ready to make a deal with Bob.

Bob makes an offer Alice can refuse

Daml does a heck of a job modeling a party’s rights and obligations. Therefore Alice can never get into an obligable position against her will.

Bob goes ahead and drafts a GardeningOffer contract. He becomes the signatory of that contract and offers Alice the choice to accept it or refuse it. In his offer, Bob mentions the amount of money he is to receive for his work, an id for the payment (should Alice accept it) and finally a list of his trusted Drachma operator parties that Alice can use for the ACH payment.

The GardeningOffer Daml template and mowTheLawn scenario

Notice that if Alice (the beneficiary) chooses the AcceptOffer happy path, a GardeningContract and a ReceiveFundsRequest contract will be created. The GardeningContract will be the official agreement between Alice and Bob and the ReceiveFundsRequest will be a contract addressed to Bob in order to receive payment.

Let’s take a closer look at the body of the AcceptOffer choice. It requires Alice to pass her Customer contract id as well as the id of her bank account that she just verified. Daml will fetch the Customer contract and assert that it belongs to Alice and that the operator is one that Bob also trusts. It will then create two Metadata records that will piggyback on the ACH payment and help identify it later. Finally it will exercise the Customer_SendFunds choice on behalf of Alice and create the GardeningContract agreement between the two parties.

It’s official. Per the GardeningContract Bob must mow Alice’s lawn and Alice must reimburse Bob with $59.99 in the form of an ACH transfer. Bob may start mowing, but he also needs to respond to the ReceiveFundsRequest and specify where he would like the funds to be deposited.

1_kud3y24qQrG4iW-NHLUQEg (1)
Bob accepting funds from Alice

For that he exercises the ReceiveFundsRequest_AcceptFunds choice and passes his bank account id and optionally any clearing instructions addressed to his bank. This creates a TransferAgreement that is validated by the operator and converted into a TransferRequest which once again hits the Dwolla API. The request will create a transfer resource in Dwolla’s side and a Transfer Daml contract containing the details of the ACH transfer.

Bob viewing the Transfer Daml contract

Settling the deal

Being a top professional, Bob has done an awesome job mowing Alice’s lawn. The ACH Network has also processed the fund transfer between Alice and Bob’s bank accounts. What is left is to settle the GardeningContract. Before we do that let’s take a look at it:

The GardeningContract Daml template

The contract is signed by both Alice and Bob (gardener and beneficiary are both signatories). Recall that neither party was forced into this obligation, as Bob created a GardeningOffer and Alice accepted. Daml would refuse to create this contract outright, should either Alice or Bob attempt it, since it would be missing the consent (signature) of the other party.

To settle it, Alice can exercise the SettleTransfer choice and pass the Transfer contract id as proof of payment. Daml will first assert that the contract has not already been settled and then fetch the details of the transfer in order to validate them against the contract terms. The sender, receiver, amount, status of transfer and invoice id are checked. Finally the contract is updated with a populated optAchId field containing the id of the ACH transfer.

Alice viewing the settled GardeningContract

Wrapping up

We have used the power of Daml and Dwolla to create a multi-party workflow that triggers an ACH transfer and settles an agreement. I would encourage you to further explore the Drachma GitHub project and submit any valuable feedback or contributions! I am leaving you with a snapshot of the final Daml ledger active contract set. Cheers!

The final Daml Active Contract Set