Skip to content
GitHub

Accounting concepts

Accounts and assets

Rafiki uses a combination of liquidity (credit) and settlement (debit) accounts to perform double-entry accounting.

In this context, accounts in Rafiki are specifically the accounts that peers hold with one another. These are not customer accounts. This distinction is crucial for understanding how Rafiki handles transactions and settlements.

Liquidity accounts

A liquidity account holds a non-negative balance, with Rafiki ensuring that total debits do not exceed total credits.

There is one liquidity account for each of the following resources:

  • Asset
  • Peer
  • Wallet address
  • Incoming payment
  • Outgoing payment

Settlement accounts

A settlement account holds a non-positive balance, with Rafiki ensuring that total credits do not exceed total debits. A settlement account represents the total funds you as the ASE have deposited into Rafiki.

Before you can peer with another ASE, you must both agree on the asset you will use for settlement. The Interledger packets exchanged between you and your peer will be denominated in the agreed-upon asset.

There is one settlement account for each asset.

Assets

An asset represents an item of value that can be transferred via the Interledger Protocol. Since the Interledger Protocol aims to create an internet of value, it allows for the transfer of any asset, not just currency. In practice, however, assets are usually denominated in a currency (fiat or branded currencies).

In Rafiki, the asset type is comprised of the following properties.

PropertyTypeDescriptionExample
value BigIntA numerical amount10000
assetCodeStringShould be an ISO 4217 currency code whenever possible"USD"
assetScaleIntegerDifference in order of magnitude between the standard unit and a fractional unit2

To convert an asset amount into a currency amount that’s easier to read, apply the following formula:

Using the example from the table above, our formula looks like this:

USD

TigerBeetle

TigerBeetle is a high-performance distributed financial accounting database used by Rafiki’s backend service to store account balance data at the ILP layer. Both liquidity and settlement accounts in Rafiki correspond to TigerBeetle credit and debit accounts, respectively. TigerBeetle only holds balance data without any additional ILP packet metadata. For detailed information on TigerBeetle, including its consensus mechanism and its limitations, visit the official TigerBeetle documentation and blog.

You have the flexibility to choose whether to use TigerBeetle or opt for a separate Postgres database. However, TigerBeetle is recommended due to its speed, efficiency, and dedicated design for handling double ledger accounting. For more information about Tigerbeetle in a production environment, see Running Rafiki in production.

Liquidity

Rafiki tracks liquidity using the Interledger Protocol, which is a clearing protocol, without physically holding funds.

Asset liquidity

Asset liquidity represents the value, denominated in a given asset, that Rafiki has at its disposal in which to send or forward ILP packets. Asset liquidity increases when packets are received and decreases when packets are sent. Asset liquidity is always positive and cannot fall below zero.

Additionally, you must provide asset liquidity if you are exchanging one currency for another. Asset liquidity ensures there is enough value available to handle transactions in the specified assets.

You should define and adjust asset liquidity based on your liquidity risk profile.

Asset liquidity examples

Your Rafiki instance is configured with two assets: EUR and USD. You’ve set both to have an asset scale of 0. Your EUR liquidity is 10, and your USD liquidity is 50.

In a cross currency transaction:

  • Rafiki receives packets worth 10 EUR and sends packets worth 11 USD. Your EUR liquidity increases to 20 (10 + 10) and your USD liquidity decreases to 39 (50 - 11).
  • Rafiki receives packets worth 50 EUR which equates to 55 USD. This transaction fails because Rafiki does not have enough USD liquidity.

Peer liquidity

Peer liquidity is the credit line, denominated in the asset of the peering relationship, you extend to a peer. Peer liquidity should be defined in the peering agreement and depends on the trust between you and your peer. If peer liquidity is insufficient, payments will not be processed. When peer liquidity is used up, you and your peer should settle then reset your liquidity.

Peer liquidity example

Your peer, Cloud Nine Wallet, has a peer liquidity of 100 USD. Rafiki can send packets that total up to 100 USD to wallet addresses issued by Cloud Nine Wallet.

After the 100 USD liquidity is used up, you settle with Cloud Nine Wallet and reset the peer liquidity in Rafiki to 100 USD.

Payment liquidity

Payment liquidity is managed for incoming and outgoing payments created via Open Payments through liquidity accounts in your accounting database. When incoming or outgoing payments are created via the Open Payments APIs, a corresponding liquidity account is automatically created. Liquidity must be deposited to an outgoing payment account before the payment can be processed. You are notified to deposit or withdraw liquidity via webhook events.

Transfers

Transfers in Rafiki are based on double-entry accounting, increasing both the total debits (withdrawals )of one account and the total credits (deposits) of another by the same amount.

Single-phase transfer

A single-phase transfer posts funds to accounts immediately when the transfer is created.

Two-phase transfer

A two-phase transfer moves funds in stages.

  1. Reserve funds (pending)
  2. Resolve funds (post, void, or expire)

The name two-phase transfer is a reference to the two-phase commit protocol for distributed transactions.

Intra-Rafiki transfer examples

Remember that a settlement account will always have a zero or negative balance and a liquidity account will always have a zero or positive balance.

Deposits

A deposit is the act of debiting the settlement account and crediting the liquidity account.

Depositing asset liquidity

Debit AccountCredit Account
SettlementAsset liquidity

Example: Depositing 100 USD

USD settlement acct USD asset liquidity acct
DebitCredit
100
DebitCredit
100

Depositing peer liquidity

Debit AccountCredit Account
SettlementPeer liquidity

Example: Peering relationship in USD, depositing 100 USD

USD settlement acct USD peer liquidity acct
DebitCredit
100
DebitCredit
100

Depositing outgoing payment liquidity

Debit AccountCredit Account
SettlementOutgoing payment

Example: Depositing 35 USD

USD settlement acctUSD outgoing payment liquidity acct
DebitCredit
35
DebitCredit
35

Withdrawals

A withdrawal is the act of debiting the liquidity account and crediting the settlement account.

Withdrawing asset liquidity

Debit AccountCredit Account
Asset liquiditySettlement

Example: Withdrawing 50 USD

USD asset liquidity acctUSD settlement acct
DebitCredit
50
DebitCredit
50

Withdrawing peer liquidity

Debit AccountCredit Account
Peer liquiditySettlement

Example: Peering relationship in USD, withdrawing 50 USD

USD peer liquidity acctUSD settlement acct
DebitCredit
50
DebitCredit
50

Withdrawing wallet address liquidity

Debit AccountCredit Account
Wallet addressSettlement

Example: Withdrawing 2 USD

USD wallet address liquidity acctUSD settlement acct
DebitCredit
2
DebitCredit
2

Withdrawing incoming payment liquidity

Debit AccountCredit Account
Incoming paymentSettlement

Example: Withdrawing 25 USD

USD incoming payment liquidity acctUSD settlement acct
DebitCredit
25
DebitCredit
25

Withdrawing outgoing payment liquidity

Debit AccountCredit Account
Outgoing paymentSettlement

Example: Withdrawing 1 USD

USD outgoing payment liquidity acctUSD settlement acct
DebitCredit
1
DebitCredit
1

Payments in the same asset

Send amount < receive amount

Debit AccountCredit Account
Outgoing paymentIncoming payment
Asset liquidityIncoming payment

Example: Sender consented to a payment of 14 USD but the quote promised to deliver 15 USD.

USD outgoing payment liquidity acctUSD asset liquidity acctUSD incoming payment liquidity acct
DebitCredit
14
DebitCredit
1
DebitCredit
15

Send amount > receive amount

Debit AccountCredit Account
Outgoing paymentIncoming payment
Outgoing paymentAsset liquidity

Example: Sender consented to a payment of 15 USD but the quote promised to deliver 14 USD.

USD outgoing payment liquidity acctUSD asset liquidity acctUSD incoming payment liquidity acct
DebitCredit
15
DebitCredit
1
DebitCredit
14

Cross currency payments

Exchanging currencies

Debit AccountCredit AccountAsset
Outgoing paymentAsset liquidityUSD
Asset liquidityIncoming paymentEUR

Example: Outgoing payment for 10 USD, incoming payment receives 9 EUR.

USD outgoing payment liquidity acctUSD asset liquidity acct
DebitCredit
10
DebitCredit
10
EUR asset liquidity acctEUR incoming payment liquidity acct
DebitCredit
9
DebitCredit
9

Interledger transfer examples

In these examples, the sender and receiver do not have wallet addresses at the same Rafiki instance.

Remember that a settlement account will always have a zero or negative balance and a liquidity account will always have a zero or positive balance.

Sending connector

Same asset

Debit AccountCredit Account
Outgoing paymentPeer liquidity

Example: Sender creates an outgoing payment for 100 USD to an incoming payment at a peer’s Rafiki instance. The peering relationship is in USD.

USD outgoing payment liquidity acctUSD peer liquidity acct
DebitCredit
100
DebitCredit
100

Cross currency

Debit AccountCredit AccountAsset
Outgoing paymentAsset liquidityUSD
Asset LiquidityPeer LiquidityEUR

Example: Sender creates an outgoing payment for 100 USD to an incoming payment at a peer’s Rafiki instance. The peering relationship is in EUR, so payment is converted on the sending side.

USD outgoing payment liquidity acctUSD asset liquidity acct
DebitCredit
100
DebitCredit
100
EUR asset liquidity acctEUR peer liquidity acct
DebitCredit
90
DebitCredit
90

Receiving connector

Same asset

Debit AccountCredit Account
Peer liquidityIncoming payment

Example: An incoming payment receives 100 USD from an outgoing payment at a peer’s Rafiki instance.

USD peer liquidity acctUSD incoming payment liquidity acct
DebitCredit
100
DebitCredit
100

Cross currency

Debit AccountCredit AccountAsset
Peer liquidityAsset liquidityUSD
Asset liquidityIncoming paymentEUR

Example: A Rafiki instance receives 10 USD from a peer (peering relationship in USD) to be deposited in an incoming payment liquidity account denominated in EUR. The payment is converted to EUR and deposited.

USD peer liquidity acctUSD asset liquidity acct
DebitCredit
10
DebitCredit
10
EUR asset liquidity acctEUR incoming payment liquidity acct
DebitCredit
9
DebitCredit
9

Connector

Same asset

Debit AccountCredit Account
Peer liquidityPeer liquidity

Example: Rafiki forwards 10 USD from peer A to peer B.

USD peer “A” liquidity acctUSD peer “B” liquidity acct
DebitCredit
10
DebitCredit
10

Cross currency

Debit AccountCredit AccountAsset
Peer liquidityAsset liquidityUSD
Asset liquidityPeer liquidityEUR

Example: Rafiki receives 100 USD from peer A and forwards 90 EUR to peer B.

USD peer “A” liquidity acctUSD asset liquidity acct
DebitCredit
100
DebitCredit
100
EUR asset liquidity acctEUR peer “B” liquidity acct
DebitCredit
90
DebitCredit
90