R3 Corda Settler Tutorial — Integrate a Custom Off-Ledger Payment Rail
Please note that I am not affiliated with R3.
Corda Settler is a reference CorDapp implemented by R3 that provides a framework for handling on-ledger settlement through off-ledger payments. These could be payments via cryptocurrencies subject to public blockchains as well as via traditional payment systems like a bank API. In this tutorial, we’ll learn how to leverage the Corda Settler CorDapp to implement and integrate a custom payment rail.
This tutorial assumes you are familiar with the basic Corda Key Concepts as well as having a basic understanding of writing simple flows. The Corda 100 Developer Training is a great place to start if you are new to Corda.
“ A key challenge for the adoption of blockchain technology at scale will be avoiding having blockchain implementations become isolated systems, unable to plug into what exists today … Corda Settler is an initial step to bridge the emerging and existing world.”
— Todd McDonald
Corda Settler is a CorDapp allowing settlement using off-ledger payment rails. It is easily interoperable with other CorDapps (including your own), supports cryptocurrency digital payments as well as traditional bank API’s, and returns a cryptographic proof of settlement.
It’s important to understand the concept of Oracle services in Corda. Oracles are an optional Corda network participant that can be used as the authority on non-deterministic and off-ledger data. This is what will be used for Corda Settler in order to confirm payments have been made and balances have been updated in the off-ledger payment rail.
Here are the steps that occur in the reference Corda Settler CorDapp. The example R3 uses is XRP cryptocurrency tokens from the Ripple blockchain.
We can extend this CorDapp (as we will do in the next section) to apply these same steps to our own payment rail. Alternatively, we could implement our own settlement CorDapp from scratch using this as a reference — this would be a good idea for production, as the Corda Settler CorDapp is very bare-bones, and you would want to be more thorough with a production application.
Steps in Settler CorDapp
- Create an obligation — Standard flow dynamic involving creating a transaction with an output state and gathering signatures.
- Get exchange rate from FX-Oracle — Common Oracle flow involving requesting a non-deterministic exchange rate using an agreed-upon Oracle service. This step isn’t necessary in all cases, but for the Ripple XRP example we need the current XRP value since it fluctuates over time.
- Novate obligation with relevant currency (ex. XRP) — After receiving the FX rate, update the obligation to be in terms of the currency to be transferred.
- Add additional settlement terms — Update the obligation’s settlement method to be the SettlementMethod type defined for our payment rail (more on this later).
- Initiate payment on the off-ledger rail — Make payment using a custom implementation of MakeOffLedgerPayment flow.
- Obtain confirmation from Settler Oracle — Use Settlement Oracle to verify the payment was received by the recipient’s off-ledger account.
- Obtain signatures and settle the obligation — Once payment is verified, collect signatures, send to a notary and both parties can mark the obligation as settled in their vaults.
Implement a Custom Payment Rail
- Create a CordaService API to interface with the payment rail. @CordaService annotation on class
- Sub-class MakeOffLedgerPayment for creating a payment using your payment rail.
- Add a SettlementMethod type and Payment type for your payment rail.
- Create an Oracle to verify payments.
Step 1 — Create a CordaService API to interface with the payment rail.
Use @CordaService annotation to create a service that interfaces with the payment rail to check balances, make payments, and any actions needed for that payment rail.
The implementation of the API methods are up to you to determine based on the specifics of your payment rail, but if you need inspiration check the XRP example methods: checkObligeeReceivedPayment and hasPaymentSettled.
Step 2 — Sub-class MakeOffLedgerPayment for creating a payment using your payment rail.
Settler payment rails are created by sub-classing MakeOffLedgerPayment abstract FlowLogic class.
Override these three methods:
setup() — Perform any setup tasks needed for your payment rail. You may need to authenticate with an external API for example. In the case of XRP, we need to create a sequence number to use in the transaction.
checkBalance() — Use CordaService API to check balances and verify funds exist. This ensures that the Party sending payment indeed has funds in this external payment system available in order to make payment. Bank API’s will need to check the sender’s balance before initiating payment, while with cryptocurrencies public nodes can be used to make this query.
makePayment() — Make a payment using the API or in the case of cryptocurrencies initiate a transfer using public nodes of that external blockchain network. For XRP, we use the Ripple public nodes to initiate the transfer.
Step 3 — Add a Settlement Method type and Payment type to your payment rail.
The SettlementMethod interface just requires an accountToPay property, but we will implement OffLedgerPayment which includes the settlementOracle and paymentFlow properties.
The Payment interface requires the three fields specified below, of which you can add more if relevant. The field paymentReference could refer to a transaction ID or some other identifier that the Oracle can use to verify the transaction.
Step 4 — Create an oracle to verify payments.
We will need an Oracle service on the network that has flows implemented for verifying payments on the given payment rail. This again can be done through integration with an external API or through interaction with an external blockchain network for cryptocurrency rails.
In this example we are going to use the Oracle provided in the Settler CorDapp and modify it to support our new payment rail.
To do this we will modify VerifySettlement.kt from the Settler CorDapp.
Here we are adding our SettlementMethod into the when/is clause.
The verify function needs to use the @CordaService we created in Step 1:
And for a more detailed example, see the XRP implementation of this method.
Now all the parts are connected and settlement is possible!
R3 Corda Settler Tutorial — Integrate a Custom Off-Ledger Payment Rail was originally published in Corda on Medium, where people are continuing the conversation by highlighting and responding to this story.