Monday, November 24, 2014

RippleDex, a 100% Dart-powered Ripple experiment

The last three weeks, I have been working on a small experimental project to showcase both Ripple and Dart technology. I've been working on a Dart port of ripple-lib for several weeks and I wanted something to showcase it's current state of operation.

What does it do?

RippleDex is a service that monitors the Ripple network for value exchange. With this information, it tries to be an index for the currencies that are available inside Ripple. In the current state, currencies can onle be expressed in comparison to the native currency XRP and only XRP trades are considered for the calculation of the index. However, the plan is to extend the functionality and take all value exchanges into account.

How does it work?

The website itself has a page with a very brief explanation on the technology that is used to build RippleDex. It is 100% Dart-powered and since Dart is a fairly young language, it uses several experimental technologies. The code is hosted entirely on GitHub. The backend code runs on Google Compute Engine and is deployed using Docker. The website is hosted on GitHub pages and only serves static HTML pages that query the API.

daemon

The daemon that does the important work: monitoring all Ripple transaction in search for exchange of value. MongoDB is used to store the data. mongo_dart is a MongoDB driver for Dart that works surprisingly well. The main functionality here is the ripple-lib library that provides an easy-to-use stream of transactions. 
For those that know Ripple and wonder how to find value exchanges in the transaction feed, I've come up with the following strategy: Every Payment or OfferCreate transaction can delete or modify ledger entries of the type Offer. Whenever that happens, and only when that happens, two people did actually exchange currency. The actual exchange can be calculated from the PreviousFields and the FinalFields data from the transaction metadata.

api

As described on the website, the actual information endpoint is provided at api.rippledex.com. The service is hosted on Google Compute Engine using the Dart server capabilities. There are currently two endpoints: a static gateways endpoint that has a list of known gateways (explained below) and the price endpoint that allows anyone to query the information gathered by the daemon.

gateways

An effort to maintain a list of known established gateways. First of all, this allows us to ignore irrelevant transactions. But furthermore, this information is required when we want to provide a gateway-generic currency index. Malicious gateways could manipulate the statistics, so a trusted list is necessary to create a generic index calculated over all gateways according to their weight in the transaction volume. The list is easy to interpret and all contributions are more than welcome. Changed to the list are automatically taken into account by both the daemon and the API.

webcomponents

In order to simplify the use of the API, both for other developers and for myself in the sample site, I've created some web components to interact with the API using nothing but HTML. The components are made with PolymerDart, but can be compiled to Javascript to be used in any website with a simple HTML import. 
Currently, I created two components, both of them are used in the rippledex.com homepage.

  • <rippledex-issue-selector>
    This component provides an input element to select a currency/issuer pair from the list of trusted gateways. It supports change events, defining a default issue, providing HTML to insert between the two selector menus and it can be styled using CSS and the shadow DOM selectors.
  • <rippledex-convert>
    Convert any issue into another one. It's as easy as that. Provide an amount, the issue this amount is in and a base issue, and the component will contain the converted value in the base amount. Currently issues must consist of a currency and an issuer, but I plan to add support for just currencies. That way, this element can replace any price-ticker on the net and it will be updated live from the Ripple network!

shared

This helper package contains functionality used by both the daemon and the API packages. Nothing special, logger initialization, a MongoDB interface and several model classes.

Can we help?

What do you think? All help is always more than appreciated. 

What I imagine RippleDex to become is a widely-used price index for Ripple-related services. The fact that its development is this open, allows developers to put a lot of trust in the service. After all, there will be a community that can help fix issues as they occur. 
A gateway-generic price index is very useful for listing prices in the preferred currency of the users of your service.

What does still need to be done for RippleDex to become useful?

A ran into several issues while developing this project. Some of them small and trivial, some quite crucial for a useful service.
  • I suck at website design. I used a very basic Bootstrap UI that is so basic that it's not even worth to be called a UI. Someone with some experience with HTML design could really contribute at that part.
  • I could not get HTTPS to work. I bought a certificate for the domain api.rippledex.com, but I failed to get it up and running for the Dart server, even though Dart supports HTTPS. A lot of tutorials can be found for configuring existing web servers with SSL, but Dart is so new that I doubt that a lot people actually did it before.
    Concerning the rippledex.com homepage, GitHub is thinking about a way to allow users of GitHub pages for custom domains to support HTTPS. 
  • I don't know if (D)DoS or other load-related measures will become a problem, but we better be prepared. The service runs on Compute Engine, so it can always grow if performance becomes a problem. But more computers means a higher cost, so accepting donations or displaying ads might be a requirement in the future.
  • Currently only XRP exchanges are taken into account. This means that whenever two people exchange non-XRP currency for non-XRP currency, the exchange is ignored. There should be a way to take these transactions into account to create a global price index of an issue. I'll probably look into this more deeply in the future, but all suggestions are welcome.
So, if you find any of this interesting, consider pulling the code from GitHub and taking a look at it! At this point, this project is nothing more than a demonstration of the possibilities of Dart and Ripple, but with a little more work, it can grow into an actual useful service.