Merge pull request #68 from mDuo13/gh-pages

REST API tool improvements
This commit is contained in:
Rome Reginelli
2014-09-25 17:59:10 -07:00
7 changed files with 349 additions and 166 deletions

View File

@@ -98,7 +98,7 @@ h2 {
#output {
width: 60%;
}
p, h3 {
h3 {
margin:16px 0;
font-family:'open sans';
font-weight:300;
@@ -150,7 +150,7 @@ p, h3 {
}
#request_options > div {
float:right;
/* float:right;
margin:0;
width:200px;
color:#fff;
@@ -161,23 +161,25 @@ p, h3 {
background-image:linear-gradient(283deg, rgba(255,255,255,0.1) 50%, transparent 55%), linear-gradient(top, rgba(255,255,255,0.15), transparent);
background-image:-webkit-linear-gradient(283deg, rgba(255,255,255,0.1) 50%, transparent 55%), -webkit-linear-gradient(top, rgba(255,255,255,0.15), transparent);
background-image:-moz-linear-gradient(283deg, rgba(255,255,255,0.1) 50%, transparent 55%), -moz-linear-gradient(top, rgba(255,255,255,0.15), transparent);
*/
border-radius:4px;
border-bottom:1px solid #fff;
background-color: #346AA9;
font-weight:300;
font-size:16px;
/* line-height:50px; */
/* line-height:50px;
text-align:center;
cursor:default;
user-select:none;
-webkit-user-select:none;
-moz-user-select:none;
*/
margin-top: 5px;
}
#request_button {
background:#3a87ad;
background-color: #346AA9;
}
#request_button.depressed {
background:#295F7A;
@@ -290,9 +292,9 @@ ul.toolbar li {
border:1px dotted #3a87ad;
}
#selected_command {
/*#selected_command {
margin-top:-32px;
}
}*/
#selected_command a {
text-decoration:none;
@@ -410,7 +412,8 @@ span.cm-atom {
#rest_url_wrapper {
font-family: sans-serif;
display: inline-block;
margin-bottom: -11px;
text-indent: -2em;
padding-left: 2.5em;
}
#rest_url {
@@ -418,4 +421,37 @@ span.cm-atom {
border: 0;
background: none;
font-size:13px;
vertical-align: top;
}
#rest_url .editable {
font-weight: bold;
font-family:'inconsolata',monospace;
border-width: 0 0px 1px 0;
border-style: dotted;
border-color: #aaa;
min-width: 5em;
background: none;
vertical-align: top;
}
#rest_url .non_editable {
vertical-align: top;
}
#rest_url_wrapper p {
margin: 0;
}
#rest_url div {
display: inline-block;
}
#rest_url input {
margin: 0 !important;
}
#rest_url div label,
#rest_url div input {
display: block;
}

View File

@@ -7,6 +7,8 @@ var rest_url = $('#rest_url');
var rest_method = $("#rest_method");
var selected_command = $("#selected_command");
var spinner = $(".loader");
var reminders = $("#rest_url_wrapper .rest_reminders");
var test_warning = $("#test_warning");
var GET = "GET";
var POST = "POST";
@@ -14,6 +16,8 @@ var PUT = "PUT";
var DELETE = "DELETE";
var URL_BASE = "https://api.ripple.com:443";
var DOC_BASE = "ripple-rest.html";
function slugify(str) {
str = str.replace(/^\s+|\s+$/g, ''); // trim
@@ -57,32 +61,46 @@ $(commands).click(function() {
//---------- List of requests ------------------------//
var DEFAULT_ADDRESS_1 = "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn";
var DEFAULT_ADDRESS_2 = "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX";
var DEFAULT_HASH = "9D591B18EDDD34F0B6CF4223A2940AEA2C3CC778925BABF289E0011CD8FA056E";
Request('Generate Account', {
method: GET,
path: "/v1/accounts/new",
description: 'Generate the keys for a potential new account',
link: 'ripple-rest.html#generating-accounts'
link: '#generating-accounts'
});
Request('Get Account Balances', {
method: GET,
path: '/v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/balances',
path: '/v1/accounts/{:address}/balances',
description: 'Retrieve the current balances for the given Ripple account',
link: 'ripple-rest.html#account-balances'
link: '#account-balances',
params: {
"{:address}": DEFAULT_ADDRESS_1
}
});
Request('Get Account Settings', {
method: GET,
path: '/v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/settings',
path: '/v1/accounts/{:address}/settings',
description: 'Retrieve the current settings for the given Ripple account',
link: 'ripple-rest.html#account-settings'
link: '#account-settings',
params: {
"{:address}": DEFAULT_ADDRESS_1
}
});
Request('Update Account Settings', {
method: POST,
path: '/v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/settings',
path: '/v1/accounts/{:address}/settings',
description: 'Change the current settings for the given Ripple account. <span class="btn-danger">Please, only use test accounts here.</span>',
link: 'ripple-rest.html#updating-account-settings',
link: '#updating-account-settings',
test_only: true,
params: {
"{:address}": DEFAULT_ADDRESS_1
},
body: {
secret: "sssssssssssssssssssssssssssss",
settings: {
@@ -97,21 +115,28 @@ Request('Update Account Settings', {
Request('Prepare Payment', {
method: GET,
path: '/v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/payments/paths/ra5nK24KXen9AHvsdFTKHSANinZseWnPcX/1+USD+rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn',
path: '/v1/accounts/{:source_address}/payments/paths/{:destination_address}/{:amount}?{:query_params}',
description: 'Change the current settings for the given Ripple account',
link: 'ripple-rest.html#preparing-a-payment'
link: '#prepare-payment',
params: {
"{:source_address}": DEFAULT_ADDRESS_1,
"{:destination_address}": DEFAULT_ADDRESS_2,
"{:amount}": "1+USD+rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"{:query_params}": "source_currencies=USD"
}
});
Request('Submit Payment', {
method: POST,
path: '/v1/payments',
description: 'Send a prepared payment to the network. <span class="btn-danger">Please, only use test accounts here.</span>',
link: 'ripple-rest.html#submitting-a-payment',
link: '#submitting-a-payment',
test_only: true,
body: {
"secret": "sssssssssssssssssssssssssssss",
"client_resource_id": "348170b9-16b9-4927-854d-7f9d4a2a692d",
"payment": {
"source_account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"source_account": DEFAULT_ADDRESS_1,
"source_tag": "",
"source_amount": {
"value": "1",
@@ -119,12 +144,12 @@ Request('Submit Payment', {
"issuer": ""
},
"source_slippage": "0",
"destination_account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"destination_account": DEFAULT_ADDRESS_2,
"destination_tag": "",
"destination_amount": {
"value": "1",
"currency": "USD",
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn"
"issuer": DEFAULT_ADDRESS_1
},
"invoice_id": "",
"paths": "[]",
@@ -136,30 +161,46 @@ Request('Submit Payment', {
Request("Confirm Payment", {
method: GET,
path: "/v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/payments/9D591B18EDDD34F0B6CF4223A2940AEA2C3CC778925BABF289E0011CD8FA056E",
path: "/v1/accounts/{:address}/payments/{:hash}",
description: "Retrieve details of a payment and its status",
link: "ripple-rest.html#confirming-a-payment"
link: "#confirming-a-payment",
params: {
"{:address}": DEFAULT_ADDRESS_1,
"{:hash}": DEFAULT_HASH
}
});
Request("Get Payment History", {
method: GET,
path: "/v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/payments",
path: "/v1/accounts/{:address}/payments?{:query_params}",
description: "Browse through the history of payments sent and received by an account",
link: "ripple-rest.html#payment-history",
link: "#payment-history",
params: {
"{:address}": DEFAULT_ADDRESS_1,
"{:query_params}": "direction=incoming&exclude_failed=true"
}
});
Request("Get Trustlines", {
method: GET,
path: "/v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/trustlines?currency=USD",
path: "/v1/accounts/{:address}/trustlines?{:query_params}",
description: "Check the status of one or more trustlines attached to an account",
link: "ripple-rest.html#reviewing-trustlines"
link: "#reviewing-trustlines",
params: {
"{:address}": DEFAULT_ADDRESS_1,
"{:query_params}": "currency=USD&counterparty=ra5nK24KXen9AHvsdFTKHSANinZseWnPcX"
}
});
Request("Grant Trustline", {
method: POST,
path: "/v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/trustlines",
path: "/v1/accounts/{:address}/trustlines",
description: "Add or modify a trustline from this account. <span class='btn-danger'>Please, only use test accounts here.</span>",
link: "ripple-rest.html#granting-a-trustline",
link: "#granting-a-trustline",
test_only: true,
params: {
"{:address}": DEFAULT_ADDRESS_1
},
body: {
"secret": "sneThnzgBgxc3zXPG....",
"trustline": {
@@ -173,37 +214,44 @@ Request("Grant Trustline", {
Request("Check Notifications", {
method: GET,
path: "/v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/notifications/9D591B18EDDD34F0B6CF4223A2940AEA2C3CC778925BABF289E0011CD8FA056E",
path: "/v1/accounts/{:address}/notifications/{:hash}",
description: "Browse through the history of payments sent and received by an account",
link: "ripple-rest.html#checking-notifications"
link: "#checking-notifications",
params: {
"{:address}": DEFAULT_ADDRESS_1,
"{:hash}": DEFAULT_HASH
}
});
Request("Check Connection", {
method: GET,
path: "/v1/server/connected",
description: "Check whether the REST server is connected to a rippled server",
link: "ripple-rest.html#check-connection-state"
link: "#check-connection-state"
});
Request("Get Server Status", {
method: GET,
path: "/v1/server",
description: "Retrieve information about the current status of the Ripple-REST server and the rippled server it is connected to",
link: "ripple-rest.html#get-server-status"
link: "#get-server-status"
});
Request("Retrieve Ripple Transaction", {
method: GET,
path: "/v1/tx/85C5E6762DE7969DC1BD69B3C8C7387A5B8FCE6A416AA1F74C0ED5D10F08EADD",
path: "/v1/tx/{:hash}",
description: "Retrieve a raw Ripple transaction",
link: "ripple-rest.html#retrieve-ripple-transaction"
link: "#retrieve-ripple-transaction",
params: {
"{:hash}": DEFAULT_HASH
}
});
Request("Generate UUID", {
method: GET,
path: "/v1/uuid",
description: "Create a universally-unique identifier (UUID) to use as the client resource ID for a payment",
link: "ripple-rest.html#create-client-resource-id"
link: "#create-client-resource-id"
});
//---------- End req. List ---------------------------//
@@ -221,8 +269,13 @@ var cm_response = CodeMirror(response_body.get(0), {
readOnly: true
});
function update_method() {
method = $(this).val();
function update_method(el) {
if (el === undefined) {
method = $(this).val();
} else {
method = $(el).val();
}
if (method == GET || method == DELETE) {
request_body.hide();
} else {
@@ -231,12 +284,47 @@ function update_method() {
}
}
function change_path(command) {
rest_url.empty();
reminders.html("&nbsp;");
var re = /(\{:[^}]+\})/g; // match stuff like {:address}
params = command.path.split(re);
//console.log(params);
for (i=0; i<params.length; i++) {
if (params[i].match(/\{:[^}]+\}/) !== null) {
if (command.params === undefined || command.params[params[i]] === undefined) {
var default_val = params[i];
} else {
var default_val = command.params[params[i]];
}
//rest_url.append("<span class='editable' contenteditable='true' id='resturl_"+params[i]+"'>"+default_val+"</span>");
var new_div = $("<div>").appendTo(rest_url);
var new_param = $("<input type='text' id='resturl_"+params[i]+"' value='"+default_val+"' class='editable' title='"+params[i]+"' />").appendTo(new_div);
new_param.autosizeInput({"space": 0});
//var new_label = $("<label class='reminder' for='resturl_"+params[i]+"'>"+params[i]+"</label>").appendTo(new_div);
} else {
rest_url.append("<span class='non_editable'>"+params[i]+"</span>");
}
}
}
function select_request(request) {
command = requests[request];
if (command.test_only === true) {
test_warning.show();
} else {
test_warning.hide();
}
if (command.description) {
$(description).html($('<a>')
.attr('href', command.link)
.attr('href', DOC_BASE+command.link)
.html(command.description));
$(description).show();
} else {
@@ -244,15 +332,19 @@ function select_request(request) {
}
selected_command.html($('<a>')
.attr('href', command.link)
.attr('href', DOC_BASE+command.link)
.text(command.name));
//rest_url.val(command.path);
rest_url.text(command.path);
//rest_url.text(command.path);
change_path(command);
rest_method.val(command.method);
rest_method.change();
// rest_method.val(command.method);
// rest_method.change();
request_button.val(command.method);
request_button.text(command.method+" request");
update_method(request_button);
if (command.method == POST || command.method == PUT) {
cm_request.setValue(JSON.stringify(command.body, null, 2));
@@ -270,22 +362,33 @@ function get_uuid(callback) {
$.get(URL_BASE + "/v1/uuid").done(callback);
}
function get_path() {
s = "";
rest_url.find(".non_editable, .editable").each(function() {
if (this.tagName == "INPUT") {
s += $(this).val();
} else {
s += $(this).text();
}
});
return s;
}
function send_request() {
var method = rest_method.val();
//var method = rest_method.val();
var method = request_button.val();
if (method != GET && method != POST && method != PUT && method != DELETE) {
console.log("ERROR: unrecognized http method");
return;
}
//var path = rest_url.val();
var path = rest_url.text();
var path = get_path();
$(this).addClass('depressed');
response_body.addClass('obscured');
if (method == PUT || method == POST) {
var body = cm_request.getValue();
console.log(body);
$.ajax({
type: method,
url: URL_BASE + path,
@@ -326,7 +429,7 @@ function reset_response_area() {
$(document).ready(function() {
request_button.click(send_request);
rest_method.change(update_method);
//rest_method.change(update_method);
get_uuid(function(resp,status,xhr) {
requests["submit-payment"].body.client_resource_id = resp.uuid;

1
js/jquery.autosize.input.min.js vendored Normal file
View File

@@ -0,0 +1 @@
var Plugins;(function(n){var t=function(){function n(n){typeof n=="undefined"&&(n=30);this.space=n}return n}(),i;n.AutosizeInputOptions=t;i=function(){function n(t,i){var r=this;this._input=$(t);this._options=$.extend({},n.getDefaultOptions(),i);this._mirror=$('<span style="position:absolute; top:-999px; left:0; white-space:pre;"/>');$.each(["fontFamily","fontSize","fontWeight","fontStyle","letterSpacing","textTransform","wordSpacing","textIndent"],function(n,t){r._mirror[0].style[t]=r._input.css(t)});$("body").append(this._mirror);this._input.on("keydown keyup input propertychange change",function(){r.update()});(function(){r.update()})()}return n.prototype.getOptions=function(){return this._options},n.prototype.update=function(){var n=this._input.val()||"",t;n!==this._mirror.text()&&(this._mirror.text(n),t=this._mirror.width()+this._options.space,this._input.width(t))},n.getDefaultOptions=function(){return this._defaultOptions},n.getInstanceKey=function(){return"autosizeInputInstance"},n._defaultOptions=new t,n}();n.AutosizeInput=i,function(t){var i="autosize-input",r=["text","password","search","url","tel","email","number"];t.fn.autosizeInput=function(u){return this.each(function(){if(this.tagName=="INPUT"&&t.inArray(this.type,r)>-1){var f=t(this);f.data(n.AutosizeInput.getInstanceKey())||(u==undefined&&(u=f.data(i)),f.data(n.AutosizeInput.getInstanceKey(),new n.AutosizeInput(this,u)))}})};t(function(){t("input[data-"+i+"]").autosizeInput()})}(jQuery)})(Plugins||(Plugins={}))

View File

@@ -129,21 +129,25 @@ mixpanel.init("132d42885e094171f34467fc54da6fab");
<div id='io_wrapper'>
<div id='input' class='io'>
<h2>REST Request</h2>
<div id='request_options'>
<div class="button btn btn-primary api" id='request_button'>Send request</div>
<div id='test_warning' class='alert alert-danger' style='display:none;'>
<h4>Test accounts only!</h4>
<p>Never submit account secrets to a server you do not control, unless you are prepared to lose ownership of the account!</p>
</div>
<div style="clear:both;"></div>
<h3 id='selected_command' title='Reference information'></h3>
<p id='description'></p>
<div id='invalid'>Invalid JSON</div>
<select id='rest_method'>
<!-- <select id='rest_method'>
<option value='GET'>GET</option>
<option value='POST'>POST</option>
</select>
</select>-->
<div id='rest_url_wrapper'>
<span id='rest_host'>https://api.ripple.com</span><span id='rest_url' contenteditable='true'></span>
<p><span id='rest_host'>https://api.ripple.com</span><span id='rest_url'></span></p>
</div>
<div id='request_body'></div>
<div id='request_options'>
<div class="button btn btn-primary api" id='request_button'>Send request</div>
</div>
</div>
<div id='output' class='io'>
<h2>Response</h2>
@@ -232,6 +236,7 @@ mixpanel.init("132d42885e094171f34467fc54da6fab");
<script type='text/javascript' src='js/es5-shim.js'></script>
<script src='//cdnjs.cloudflare.com/ajax/libs/codemirror/3.16.0/codemirror.min.js'></script>
<script type='text/javascript' src='js/cm-javascript.min.js'></script>
<script type='text/javascript' src='js/jquery.autosize.input.min.js'></script>
<script type='text/javascript' src='js/apitool-rest.js'></script>

View File

@@ -132,15 +132,15 @@ mixpanel.init("132d42885e094171f34467fc54da6fab");
<div id='io_wrapper'>
<div id='input' class='io'>
<h2>WebSocket Request</h2>
<div id='request_options'>
<div class="button btn btn-primary api" id='request_button'>Send request</div>
</div>
<div style="clear:both;"></div>
<h3 id='selected_command' title='Reference information'>server_info</h3>
<p id='description'></p>
<div id='invalid'>Invalid JSON</div>
<p>JSON</p>
<div id='request'></div>
<div id='request_options'>
<div class="button btn btn-primary api" id='request_button'>Send request</div>
</div>
</div>
<div id='output' class='io'>
<h2>Response</h2>

View File

@@ -1,32 +1,48 @@
# Ripple-REST API #
The `ripple-rest` API makes it easy to access the Ripple system via a RESTful web interface. In this section, we will cover the concepts you need to understand, and get you started accessing the API and learning how to use it.
The Ripple-REST API provides a simplified, easy-to-use interface to the Ripple Network via a RESTful API. This page explains how to use the API to send and receive payments on Ripple.
While there are other APIs to use with Ripple (i.e. Accessing the `rippled` server directly via a web socket), this documentation is meant only for the `ripple-rest` API as this is the high-level API recommended for working with Ripple and some of the endpoints provide abstractions to make it much easier to use than the traditional websocket APIs.
We recommend Ripple-REST for users just getting started with Ripple, since it provides high-level abstractions and convenient simplifications in the data format. If you prefer to access a `rippled` server directly, you can use [rippled's WebSocket or JSON-RPC APIs](rippled-apis.html) instead, which provide the full power of Ripple at the cost of more complexity.
Installation instructions and source code can be found in the `ripple-rest` repository <a href="https://github.com/ripple/ripple-rest" target="_blank">here</a>.
Older versions of the `ripple-rest` documentation will archived <a href="https://github.com/ripple/ripple-dev-portal/archive" target="_blank">here</a>.
Installation instructions and source code can be found in the [Ripple-REST repository](https://github.com/ripple/ripple-rest).
## Available API Routes ##
* [`GET /v1/accounts/new`](#generating-accounts)
* [`GET /v1/accounts/{:address}/payments/paths`](#preparing-a-payment)
* [`GET /v1/accounts/{:address}/payments`](#confirming-a-payment)
* [`GET /v1/accounts/{:address}/balances`](#account-balances)
* [`GET /v1/accounts/{:address}/settings`](#account-settings)
* [`GET /v1/accounts/{:address}/trustlines`](#reviewing-trustlines)
* [`GET /v1/accounts/{:address}/notifications/{:transaction_hash}`](#checking-notifications)
* [`GET /v1/server/connected`](#check-connection-state)
* [`GET /v1/server`](#get-server-status)
* [`GET /v1/tx`](#retrieve-ripple-transaction)
* [`GET /v1/uuid`](#create-client-resource-id)
#### Accounts ####
* [Generate Account - `GET /v1/accounts/new`](#generating-accounts)
* [Get Account Balances - `GET /v1/accounts/{:address}/balances`](#account-balances)
* [Get Account Settings - `GET /v1/accounts/{:address}/settings`](#account-settings)
* [Update Account Settings - `POST /v1/accounts/{:address}/settings`](#updating-account-settings)
#### Payments ####
* [Prepare Payment - `GET /v1/accounts/{:address}/payments/paths`](#prepare-payment)
* [Submit Payment - `POST /v1/payments`](#submitting-a-payment)
* [Confirm Payment - `GET /v1/accounts/{:address}/payments/{:payment}`](#confirming-a-payment)
* [Get Payment History - `GET /v1/accounts/{:address}/payments`](#confirming-a-payment)
#### Trustlines ####
* [Get Trustlines - `GET /v1/accounts/{:address}/trustlines`](#reviewing-trustlines)
* [Grant Trustline - `POST /v1/accounts/{:address}/trustlines`](#granting-a-trustline)
#### Notifications ####
* [Check Notifications - `GET /v1/accounts/{:address}/notifications/{:transaction_hash}`](#checking-notifications)
#### Status ####
* [Check Connection - `GET /v1/server/connected`](#check-connection-state)
* [Get Server Status - `GET /v1/server`](#get-server-status)
#### Utilities ####
* [Retrieve Ripple Transaction - `GET /v1/tx`](#retrieve-ripple-transaction)
* [Generate UUID - `GET /v1/uuid`](#create-client-resource-id)
* [`POST /v1/payments`](#submitting-a-payment)
* [`POST /v1/accounts/{:address}/settings`](#updating-account-settings)
* [`POST /v1/accounts/{:address}/trustlines`](#granting-a-trustline)
## API Overview ##
@@ -34,7 +50,7 @@ Older versions of the `ripple-rest` documentation will archived <a href="https:/
Ripple is a system for making financial transactions. You can use Ripple to send money anywhere in the world, in any currency, instantly and for free.
In the Ripple world, each account is identified by a <a href="https://ripple.com/wiki/Account" target="_blank">Ripple Address</a>. A Ripple address is a string that uniquely identifies an account, for example: `rNsJKf3kaxvFvR8RrDi9P3LBk2Zp6VL8mp`
In the Ripple world, each account is identified by a [Ripple Address](https://ripple.com/wiki/Account). A Ripple address is a string that uniquely identifies an account, for example: `rNsJKf3kaxvFvR8RrDi9P3LBk2Zp6VL8mp`
A Ripple ___payment___ can be sent using Ripple's native currency, XRP, directly from one account to another. Payments can also be sent in other currencies, for example US dollars, Euros, Pounds or Bitcoins, though the process is slightly more complicated.
@@ -60,34 +76,45 @@ Note that when you submit a payment for processing, you have to assign a unique
The Ripple protocol supports multiple types of transactions other than just payments. Transactions are considered to be any changes to the database made on behalf of a Ripple Address. Transactions are first constructed and then submitted to the network. After transaction processing, meta data is associated with the transaction which itemizes the resulting changes to the ledger.
+ Payment: A Payment transaction is an authorized transfer of balance from one address to another. (This maps to rippled's [Payment transaction type](transactions.html#payment))
+ Trustline: A Trustline transaction is an authorized grant of trust between two addresses. (This maps to rippled's [TrustSet transaction type](transactions.html#payment))
+ Setting: A Setting transaction is an authorized update of account flags under a Ripple Account. (This maps to rippled's [AccountSet transaction type](transactions.html#payment))
* Payment: A Payment transaction is an authorized transfer of balance from one address to another. (This maps to rippled's [Payment transaction type](transactions.html#payment))
* Trustline: A Trustline transaction is an authorized grant of trust between two addresses. (This maps to rippled's [TrustSet transaction type](transactions.html#payment))
* Setting: A Setting transaction is an authorized update of account flags under a Ripple Account. (This maps to rippled's [AccountSet transaction type](transactions.html#payment))
## Getting Started ##
### Setup ###
Before you can use the `ripple-rest` API, you will need to have three things:
You don't need to do any setup to retrieve information from a public Ripple-REST server. Ripple Labs hosts a public Ripple-REST server here:
* An installed version of `ripple-rest` running locally or remotely. Instructions on installing `ripple-rest` can be found in the [readme.md file in the Github Repository](https://github.com/ripple/ripple-rest).
`https://api.ripple.com`
* An activated Ripple account. If you don't have a Ripple account, you can use the Ripple web client to create one, as described in the <a href="https://support.ripplelabs.com/hc/en-us/categories/200194196-Set-Up-Activation" target="_blank">online support</a>. Make sure you have a copy of the Ripple address for your account; the address can be found by clicking the *Show Address* button in the __Fund__ tab of the [web client](https://rippletrade.com/).
However, in order to submit payments or other transactions, you need an activated Ripple account. See the [online support](https://support.ripplelabs.com/hc/en-us/categories/200194196-Set-Up-Activation) for how you can create an account using the [Ripple Trade client](https://rippletrade.com/).
* The URL of the server running the `ripple-rest` API that you wish to use. In this documentation, we will assume that the server is installed and running on a server you have connectivity to.
Make sure you know both the account address and the account secret for your account:
* The *address* can be found by clicking the *Show Address* button in the __Fund__ tab of Ripple Trade
* The *secret* is provided when you first create your account. **WARNING: If you submit your secret to a server you do not control, your account can be stolen, along with all the money in it.** We recommend using a test account with very limited funds on the public Ripple-REST server.
As a programmer, you will also need to have a suitable HTTP client library that allows you to make secure HTTP (`HTTPS`) requests. To follow the examples below, you will need to have access to the `curl` command-line tool.
If you want to run your own Ripple-REST server, see the [installation instructions](https://github.com/ripple/ripple-rest/#installing-and-running).
As a programmer, you will also need to have a suitable HTTP client that allows you to make secure HTTP (`HTTPS`) GET and POST requests. There are lots of options, including:
* The [`curl`](http://curl.haxx.se/) commandline utility
* The [Poster Firefox extension](https://addons.mozilla.org/en-US/firefox/addon/poster/)
* The [Postman Chrome extension](https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en)
You can also use the [REST API Tool](rest-api-tool.html) here on the Dev Portal to try out the API.
[Try it! >](rest-api-tool.html)
### Exploring the API ###
Let's start by using `curl` to see if the `ripple-rest` API is currently running. Type the following into a terminal:
A REST API makes resources available via HTTP, the same protocol used by your browser to access the web. This means you can even use your browser to get a response from the API. Try visiting the following URL:
`curl http://[ripple-rest-server]/v1/server`
https://api.ripple.com/v1/server
After a short delay, the following response should be displayed:
The response should be a page with content similar to the following:
```js
{
@@ -120,54 +147,70 @@ After a short delay, the following response should be displayed:
}
```
The `ripple-rest` API conforms to the following general behavior for a web interface:
The `ripple-rest` API conforms to the following general behavior for [RESTful API](http://en.wikipedia.org/wiki/Representational_state_transfer):
* The HTTP method identifies what you are trying to do. Generally, HTTP `GET` requests are used to retrieve information, while HTTP `POST` requests are used to make changes or submit information.
* You make HTTP (or HTTPS) requests to the API endpoint, including the desired resources within the URL itself.
* You make HTTP (or HTTPS) requests to the API endpoint, indicating the desired resources within the URL itself. (The public server, for the sake of security, only accepts HTTPS requests.)
* If more complicated information needs to be sent, it will be included as JSON-formatted data within the body of the HTTP POST request.
* Upon successful completion, the server returns an [HTTP status code](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) of 200 OK, and a `Content-Type` value of `application/json`. The body of the response will be a JSON-formatted object containing the information returned by the endpoint.
* Upon completion, the server will return an HTTP status code of 200 (OK), and a `Content-Type` value of `application/json`. The body of the response will be a JSON-formatted object containing the information returned by the endpoint.
* The returned JSON object will include a `success` field indicating whether the request was successful or not.
As an additional convention, all responses from Ripple-REST contain a `"success"` field with a boolean value indicating whether or not the success
### Errors ###
There are two different ways in which errors are returned by the `ripple-rest` API:
When errors occur, the server returns an HTTP status code in the 400-599 range, depending on the type of error. The body of the response contains more detailed information on the cause of the problem. (*Note:* Old versions of Ripple-REST return 200 OK regardless of the outcome.)
Low-level errors are indicated by the server returning an appropriate HTTP status code. The following status codes are currently supported:
In general, the HTTP status code is indicative of where the problem occurred:
+ `Bad Request (400)` The JSON body submitted is malformed or invalid.
+ `Method Not Accepted (404)` The endpoint is not allowed.
+ `Gateway Timeout (502)` The rippled server is taking to long to respond.
+ `Bad Gateway (504)` The rippled server is non-responsive.
* Codes in the 200-299 range indicate success. (*Note:* Old versions of Ripple-REST return 200 OK even in some failure cases.)
* Codes in the 400-499 range indicate that the request was invalid or incorrect somehow. For example:
* `400 Bad Request` occurs if the JSON body is malformed. This includes syntax errors as well as when invalid or mutually-exclusive options are selected.
* `404 Not Found` occurs if the path specified does not exist, or does not support that method (for example, trying to POST to a URL that only serves GET requests)
* Codes in the 500-599 range indicate that the server experienced a problem. This could be due to a network outage or a bug in the software somewhere. For example:
* `502 Bad Gateway` occurs if Ripple-REST could not contact its `rippled` server at all.
* `504 Gateway Timeout` occurs if the `rippled` server took too long to respond to the Ripple-REST server.
Application-level errors are described further in the body of the JSON response with the following fields:
When possible, the server provides a JSON response body with more information about the error. These responses contain the following fields:
+ `success` This will be set to `false` if an error occurred.
+ `error` A short string identifying the error that occurred.
+ `message` A longer human-readable string explaining what went wrong.
| Field | Value | Description |
|-------|-------|-------------|
|`success` | Boolean | `false` indicates that an error occurred. |
| `error_type` | String | A short string identifying the error that occurred. |
| `message` | String | A longer human-readable string explaining what went wrong. |
### API Objects ###
# Formatting Conventions #
#### <a id="amount_object"></a> 1. Amount ####
## Quoted Numbers ##
In any case where a large number should be specified, Ripple-REST uses a string instead of the native JSON number type. This avoids problems with JSON libraries which might automatically convert numbers into native types with differing range and precision.
You should parse these numbers into a numeric data type with adequate precision. If it is not clear how much precision you need, we recommend using an arbitrary-precision data type.
## <a id="amount_object"></a> Currency Amounts ##
All currencies on the Ripple Network have issuers, except for XRP. In the case of XRP, the `issuer` field may be omitted or set to `""`. Otherwise, the `issuer` must be a valid Ripple address of the gateway that issues the currency.
For more information about XRP see [the Ripple wiki page on XRP](https://ripple.com/wiki/XRP). For more information about using currencies other than XRP on the Ripple Network see [the Ripple wiki page for gateways](https://ripple.com/wiki/Ripple_for_Gateways).
Amount Object:
### Amounts in JSON ###
When an amount of currency (or other asset) is specified as part of a JSON body, it is encoded as an object with three fields:
| Field | Value | Description |
|-------|-------|-------------|
| value | String (Quoted decimal) | The quantity of the currency |
| currency | String | Three-digit [ISO 4217 Currency Code](http://www.xe.com/iso4217.php) specifying which currency |
| issuer | String | The Ripple address of the account issuing the currency. This is usually an [issuing gateway](https://wiki.ripple.com/Gateway_List). Always an empty string for XRP. |
Example Amount Object:
```js
{
"value": "1.0",
"currency": "USD",
"issuer": "r..."
"issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q"
}
```
@@ -181,54 +224,30 @@ or for XRP:
}
```
#### <a id="payment_object"></a> 2. Payment ####
The `value` field can get very large or very small. See the [Currency Format](https://wiki.ripple.com/Currency_Format) for the exact limits of Ripple's precision.
### Amounts in URLs ###
When an amount of currency has to be specified in a URL, you use the same fields as the JSON object -- value, currency, and issuer -- but concatenate them with `+` symbols.
Example Amount:
`1.0+USD+rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q`
When specifying an amount of XRP, you can omit the issuer entirely. For example:
`1.0+XRP`
## <a id="payment_object"></a> Payment Objects ##
The `Payment` object is a simplified version of the standard Ripple transaction format.
This `Payment` format is intended to be straightforward to create and parse, from strongly or loosely typed programming languages. Once a transaction is processed and validated it also includes information about the final details of the payment.
<!-- A minimal `Payment` object will look like this:
An example Payment object looks like this:
```js
{
"src_address": "rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz",
"dst_address": "rNw4ozCG514KEjPs5cDrqEcdsi31Jtfm5r",
"dst_amount": {
"value": "0.001",
"currency": "XRP",
"issuer": ""
}
}
```
-->
+ `source_address` is the Ripple address for the source account, as a string.
+ `destination_address` is the Ripple address for the destination account, as a string.
+ `destination_amount` is an [Amount](#amount_object) object representing the amount that should be deposited into the destination account.
The full set of fields accepted on `Payment` submission is as follows:
+ `source_tag` is an optional unsigned 32 bit integer (0-4294967294, inclusive) that is generally used if the sender is a hosted wallet at a gateway. This should be the same as the `destination_tag` used to identify the hosted wallet when they are receiving a payment.
+ `destination_tag` is an optional unsigned 32 bit integer (0-4294967294, inclusive) that is generally used if the receiver is a hosted wallet at a gateway.
+ `source_slippage` can be specified to give the `source_amount` a cushion and increase its chance of being processed successfully. This is helpful if the payment path changes slightly between the time when a payment options quote is given and when the payment is submitted. The `source_address` will never be charged more than `source_slippage` + the `value` specified in `source_amount`.
+ `invoice_id` is an optional 256-bit hash field that can be used to link payments to an invoice or bill.
+ `paths` is a "stringified" version of the Ripple PathSet structure. Most users of this API will want to treat this field as opaque. See the [Ripple Wiki](https://ripple.com/wiki/Payment_paths) for more information about Ripple pathfinding.
+ `flag_no_direct_ripple` is a boolean that can be set to `true` if `paths` are specified and the sender would like the Ripple Network to disregard any direct paths from the `source_address` to the `destination_address`. This may be used to take advantage of an arbitrage opportunity or by gateways wishing to issue balances from a hot wallet to a user who has mistakenly set a trustline directly to the hot wallet. Most users will not need to use this option.
+ `flag_partial_payment` is a boolean that, if set to true, indicates that this payment should go through even if the whole amount cannot be sent because of a lack of liquidity or funds in the `source_address` account. The vast majority of senders will never need to use this option.
Payment Object:
```js
{
/* User Specified */
"source_address": "rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz",
"source_tag": "",
@@ -245,43 +264,62 @@ Payment Object:
"currency": "XRP",
"issuer": ""
},
/* Advanced Options */
"invoice_id": "",
"paths": "[]",
"flag_no_direct_ripple": false,
"flag_partial_payment": false
}
```
The fields of a Payment object are defined as follows:
| Field | Value | Description |
|-------|-------|-------------|
| `source_address` | String | The Ripple address of the account sending the payment |
| `destination_address` | String |The Ripple address of the account receiving the payment |
| `destination_amount` | [Amount Object](#amount_object) | The amount of currency that should be deposited into the account receiving the payment. |
| `source_tag` | Unsigned Integer | (Optional) A 32-bit unsigned integer (0-4294967294, inclusive) that is generally used if the sender is a hosted wallet at a gateway. This should be the same as the `destination_tag` used to identify the hosted wallet when they are receiving a payment. |
| `destination_tag` | Unsigned Integer | (Optional) A 32-bit unsigned integer (0-4294967294, inclusive) that is generally used if the recipient of the payment is a hosted wallet at a gateway. |
| `source_slippage` | String (Quoted decimal number) | can be specified to give the `source_amount` a cushion and increase its chance of being processed successfully. This is helpful if the payment path changes slightly between the time when a payment options quote is given and when the payment is submitted. The `source_address` will never be charged more than `source_slippage` + the `value` specified in `source_amount`. |
| `invoice_id` | String | (Optional) 256-bit hash that can be used to link payments to an invoice or bill. |
| `paths` | String | A "stringified" version of the Ripple PathSet structure. You can get a path for your payment from the [Prepare Payment](#prepare-payment) method. |
| `flag_no_direct_ripple` | Boolean | (Optional, defaults to false) `true` if `paths` are specified and the sender would like the Ripple Network to disregard any direct paths from the `source_address` to the `destination_address`. This may be used to take advantage of an arbitrage opportunity or by gateways wishing to issue balances from a hot wallet to a user who has mistakenly set a trustline directly to the hot wallet. Most users will not need to use this option. |
| `flag_partial_payment` | Boolean | (Optional, defaults to false) If set to `true`, fees will be deducted from the delivered amount instead of the sent amount. (*Caution:* There is no minimum amount that will actually arrive as a result of using this flag; only a miniscule amount may actually be received.) See [Partial Payments](transactions.html#partial-payments) |
# PAYMENTS #
`ripple-rest` provides access to `ripple-lib`'s robust transaction submission processes. This means that it will set the fee, manage the transaction sequence numbers, sign the transaction with your secret, and resubmit the transaction up to 10 times if `rippled` reports an initial error that can be solved automatically.
## Making Payments ##
## Payments ##
### Preparing a Payment ###
## Prepare Payment ##
__GET /v1/accounts/{:address}/payments/paths/{:destination_account}/{:destination_amount}__
[Try it! >](rest-api-tool.html#prepare-payment)
To prepare a payment, you first make an HTTP `GET` call to the above endpoint. This will generate a list of possible payments between the two parties for the desired amount, taking into account the established trustlines between the two parties for the currency being transferred. You can then choose one of the returned payments, modify it if necessary (for example, to set slippage values or tags), and then submit the payment for processing.
Before you make a payment, it is necessary to figure out the possible ways in which that payment can be made. This method gets a list possible ways to make a payment, but it does not affect the network: consider it like getting quotes before actually making the payment.
You can then choose one of the returned payment objects, modify it as desired (for example, to set slippage values or tags), and then submit the payment for processing.
The following URL parameters are required by this API endpoint:
+ `address` *[required]* The Ripple address for the source account.
+ `destination_account` *[required]* The Ripple address for the destination account.
+ `destination_amount` *[required]* The amount to be sent to the destination account. Note that this value uses `+` characters to separate the `value`, `currency` and `issuer` fields.
+ For XRP, the format is: `0.1+XRP`
| Field | Value | Description |
|-------|-------|-------------|
| `address` | String | The Ripple address for the account that would send the payment. |
| `destination_account` | String | The Ripple address for the account that would receive the payment. |
| `destination_amount` | String ([URL-formatted Amount](#amounts-in-urls) | The amount that the destination account should receive. |
+ For other currencies, you need to include the Ripple address of the currency's issuer, like this: `0.1+USD+r...`
Optionally, you can also include the following as a query parameter:
Optionally, you can also include the following as a query string parameter:
| Field | Value | Description |
|-------|-------|-------------|
| `source_currencies` | Comma-separated list of source currencies. Each should be an [ISO 4217 currency code](http://www.xe.com/iso4217.php), or a `{:currency}+{:issuer}` string. | Filters possible payments to include only ones that spend the source account's balances in the specified currencies. If an issuer is not specified, include all issuances of that currency held by the sending account. |
`source_currencies` *[optional]* A comma-separated list of source currencies. This is used to filter the returned list of possible payments. Each source currency can be specified either as a currency code (eg, `USD`), or as a currency code and issuer (eg, `USD+r...`). If the issuer is not specified for a currency other than XRP, then the results will be limited to the specified currency, but any issuer for that currency will be included in the results.
This method effectively performs a [ripple_path_find](rippled-apis.html#ripple-path-find) and constructs a payment object for the paths it finds.
Note that this call is a wrapper around the [Ripple path-find](https://ripple.com/wiki/RPC_API#path_find) command, and returns an array of [`Payment`](#payment_object) objects, like this:
Response Body:
```js
{

View File

@@ -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 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 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: