Inside the Code of Ripple Client: the Newest Mobile Payment App for iOS

The Ripple Labs team just announced its second iPhone app, Ripple Client, that runs on the Ripple network, the revolutionary distributed payment system. I have been following the development of the app over the past few weeks and want to discuss the design of the app and how others can build similar iOS apps using the same open-source frameworks.

Before beginning, check out the source code for the Ripple Client iOS app, which is freely available on GitHub: https://github.com/Ripple/Ripple-client-ios

Inside the Ripple network users communicate using real-time websocket connections to quickly propagate transactions through the network for confirmation. The official Ripple reference client uses websocket communication to send and receive money in fiat currency in seconds. In this post, I will explain how to make an iOS native client to the Ripple network communicate securely with servers that validate transactions and broadcast messages to other interested clients.

The Javascript Ripple Library

The most fully developed client library for Ripple is written in javascript and includes websockets for communication and powerful client-side cryptography using Stanford’s Javascript Crypto Library (SJCL). The ripple-lib javascript library can run in web browsers, on servers with node.js, and any javascript environment that implements a websockets interface.

To get started with ripple-lib.js, include the library in your web browser or in node.js using npm install ripple-lib. Every client in ripple-lib must establish a connection to the network by connecting to a remote server running the Ripple network daemon, rippled. Here is an example of establishing a connection to the Ripple network.

var remote = Ripple.Remote.from_config({
“trusted” : false,
“websocket_ip” : “s1.Ripple.com”,
“websocket_port” : 443,
“websocket_ssl” : true,
“local_signing” : true
});

When creating a new Ripple.Remote object we establish a persisent websocket connection to a public Ripple server at s1.Ripple.com using encrypted SSL (https). The option for local signing means our client is going to use its secret key and Ripple’s elliptic curve digital signature algorithm to create transactions securely and locally without divulging its secret key to the server.

Once a connection to the network is established the ripple-lib can register listeners for transactions and events related to your account. It can build transactions, cryptographically sign them, and send balances to the remote server over websockets. ripple-lib includes objects for Ripple Addresses, Amounts based in various currencies, Transactions, and more. Together these objects make up the Ripple javascript api, and will be your primary means of access to the network. The following is an example usage of the JS api, building, signing, and submitting a transaction, and registering callbacks:

Constructing a transaction:
function setTransaction(data) {
remote.set_secret(data.account, data.secret);

A ripple transaction generally requires a sender account, a recipient address, an amount, a currency to send from, and a currency to send to.

var currency = data.to_currency;
var from_currency = data.from_currency;
var amount = data.amount;
var recipient = data.recipient_address;

Use the remote to ensure the recipient is valid, then set them as the issuer of trust. To make a transaction happen a path must be discovered that connects the various buys and asks on the network ledgers between two currencies:

remote.request_account_info(recipient);
amount.set_issuer(recipient);
paths = remote.request_ripple_path_find(data.account, recipient, amount);

Once you have found a path between the sending currency and the destination currency, construct a transaction with that path and submit it to the network.

var tx = remote.transaction()
tx.payment(account, addr, amount)
tx.paths(paths)
tx.submit();
}

Integrating Ripple Lib JS Into a Native iOS app

The Ripple Lib JS is a powerful tool and by far the best client library for Ripple, but historically using javascript to build iOS apps was not acceptable. Designers and engineers cringe at the idea of using tools like phonegap to build javascript and html apps for ios and android. Native mobile applications using iOS’s Cocoa Touch framework are almost always more performant, striking and effective that their javascript, html counterparts.

The Ripple iOS app uses an innovative solution to leverage both the beauty of Native Cocoa Touch while using the ripple-lib javascript library for interaction with the Ripple transaction and account APIs. The app uses a webview javascript bridge between objective-c and javascript, running the open-source library at https://github.com/marcuswestin/WebViewJavascriptBridge.

@class WebViewJavascriptBridge;
@interface RippleJSManager : NSObject {
UIWebView * _webView;
WebViewJavascriptBridge * _bridge;


}

The bridge allows Objective-C to send messages to javascript and register listeners for messages coming from javascript, allowing the app to use native data structures and hardware-accelerated UI graphics while interacting with the ripple-lib js library.

On the javascript side the webview listens for a custom event triggered when the bridge to Objective-C is ready

document.addEventListener(‘WebViewJavascriptBridgeReady’, onBridgeReady, false)
function onBridgeReady(event) {
var bridge = event.bridge
bridge.init(function(message, responseCallback) {
var data = { ‘Javascript Responds’:’Wee!’ }
responseCallback(data)
});
}

Once the bridge is established both ways the javascript library can listen for messages from Obj-C and proxy them to the Ripple API. The following listener will get the user’s account balances in its various currencies:

bridge.registerHandler(‘account_lines’, function(data, responseCallback) {
remote.set_secret(data.account, data.secret);
remote.request_account_lines(data.account)
.on(‘success’, function (result) {
responseCallback(result)
})
.on(‘error’, function (result) {
responseCallback(result)
})
.request();
});

Sending a transaction is a multi-step affair, and the iOS app handles it gracefully by exposing a single API call that performs robust transaction submission:

bridge.registerHandler(‘send_transaction’, function(data, responseCallback) {
// send a transaction and report back the status
})

The above code would involve several different steps depending on what type of transaction and account you are interacting with, but the basic idea is that a transaction object is constructed from user input, then the JS library asks the network for a ledger path to use for the transaction. Once a path is found the JS library cryptographically signs the transaction and submits it to the network. Finally upon successful acceptance of the transaction a callback message is passed across the bridge to Obj-C for the UI to update accordingly. All of these calls are part of the set of publicly available APIs that you can leverage to easily build you own distributed payment apps.

Future Ripple Apps

Hundreds of valuable applications could be built using the Ripple payment network, which is why Ripple Labs releases all of the source code for its various applications freely on GitHub. The iOS app is no exception, and its source is released to the public in an attempt to help others build native mobile apps on the Ripple network. Ripple Labs gladly supports efforts to build on its platform and intends to grow the value of the Ripple network by building a vast ecosystem of applications and systems on top of its community’s open-source tools. Check out http://github.com/Ripple to get started with Ripple’s open-code goodness.