WS tool: all methods, curl syntax, permalinks

This commit is contained in:
mDuo13
2019-06-04 19:40:47 -07:00
parent f2c09af5a8
commit a100a2b707
3 changed files with 508 additions and 48 deletions

View File

@@ -1,4 +1,4 @@
Request("ACCOUNT METHODS");
Request("Account Methods");
Request('account_channels', {
description: "Returns information about an account's <a href='payment-channels.html'>payment channels</a>.",
@@ -22,3 +22,396 @@ Request('account_currencies', {
"ledger_index": "validated"
}
})
Request('account_info', {
description: "Retrieves information about an account, its activity, and its XRP balance.",
link: "account_info.html",
body: {
"id": 2,
"command": "account_info",
"account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"strict": true,
"ledger_index": "current",
"queue": true
}
})
Request('account_objects', {
description: "Returns the raw ledger format for all objects owned by an account.",
link: "account_objects.html",
body: {
"id": 1,
"command": "account_objects",
"account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"ledger_index": "validated",
"type": "state",
"limit": 10
}
})
Request('account_offers', {
description: "Retrieves a list of offers made by a given account that are outstanding as of a particular ledger version.",
link: "account_offers.html",
body: {
"id": 2,
"command": "account_offers",
"account": "rpP2JgiMyTF5jR5hLG3xHCPi1knBb1v9cM"
}
})
Request('account_tx', {
description: "Retrieves a list of transactions that affected the specified account.",
link: "account_tx.html",
body: {
"id": 2,
"command": "account_tx",
"account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"ledger_index_min": -1,
"ledger_index_max": -1,
"binary": false,
"limit": 2,
"forward": false
}
})
Request('gateway_balances', {
description: "Calculates the total balances issued by a given account, optionally excluding amounts held by operational addresses.",
link: "gateway_balances.html",
body: {
"id": "example_gateway_balances_1",
"command": "gateway_balances",
"account": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q",
"strict": true,
"hotwallet": ["rKm4uWpg9tfwbVSeATv4KxDe6mpE9yPkgJ","ra7JkEzrgeKHdzKgo4EUUVBnxggY4z37kt"],
"ledger_index": "validated"
}
})
Request('noripple_check', {
description: "Compares an account's DefaultRipple and NoRipple flags to the recommended settings.",
link: "noripple_check.html",
body: {
"id": 0,
"command": "noripple_check",
"account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"role": "gateway",
"ledger_index": "current",
"limit": 2,
"transactions": true
}
})
Request("Ledger Methods")
Request('ledger', {
description: "Retrieves information about the public ledger.",
link: "ledger.html",
body: {
"id": 14,
"command": "ledger",
"ledger_index": "validated",
"full": false,
"accounts": false,
"transactions": false,
"expand": false,
"owner_funds": false
}
})
Request('ledger_closed', {
description: "Returns the unique identifiers of the most recently closed ledger. (This ledger is not necessarily validated and immutable yet.)",
link: "ledger_closed.html",
body: {
"id": 2,
"command": "ledger_closed"
}
})
Request('ledger_current', {
description: "Returns the unique identifiers of the current in-progress ledger.",
link: "ledger_closed.html",
body: {
"id": 2,
"command": "ledger_current"
}
})
Request('ledger_data', {
description: "Retrieves contents of the specified ledger.",
link: "ledger_data.html",
body: {
"id": 2,
"ledger_hash": "842B57C1CC0613299A686D3E9F310EC0422C84D3911E5056389AA7E5808A93C8",
"command": "ledger_data",
"limit": 5,
"binary": true
}
})
Request('ledger_entry', {
description: "Returns a single ledger object in its raw format.",
link: "ledger_entry.html",
body: {
"id": 3,
"command": "ledger_entry",
"type": "account_root",
"account_root": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"ledger_index": "validated"
}
})
Request("Transaction Methods")
// TODO: maybe special case sign/sign_for so you can use those if you're
// connected to a local server?
Request('submit', {
description: "Submits a transaction to the network to be confirmed and included in future ledgers.",
link: "submit.html",
body: {
"id": 3,
"command": "submit",
"tx_blob": "1200002280000000240000001E61D4838D7EA4C6800000000000000000000000000055534400000000004B4E9C06F24296074F7BC48F92A97916C6DC5EA968400000000000000B732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7447304502210095D23D8AF107DF50651F266259CC7139D0CD0C64ABBA3A958156352A0D95A21E02207FCF9B77D7510380E49FF250C21B57169E14E9B4ACFD314CEDC79DDD0A38B8A681144B4E9C06F24296074F7BC48F92A97916C6DC5EA983143E9D4A2B8AA0780F682D136F7A56D6724EF53754"
}
})
Request('submit_multisigned', {
description: "Submits a multi-signed transaction to the network to be confirmed and included in future ledgers.",
link: "submit_multisigned.html",
body: {
"id": "submit_multisigned_example",
"command": "submit_multisigned",
"tx_json": {
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Fee": "30000",
"Flags": 262144,
"LimitAmount": {
"currency": "USD",
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value": "100"
},
"Sequence": 2,
"Signers": [{
"Signer": {
"Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SigningPubKey": "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
"TxnSignature": "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
}
}, {
"Signer": {
"Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SigningPubKey": "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
"TxnSignature": "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
}
}],
"SigningPubKey": "",
"TransactionType": "TrustSet",
"hash": "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6"
}
}
})
Request('transaction_entry', {
description: "Retrieves information on a single transaction from a specific ledger version.",
link: "transaction_entry.html",
body: {
"id": 4,
"command": "transaction_entry",
"tx_hash": "E08D6E9754025BA2534A78707605E0601F03ACE063687A0CA1BDDACFCD1698C7",
"ledger_index": 348734
}
})
Request('tx', {
description: "Retrieves information on a single transaction.",
link: "tx.html",
body: {
"id": 1,
"command": "tx",
"transaction": "E08D6E9754025BA2534A78707605E0601F03ACE063687A0CA1BDDACFCD1698C7",
"binary": false
}
})
Request('tx_history', {
description: "Retrieves some of the most recent transactions made. (DEPRECATED)",
link: "tx_history.html",
body: {
"id": 5,
"command": "tx_history",
"start": 0
}
})
Request("Path and Order Book Methods")
Request('book_offers', {
description: "Retrieves a list of offers, also known as the order book, between two currencies.",
link: "book_offers.html",
body: {
"id": 4,
"command": "book_offers",
"taker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"taker_gets": {
"currency": "XRP"
},
"taker_pays": {
"currency": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
},
"limit": 10
}
})
Request('deposit_authorized', {
description: "Checks whether one account is authorized to send payments directly to another.",
link: "deposit_authorized.html",
body: {
"id": 1,
"command": "deposit_authorized",
"source_account": "rEhxGqkqPPSxQ3P25J66ft5TwpzV14k2de",
"destination_account": "rsUiUMpnrgxQp24dJYZDhmV4bE3aBtQyt8",
"ledger_index": "validated"
}
})
Request('path_find', {
description: "Searches for a path along which a payment can possibly be made, and periodically sends updates when the path changes over time.",
link: "path_find.html",
body: {
"id": 8,
"command": "path_find",
"subcommand": "create",
"source_account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"destination_account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"destination_amount": {
"value": "0.001",
"currency": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
}
})
Request('ripple_path_find', {
description: "Searches one time for a payment path.",
link: "ripple_path_find.html",
body: {
"id": 8,
"command": "ripple_path_find",
"source_account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"source_currencies": [
{
"currency": "XRP"
},
{
"currency": "USD"
}
],
"destination_account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"destination_amount": {
"value": "0.001",
"currency": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
}
})
Request("Payment Channel Methods")
Request('channel_authorize', {
description: "Creates a signature that can be used to redeem a specific amount of XRP from a payment channel.",
link: "channel_authorize.html",
body: {
"id": "channel_authorize_example_id1",
"command": "channel_authorize",
"channel_id": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"secret": "s████████████████████████████",
"amount": "1000000"
}
})
Request('channel_verify', {
description: "Checks the validity of a signature that can be used to redeem a specific amount of XRP from a payment channel.",
link: "channel_verify.html",
body: {
"id": 1,
"command": "channel_verify",
"channel_id": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"signature": "304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064",
"public_key": "aB44YfzW24VDEJQ2UuLPV2PvqcPCSoLnL7y5M1EzhdW4LnK5xMS3",
"amount": "1000000"
}
})
Request("Subscription Methods")
Request('subscribe', {
description: "Requests periodic notifications from the server when certain events happen.",
link: "subscribe.html",
body: {
"id": "Example watch one account and all new ledgers",
"command": "subscribe",
"streams": ["ledger"],
"accounts": ["rrpNnNLKrartuEqfJGpqyDwPj1AFPg9vn1"]
}
})
Request('unsubscribe', {
description: "Tells the server to stop sending messages for a particular subscription or set of subscriptions.",
link: "unsubscribe.html",
body: {
"id": "Example stop watching one account and new ledgers",
"command": "unsubscribe",
"streams": ["ledger"],
"accounts": ["rrpNnNLKrartuEqfJGpqyDwPj1AFPg9vn1"]
}
})
Request("Server Info Methods")
Request('fee', {
description: "Reports the current state of the open-ledger requirements for the transaction cost.",
link: "fee.html",
body: {
"id": "fee_websocket_example",
"command": "fee"
}
})
Request('server_info', {
description: "Reports a human-readable version of various information about the rippled server being queried.",
link: "server_info.html",
body: {
"id": 1,
"command": "server_info"
}
})
Request('server_state', {
description: "Reports a machine-readable version of various information about the rippled server being queried.",
link: "server_state.html",
body: {
"id": 1,
"command": "server_state"
}
})
Request("Utility Methods")
Request('ping', {
description: "Checks that the connection is working.",
link: "ping.html",
body: {
"id": 1,
"command": "ping"
}
})
Request('random', {
description: "Provides a random number, which may be a useful source of entropy for clients.",
link: "random.html",
body: {
"id": 1,
"command": "random"
}
})

View File

@@ -5,11 +5,9 @@ const request_button = $('.send-request')
const conn_btn = $(".connection")
const stream_pause = $(".stream-pause")
const stream_unpause = $(".stream-unpause")
const GET = "GET"
const POST = "POST"
const PUT = "PUT"
const DELETE = "DELETE"
const trash_button = $(".wipe-responses")
const permalink_button = $(".permalink")
const curl_button = $(".curl")
let STREAM_PAUSED = false
@@ -59,17 +57,17 @@ function generate_table_of_contents() {
}
function make_commands_clickable() {
commandlist.children("li").click(function() {
var cmd = slugify($(this).text().trim());
commandlist.children("li").click(function() {
var cmd = slugify($(this).text().trim());
if (!requests[cmd]) return;
if (!requests[cmd]) return;
select_request(cmd, true);
window.location.hash = cmd;
select_request(cmd);
window.location.hash = cmd;
$(this).siblings().removeClass('selected');
$(this).addClass('selected');
});
$(this).siblings().removeClass('selected');
$(this).addClass('selected');
});
}
const cm_request = CodeMirror(request_body.get(0), {
@@ -81,16 +79,17 @@ const cm_request = CodeMirror(request_body.get(0), {
})
function select_request(request) {
let el
if (request === undefined) {
var el = commandlist.children("li:not(.separator)").eq(0)
request = slugify(el.text())
el = commandlist.children("li:not(.separator)").eq(0)
const request = slugify(el.text())
} else {
var el = commandlist.find("li a[href='#"+request+"']").parent()
el = commandlist.find("li a[href='#"+request+"']").parent()
}
$(el).siblings().removeClass('selected');
$(el).addClass('selected');
command = requests[request];
const command = requests[request];
if (command.description) {
$(".api-method-description-wrapper .blurb").html(command.description)
@@ -117,7 +116,7 @@ function select_request(request) {
};
function send_request() {
if (typeof socket === "undefined" || socket.readyState !== 1) {
if (typeof socket === "undefined" || socket.readyState !== WebSocket.OPEN) {
alert("Can't send request: Must be connected first!")
return
}
@@ -136,6 +135,9 @@ function send_request() {
let socket;
function connect_socket() {
if (typeof socket !== "undefined" && socket.readyState < 2) {
socket.close()
}
$(".connect-loader").show()
const selected_server_el = $("input[name='wstool-1-connection']:checked")
const conn_url = selected_server_el.val()
@@ -149,9 +151,8 @@ function connect_socket() {
$(".connect-loader").hide()
})
socket.addEventListener('close', (event) => {
const new_conn_url = $("input[name='wstool-1-connection']:checked").val()
const new_conn_url = get_current_server()
if (event.wasClean && event.originalTarget.url == new_conn_url) {
console.log("socket clean:", event, "vs", new_conn_url)
conn_btn.text(selected_server_el.data("shortname") + " (Not Connected)")
conn_btn.removeClass("btn-success")
conn_btn.removeClass("btn-danger")
@@ -162,7 +163,7 @@ function connect_socket() {
}
})
socket.addEventListener('error', (event) => {
const new_conn_url = $("input[name='wstool-1-connection']:checked").val()
const new_conn_url = get_current_server()
if (event.originalTarget.url == new_conn_url) {
console.error("socket error:", event)
conn_btn.text(selected_server_el.data("shortname") + " (Failed to Connect)")
@@ -216,35 +217,105 @@ function connect_socket() {
})
}
handle_select_server = function(event) {
const handle_select_server = function(event) {
if (typeof socket !== "undefined") { socket.close(1000) }
connect_socket()
response_wrapper.empty()
}
function get_compressed_body() {
let compressed_body;
try {
const body_json = JSON.parse(cm_request.getValue())
compressed_body = JSON.stringify(body_json, null, null)
} catch(e) {
// Probably invalid JSON. We'll make a permalink anyway, but we can't
// compress all the whitespace because we don't know what's escaped. We can
// assume that newlines are irrelevant because the rippled APIs don't accept
// newlines in strings anywhere
compressed_body = cm_request.getValue().replace("\n","").trim()
}
return compressed_body
}
function get_current_server() {
return $("input[name='wstool-1-connection']:checked").val()
}
const update_permalink = function(event) {
const start_href = window.location.origin + window.location.pathname
const encoded_body = encodeURIComponent(get_compressed_body())
const encoded_server = encodeURIComponent(get_current_server())
let permalink = start_href + "?server=" + encoded_server + "&req=" + encoded_body
// Future Feature: set the hash if the command matches a known method
$("#permalink-box-1").text(permalink)
}
const update_curl = function(event) {
let body
try {
// change WS to JSON-RPC syntax
params = JSON.parse(cm_request.getValue())
delete params.id
const method = params.command
delete params.command
const body_json = {"method":method, "params":[params]}
body = JSON.stringify(body_json, null, null)
} catch(e) {
alert("Can't provide curl format of invalid JSON syntax")
return
}
const server = $("input[name='wstool-1-connection']:checked").data("jsonrpcurl")
const curl_syntax = "curl -H 'Content-Type: application/json' -d '"+body+"' "+server
$("#curl-box-1").text(curl_syntax)
}
function load_from_permalink(params) {
const server = params.get("server")
if (server) {
const server_checkbox = $("input[value='"+server+"']")
if (server_checkbox.length === 1) {
server_checkbox.prop("checked", true)
// relies on connect_socket() being run shortly thereafter
}
}
let req_body = params.get("req")
if (req_body) {
try {
req_body_json = JSON.parse(req_body)
req_body = JSON.stringify(req_body_json, null, 2)
} catch(e) {
console.warn("Loaded request body is invalid JSON:", e)
}
cm_request.setValue(req_body)
}
}
$(document).ready(function() {
//wait for the Requests to be populated by another file
generate_table_of_contents();
make_commands_clickable();
generate_table_of_contents()
make_commands_clickable()
const search_params = new URLSearchParams(window.location.search)
if (window.location.hash) {
var cmd = window.location.hash.slice(1).toLowerCase();
select_request(cmd);
} else if (search_params.has("server") || search_params.has("req")) {
load_from_permalink(search_params)
} else {
select_request();
}
// TODO: permalink stuff here?
// if (urlParams["base_url"]) {
// //TODO: change_base_url(urlParams["base_url"]);
// }
connect_socket()
request_button.click(send_request);
request_button.click(send_request)
$("input[name='wstool-1-connection']").click(handle_select_server)
stream_pause.click((event) => {
STREAM_PAUSED = true
@@ -257,17 +328,10 @@ $(document).ready(function() {
stream_unpause.hide()
})
trash_button.click((event) => {
response_wrapper.empty()
})
permalink_button.click(update_permalink)
curl_button.click(update_curl)
});
var urlParams;
(window.onpopstate = function () {
var match,
pl = /\+/g, // Regex for replacing addition symbol with a space
search = /([^&=]+)=?([^&]*)/g,
decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
query = window.location.search.substring(1);
urlParams = {};
while (match = search.exec(query))
urlParams[decode(match[1])] = decode(match[2]);
})();

View File

@@ -61,6 +61,9 @@
<button class="btn btn-outline-secondary stream-unpause" title="Unpause Subscriptions" style="display:none;">
<i class="fa fa-play"></i>
</button>
<button class="btn btn-outline-secondary wipe-responses" title="Delete All Responses">
<i class="fa fa-trash"></i>
</button>
</div><!--/.btn-group-->
</div><!--/.btn-toolbar.response-options-->
@@ -87,25 +90,25 @@
<div class="modal-body">
<div class="form-check">
<input class="form-check-input" type="radio" name="wstool-1-connection" id="wstool-1-connection-s1" value="wss://s1.ripple.com/" data-shortname="Main Net" checked>
<input class="form-check-input" type="radio" name="wstool-1-connection" id="wstool-1-connection-s1" value="wss://s1.ripple.com/" data-jsonrpcurl="https://s1.ripple.com:51234/" data-shortname="Main Net" checked>
<label class="form-check-label" for="wstool-1-connection-s1">
s1.ripple.com (Main Net Public Server)
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="wstool-1-connection" id="wstool-1-connection-s2" value="wss://s2.ripple.com/" data-shortname="Full History">
<input class="form-check-input" type="radio" name="wstool-1-connection" id="wstool-1-connection-s2" value="wss://s2.ripple.com/" data-jsonrpcurl="https://s2.ripple.com:51234/" data-shortname="Full History">
<label class="form-check-label" for="wstool-1-connection-s2">
s2.ripple.com (Full History Public Server)
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="wstool-1-connection" id="wstool-1-connection-testnet" value="wss://s.altnet.rippletest.net:51233/" data-shortname="Test Net">
<input class="form-check-input" type="radio" name="wstool-1-connection" id="wstool-1-connection-testnet" value="wss://s.altnet.rippletest.net:51233/" data-jsonrpcurl="https://s.altnet.rippletest.net:51234/" data-shortname="Test Net">
<label class="form-check-label" for="wstool-1-connection-testnet">
s.altnet.rippletest.net (Test Net Public Server)
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="wstool-1-connection" id="wstool-1-connection-localhost" value="ws://localhost:6006/" data-shortname="Local server">
<input class="form-check-input" type="radio" name="wstool-1-connection" id="wstool-1-connection-localhost" value="ws://localhost:6006/" data-jsonrpcurl="http://localhost:5005/" data-shortname="Local server">
<label class="form-check-label" for="wstool-1-connection-localhost">
localhost:6006 (Local <code>rippled</code> Server on port 6006) <br/>
<small>(Requires that you <a href="install-rippled.html">run <code>rippled</code></a> on this machine with default WebSocket settings)</small>