Ripple Client Server Protocol/API
The interface between inter-user accounting clients and the Ripple backend, either standalone or distributed.
- Issues between standalone and distributed engines
- Future directions
- Client API Request Examples
A single Ripple server can support multiple clients.
- The client-server communications might be initiated by either side, as in XMPP, or client-initiated only, as in HTTP.
A client instance can register and manage nodes and credit relationships between them.
- To register a node, a client requests that the server create the node.
- To register a credit relationship between node A and node B, node A's client requests that the server register the relationship. The server then asks node B's client, which may be different from node A's client, to confirm the relationship.
- Node A's request
- Establishes the unit of value for the relationship, and node A's account data; node B's confirmation establishes node B's account data.
- If Node A has already established credit relationships with other nodes, incoming and outgoing exchange rates are established between all of node A's other relationships and the new relationship with node B
- Node B's confirmation
- If Node B has already established credit relationships with other nodes, exchange rates are established between them and the new credit relationship with Node A
- Node A's request
- If a node is unwilling to exchange between certain subsets of its relationships when available credit permits, it should properly be represented as two nodes for the routing system to function optimally.
- For the standalone backend, relationships must be between nodes on a single Ripple server. For the distributed version, relationships may also be between nodes on different Ripple servers. (This defines standalone and distributed.)
- A client instance can delete its nodes
- A client instance can delete a relationship that its node is party to, with the permission of the other party.
A client can update data for nodes and credit relationships
- Data that can be updated:
- credit and issuance limits for each relationship account
- exchange rates between a node's relationships
- When set (including initially) this data has an expiry time after which it is invalid and must be updated before the accounts in question can be used again. Before the expiry time, Ripple may commit transactions on the accounts in question as long as the balance remains within their respective credit limits.
- Changing a credit limit may leave the account balance outside that limit. This is permissible, and simply means that any transactions on that relationship must move the balance closer zero, never further away, until the balance is once again within the account limits.
- Updates may be pushed by client pre-emptively, before or after expiry time, or pulled by server as needed, if that mode is supported by the client.
- A reconciliation must occur before new account data can be registered.
- A client may request a reconciliation with the Ripple server for some or all of its accounts.
- The reconciliation may be hard, meaning the cumulative balances for the accounts in question are reset to zero or soft, meaning they are not. In other words, new credit limits set after a hard reconciliation are relative to the current balance, and credit limits after a soft reconciliation are still relative to the balance at the last hard reconciliation.
- A hard reconciliation must be followed by a data update. A soft reconciliation may optionally be followed by a data update.
- A client can tag nodes with one or more addresses.
- Multiple nodes may have the same address, but they must be on the same client.
- Payment is between two addresses, called the paying and receiving addresses. Each address may consist of multiple nodes.
- Both paying and receiving clients must approve a payment before it occurs.
- Either paying or receiving client may initiate the payment process.
- Payment consists of value transfer along a pathset of one or more paths of accounts between payer and recipient.
- Payment is denominated in payment units, which may or may not be the same as the units on any account used in the transaction.
Two interfaces may be useful:
- HTTP/REST client request, server respond model, where server must wait for client to check in to send certain information
- XMPP real-time messaging, where server can push or request information from the client as it needs
GET methods should generally have standard ways of filtering, sorting and limiting results.
JSON for parameters and results. (Maybe XML as well if a client wants?)
RESTful principles, GET/POST. GET is idempotent, POST for state-changing methods.
We'll need to allow for and control remote access, probably in a similar way to a database server, by IP address and by user/password authentication (regular HTTP authentication). We might add PKI stuff (HTTPS) later.
To implement, we'll need to store client identites (IP address, user, password) in the database, as well as have a configuration option (command line/config file) for which policies to implement.
For each method, need to specify:
- HTTP method (GET|POST) and URL
- permitted/required GET/POST parameters
For GET methods, given parameters are for filtering results. Every GET method also has the following parameters:
Rippler Server API
Client interface for an account system to the Ripple transaction server.
Account system data will be defined manually by the Ripple server admin.
- register user
- get users
- delete user
- register account
name owner partner
- get accounts
- get account detail
- delete account
- register exchange
- get exchanges
- add account to exchange
- remove account from exchange
- delete exchange
- request payment -
- params: (payment request details)
- get payment requests -
- optional params:
- optional params:
- accept/reject/withdraw payment request -
- init payment -
- params: (payment details)
- returns <payment_id>
- find pathset -
deadline=<datetime> max_cost_amount=<decimal> max_cost_units=<unit_id>
- returns ID of authorized pathset found, and its cost. Payer can then commit or search for more.
- commit pathset -
- cancel payment -
- get payments -
- optional params:
- optional params:
- get payment detail/documentation (including signed messages, for protocol) -
- id = <UUID>
- paying_exchanges = <list of accounts>
- receiving_exchanges = <list of accounts>
- units = <string>
- amount = <decimal>
- for_payer = (true|false) - whether amount is for payer or from recipient
- date = <datetime>
- deadline = <datetime>
Account System API
Account systems must provide the following to the transaction module:
- confirm account
- payment request
- query accounts
- query set of potential accounts for next hop in path being searched
payment_id <accounts_to_query> from_account path_amount units account_amount deadline
- available credit on each account, up to requested amount (in both path units and account units)
- priority score for each account (optional)
- authorize pathset
- freeze credit for accounts in pathset
payment_id <list of accounts> <list_of_amount_for_each_account>
- commit pathset
Issues between standalone and distributed engines
To support both local and remote user identification for the distributed server, local users are identified by username only, and remote users by their Ripple ID (user@ripplehost:port). Apps developed on the standalone server should support Ripple usernames in this format for forward compatibility to the distributed server.
The distributed server will store signed messages as part of each account history and payment. These are not available on the standalone server. Could just have optional JSON return fields for these where necessary, that are left empty by the standalone server. These are only useful for auditing, and aren't central to regular operations.
Customizable routing policy
Let the client specify a callback URL or formula that takes available data at each hop and makes more complex decisions about where to route and what exchange rates to use.