Merge pull request #84 from mDuo13/gh-pages

Gateway Services Spec Draft (+bonuses)
This commit is contained in:
Rome Reginelli
2014-10-27 15:37:19 -07:00
12 changed files with 1300 additions and 73 deletions

View File

@@ -1,12 +1,6 @@
ripple-dev-portal
=================
This Ripple Developer Portal is focused solely on documentation for the [`ripple-rest`](https://github.com/ripple/ripple-rest) API. The developer portal is a static site leveraging a fork of [`flatdoc`](https://github.com/rstacruz/flatdoc).
The documentation is stored in the "API.md" file in the root of the `ripple-dev-portal` repository. Versioning for the documentation will match the tagged release version for `ripple-rest`.
### The ripple-dev-portal is currently hosted at https://dev.ripple.com ###
The [Ripple Developer Portal](https://dev.ripple.com) is the authoritative source for Ripple documentation, including the `rippled` server, Ripple-REST API, Gatewayd, and other Ripple software.
Please contribute pull requests to the **gh-pages** branch with any improvements or revisions.

View File

@@ -62,8 +62,35 @@ body .content-root {
.content pre {
background: none;
}
@media (max-width: 990px) {
.navbar .container {
width: 100% !important;
}
}
/* end bootstrap code styling fix */
/* redo some of flatdoc's styling */
.content i, .content em {
color: #303044;
}
.content h4, .content h3 {
color: #303044 !important;
font-family: montserrat;
}
.content h4 {
font-size: 14pt;
}
.content h3 {
font-size: 13pt;
}
/* end flatdoc styling fix */
.menubar {
padding-top: 10px;
}
@@ -98,9 +125,28 @@ color: #f09 !important;
}
@media (min-width: 720px) {
@media (min-width: 860px) {
body, td, textarea, input {
font-size: 13pt;
}
.content {
font-size: 13pt;
max-width: 900px;
}
.no-literate .content-root {
max-width: 1094px;
padding-left: 300px;
}
.menubar {
right: 794px;
width: 300px;
}
.menubar.fixed {
right: 794px;
width: 294px;
}
}

202
gateway_services.html Normal file
View File

@@ -0,0 +1,202 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<title>Ripple Developer Portal: Gateway Services</title>
<!-- favicon -->
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Flatdoc -->
<script src="https://dev.ripple.com/vendor/flatdoc/v/0.8.0/legacy.js"></script>
<script src="https://dev.ripple.com/vendor/flatdoc/v/0.8.0/flatdoc.js"></script>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/bootstrap.min.js"></script>
<!-- Flatdoc theme -->
<link href="vendor/flatdoc/v/0.8.0/theme-white/style.css" rel="stylesheet">
<script src="vendor/flatdoc/v/0.8.0/theme-white/script.js"></script>
<!-- Custom Stylesheets -->
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:600italic,400,700,300" rel="stylesheet" type="text/css">
<link href="css/main.css" rel="stylesheet">
<link href="css/custom.css" rel="stylesheet">
<link rel="shortcut icon" href="favicon.ico?v=2" type="image/x-icon">
<link rel="icon" href="favicon.ico?v=2" type="image/x-icon">
<!-- start Mixpanel -->
<script type="text/javascript">(function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;a=e.createElement("script");a.type="text/javascript";a.async=!0;a.src=("https:"===e.location.protocol?"https:":"http:")+'//cdn.mxpnl.com/libs/mixpanel-2.2.min.js';f=e.getElementsByTagName("script")[0];f.parentNode.insertBefore(a,f);b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==
typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.set_once people.increment people.append people.track_charge people.clear_charges people.delete_user".split(" ");for(g=0;g<i.length;g++)f(c,i[g]);
b._i.push([a,e,d])};b.__SV=1.2}})(document,window.mixpanel||[]);
mixpanel.init("132d42885e094171f34467fc54da6fab");
</script>
<script>if (window.location.host == "dev.ripple.com") { mixpanel.track("gateway_services"); }</script>
<!-- end Mixpanel -->
<!-- start google analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-49188512-1', 'ripple.com');
ga('send', 'pageview');
</script>
<!-- end google analytics -->
<!-- syntax selection js -->
<script src="js/multicodetab.js"></script>
<!-- Code to load Flatdoc; commented out on compiled page -->
<script>
$(".flatdoc-content").empty();
$(".content-root .menubar .menu").empty();
Flatdoc.run({
fetcher: Flatdoc.file('gateway_services_spec.md')
});
$(document).on('flatdoc:ready', $().multicode_tabs);
</script>
<!-- end flatdoc load -->
<!-- Alternate multicode tabs for compiled page:
<script>
$(document).ready(function() {
$(".multicode").minitabs()
make_code_expandable();
});
</script>
<!--end alt code for compiled page -->
<link type="text/css" rel="stylesheet" href="css/mod.css">
<script src="js/expandcode.js"></script>
<script src="js/fixsidebarscroll.js"></script>
</head>
<body role='flatdoc' class='no-literate'>
<div style="position:fixed; top: 50px; right: 100px; background: red; color: white; padding: 10px; z-index:3">DRAFT</div>
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="https://dev.ripple.com/"><img class="small_logo" src="assets/img/ripple_logo_small.png"></a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="/">Resources</a></li>
<li><a href="https://www.bountysource.com/teams/ripple/bounties">Bounties</a></li>
<li><a href="https://ripplelabs.atlassian.net/">Bug Tracking</a></li>
<li><a href="https://ripple.com/dev/blog/">Dev Blog</a></li>
<li><a href="https://ripple.com/forum/viewforum.php?f=2&sid=c016bc6b934120b7117c0e136e74de98">Forums</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Tool <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="ripple-api-tool.html">WebSocket Tool</a></li>
<li><a href="rest-api-tool.html">REST Tool</a></li>
</ul>
</li>
</ul>
<div class='right'>
<!-- GitHub buttons -->
<iframe src="https://dev.ripple.com/vendor/ghbtn.html?user=ripple&repo=ripple-dev-portal&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="110" height="20"></iframe>
</div>
</div><!--/.nav-collapse -->
</div>
</div>
<div class='content-root'>
<div class='menubar'>
<div class='menu section' role='flatdoc-menu'></div>
</div>
<div role='flatdoc-content' class='content'>
</div>
</div>
<div class="footer">
<div class="container">
<p class="text-muted">
<div class="row">
<div class="col-md-2">
<ul class="footer_links applications">
<li><a href="https://www.rippletrade.com">Ripple Trade</a>
<li><a href="https://www.ripplecharts.com">Ripple Charts</a>
<li><a href="https://ripple.com/graph">Ripple Graph</a>
<li><a href="http://codius.org/">Codius</a>
</ul>
</div>
<div class="col-md-2">
<ul class="footer_links middleware">
<li><a href="gatewayd.html">Gatewayd</a>
<li><a href="ripple-rest.html">Ripple REST</a>
<li><a href="https://github.com/ripple/ripple-lib">Ripple Lib</a>
</ul>
</div>
<div class="col-md-2">
<ul class="footer_links core_network">
<li><a href="rippled-apis.html">rippled</a>
<li><a href="transactions.html">Transactions</a>
<li><a href="consensus-whitepaper.html">Consensus</a>
</ul>
</div>
<div class="col-md-2">
<ul class="footer_links bounties">
<li><a href="https://www.bountysource.com/teams/ripple/bounties">Bounties</a>
<li><a href="https://ripplelabs.atlassian.net/">Bug tracking</a>
<li><a href="guidelines.html">Brand guidelines</a>
<li><a href="https://ripple.com/dev/blog/">Dev blog</a>
<li><a href="https://ripple.com/forum/viewforum.php?f=2&sid=c016bc6b934120b7117c0e136e74de98">Forums</a>
<li><a href="https://ripple.com/wiki/Main_Page">Wiki</a>
</ul>
</div>
<div class="col-md-4 mail_chimp">
<p>Join the mailing list!</p>
<label for="mce-EMAIL">Email address</label>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-081711.css" rel="stylesheet" type="text/css">
<style type="text/css">
#mc_embed_signup{clear:left; font:14px; }
</style>
<div id="mc_embed_signup">
<form action="//ripple.us4.list-manage.com/subscribe/post?u=245dbc1c47849f034390dc5bf&amp;id=4dfbe160d0" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="" required>
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px; top: -50px;"><input type="text" name="b_245dbc1c47849f034390dc5bf_4dfbe160d0" tabindex="-1" value=""></div>
<input type="submit" value="Submit" name="subscribe" id="mc-embedded-subscribe" class="button btn btn-primary">
</form>
</div>
<!--End mc_embed_signup-->
</div>
</div>
</p>
</div>
</div>
</body>
</html>

976
gateway_services_spec.md Normal file
View File

@@ -0,0 +1,976 @@
# Introduction #
The Gateway Services initiative aims to make gateways interoperable, extending the connectivity of the Ripple Network beyond the bounds of the Ripple ledger. The goal is to allow anyone who's connected to Ripple (not just Ripple account holders) to look up another Ripple-connected entity, find a path between them, quote the cost of a payment, and then make that payment, in a way that is consistent, regulation-compliant, and standards-compliant. It defines a series of REST API calls that make it possible for other gateways and Ripple client applications to perform all of these actions.
Gateways that implement these services can easily link with one another, allowing users who have a business relationship with one of them to send and receive money to parties that are connected to other gateways in an automated fashion, while remaining regulation-compliant. Our Gatewayd framework will implement all these services, so gateway operators using Gatewayd don't need to do anything beyond standard configuration, and those with custom gateway software can use Gatewayd as a reference implementation.
<div class='danger alert'>
This document, and the APIs it defines, are a work in progress. Do not go implementing them already! We are exposing these explanations as guidance to where we are heading, with the intent of getting feedback to refine them as necessary.<br><br>
All names, URLs, and addresses in this document are used for example purposes only, and do not reflect actual services or a commitment to provide actual services.
</div>
## Components ##
| Service | Description | Based On | Replaces |
| ------- | ----------- | -------- | -------- |
| [host-meta](#host-meta) | Provides useful metadata about a gateway or service provider, and lists all service endpoints provided by the domain | [RFC6415](http://tools.ietf.org/html/rfc6415) | [ripple.txt](https://ripple.com/wiki/Ripple.txt) |
| [webfinger](#webfinger) | Performs reverse lookup of Ripple addresses, and lists service endpoints for interacting with a specified account holder | [RFC7033](http://tools.ietf.org/html/rfc7033) | [Federation Name Lookup](https://ripple.com/wiki/Federation_protocol) |
| [bridge-payments](#bridge-payments) | Plans payments from any Ripple-connected wallet to any other, connecting through gateways as necessary. | [Ripple-REST payments](http://dev.ripple.com/ripple-rest.html#payments) | [Bridge protocol](https://ripple.com/wiki/Services_API) |
| user-account | Provides standard method for registering an account with a Gateway, and provides signed claims about a user's identity similar to bridge-payment's required claims | [OpenID Connect Claims](http://openid.net/specs/openid-connect-core-1_0.html#Claims), [JWT](http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25) | -- |
| wallet-payment | Makes outgoing payments and monitors for incoming payments, and works with hosted wallets. | [Ripple-REST payments](http://dev.ripple.com/ripple-rest.html#payments) | -- |
| wallet-info | Shows information about a wallet, and works with hosted wallets | [Ripple-REST accounts](http://dev.ripple.com/ripple-rest.html#accounts) | -- |
| wallet-balances | Shows information about balances in multiple currencies, and works with hosted wallets. | [Ripple-REST accounts](http://dev.ripple.com/ripple-rest.html#accounts) | -- |
| wallet-history | Shows history of payments sent and received, and works with hosted wallets. | [Ripple-REST payment history](http://dev.ripple.com/ripple-rest.html#payment-history) | -- |
## Event Sequence ##
The Gateway Services APIs are built to support many different process flows, but most of them can be simplified down to a simple payment flow through one or more gateways, such as the following:
[![Gateway Services sequence diagram](img/gateway_services_sequence.png)](img/gateway_services_sequence.png)
In this sequence, the client application starts with three pieces of information that define the payment that the user would like to make:
* A unique identifier for the originator of the payment
* A unique identifier for the beneficiary of the payment
* An amount, including a currency, that the beneficiary should receive
Initially, the client application uses the identifiers to determine which domains it should query. In the example image, federation addresses (_user@service.tld_) are used, so the domain can be determined directly from the URI. See [Gateway Services Identifiers](#gateway-services-identifiers) for more information. The client queries each domain's host-meta to confirm that it has the necessary Gateway Services available, and where those services are provided.
If they provide a WebFinger service, the client application looks up the originator and beneficiary of the payment using WebFinger. A successful response with a bridge-payments link indicates that the accounts are valid and connected to Ripple through the gateways.
Now the client gets quotes for ways to make the payment. It asks the sending gateway for quotes. In this example, the sending gateway determines that it cannot make a payment to the receiving account directly. It requests host-meta and WebFinger from the receiving gateway just like the client did (not pictured), then gets quotes for the desired payment from the receiving Gateway. Each quote contains a wallet-payment object that the gateway wants to receive in exchange for making the desired outgoing payment.
*Note:* The client could skip this recursive process by calling the destination gateway directly, but in our example the sending user does not have a way to pay the receiving gateway directly. (He neither holds euros nor has a Ripple account.) Gateway Services makes it possible to connect the two because both gateways have Ripple accounts.
The inbound gateway takes the quotes it received from the outbound gateway, chooses one or more that it likes, and pads them to account for its own costs and risks before presenting them back to the client as quotes for the whole payment.
The client chooses a quote and accepts it, which causes the inbound gateway to accept the corresponding quote from the outbound gateway. It sends back a message to the client indicating success. At this point, all parties are ready for the chain of payments to be made.
Finally, the client performs a wallet-payment call, which either pulls the money directly out of the appropriate account (if possible), or redirects the client to a place where the user can push the money back. An invoice ID on the payment lets the inbound gateway know which Gateway Transaction the incoming payment is meant to pay for.
After receiving money from the sender, the inbound performs the same call on the outbound gateway, and sends the payment (in this example, a Ripple payment) with the invoice ID that the outbound gateway is looking for. When the outbound gateway receives the payment, it recognizes the amount and invoice ID, which prompts it to send the final outgoing payment to the destination.
# Gateway Services Identifiers #
Several APIs require you to identify the sender or recipient of a payment. Since several different types of identifiers can be used this way, Gateway Services defines a standard way to create a Universal Resource Identifier (URI) for each type of resource. Any party of a payment should have a URI associated with it that can be WebFingered. This may include:
* The originator (sender) of a payment
* The beneficiary (receiver) of the payment
* Up to two gateways operating as inbound bridge (onto Ripple) and/or outbound bridges (off of Ripple)
* Up to two "Participating parties" (one on each end of the transaction), for example the clerk at a store receiving or handing out cash. This may be important for compliance purposes, especially for remittance.
As a general rule on the web at large, any URI starts with a "scheme" portion, followed by a colon, for example `http:`. Gateway service supports using URIs with several different schemes as identifiers to represent the parties to a payment. Depending on the scheme, a particular URI may map to something different:
* `acct:` identifiers refer to a user account at a particular service, such as an account at a bank or financial service.
* `ripple:` identifiers refer to a specific Ripple account in the shared global ledger
* `http:` and `https:` identifiers, always followed by *a domain only*, refer to a specific business entity that is connected to Ripple
* Other identifiers can be used, depending on the configuration of the gateway being used.
An identifier can only be used if a JRD with the necessary information can be found by WebFingering that identifier. Part of the challenge is knowing which WebFinger service to use to look up the desired URI. This is a matter of finding out the right domain to use from the URI.
## Native Identifiers ##
Some kinds of URIs provide a single clear domain that can be used to perform the WebFinger request. A client application must use the following rules for where to WebFinger identifiers in the following formats:
| Type of Identifier | Example | Where to WebFinger |
|--------------------|---------|--------------------|
| Email address | acct:bob@ripple.com | Domain from the email |
| Email-style Federation address | acct:bob@fidor.de | Domain from the address
| Ripple Address | ripple:rBWay8KRdmroZra4DTXi6h5cLtPhs5mH7v | Domain from the Ripple AccountRoot object |
| Ripple Address with Destination Tag | ripple:rBWay8KRdmroZra4DTXi6h5cLtPhs5mH7v?dt=103047 | Domain from the Ripple AccountRoot object |
| Ripple Name | ripple:bob | Domain from the Ripple AccountRoot object |
| Domain | http://snapswap.us | Use [host-meta](#host-meta) instead. |
In the case where a particular email does not provide sufficient information to send a payment, client applications may optionally use a [WebFist](http://www.onebigfluke.com/2013/06/bootstrapping-webfinger-with-webfist.html) service to check for alternate places to WebFinger the provided address.
## Additional Identifiers ##
Additional identifiers may be supported, in order to provide compatibility with other payment systems. Decide where to WebFinger additional URI formats according to the following rules:
Client Applications should either:
* Be explicitly linked to a particular gateway (e.g. a Fidor app that uses only Fidor-hosted Gateway Services), _or_
* Only WebFinger gateways explicitly chosen by the user.
* Client apps can make this easier by using a central "Registry" of gateways and presenting choices to the user. <span class='draft-comment'>No spec for such a registry exists at this time.</span>
Gateway Services providers can recursively WebFinger the **reciever** of a payment based on the **outbound bridges** it trusts that are capable of handing the **destination currency**. Gateways should take responsibility for the outbound bridges that they trust to make the last mile of a payment. This might mean only using outbound bridges that are operated by the same business entity or its partners.
As long as the identifier is reasonably likely to *uniquely* refer to a particular account or person, arbitrary identifiers may be used. We recommend specific formats for the following types of identifiers: <span class='draft-comment'>Format and examples are non-final mockups.</span>
| Type of Identifier | Format | Example |
|--------------------|---------|---------|
| US Bank number | usbn:{routing}+{bank acct num} | usbn:2209348904802+23401011034 |
| IBAN | iban:{some iban format??} | iban:9293722341 |
| Credit/Debit card | card:{15-16 digit card number} | card:4811738483484923 |
| Coin address | bitcoin:{bitcoin address} | bitcoin:b238974jsv9sd8sdf923as33f |
| Paypal address | paypal:{email address used as PayPal login}<br>paypal:{phone number?} | acct:rome@ripple.com@paypal.com acct:paypal:rome@ripple.com |
| Google wallet | google:{email address} | google:mduo13@gmail.com |
| Square cash | square:{email address} | square:rome@ripple.com |
## Currency Codes ##
Currency codes in Gateway Services are specified as they are in Ripple. In most common cases, this means that currencies are provided as three-letter [ISO4217](http://www.xe.com/iso4217.php/) identifiers such as `"USD"`. Three-letter identifiers should be **case-insensitive**.
A currency can also be provided as a 160-bit hexadecimal string, in case it has unusual properties such as built-in demurrage. For example, gold with 0.5% annual demurrage from [Gold Bullion International](http://www.bullioninternational.com/digital-physical-gold/) is represented as the string `"0158415500000000C1F76FF6ECB0BAC600000000"`.
It is RECOMMENDED that Gateway Services providers and clients should be able to recognize hex values that refer to common 3-letter currencies. This can be achieved by the following method:
* Convert three-letter codes to uppercase. (This is important! Even though "btc" is considered the same as "BTC", both should map to the same hex)
* Determine the hex ASCII codes for those letters. For example, "JPY" is "4A5059".
* Render the hex code as "000000000000000000000000" + the hex of the 3-letter currency code + "0000000000"
* If this code matches a hex code that is provided directly, then they are the same currency.
See [Currency Format](https://wiki.ripple.com/Currency_format) for more detailed information on the hex representation..
# Host-Meta #
Host-Meta tells you about things operated by a domain.
[RFC6415](http://tools.ietf.org/html/rfc6415) defines a standardized way to publish metadata, including information about resources controlled by the host, for any domain. In contrast to the original spec, **Ripple uses the JSON version of host-meta exclusively**, and never queries for the XML version. This spec defines several Ripple-centric resources which a host can advertise in a host-meta file, so that other applications can automatically **find** the host's other Gateway services, and **verify** the domain's various Ripple assets. This extends and replaces the functionality of the [ripple.txt](https://wiki.ripple.com/Ripple.txt) spec.
The response to a host-meta request is a document called a JRD (JSON resource descriptor; there is also an XML version called an XRD).
#### Request Format ####
```
GET /.well-known/host-meta.json
```
Alternate request format:
```
GET /.well-known/host-meta
Accept: application/json
```
__*Note:*__ Some domains that do not use Gateway Services may implement host-meta without providing a JRD. In this case, the alternate request format may return an XRD document instead of a Not Found error.
Here is an example of an entire host-meta JRD:
__`GET https://latambridgepay.com/.well-known/host-meta.json`__
```
{
"subject": "https://latambridgepay.com",
"expires": "2014-01-30T09:30:00Z",
"properties": {
"name": "Latam Bridge Pay",
"description": "Ripple Gateway to and from Latin American banks.",
"rl:type": "gateway",
"rl:domain": "latambridgepay.com",
"rl:accounts": [
{
"address": "r4tFZoa7Dk5nbEEaCeKQcY3rS5jGzkbn8a",
"rl:currencies": [
"USD",
"BRL",
"PEN",
"MXN"
]
}
],
"rl:hotwallets": [
"rEKuBLEX2nHUiGB9dCGPnFkA7xMyafHTjP"
]
},
"links": [
{
"rel": "lrdd",
"template": "https://latambridgepay.com/.well-known/webfinger.json?q={uri}",
"properties": {
"rl:uri_schemes": ["paypal","bitcoin","acct","ripple"]
}
},
{
"rel": "https://gatewayd.org/gateway-services/bridge_payments",
"href": "https://latambridgepay.com/v1/bridge_payments",
"properties": {
"version": "1",
"additional_info_definitions":{
"bank": {
"type": "AstropayBankCode",
"label": {
"en": "Astropay Bank Code"
},
"description": {
"en": "Bank code from Astropay's documentation"
}
},
"country": {
"type": "AstropayCountryCode",
"label": {
"en": "Astropay Country Code",
},
"description": {
"en": "Country code from Astropay's documentation"
}
},
"cpf": {
"type": "PersonalIDNumber",
"label": {
"en": "Personal Government ID Number"
},
"description": {
"en": "Personal ID number from the Astropay documentation"
},
}
"name": {
"type": "FullName",
"label": {
"en": "Sender's Full Name"
},
"description": {
"en": "First and last name of sender"
}
},
"email": {
"type": "EmailAddress",
"label": {
"en": "Sender's Email Address"
},
"description": {
"en": "Sender's Email Address"
}
},
"bdate": {
"type": "Date",
"label": {
"en": "YYYYMMDD"
},
"description": {
"en": "Sender's date of birth"
}
}
}
}
}
]
}
```
This file is divided up into the following elements:
## Host-Meta Aliases ##
[Aliases are NOT RECOMMENDED](http://tools.ietf.org/html/rfc6415#section-3.1) in host-meta, according to the spec. Consumers of Gateway Services should not rely on any content there.
## Host-Meta Properties ##
```js
...
"properties": {
"name": "Latam Bridge Pay",
"description": "Ripple Gateway to and from Latin American banks.",
"rl:type": "gateway",
"rl:domain": "latambridgepay.com",
"rl:accounts": [
{
"address": "r4tFZoa7Dk5nbEEaCeKQcY3rS5jGzkbn8a",
"rl:currencies": [
"USD",
"BRL",
"PEN",
"MXN"
]
}
],
"rl:hotwallets": [
"rEKuBLEX2nHUiGB9dCGPnFkA7xMyafHTjP"
]
}
...
```
Ripple defines the following properties:
| Property | Value | Description |
|----------|-------|-------------|
| rl:type | String | What type of Ripple entity this domain is. Valid types are `"gateway"`, `"merchant"`, `"bridge"`, `"wallet-service"`, `"end-user"`. Other custom types are allowed. |
| rl:domain | String | The domain this host-meta document applies to, which should match the one it is being served from. For example, `"coin-gate.com"` |
| rl:accounts | Array of objects | Each member of this array should be an [account definition object](#acct_def_obj) for an issuing account (cold wallet) operated by this host |
| rl:hotwallets | Array of strings | Each member of this array should be either a base-58-encoded Ripple Address or a Ripple Name for a hot wallet operated by the host |
Gateway Services clients may also use the standard "name" and "description" properties.
<span class='draft-comment'>TBD: format for providing a JWT-signing PubKey in the properties. (Possibly use OpenID format?)</span>
#### Account Definition Object <a name="acct_def_obj"></a> ####
An account definition object is a JSON object with the following properties:
| Property | Value | Description |
|----------|-------|-------------|
| address | String | Base-58-encoded Ripple address |
| rl:name | String | (Optional) The [Ripple Name](https://ripple.com/dev-blog/introducing-ripple-names/) of this account, omitting the leading tilde (~) |
| rl:currencies | Object | Map of currencies issued from this address, where field names are the currency codes and values are the maximum amount issued, as a string containing a decimal number. |
Example account definition object:
```js
{
"address": "rLtys1YJHGj8oTpECWSzDv77YRGDWGduUX",
"rl:currencies": {
"BTC": "1000000"
}
}
```
## Host-Meta Links ##
The `links` field contains links to almost anything. The meaning of the link is identified by a relation type, typically a URI, in the `rel` field of the link object. Gateways should use links to advertise the other Gateway Services APIs that they offer.
Gateway Services requires the following links in host-meta:
* [Webfinger Link](#webfinger_link)
* [Bridge Payments Link](#bridge_payments_link)
* <span class='draft-comment'>(As additional services are defined, they should have links added to host-meta.)</span>
### WebFinger Link <a name="webfinger_link"></a> ###
This link indicates where the [WebFinger (lrdd) service](#webfinger) is provided.
```js
...
"links": [
{
"rel": "lrdd",
"template": "https://latambridgepay.com/.well-known/webfinger.json?q={uri}",
"properties": {
"rl:uri_schemes": ["paypal","bitcoin","acct","ripple"]
}
},
...
```
Gateway Services requires the use of the [Webfinger protocol](https://code.google.com/p/webfinger/wiki/WebFingerProtocol). The fields of the link are defined as follows:
| Field | Value |
|----------|--------|
| rel | `lrdd` |
| template | The URL of your webfinger service, with `{uri}` in place of the resource to look up. |
| properties | Object with properties of this link |
The `properties` field should contain the following field:
| Field | Value | Description |
|----------------|-------|-------------|
| rl:uri_schemes | Array | Each member of this array refers to the scheme section (the part before the first colon) of [Gateway Services Identifiers](#gateway-services-identifiers) that can be WebFingered at this location. By default, Gateway Services providers should support `acct` and `ripple`; other schemes indicate that the gateway operates a bridge that can send to and/or receive from identifiers for those schemes. |
### Bridge Payments Link <a name="bridge_payments_link"></a> ###
This link indicates where the [Bridge-Payments Service](#bridge-payments) is provided, and information about it.
```js
...
"links": [
...
{
"rel": "https://gatewayd.org/gateway-services/bridge_payments",
"href": "https://latambridgepay.com/v1/bridge_payments",
"properties": {
"version": "1",
"bridges": [
{
"currency": "USD",
"scheme": "astropay",
"direction": "both"
},
{
"currency": "BTC",
"scheme": "bitcoin",
"direction": "in"
}
],
"additional_info_definitions":{
"bank": {
"type": "AstropayBankCode",
"label": {
"en": "Astropay Bank Code"
},
"description": {
"en": "Bank code from Astropay's documentation"
}
},
"country": {
"type": "AstropayCountryCode",
"label": {
"en": "Astropay Country Code",
},
"description": {
"en": "Country code from Astropay's documentation"
}
},
"cpf": {
"type": "PersonalIDNumber",
"label": {
"en": "Personal Government ID Number"
},
"description": {
"en": "Personal ID number from the Astropay documentation"
},
}
"name": {
"type": "FullName",
"label": {
"en": "Sender's Full Name"
},
"description": {
"en": "First and last name of sender"
}
},
"email": {
"type": "EmailAddress",
"label": {
"en": "Sender's Email Address"
},
"description": {
"en": "Sender's Email Address"
}
},
"bdate": {
"type": "Date",
"label": {
"en": "YYYYMMDD"
},
"description": {
"en": "Sender's date of birth"
}
}
}
}
}
...
```
The fields of the link are defined as follows:
| Field | Value |
|----------|--------|
| rel | `https://gatewayd.org/gateway-services/bridge_payments` |
| href | The base URL of the gateway's bridge-payments service. |
| properties | Object with key-value map of properties for this link. |
#### Properties ####
The following properties should be provided:
| Field | Value |
|----------|--------|
| version | `"1"` for this version of the spec. |
| bridges | Array of objects describing any Ripple bridges operated by this gateway. |
| additional\_info\_definitions | Definitions of all additional fields that may be requested to make payments through this API. |
Each member of the `bridges` array should be an object with the following fields:
| Field | Value | Description |
|-----------|--------|-------------|
| currency | String | Currency code for the currency supported by this bridge. |
| scheme | String | A valid URI scheme that matches identifiers used to make non-Ripple payments to or from this bridge. See [Gateway Services Identifiers](#gateway-services-identifiers) for a list of schemes. The scheme `ripple` is not valid here. |
| direction | String | Whether this bridge supports payments into the Ripple network (`in`), payments out from the Ripple network (`out`) or payments in both directions (`both`). Any other values of this field are invalid. |
Each field name in the `additional_info` object should match a field that may be requested by the [Get Quotes method](#get-quotes). The contents of that field in the host-meta should be a definition of the field, so that client applications can create a user interface to request the user to fill in those fields.
| Field | Value | Description |
|----------|--------|-------------|
| type | String ([Additional Info Types](#additional-info-type-reference)) | What sort of validation should be performed on this field. |
| label | Object | Map of brief labels for this field. Keys should be [two-character ISO-639.1 codes](http://www.loc.gov/standards/iso639-2/php/code_list.php), and values should be human-readable Unicode strings (in the corresponding language) suitable for display in a UI. |
| description | Object | Map of longer descriptions for this field. Keys should be [two-character ISO-639.1 codes](http://www.loc.gov/standards/iso639-2/php/code_list.php), and values should be human-readable Unicode strings (in the corresponding language) suitable for display in a UI. |
For the label and description fields, client applications can choose which language to display, and which languages to fall back on in cases where the preferred language is not provided.
### Additional Info Type Reference ###
<span class='draft-comment'>TBD</span>
# WebFinger #
WebFinger tells you about a person, hopefully including how to send money to that person.
[RFC7033](http://tools.ietf.org/html/rfc7033) defines the WebFinger protocol as a way to discover information about people or other entities on the internet, from a URI that might not be usable as a locator otherwise, such as an account or email address. The response to a WebFinger request is like the response to a Host-Meta request, but relates to a specific user (or resource) instead of to the domain. The response to a WebFinger request is also called a JRD (JSON Resource Descriptor)
Gateway Services uses WebFinger to identify the possible beneficiaries of a payment. The *aliases* and *links* in the WebFinger response provide information about a user with regards to Ripple, including what accounts represent that user, and what services can be used to send money to the user.
#### Request format: ####
```
GET /.well-known/webfinger.json?resource={uri}
```
Alternate request format:
```
GET /.well-known/webfinger?resource={uri}
Accept: application/json
```
The following parameters must be provided in the URL:
| Field | Value | Description |
|-------|-------|-------------|
| uri | A valid, URL-encoded [Gateway Services URI](gateway-services-identifiers) | The resource to look up. For Gateway Services, should be an account that might send or receive money, or be otherwise involved in a payment. |
#### Response Format ####
The response is a JRD, in a similar format to the response to [host-meta](#host-meta). Gateway Services uses specific [Aliases](#webfinger_aliases) and [Links](#webfinger_links) as described.
#### Example request: ####
__`GET https://latambridgepay.com/.well-known/webfinger?resource=ripple:bob`__
#### Example response: ####
```js
{
"subject": "ripple:bob",
"expires": "2014-10-07T22:46:35.097Z",
"aliases": [
"ripple:bob",
"ripple:rBWay8KRdmroZra4DTXi6h5cLtPhs5mH7v",
"paypal:bob@bob-way.com"
],
"links": [
{
"rel": "https://gatewayd.org/gateway-services/bridge_payments",
"href": "https://latambridgepay.com/v1/bridge_payments",
"properties": {
"version": "1",
"send_to":
[
{
"uri": "acct:bob@bob-way.com",
"currencies": ["USD", "XAU"]
},
{
"uri": "paypal:bob@bob-way.com",
"currencies": ["USD"]
},
{
"uri": "bitcoin:1Y23423jf9234...",
"currencies": ["BTC"]
}
]
}
}
]
}
```
## Webfinger Aliases <a id="webfinger_aliases"></a> ##
```js
...
"aliases": [
"ripple:bob",
"ripple:rBWay8KRdmroZra4DTXi6h5cLtPhs5mH7v",
"paypal:bob@bob-way.com"
],
...
```
The `aliases` field of a WebFinger document can contain various values, including ones that are not related to Ripple. Aliases that match supported [Gateway Services URIs](#gateway-services-identifiers) can be used to identify this account as a party to a payment.
If you WebFinger any of the aliases at the same domain, the resulting document should be the same. Optionally, the `subject` field may change to reflect the resource requested in the URL. Alternatively, the `subject` field can remain the same, to indicate the preferred URI for a particular resource.
<span class='draft-comment'>(TODO: Discuss weird edge cases here where an alias does not necessarily mean that the user can be paid according to that scheme by this gateway.)</span>
## Webfinger Links <a id="webfinger_links"></a> ##
The `links` field of a WebFinger document should contain link elements describing where to find the following APIs:
* Bridge Payments
* <span class='draft-comment'>As we add other APIs that are relevant for a particular user, links to those APIs should be added to the WebFinger response.</span>
* Optionally, additional links with information relevant to this party can be added. <span class='draft-comment'>The Gateway Services spec may grow to include some uses of additional links, for example location data that can be used by client applications to select from agents in different regions.</span>
### Bridge Payments Link <a id='webfinger_bridgepayments_link'></a> ###
```js
...
{
"rel": "https://gatewayd.org/gateway-services/bridge_payments",
"href": "https://latambridgepay.com/v1/bridge_payments",
"properties": {
"version": "1",
"send_to":
[
{
"uri": "acct:bob@bob-way.com",
"currencies": ["USD", "XAU"]
},
{
"uri": "paypal:bob@bob-way.com",
"currencies": ["USD"]
},
{
"uri": "bitcoin:1Y23423jf9234...",
"currencies": ["BTC"]
}
]
}
}
...
```
The Bridge-Payments link indicates where to find the [Bridge-Payments](#bridge-payments) service for the user in the URL; the URL provided is used as the base for Bridge-Payments methods. Unlike the version of this link in host-meta, the version in the WebFinger JRD does not have a definition of all the fields that might be requested in the `additional_info` paramter. (That information is omitted because it is not related to the resource being WebFingered.)
Instead, the Bridge-Payments link the WebFinger JRD has a `send_to` property, which indicates which identifiers should be used to send different currencies to the resource being queried. Each element in the `send_to` array should be an object with the following fields:
| Field | Value | Description |
|-------|-------|-------------|
| uri | A valid [Gateway Services URI](#gateway-services-identifiers) | This identifies a particular identifier that should be used at this gateway-services link when the resource in the URL is receiving a payment. It may or may not be the same as the URI from the request. Any given URI should only appear once in the `send_to` array. |
| currencies | Array | The [currency codes](#currency-codes) for one or more currencies that should be sent to the associated identifier using this bridge-payments service. |
It is possible that a provider of Gateway Services may only provide WebFinger on a particular domain, so that the `href` for Bridge-Payments may be different for different resources. For example, an individual can set up her personal domain to run WebFinger, so that querying the person's personal email address returns a link to a bridge-payments service operated by a chosen gateway. It is even possible that there may be multiple instances of the Bridge-Payments link (with the same `rel`) but different destinations and properties, indicating that the resource has multiple Gateway Services providers it trusts.
# Bridge Payments #
The Bridge Payments service consists of the following three API calls.
The URL for all the Bridge Payments calls is relative to the base URL defined in the [Host-Meta Bridge Payments Link](#bridge-payments-link). This should always include at least: `/v1/bridge_payments` (The v1 may change in future versions.)
* [Get Quotes - `GET /quotes/{sender}/{receiver}/{amount}`](#get-quotes)
* [Accept Quote - `POST /`](#accept-quote)
* [Check Status - `GET /{id}`](#check-status)
All three of these operate on a single type: the Gateway Transaction object.
## Gateway Transaction Objects ##
A Gateway Transaction defines is a type of object that represents a payment through a gateway. This is like a contract, representing a chain of steps that complete the intended payment from a sender to a receiver.
It looks like this:
```js
{
"id": "9876A034899023AEDFE",
"state": "quote",
"created": "2014-09-23T19:20:20.000Z",
"source": {
"uri": "bobway@snapswap.us",
"claims_required": ["dob","us_ssn","zip"],
"claims_jwts": ["eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmYW1pbHlfbmFtZSI6IlJlZ2luZWxsaSIsImdpdmVuX25hbWUiOiJSb21lIn0.o0l4dfizDHOlbqJonkwyqBhufIwfXX9Ltjv56Fcn9SQ", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXNzYWdlIjoiQ29uZ3JhdHVsYXRpb25zLCB5b3UgZGVjb2RlZCBhIEpXVCJ9.msBhzh2yzZabnMei9b1mchspWXWS0xOxCf4Vlhd6mAg"],
"additional_info": {
"bank_account": "073240754",
"routing_number": "23790832978",
"country": "USA",
"bank_name": "Example Bank USA"
}
},
"wallet_payment": {
"destination": "ripple:snapswap"
"primary_amount": {
"amount": "5.125",
"currency": "USD",
"issuer": ""
},
"invoice_id": "87246",
"expiration": "2014-09-23T20:20:20.000Z",
},
"destination": {
"uri": "acct:stefan@fidor.de",
"claims_required": [],
"claims_jwts": [],
"additional_info": {
"zip": "83902-1135"
}
},
"destination_amount": {
"amount": "5",
"currency": "USD",
"issuer": "r4tFZoa7Dk5nbEEaCeKQcY3rS5jGzkbn8a"
},
"parties": {
"inbound_bridge": "https://snapswap.us",
"outbound_bridge": "http://ripple.fidor.de",
"sending_agent": "handler33@brickandmort.ar",
"receiving_agent": ""
}
}
```
The fields are defined as follows:
| Field | Value | Description |
|--------------------|--------|-------------|
| id | String | An identifying hash value that uniquely describes this gateway payment. This is a 256-bit hash of the Gateway Transaction object, omitting the `wallet_payment`, the `state`, and the `id` itself. If any Ripple transactions are made as part of this gateway transaction, they should use this value as the `InvoiceID` field of the Ripple payment. Not included until the response to Accept Quote. |
| created | String | The time that this resource was initially created as part of a Get-Quotes request, as an ISO8601 extended format string. This time never changes throughout the lifetime of the object. This is included so that the hashed ID is different if the same parties make a payment for the same amount on different dates. |
| state | String | What state the payment is in. Valid states are: `"quote"`, `"invoice"`, `"in_progress"`, `"complete"`, and `"canceled"`. |
| source | Object | Information about the originator of the payment. |
| wallet\_payment | Object | An object that defines the payment which will initiate the entire chain of necessary transactions. After you accept the quote, you post the **wallet\_payment** object to the appropriate API to make the payment that starts the chain. <span class='draft-comment'>(This object is not yet fully defined.)</span> |
| wallet\_payment.expiration | String | Expiration time in ISO8601 extended format. The initial wallet payment will not be accepted if it arrives after this time. When the quote is accepted, the gateway may optionally extend the expiration to a later time. |
| destination | Object | Info about the ultimate beneficiary of the payment, in the same format as `source`. |
| destination\_amount | Object | The amount of money that is received at the destination. The `issuer` field may be an empty string for non-Ripple addresses or cases where any trusted issuer is accepted. |
| parties | Object | Info about intermediary parties in the transaction. A value of `""` indicates that the party is not involved or the field is not applicable this this transaction. |
| parties.inbound\_bridge | String (URI) | The gateway provider responsible for receiving a non-Ripple payment and making a Ripple payment. Should be identified by `http://` or `https://` and a domain that has a [host-meta](#host-meta) |
| parties.outbound\_bridge | String (URI) | The gateway provider responsible for paying the destination amount, if not the same as `inbound_bridge`. Should be identified by `http://` or `https://` and a domain that has a [host-meta](#host-meta) |
| parties.sending\_agent | String (URI) | Another involved party responsible for handling money on behalf of the `source` party. |
| parties.receiving\_agent | String (URI) | Another involved party responsible for handling money on behalf of the `destination` party. |
<span class='draft-comment'>(Possible additional parties: the sender and receiver, again, but as URIs that can definitely be WebFingered at a single definitive domain.)</span>
The `source` and `destination` objects are defined in the same way, as follows:
| Field | Value | Description |
|--------------------|--------|-------------|
| uri | String | A WebFinger-able unique identifier for this account or person. |
| claims\_required | Array | A list of pieces of information that are necessary to make this payment. |
| claims_jwts | Array | Array of [JWTs](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-28). Each JWT contains one or more claims about this account or person, and is signed by some authority who vouches for those claims.
| additional_info | Object | If additional addressing information is necessary to make the payment, this field contains key-value pairs. The Get Quotes method returns `""` to indicate fields where information is needed. The definitions of these fields is provided in the host-meta. |
<span class='draft-comment'>Potential future feature - document / estimate all fees including ones on the initiating payment.</span>
### Calculating the Gateway Transaction ID ###
The `id` field of the Gateway Transaction should be a hash that uniquely identifies the overarching payment goal, not just one step along the chain. To do this, there are specific rules for calculating the ID.
<span class='draft-comment'>(Rough draft of this section, subject to change)</span>
1. Create a JSON object with all the fields of the Gateway Transaction Object __except__: `id`, `state`, and `wallet_payment`.
2. Serialize the object as a UTF-8 string, with all the fields in alphabetical order, and no whitespace between elements.
3. Take the SHA-256 hash of the serialized string, and use this as the `id` value.
## Get Quotes ##
Get Quotes tells you what your options are for making a payment.
__`GET /v1/bridge_payments/quotes/{sender}/{receiver}/{amount}`__
This API should accept parameters that are formatted as follows:
| Parameter | Format | Example(s) |
|-----------|--------|------------|
| sender | A URL-encoded (%-escaped) [Gateway Services Identifier](#gateway-services-identifiers) | acct%3Abob%40ripple.com |
| receiver | A URL-encoded (%-escaped) [Gateway Services Identifier](#gateway-services-identifiers) | ripple%3AraLiCEoiYDN3aTw2ZnGmEVXWwYXWiAxR7n |
| amount | Decimal value, and [code for the currency to be received](#currency-codes), concatenated with a `+` | 10.99+USD |
The response to Get Quotes is a JSON object with two top-level fields:
| Field | Value | Description |
|-----------------|---------|-------------|
| success | Boolean | `true` if this method succeeded |
| bridge_payments | Array | Array of [Payment Objects](#gateway-transaction-objects) in the `quote` state that represent possible payments, which could result in the destination amount being paid to the ultimate beneficiary. |
The Gateway Services implementation can use custom business logic to determines which bridge_payments to include in the response, if any. This can depend on the sender, the receiver, the currency and amount, or other factors.
Get Quotes is intended to be a recursive process: if the Gateway Services provider does not know how to make an outgoing payment to the receiver in the specified currency, it can perform a Get Quotes call using another gateway that it trusts, then return quotes accordingly (possibly marked up from the quotes of the other gateway). In this case, most portions of the payment object remain the same throughout, but the `wallet_payment` object at each stage reflects the payment that must be made to continue the chain.
Some fields of each gateway transaction object may be omitted or not in their final state:
* The `id` field is omitted until the quote is accepted by both parties (see [Accept Quote](#accept-quote)) because it is a hash of the immutable portions of the gateway transaction object.
* The `state` field has the value `"quote"` to indicate that this is just a potential gateway transaction, and is not yet valid.
* The `source.claims_jwts` field may be empty, even though `source.claims_required` is not empty. This indicates that this transaction requires signed claims from an authority the gateway trusts before it can be made.
* The `source.additional_info` field may contain several fields whose value is the empty string `""`. This indicates that the client must provide values for those fields in order to accept the payment.
* The `destination.claims_jwts` and `destination.additional_info` fields may require population in the same manner as the corresponding `source` fields.
### Get Quotes Example ###
Request:
```
GET https://latambridgepay.com/v1/bridge_payments/acct%3Abobway%40snapswap.us/acct%3Astefan%40fidor.de/5+USD
```
Response:
```js
{
"success": true,
"bridge_payments": [
{
"state": "quote",
"created": "2014-09-23T19:20:20.000Z",
"source": {
"uri": "acct:bobway@snapswap.us",
"claims_required": [],
"claims_jwts": [],
"additional_info": {}
},
"wallet_payment": {
"destination": "ripple:snapswap",
"primary_amount": {
"amount": "5.125",
"currency": "USD",
"issuer": ""
},
"invoice_id": "78934",
"expiration": "2014-09-23T20:20:20.000Z"
},
"destination": {
"uri": "acct:stefan@fidor.de",
"claims_required": [],
"claims_jwts": [],
"additional_info": {}
},
"destination_amount": {
"amount": "5",
"currency": "USD",
"issuer": "r4tFZoa7Dk5nbEEaCeKQcY3rS5jGzkbn8a"
},
"parties": {
"inbound_bridge": "https://snapswap.us",
"outbound_bridge": "http://ripple.fidor.de",
"sending_agent": "",
"receiving_agent": ""
}
},
{
"state": "quote",
"created": "2014-09-23T19:20:20.000Z",
"source": {
"uri": "acct:bobway@snapswap.us",
"claims_required": [],
"claims_jwts": [],
"additional_info": {}
},
"wallet_payment": {
"destination": "bitcoin:1AAHyhHQzRyKkUaCmAi8dPanXoxqHuGdEJ",
"primary_amount": {
"amount": "0.0140",
"currency": "BTC",
"issuer": ""
},
"invoice_id": "",
"expiration": "2014-09-23T20:20:20.000Z"
},
"destination": {
"uri": "acct:stefan@fidor.de",
"claims_required": [],
"claims_jwts": [],
"additional_info": {}
},
"destination_amount": {
"amount": "5",
"currency": "USD",
"issuer": "r4tFZoa7Dk5nbEEaCeKQcY3rS5jGzkbn8a"
},
"parties": {
"inbound_bridge": "https://snapswap.us",
"outbound_bridge": "http://ripple.fidor.de",
"sending_agent": "",
"receiving_agent": ""
}
}
]
}
```
## Accept Quote ##
Bridge Payments lets you tell the gateway which payment you are making, so it can be ready.
Request:
```
POST /v1/bridge_payments/
{ .. gateway transaction object ... }
```
No URL parameters. The request body is a single [Gateway Transaction Object](#gateway-transaction-objects) in the `quote` state, as provided by the [Get Quotes method](#get-quotes). Before submitting the request, the client may modify the following fields:
* `source.claims_jwts`, `source.additional_info`, `destination.claims_jwts`, and `destination.additional_info`: Provide any necessary information, along with claims signed by appropriate authorities, that the gateway requests in order to make this payment.
* `sending_agent`, if the client wishes to name an applicable participating party
* All other fields should be left exactly as provided by the Get Quotes method. <span class='draft-comment'>We should discuss validation of the quote. Should the server check that the sender did not change any fields to unacceptable values (basically rewriting the contract)? How does it enforce expiration dates?</span>
Response:
If the quote is valid and all necessary information is provided, the server returns `200 OK` with the request body containing two top-level fields:
| Field | Value | Description |
|-----------------|---------|-------------|
| success | Boolean | `true` if this method succeeded |
| bridge_payment | [Gateway Transaction object](#gateway-transaction-objects) | The accepted gateway transaction object, as saved. |
The Gateway Transaction object should reflect the object provided in the request, with the following exceptions:
* The `id` field should be provided as an identifying hash for the transaction, not including the `state` field nor the `id` itself. <span class='draft-comment'>(Slightly more detail necessary here.)</span>
* The `state` field should be updated to `invoice` status to indicate that the quote has been accepted by both the client and the Gateway Services provider.
* Optionally, the Gateway Services provider may extend the `expiration` field to a later time than originally provided. The expiration CANNOT change to earlier than was quoted.
### Error: Sender Claims Required ###
```
400 Bad Request
{
success: false,
"sender_claims_required": [
"bank_account",
"routing_number",
"country",
"bank_name",
]
}
```
## Check Status ##
Bridge payment status checks tells you whether a payment has happened yet.
__`GET https://latambridgepay.com/v1/bridge_payments/9876`__
Response:
```js
{
"id": "9876A034899023AEDFE",
"state": "invoice",
"created": "2014-09-23T19:20:20.000Z",
"source": {
"uri": "acct:bobway@snapswap.us",
"claims_required": [],
"claims_jwts": [],
"additional_info": {}
},
"wallet_payment": {
"destination": "ripple:snapswap",
"primary_amount": {
"amount": "5.125",
"currency": "USD",
"issuer": ""
},
"invoice_id": "78934",
"expiration": "2014-09-23T20:20:20.000Z"
},
"destination": {
"uri": "acct:stefan@fidor.de",
"claims_required": [],
"claims_jwts": [],
"additional_info": {}
},
"destination_amount": {
"amount": "5",
"currency": "USD",
"issuer": "r4tFZoa7Dk5nbEEaCeKQcY3rS5jGzkbn8a"
},
"parties": {
"inbound_bridge": "https://snapswap.us",
"outbound_bridge": "http://ripple.fidor.de",
"sending_agent": "",
"receiving_agent": ""
}
}
```

View File

@@ -13,6 +13,7 @@ Gatewayd's features include:
- gateway administration
- support for custom plugins
## Dependencies
1. [Node.js](http://nodejs.org/)
@@ -34,6 +35,9 @@ Gatewayd's features include:
- The Ripple REST API provides a simplified HTTP/JSON interface to all the Ripple protocol network operations, such as payments and other transactions.
4. [git](http://git-scm.com/) is required for installation and updating. It is not used during general operation.
## Gatewayd Architecture ##
A gateway acts as a link between Ripple's shared global Ledger and value outside of the network, such as traditional banking balances, other virtual currencies, or more. Thus, gatewayd sits between the `rippled` server (which participates in the network that defines the Ripple global ledger) and some source of information about external activities. Gatewayd's main job is to monitor each side for transactions and translate them into the appropriate actions on the other side.
@@ -95,7 +99,7 @@ All tables have the following common fields:
A user is a fundamental unit of identity for your gateway's customers; these persist to the *User* table. Each user is linked to any number of External Accounts as well as any number of Ripple Addresses, which are persisted to their own tables.
*Note:* The User model is expected to change dramatically in future versions of of Gatewayd. The current model should be considered DEPRECATED.
__*Note:*__ The User model is expected to change dramatically in future versions of of Gatewayd. The current model should be considered DEPRECATED.
In addition to the common fields, the User model has the following:
@@ -148,7 +152,7 @@ The [incoming process](#gatewayd-services) automatically creates records for new
#### Future Models ####
*Note:* As development on Gatewayd continues, the data model is expected to change. In particular, we expect to create a "Gateway Transaction" object to link External and Ripple transactions, and a "Policy" object that links a Gateway Transaction to the business logic of executing it (for example, setting custom fees for different types of actions or different customers).
__*Note:*__ As development on Gatewayd continues, the data model is expected to change. In particular, we expect to create a "Gateway Transaction" object to link External and Ripple transactions, and a "Policy" object that links a Gateway Transaction to the business logic of executing it (for example, setting custom fees for different types of actions or different customers).
## Authentication ##
@@ -165,7 +169,7 @@ Depending on your situation, there are some configuration variables you can set:
* The `KEY` option (not defined by default) sets the API key used for Basic Auth. The username is required to be "admin@<em>yourdomain.com</em>", based Gatewayd's `DOMAIN` setting, and the API key is the password. [In the future](https://github.com/ripple/gatewayd/compare/no-username-auth), you will be able to authenticate by sending the API key as either the username or the password and leaving the other field blank.
* You can generate a new `KEY` value with the [Set API Key](#set-api-key) method. (Use the commandline version if it's your first time.)
*Exception:* Gatewayd's HTTP server also serves a `ripple.txt` response that imitates a text file, but is actually dynamically generated based on its current configuration. This route is intended to be public, and is not protected even when BASIC_AUTH is enabled. However, it is disabled if the `HTTP_SERVER` option is disabled.
__*Exception:*__ Gatewayd's HTTP server also serves a `ripple.txt` response that imitates a text file, but is actually dynamically generated based on its current configuration. This route is intended to be public, and is not protected even when BASIC_AUTH is enabled. However, it is disabled if the `HTTP_SERVER` option is disabled.
Gatewayd implements authentication using the [Passport Node.js Module](http://passportjs.org/), so if you are familiar with Passport, you can easily customize the authentication scheme for Gatewayd to fit your needs.
[[Source]<br>](https://github.com/ripple/gatewayd/blob/master/lib/http/passport_auth.js "Source")
@@ -190,6 +194,9 @@ All issuances of non-XRP currency and assets come from the cold wallet; it effec
Although you could send the issuances directly to customers from the account issuing them, that exposes you to risk: if the account issuing the currency is compromised, potentially unlimited issuances could be made on your behalf. Using a hot/cold wallet distinction decreases the chances that your issuing account will be compromised, because you can keep it safely offline while day-to-day business is happening. The hot wallet, which is exposed to the most risk, can only lose as much money as it holds.
# Gatewayd Usage #
## Installation
@@ -211,6 +218,7 @@ The update process for gatewayd may change in the future, but for now, updating
5. Restart the gatewayd processes. (This ends downtime)<br/>
`bin/gateway start`
## Configuration ##
Before you can run gatewayd, you need to set up the appropriate accounts that will be used to store and send funds in the Ripple network. You also need to define which currencies your gateway issues. Beyond that, there are some options you can set if they fit your needs.
@@ -223,7 +231,7 @@ The actual process of configuring gatewayd with the appropriate accounts is easy
[Ripple Client](https://ripple.com/client/#/register)
*Note:* The key generation process in the Ripple Client happens on your local machine, and is never sent to Ripple or anyone else. You can even go offline while you generate the key (as long as you've fully loaded the page first).
__*Note:*__ The key generation process in the Ripple Client happens on your local machine, and is never sent to Ripple or anyone else. You can even go offline while you generate the key (as long as you've fully loaded the page first).
Save the secret key somewhere that it will be completely safe. Never send it unencrypted to an untrusted entity such as your web host.
@@ -239,7 +247,7 @@ Set the address _and_ the secret key for the hot wallet in gatewayd using the co
bin/gateway set_hot_wallet rhfyVnzjPvvtdnZNSiNufRCZhHpc9yh1rA ssmgxde6ozSViVkuWvsC6HJxpLvH4
(*Tip:* Ripple addresses always start with `r`; Ripple secrets always start with `s`.)
(__*Tip:*__ Ripple addresses always start with `r`; Ripple secrets always start with `s`.)
Define which currencies your gateway will support. (This does not include XRP, which is necessary for every Ripple account and gateway.) You can do this with the commandline as well. Run the `add_currency` command with the 3-letter ISO 4217 currency codes for whichever currencies you want to support:
@@ -253,7 +261,7 @@ At this point, you need to create trustlines between the hot and cold wallet acc
bin/gateway set_trust USD 1000
bin/gateway set_trust XAU 2
*Aside:* Keep in mind the very different values for currencies. In this example, the two troy ounces of gold (XAU 2) are, at the time of writing, worth approximately $2600 USD.) Fortunately, gatewayd supports very large and small numbers.
__*Aside:*__ Keep in mind the very different values for currencies. In this example, the two troy ounces of gold (XAU 2) are, at the time of writing, worth approximately $2600 USD.) Fortunately, gatewayd supports very large and small numbers.
The last step before you can start your gateway is to set the last payment hash. This indicates a cutoff point in time, where the gateway should monitor Ripple for payments that are newer and try to process them, but ignore payments that are older. To get a good starting value, look up the transaction history for the cold wallet and choose the most recent transaction.
@@ -263,15 +271,15 @@ After installation, start the gateway processes by running the command:
bin/gateway start
## Command Line Interface ##
In addition to the REST interface, many pieces of Gatewayd can be controlled directly through the commandline. This is done by running the `gateway` script (`bin/gateway` from the project's top level directory) with the relevant commands.
You can get usage information for the commandline as follows:
```
bin/gateway -h
```
bin/gateway -h
# Gatewayd API Reference #
@@ -322,7 +330,7 @@ The API serves several purposes: it provides an easy way to customize settings w
* [Retrieve Hot Wallet - `GET /v1/config/wallets/hot`](#retrieve-hot-wallet)
* [Set Last Payment Hash - `POST /v1/config/last_payment_hash`](#set-last-payment-hash)
* [Retrieve Last Payment Hash - `GET /v1/config/last_payment_hash`](#retrieve-last-payment-hash)
* [Set Gateway Domain - `POST /v1/config/domin`](#set-gateway-domain)
* [Set Gateway Domain - `POST /v1/config/domain`](#set-gateway-domain)
* [Retrieve Domain - `GET /v1/config/domain`](#retrieve-domain)
* [Set API Key - `POST /v1/config/key`](#set-api-key)
* [Retrieve API Key - `GET /v1/config/key`](#retrieve-api-key)
@@ -631,7 +639,7 @@ This method retrieves the list of all external transactions that are no longer
considered pending. This includes all deposits that have been issued as a
balance with a Ripple payment, and all withdrawals that have been cleared.
*Note:* There is an apparent bug with this method, where both deposits and withdrawals are returned in the "deposits" field. (See [Issue #240](https://github.com/ripple/gatewayd/issues/240) for details and status.)
__*Note:*__ There is an apparent bug with this method, where both deposits and withdrawals are returned in the "deposits" field. (See [Issue #240](https://github.com/ripple/gatewayd/issues/240) for details and status.)
Response Body:
@@ -995,7 +1003,7 @@ payment. In the case that a payment will never make it into the Ripple
ledger the outgoing payment is marked as "failed". This method lists the
history of such payments.
*Note:* Currently, a payment is removed from this list if you [retry](#retry-failed-payment) it. In the future, this behavior may change so that old failures remain until manually deleted, and retrying creates a separate transaction, in order to preserve historical data on transaction failure for analysis. (See [Issue #239](https://github.com/ripple/gatewayd/issues/239) for status.)
__*Note:*__ Currently, a payment is removed from this list if you [retry](#retry-failed-payment) it. In the future, this behavior may change so that old failures remain until manually deleted, and retrying creates a separate transaction, in order to preserve historical data on transaction failure for analysis. (See [Issue #239](https://github.com/ripple/gatewayd/issues/239) for status.)
If you want to remove a failed payment without retrying it, you can delete the corresponding record from the database.
@@ -1082,7 +1090,7 @@ use this method to retrying a payment. This method simply changes the
payment's state from "failed" to "outgoing", effectively enqueueing the
transaction to be re-submitted to Ripple.
*Note:* In the future, this behavior may change to preserve the old, failed transaction for historical purposes and create a new, separate transaction to be submitted to Ripple. See [Issue #239](https://github.com/ripple/gatewayd/issues/239) for details.
__*Note:*__ In the future, this behavior may change to preserve the old, failed transaction for historical purposes and create a new, separate transaction to be submitted to Ripple. See [Issue #239](https://github.com/ripple/gatewayd/issues/239) for details.
Response Body:
@@ -1235,7 +1243,7 @@ balance.getAccountBalance(null, callback);
```
</div>
*Note:* There is no commandline version for this method yet.
__*Note:*__ There is no commandline version for this method yet.
This method lists the funds that are held by the hot wallet, ready to be
distributed to clients.
@@ -1284,7 +1292,7 @@ balance.getLiabilities(callback);
```
</div>
*Note:* There is no commandline version for this method yet.
__*Note:*__ There is no commandline version for this method yet.
Every asset that the gateway holds and for which it issues currency is
a liability of the gateway. This method lists total liabilities for each type
@@ -1567,7 +1575,7 @@ gateway.config.save(callback);
This method tells gatewayd which Postgres database to use.
*Caution:* This method contains sensitive database credentials. Do not use it on unsafe channels!
__*Caution:*__ This method contains sensitive database credentials. Do not use it on unsafe channels!
Response Body:
@@ -1612,7 +1620,7 @@ Response Body:
}
```
*Caution:* This method contains sensitive database credentials. Do not use it on unsafe channels!
__*Caution:*__ This method contains sensitive database credentials. Do not use it on unsafe channels!
### Set Ripple-REST URL ###
@@ -1720,7 +1728,7 @@ gateway.config.set('COLD_WALLET', "rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD");
Set the gateway cold wallet, from which funds are issued.
*Note:* If the cold wallet is already set, the REST version returns 304 Not Modified.
__*Note:*__ If the cold wallet is already set, the REST version returns 304 Not Modified.
Response Body:
@@ -1803,7 +1811,7 @@ gateway.api.setHotWallet(address, secret, callback);
The hot wallet holds and sends funds to customers automatically. This method
sets the Ripple account to use as the hot wallet. If the *address* and *secret* fields are omitted from the REST or commandline versions, then a new wallet address and secret are generated on the fly. (You still need to fund the hot wallet with at least the account reserve in XRP before you can use it.)
*Caution:* This method request contains account secrets! Be especially careful not to transmit this data over insecure channels.
__*Caution:*__ This method request contains account secrets! Be especially careful not to transmit this data over insecure channels.
Response Body:
@@ -2042,7 +2050,7 @@ gateway.config.save(callback);
This method reset's the gateway's API key, which is used for authenticating to the REST API. (See [Authentication](#authentication) for more details.)
The REST version accepts a key parameter, which it sets as the API key. The commandline version generates and returns a new key randomly. (*Note:* This behavior may be changed to be more uniform. See [Issue #245](https://github.com/ripple/gatewayd/issues/245) for more details.)
The REST version accepts a key parameter, which it sets as the API key. The commandline version generates and returns a new key randomly. (__*Note:*__ This behavior may be changed to be more uniform. See [Issue #245](https://github.com/ripple/gatewayd/issues/245) for more details.)
Response Body:
@@ -2171,7 +2179,7 @@ Response Body:
}
```
*Note:* The amounts for each currency do not currently mean anything. If you [add supported currencies](#add-supported-currency) using the REST API, they will always be set to 0. You can manually set the values by editing the `config/config.json` file, but there is no meaningful effect.
__*Note:*__ The amounts for each currency do not currently mean anything. If you [add supported currencies](#add-supported-currency) using the REST API, they will always be set to 0. You can manually set the values by editing the `config/config.json` file, but there is no meaningful effect.
### Remove Supported Currency ###
@@ -2529,12 +2537,13 @@ Response Body:
monit: { memory: 0, cpu: 0 } } ]
```
## User-Auth Methods ##
### Log In User ###
[[Source]<br>](https://github.com/ripple/gatewayd/blob/master/lib/http/controllers/public/login_user.js "Source")
*Caution:* This method is deprecated, and may be removed without further notice.
__*Caution:*__ This method is deprecated, and may be removed without further notice.
<div class='multicode'>
*REST*
@@ -2548,7 +2557,7 @@ POST /v1/users/login
```
</div>
*Note:* This method intentionally lacks commandline and Javascript versions.
__*Note:*__ This method intentionally lacks commandline and Javascript versions.
Verifies that a user has the correct username and password combination. Used
for the web application and requires user credentials in place of an API key.
@@ -2561,7 +2570,7 @@ over an unsecure connection.
### Retrieve User ###
[[Source]<br>](https://github.com/ripple/gatewayd/blob/master/lib/http/controllers/resources/users_controller.js#L38 "Source")
*Caution:* This method is deprecated, and may be removed without further notice.
__*Caution:*__ This method is deprecated, and may be removed without further notice.
<div class='multicode'>
*REST*
@@ -2616,7 +2625,7 @@ Response Body:
### List User External Accounts ###
[[Source]<br>](https://github.com/ripple/gatewayd/blob/master/lib/http/controllers/api/list_user_external_accounts.js "Source")
*Caution:* This method is deprecated, and may be removed without further notice.
__*Caution:*__ This method is deprecated, and may be removed without further notice.
<div class='multicode'>
*REST*
@@ -2664,7 +2673,7 @@ Response Body:
### List User External Transactions ###
[[Source]<br>](https://github.com/ripple/gatewayd/blob/master/lib/http/controllers/users/index.js#L24 "Source")
*Caution:* This method is deprecated, and may be removed without further notice.
__*Caution:*__ This method is deprecated, and may be removed without further notice.
<div class='multicode'>
*REST*
@@ -2682,7 +2691,7 @@ gateway.data.externalTransactions.forUser(id, callback);
```
</div>
*Note:* This method intentionally lacks a commandline version.
__*Note:*__ This method intentionally lacks a commandline version.
List all external (non-Ripple) transaction records for a given user. These
records are the user's deposits into the gateway and withdrawals from it.
@@ -2717,7 +2726,7 @@ Response Body:
### List User Ripple Addresses ###
[[Source]<br>](https://github.com/ripple/gatewayd/blob/master/lib/http/controllers/users/index.js#L36 "Source")
*Caution:* This method is deprecated, and may be removed without further notice.
__*Caution:*__ This method is deprecated, and may be removed without further notice.
<div class='multicode'>
*REST*
@@ -2735,7 +2744,7 @@ gateway.data.rippleAddresses.readAll({ user_id: id }, callback);
```
</div>
*Note:* This method intentionally lacks a commandline version.
__*Note:*__ This method intentionally lacks a commandline version.
To list all ripple addresses for a given user, pass the user's ID to this
method. Most users will have at least one independent address and one hosted
@@ -2781,7 +2790,7 @@ Response Body:
### List User Ripple Transactions ###
[[Source]<br>](https://github.com/ripple/gatewayd/blob/master/lib/http/controllers/users/index.js#L46 "Source")
*Caution:* This method is deprecated, and may be removed without further notice.
__*Caution:*__ This method is deprecated, and may be removed without further notice.
<div class='multicode'>
*REST*
@@ -2799,7 +2808,7 @@ gateway.data.rippleTransactions.forUser(id, callback);
```
</div>
*Note:* This method intentionally lacks a commandline version.
__*Note:*__ This method intentionally lacks a commandline version.
To list all Ripple transactions for a given user, pass the user's ID to this
method. The response includes an array of transactions made to or from any of

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

@@ -186,7 +186,7 @@ Request("Get Trustlines", {
method: GET,
path: "/v1/accounts/{:address}/trustlines?{:query_params}",
description: "Check the status of one or more trustlines attached to an account",
link: "#reviewing-trustlines",
link: "#get-trustlines",
params: {
"{:address}": DEFAULT_ADDRESS_1,
"{:query_params}": "currency=USD&counterparty=ra5nK24KXen9AHvsdFTKHSANinZseWnPcX"
@@ -197,7 +197,7 @@ Request("Grant Trustline", {
method: POST,
path: "/v1/accounts/{:address}/trustlines",
description: "Add or modify a trustline from this account.",
link: "#granting-a-trustline",
link: "#grant-trustline",
test_only: true,
params: {
"{:address}": DEFAULT_ADDRESS_1
@@ -217,7 +217,7 @@ Request("Check Notifications", {
method: GET,
path: "/v1/accounts/{:address}/notifications/{:hash}",
description: "Browse through the history of payments sent and received by an account",
link: "#checking-notifications",
link: "#check-notifications",
params: {
"{:address}": DEFAULT_ADDRESS_1,
"{:hash}": DEFAULT_HASH
@@ -228,7 +228,7 @@ Request("Check Connection", {
method: GET,
path: "/v1/server/connected",
description: "Check whether the REST server is connected to a rippled server",
link: "#check-connection-state"
link: "#check-connection"
});
Request("Get Server Status", {

View File

@@ -64,7 +64,7 @@ mixpanel.init("132d42885e094171f34467fc54da6fab");
<script src='js/expandcode.js'></script>
</head>
<body role='flatdoc' class='no-literate'>
<body>
<!--Draft warning would go here-->
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">

View File

@@ -60,7 +60,7 @@ mixpanel.init("132d42885e094171f34467fc54da6fab");
</head>
<body role='flatdoc' class='no-literate'>
<body>
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">

View File

@@ -25,16 +25,16 @@ Installation instructions and source code can be found in the [Ripple-REST repos
#### Trustlines ####
* [Get Trustlines - `GET /v1/accounts/{:address}/trustlines`](#reviewing-trustlines)
* [Grant Trustline - `POST /v1/accounts/{:address}/trustlines`](#granting-a-trustline)
* [Get Trustlines - `GET /v1/accounts/{:address}/trustlines`](#get-trustlines)
* [Grant Trustline - `POST /v1/accounts/{:address}/trustlines`](#grant-trustline)
#### Notifications ####
* [Check Notifications - `GET /v1/accounts/{:address}/notifications/{:transaction_hash}`](#checking-notifications)
* [Check Notifications - `GET /v1/accounts/{:address}/notifications/{:transaction_hash}`](#check-notifications)
#### Status ####
* [Check Connection - `GET /v1/server/connected`](#check-connection-state)
* [Check Connection - `GET /v1/server/connected`](#check-connection)
* [Get Server Status - `GET /v1/server`](#get-server-status)
#### Utilities ####
@@ -831,7 +831,7 @@ The following URL parameters are required by this API endpoint:
| Field | Type | Description |
|-------|------|-------------|
| payment | Object | A [payment object](#payment-object) for the transaction. |
| payment | Object | A [payment object](#payment-objects) for the transaction. |
If the `payment.state` field has the value `"validated"`, then the payment has been finalized, and is included in the shared global ledger. However, this does not necessarily mean that it succeeded. Check the `payment.result` field for a value of `"tesSUCCESS"` to see if the payment was successfully executed. If the `payment.partial_payment` flag is *true*, then you should also consult the `payment.destination_balance_changes` array to see how much currency was actually delivered to the destination account.

View File

@@ -524,7 +524,7 @@ It is possible for an offer to become temporarily or permanently *unfunded*:
* The offer becomes funded again when the trust line is no longer frozen.
* If the creator does not have enough XRP for the reserve amount of a new trust line required by the offer. (See [Offers and Trust](#offers-and-trust).)
* The offer becomes funded again when the creator obtains more XRP, or the reserve requirements decrease.
* If the Expiration time included in the offer is later than the close time of the most recently-closed ledger. (See [Expiration](#expiration).)
* If the Expiration time included in the offer is before the close time of the most recently-closed ledger. (See [Expiration](#expiration).)
An unfunded transaction can remain on the ledger indefinitely, but it does not have any effect. The only ways an offer can be *permanently* removed from the ledger are:

View File

@@ -266,7 +266,7 @@ HTTP Status: 200 OK
| status | String | `"error"` if the request caused an error |
| type | String | Typically `"response"`, which indicates a successful response to a command. |
| error | String | A unique code for the type of error that occurred |
| request | Object | A copy of the request that prompted this error, in JSON format. *Caution:* If the request contained any account secrets, they are copied here! |
| request | Object | A copy of the request that prompted this error, in JSON format. __*Caution:*__ If the request contained any account secrets, they are copied here! |
#### JSON-RPC API Error Response Format ####
Some JSON-RPC requests will respond with an error code on the HTTP layer. In these cases, the response is a plain-text explanation in the response body. For example, if you forgot to specify the command in the `method` parameter, the response is like this:
@@ -282,7 +282,7 @@ For other errors that returned with HTTP status code 200 OK, the responses are f
| result | Object | Object containing the response to the query |
| result.error | String | A unique code for the type of error that occurred |
| result.status | String | `"error"` if the request caused an error |
| result.request | Object | A copy of the request that prompted this error, in JSON format. *Caution:* If the request contained any account secrets, they are copied here! *Note:* The request is re-formatted in WebSocket format, regardless of the request made. This may be changed in the future: See [RIPD-279](https://ripplelabs.atlassian.net/browse/RIPD-279). |
| result.request | Object | A copy of the request that prompted this error, in JSON format. __*Caution:*__ If the request contained any account secrets, they are copied here! __*Note:*__ The request is re-formatted in WebSocket format, regardless of the request made. This may be changed in the future: See [RIPD-279](https://ripplelabs.atlassian.net/browse/RIPD-279). |
### Caution on Errors ###
@@ -317,7 +317,7 @@ Many API methods require you to specify an instance of the ledger, with the data
There is also a deprecated `ledger` parameter which accepts any of the above three formats. *Do not* use this parameter; it may be removed without further notice.
If you do not specify a ledger, the `current` (in-progress) ledger will be chosen by default. If you provide more than one field specifying ledgers, the deprecated `ledger` field will be used first if it exists, falling back to `ledger_hash`. The `ledger_index` field is ignored unless neither of the other two are present. *Note:* Do not rely on this default behavior; it is subject to change. Instead, you should always specify a ledger version in each call.
If you do not specify a ledger, the `current` (in-progress) ledger will be chosen by default. If you provide more than one field specifying ledgers, the deprecated `ledger` field will be used first if it exists, falling back to `ledger_hash`. The `ledger_index` field is ignored unless neither of the other two are present. __*Note:*__ Do not rely on this default behavior; it is subject to change. Instead, you should always specify a ledger version in each call.
The sequence number indicates the order of the ledgers; the hash value identifies the exact contents of the ledger. Two ledgers with the same hash are always identical. For closed ledgers, hash values and sequence numbers are equally valid and correlate 1:1. However, this is not true for in-progress ledgers:
@@ -384,7 +384,7 @@ Depending on how the `rippled` server is configured, how long it has been runnin
| validating | The server is currently participating in validation of the ledger |
| proposing | The server is participating in validation of the ledger and currently proposing its own version. |
*Note:* The distinction between `full`, `validating`, and `proposing` is based on synchronization with the rest of the global network, and it is normal for a server to fluctuate between these states as a course of general operation.
__*Note:*__ The distinction between `full`, `validating`, and `proposing` is based on synchronization with the rest of the global network, and it is normal for a server to fluctuate between these states as a course of general operation.
## Modifying the Ledger ##
@@ -1596,7 +1596,7 @@ The response follows the [standard format](#response-formatting), with a success
| transactions | Array | Array of transactions matching the request's criteria, as explained below. |
| validated | Boolean | If included and set to `true`, the information in this request comes from a validated ledger version. Otherwise, the information is subject to change. |
*Note:* The server may respond with different values of `ledger_index_min` and `ledger_index_max` than you provided in the request, for example if it did not have the versions you specified on hand. If you are iterating over data, you should check these fields with every call to make sure you don't miss anything if the values change over time.
__*Note:*__ The server may respond with different values of `ledger_index_min` and `ledger_index_max` than you provided in the request, for example if it did not have the versions you specified on hand. If you are iterating over data, you should check these fields with every call to make sure you don't miss anything if the values change over time.
Each transaction object includes the following fields, depending on whether it was requested in JSON or hex string (`"binary":true`) format.
@@ -2007,7 +2007,7 @@ An example of the request format:
```
</div>
*Note:* There is no commandline syntax for `ledger_data`.
__*Note:*__ There is no commandline syntax for `ledger_data`. You can use the [`json` command](#json) to access this method from the commandline instead.
A request can include the following fields:
@@ -2218,7 +2218,7 @@ The format of each object in the `state` array depends on whether `binary` was s
## ledger_entry ##
[[Source]<br>](https://github.com/ripple/rippled/blob/master/src/ripple/module/rpc/handlers/LedgerEntry.cpp "Source")
The `ledger_entry` method returns a single entry from the specified ledger. See [LedgerEntryType](https://ripple.com/wiki/Ledger_Format#Entries) for information on the different types of objects you can retrieve. *Note:* There is no commandline version of this method. You can use the [`json`](#json) command to access this method from the commandline instead.
The `ledger_entry` method returns a single entry from the specified ledger. See [LedgerEntryType](https://ripple.com/wiki/Ledger_Format#Entries) for information on the different types of objects you can retrieve. __*Note:*__ There is no commandline version of this method. You can use the [`json` command](#json) to access this method from the commandline instead.
#### Request Format ####
@@ -2542,7 +2542,7 @@ The response follows the [standard format](#response-formatting), with a success
| validated | Boolean | True if this data is from a validated ledger version; if omitted or set to false, this data is not final. |
| (Various) | (Various) | Other fields from the [Transaction object](transactions.html) |
*Note:* If the transaction was not found, it means that the rippled server could not find it from the ledger versions on hand. However, that does not mean that the transaction does not exist; it may simply have been included in an older ledger version that the `rippled` does not have on hand anymore.
__*Note:*__ If the transaction was not found, it means that the rippled server could not find it from the ledger versions on hand. However, that does not mean that the transaction does not exist; it may simply have been included in an older ledger version that the `rippled` does not have on hand anymore.
## transaction_entry ##
[[Source]<br>](https://github.com/ripple/rippled/blob/master/src/ripple/module/rpc/handlers/TransactionEntry.cpp "Source")
@@ -2592,7 +2592,7 @@ The request includes the following parameters:
| ledger_index | String or Unsigned Integer| (Optional) The sequence number of the ledger to use, or a shortcut string to choose a ledger automatically. (See [Specifying a Ledger](#specifying-a-ledger-instance)) |
| tx_hash | String | Unique hash of the transaction you are looking up |
*Note:* This method does not support retrieving information from the current in-progress ledger. You must specify a ledger version in either `ledger_index` or `ledger_hash`.
__*Note:*__ This method does not support retrieving information from the current in-progress ledger. You must specify a ledger version in either `ledger_index` or `ledger_hash`.
#### Response Format ####
@@ -2748,7 +2748,7 @@ There are a couple possible reasons the server may fail to find the transaction:
The `tx_history` method retrieves a selection of the most recent transactions made.
*Caution:* This method is deprecated, and may be removed without further notice.
__*Caution:*__ This method is deprecated, and may be removed without further notice.
#### Request Format ####
An example of the request format:
@@ -3634,7 +3634,7 @@ There are three different modes, or sub-commands, of the path_find command. Spec
* `close` - Stop sending pathfinding information
* `status` - Get the information of the currently-open pathfinding request
Although the `rippled` server attempts to find the cheapest path or combination of paths for making a payment, it is not guaranteed that the paths returned by this method are, in fact, the best paths. Due to server load, pathfinding may not find the best results. Additionally, you should be careful with the pathfinding results from untrusted servers. A server could be modified to return less-than-optimal paths in order to earn money for its operators. If you do not have your own server that you can trust with pathfinding, you should compare the results of pathfinding from multiple servers operated by different parties, to minimize the risk of a single server returning poor results. (*Note:* A server returning less-than-optimal results is not necessarily proof of malicious behavior; it could also be a symptom of heavy server load.)
Although the `rippled` server attempts to find the cheapest path or combination of paths for making a payment, it is not guaranteed that the paths returned by this method are, in fact, the best paths. Due to server load, pathfinding may not find the best results. Additionally, you should be careful with the pathfinding results from untrusted servers. A server could be modified to return less-than-optimal paths in order to earn money for its operators. If you do not have your own server that you can trust with pathfinding, you should compare the results of pathfinding from multiple servers operated by different parties, to minimize the risk of a single server returning poor results. (__*Note:*__ A server returning less-than-optimal results is not necessarily proof of malicious behavior; it could also be a symptom of heavy server load.)
### path_find create ###
[[Source]<br>](https://github.com/ripple/rippled/blob/master/src/ripple/module/rpc/handlers/PathFind.cpp#L38 "Source")
@@ -4979,7 +4979,7 @@ If a pathfinding request is open, the response follows the same format as the in
The `ripple_path_find` method is a simplified version of [`path_find`](#path-find) that provides a single response to be used to make a payment transaction immediately. It is available in both the WebSocket and JSON-RPC APIs. However, the results tend to become outdated as time passes. Instead of making many subsequent calls, you should use [`path_find`](#path-find) instead where possible.
Although the `rippled` server attempts to find the cheapest path or combination of paths for making a payment, it is not guaranteed that the paths returned by this method are, in fact, the best paths. Due to server load, pathfinding may not find the best results. Additionally, you should be careful with the pathfinding results from untrusted servers. A server could be modified to return less-than-optimal paths in order to earn money for its operators. If you do not have your own server that you can trust with pathfinding, you should compare the results of pathfinding from multiple servers operated by different parties, to minimize the risk of a single server returning poor results. (*Note:* A server returning less-than-optimal results is not necessarily proof of malicious behavior; it could also be a symptom of heavy server load.)
Although the `rippled` server attempts to find the cheapest path or combination of paths for making a payment, it is not guaranteed that the paths returned by this method are, in fact, the best paths. Due to server load, pathfinding may not find the best results. Additionally, you should be careful with the pathfinding results from untrusted servers. A server could be modified to return less-than-optimal paths in order to earn money for its operators. If you do not have your own server that you can trust with pathfinding, you should compare the results of pathfinding from multiple servers operated by different parties, to minimize the risk of a single server returning poor results. (__*Note:*__ A server returning less-than-optimal results is not necessarily proof of malicious behavior; it could also be a symptom of heavy server load.)
#### Request Format ####
An example of the request format:
@@ -5296,7 +5296,7 @@ The following fields are deprecated, and may be omitted: `paths_canonical`, and
The `sign` method takes a transaction, specified as JSON, and a secret key, and returns a signed binary representation of the transaction that can be submitted. The result is always different, even when you provide the same transaction JSON and secret key.
*Note:* It is possible and preferable to sign a transaction without connecting to a server instead of using this command. For example, [ripple-lib's rsign.js](https://github.com/ripple/ripple-lib/blob/develop/bin/rsign.js) demonstrates offline signing of a transaction. You should prefer to do offline signing of a transaction, especially when you do not control the server you are sending a transaction to. An untrustworthy server can abuse its position to change the transaction before signing it, or worse, use your secret to sign additional arbitrary transactions as if they came from you.
__*Note:*__ It is possible and preferable to sign a transaction without connecting to a server instead of using this command. For example, [ripple-lib's rsign.js](https://github.com/ripple/ripple-lib/blob/develop/bin/rsign.js) demonstrates offline signing of a transaction. You should prefer to do offline signing of a transaction, especially when you do not control the server you are sending a transaction to. An untrustworthy server can abuse its position to change the transaction before signing it, or worse, use your secret to sign additional arbitrary transactions as if they came from you.
#### Request Format ####
An example of the request format:
@@ -5361,7 +5361,7 @@ The request includes the following parameters:
| tx_json | Object | [Transaction definition](transactions.html) in JSON format |
| secret | String | Secret key of the account supplying the transaction, used to sign it. Do not send your secret to untrusted servers or through unsecured network connections. |
| offline | Boolean | (Optional, defaults to false) If true, when constructing the transaction, do not attempt to automatically fill in or validate values. |
| build_path | Boolean | (Optional) If provided for a Payment-type transaction, automatically fill in the `Paths` field before signing. *Caution:* The server looks for the presence or absence of this field, not its value. This behavior may change. (See [RIPD-173](https://ripplelabs.atlassian.net/browse/RIPD-173) for status.) |
| build_path | Boolean | (Optional) If provided for a Payment-type transaction, automatically fill in the `Paths` field before signing. __*Caution:*__ The server looks for the presence or absence of this field, not its value. This behavior may change. (See [RIPD-173](https://ripplelabs.atlassian.net/browse/RIPD-173) for status.) |
| fee\_mult\_max | Integer | (Optional) If the transaction `Fee` is omitted, this field limits the `Fee` value that is automatically filled so that it is less than or equal to the long-term base fee times this value. |
The server automatically attempts to fill in certain fields from the `tx_json` object if they are omitted, unless you specified `offline` as true. Otherwise, the following fields from the [transaction format](transactions.html) are automatically filled in:
@@ -5438,7 +5438,7 @@ The response follows the [standard format](#response-formatting), with a success
| tx_blob | String | Binary representation of the fully-qualified, signed transaction, as hex |
| tx_json | Object | JSON specification of the [complete transaction](transactions.html) as signed, including any fields that were automatically filled in |
*Warning:* If this command results in an error messages, the message can contain the account secret from the request. Make sure that these errors are not visible to others, including:
__*Caution:*__ If this command results in an error messages, the message can contain the account secret from the request. Make sure that these errors are not visible to others, including:
* Do not write this error to a log file that can be seen by multiple people
* Do not paste this error to a public place for debugging
@@ -5510,7 +5510,7 @@ A sign-and-submit request includes the following parameters:
| secret | String | (Required if `tx_json` is supplied) Secret key of the account supplying the transaction, used to sign it. Do not send your secret to untrusted servers or through unsecured network connections. |
| fail_hard | Boolean | (Optional, defaults to false) If true, and the transaction fails locally, do not retry or relay the transaction to other servers |
| offline | Boolean | (Optional, defaults to false) If true, when constructing the transaction, do not attempt to automatically fill in or validate values. |
| build_path | Boolean | (Optional) If provided for a Payment-type transaction, automatically fill in the `Paths` field before signing. You must omit this field if the transaction is a direct XRP-to-XRP transfer. *Caution:* The server looks for the presence or absence of this field, not its value. This behavior may change. (See [RIPD-173](https://ripplelabs.atlassian.net/browse/RIPD-173) for status.) |
| build_path | Boolean | (Optional) If provided for a Payment-type transaction, automatically fill in the `Paths` field before signing. You must omit this field if the transaction is a direct XRP-to-XRP transfer. __*Caution:*__ The server looks for the presence or absence of this field, not its value. This behavior may change. (See [RIPD-173](https://ripplelabs.atlassian.net/browse/RIPD-173) for status.) |
| fee\_mult\_max | Integer | (Optional) If the transaction `Fee` is omitted, this field limits the `Fee` value that is automatically filled so that it is less than or equal to the long-term base fee times this value. |
See the [sign command](#sign) for detailed information on how the server automatically fills in certain fields.
@@ -5645,9 +5645,9 @@ The response follows the [standard format](#response-formatting), with a success
| tx_blob | String | The complete transaction in hex string format |
| tx_json | Object | The complete transaction in JSON format |
*Important:* Even if the WebSocket response has `"status":"success"`, indicating that the command was successfully received, that does not necessarily indicate that the transaction has taken place. There are many cases that can prevent a transaction from processing successfully, such as a lack of trust lines connecting the two accounts in a payment, or changes in the state of the network since the time the transaction was constructed. Even if nothing is wrong, it may take several seconds to close and validate the ledger version that includes the transaction. See the [full list of transaction responses](https://ripple.com/wiki/Transaction_errors) for details, and do not consider the transaction's results final until they appear in a validated ledger version.
__*Caution:*__ Even if the WebSocket response has `"status":"success"`, indicating that the command was successfully received, that does not necessarily indicate that the transaction has taken place. There are many cases that can prevent a transaction from processing successfully, such as a lack of trust lines connecting the two accounts in a payment, or changes in the state of the network since the time the transaction was constructed. Even if nothing is wrong, it may take several seconds to close and validate the ledger version that includes the transaction. See the [full list of transaction responses](https://ripple.com/wiki/Transaction_errors) for details, and do not consider the transaction's results final until they appear in a validated ledger version.
*Warning:* If this command results in an error messages, the message can contain an account secret, if one was provided in the request. (This is not a problem if the request contained a signed tx_blob instead.) Make sure that these errors are not visible to others, including:
__*Caution:*__ If this command results in an error messages, the message can contain an account secret, if one was provided in the request. (This is not a problem if the request contained a signed tx_blob instead.) Make sure that these errors are not visible to others, including:
* Do not write an error including your secret to a log file that can be seen by multiple people
* Do not paste an error including your secret to a public place for debugging
@@ -5721,7 +5721,7 @@ The request includes the following parameters:
| taker_gets | Object | Specification of which currency the account taking the offer would receive, as an object with `currency` and `issuer` fields (omit issuer for XRP), similar to [currency amounts](#specifying-currency-amounts). |
| taker_pays | Object | Specification of which currency the account taking the offer would pay, as an object with `currency` and `issuer` fields (omit issuer for XRP), similar to [currency amounts](#specifying-currency-amounts). |
*Note:* The other parameters of this command -- `marker`, `limit`, `proof`, and `autobridge` -- are not yet fully implemented. (See [RIPD-295](https://ripplelabs.atlassian.net/browse/RIPD-295)).
__*Note:*__ The other parameters of this command -- `marker`, `limit`, `proof`, and `autobridge` -- are not yet fully implemented. (See [RIPD-295](https://ripplelabs.atlassian.net/browse/RIPD-295)).
Normally, offers that are not funded are omitted; however, offers made by the specified `taker` account are always displayed. This allows you to look up your own unfunded offers in order to cancel them with an OfferCancel transaction.
@@ -5885,7 +5885,7 @@ The `streams` parameter provides access to the following default streams of info
* `server` - Sends a message whenever the status of the rippled server (for example, network connectivity) changes
* `ledger` - Sends a message whenever a new ledger version closes
* `transactions` - Sends a message whenever a transaction is included in a closed ledger
* `transactions_proposed` - Sends a message whenever a transaction is included in a closed ledger, as well as some transactions that have not yet been included in a validated ledger and may never be. Not all proposed transactions appear before validation, however. (Note that [even some transactions that don't succeed are included](https://ripple.com/wiki/Transaction_errors#Claimed_fee_only) in validated ledgers, because they take the anti-spam transaction fee.)
* `transactions_proposed` - Sends a message whenever a transaction is included in a closed ledger, as well as some transactions that have not yet been included in a validated ledger and may never be. Not all proposed transactions appear before validation, however. (__*Note:*__ [Even transactions that don't succeed are included](https://ripple.com/wiki/Transaction_errors#Claimed_fee_only) in validated ledgers, because they take the anti-spam transaction fee.)
Each member of the `books` array, if provided, is an object with the following fields: