diff --git a/content/demurrage.md b/content/demurrage.md deleted file mode 100644 index 467620d76b..0000000000 --- a/content/demurrage.md +++ /dev/null @@ -1,241 +0,0 @@ -Demurrage in Ripple Currencies -============================== - -[Demurrage](http://en.wikipedia.org/wiki/Demurrage_%28currency%29) is a -negative interest rate on assets held that represents the cost of -holding those assets. Ripple supports currencies that have interest or -demurrage rates built into the currency definition, such as -"XAU (-0.5%pa)". Each currency-rate combination is treated as a completely -distinct currency for purposes of pathfinding and order books. - -A gateway that wants to charge demurrage for holding assets (such as -gold) can issue a custom currency representing that asset with the -demurrage rate built-in. This is reflected in a different hex -representation for the demurraging currency. Client applications should -represent a demurraging currency by displaying the negative annual -percentage rate along with the currency code. - -XRP cannot have demurrage or interest. - -Dealing with Demurraging Currencies ------------------------------------ - -The rippled server, and consequently the official global ledger, do not -track changes in value due to demurrage in the balance of funds. This -allows demurrage costs to be applied continuously, instead of operating -on fixed intervals. It also prevents demurrage from inflicting -significant additional computational and storage load for servers that -are part of the network. Instead, the fact that particular holdings are -subject to demurrage is tracked in the ledger by virtue of the custom -currency codes. Demurrage is calculated on the entire currency as if it -were interest, according to the following formula: - -D = A \* ( e \^ (t/ τ) ) - -where: - -- D is the amount after demurrage -- A is the pre-demurrage amount as recorded in the global ledger -- e is Euler's number -- t is the number of seconds since the [Ripple - Epoch](rippled-apis.html#specifying-time) (0:00 on January 1, 2000 - UTC) -- τ is the [e-folding time](http://en.wikipedia.org/wiki/E-folding) in - seconds. This value is calculated from the desired interest rate. - -You can think of demurrage in the Ripple Network as similar to -inflation, where the value of all assets affected by it decreases over -time, but the ledger always holds amounts in year-2000 values. (This -representation was chosen as a simplification of the more complicated -representation where individual holdings could track when the demurrage -on them started accruing, because this way it becomes easier to -recognize, exchange, and represent assets with demurrage applied.) Keep -in mind, this does not reflect actual, real-world inflation: instead, -it's hypothetical inflation at a constant rate. - -### Calculating e-folding time - -It is simple to calculate from a targeted demurrage rate in annual -percent to get a τ value to use in calculating demurrage: - -1. First, subtract the demurrage percentage rate from 100% to get the - percentage of initial amount that remains after annual demurrage. - Represent it as a decimal. For example, for 0.5% annual interest, - you would get 0.995 -2. Now, take the natural log of that number. For example, ln(0.995). - For traditional demurrage (decrease in value over time), this value - will be negative. -3. Finally, take the number of seconds in one year (31536000) and - divide by the result of the natural log operation. The result is - your e-folding time in seconds, for example -6291418827.045599 - -If you're curious: Since an e-folding amount represents how long until -an investment increases e times, a negative interest rate means that the -investment would have been worth e times its value that amount of time -in the past. Alternatively, it means that after that amount of seconds, -the investment will be worth 1/e of what it used to be. - -### Canonical Calculations - -For purposes of calculating demurrage consistently across applications, -the precision used is important. Our canonical source of demurrage -calculations is ripple-lib. By following these specifications, you -should be able to reproduce the demurrage results from ripple-lib -exactly: - -First, recall the canonical formula for demurrage: - -D = A \* ( e \^ (t/ τ) ) - -where D is the post-demurrage amount, and A is the pre-demurrage amount. -For the remainder of the formula, e \^ (t/ τ), we call this the -"demurrage coefficient". The demurrage coefficient is always relative to -a specific time, such that demurrage is calculated for the period -starting at the beginning of the Ripple Epoch (00:00:00 January 1, 2000) - -The two directional calculations can therefore be simplified to: - -1. Find the demurrage coefficient for the reference time -2. Apply it to the amount to convert - 1. To convert ledger values to display values, multiply by the - demurrage coefficient - 2. To convert display values to ledger values, divide by the - demurrage coefficient - -3. Make sure that the converted value can be represented to the desired - accuracy. For example, ledger values submitted to Ripple must fit in - Ripple's [internal format](https://wiki.ripple.com/Currency_format). - -For more information on the necessary precision: - -The demurrage coefficient should be calculated entirely in [64-bit -IEEE754 -doubles](http://en.wikipedia.org/wiki/Double-precision_floating-point_format), -such as the number types native to Javascript, or the float type -available in Python. However, there are some additional notes: - -- For purposes of demurrage, one year is defined as exactly 31536000 - seconds. This is exactly 365 days, with no adjustments for leap days - or leap seconds. -- The reference time should be specified in seconds, as an integer. If - your clock provides a higher resolution, you should truncate the - reference time to seconds before using it. - -Client Applications -------------------- - -In order to accurately convey amounts in present-day terms, client -applications must adjust for demurrage. This means a few things: - -- When representing the value of a demurraging currency, the display - value should be adjusted to the "post-demurrage" values. (This - generally means that display values will be lower than the ledger - values.) -- When making offers or transactions in a demurraging currency, - amounts entered by the user should be adjusted upward, to interpret - user input as post-demurrage numbers. (This generally means that - amounts written into offers are higher than the user input value) - -Client applications must also make sure to distinguish between -currencies with differing amounts of demurrage, and to display the -correct demurrage rates for all currencies with such rates. Currently, -the only Ripple Labs-created client that supports demurrage is Ripple -Trade. - -### ripple-lib support - -Clients that are built from -[ripple-lib](https://github.com/ripple/ripple-lib) can pass a -`reference_date` as an option to the Amount.from\_human function to -account for demurrage. This function can automatically convert a -human-input number to the necessary amount to hold on the ledger to -represent that value in at a given time. (The amount that is sent to the -rippled server is the hypothetical amount one would have needed in order -to have the desired amount after enduring constant demurrage since the -Ripple Epoch.) - -For example, if you're using javascript, you can use ripple-lib utility -to calculate this manually: - -``` - // create an Amount object for an amount of the demurring currency, in this case 10 - // pass in a reference_date that represents today, - // which will calculate how much you will need to represent the requested amount for today - var demAmount = Amount.from_human('10 0158415500000000C1F76FF6ECB0BAC600000000', {reference_date:459990264}); - - // set the issuer -- optional - demAmount.set_issuer("rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"); - - // get the json format that can be used as TakerPays or TakerGets in the order creation - console.log(demAmount.to_json()); - - // this will output an Amount with ~10.75 as the value for XAU, which is what is needed to create an - // effective order today for 10 XAU -``` - - -To calculate how much a given amount has demurred up to today: - -``` - // create a new Amount object - var demAmount = Amount.from_json('10/015841551A748AD2C1F76FF6ECB0CCCD00000000/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); - - // apply interest - demAmount = demAmount.applyInterest(new Date()); - - // get the current amount: - console.log(demAmount.to_json()); - -Where Does Demurrage Go? ------------------------- - -To put it simply, the value that depreciates due to demurrage becomes -the property of the gateway issuing the currency. This means that, when -someone holding a balance of currency goes to redeem that currency from -the Gateway, the amount they get is the post-demurrage amount (the -"display amount") relative to the current moment in time. - -Note that, when the Gateway issues currency with demurrage, it must also -adjust the values it issues, so that the amount sent to the rippled -server and written in the ledger is already adjusted for demurrage up to -the point in time it was issued. - -Demurrage and Money-Making Offers ---------------------------------- - -Demurrage ensures that particular currencies "drift" in value slowly -over time, so that the same amount on the ledger is worth increasingly -less over time when redeemed. (A balance will never go negative, but it -will get closer and closer to zero value.) However, offers are not -automatically updated to compensate for demurrage that accumulated in -the time since the offer was made. This means that, if you are making an -offer to buy a demurraging currency, you must occasionally adjust your -offer to ask for higher ledger amounts to get the same post-demurrage -actual value. However, we expect this to be a complete non-issue because -the relative value of currencies (especially pseudo-currency commodities -such as precious metals) fluctuates much faster than typical rates of -demurrage. - -Since Ripple client applications already adjust for demurrage when -taking human inputs to make an offer, most users will not have to do -anything different when making offers. - -Currency Format Details ------------------------ - -Currency with demurrage or interest is represented as a 160-bit value -that begins with the value `0x01`. This sets it apart from hashes (which -are always `0x80` or higher) as well as standard currency (`0x00`) and -other currency types we may define in the future (`0x02-0x7F`). -Demurraging currency has the following format: - - 01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ - CURCODE- DATE------- RATE------------------- RESERVED--- - -- CURCODE is the 3-byte currency code, such as "USD" -- DATE is no longer used, and should always be 0. -- RATE is the e-folding time, formatted as an IEEE Double, represented - in hex. For example, -6291418827.045599 becomes "C1F76FF6ECB0BAC6". -- RESERVED is reserved for future use. It should always be given as 0, - but other values should be accepted for forward-compatibility. - diff --git a/content/gateway_guide.md b/content/gateway_guide.md index 31c6881add..6ab32a4710 100644 --- a/content/gateway_guide.md +++ b/content/gateway_guide.md @@ -284,15 +284,14 @@ Contact [partners@ripple.com](mailto:partners@ripple.com) to see how Ripple Labs There are several interfaces you can use to connect to Ripple, depending on your needs and your existing software: * [`rippled`](rippled-apis.html) provides JSON-RPC and WebSocket APIs that can be used as a low-level interface to all core Ripple functionality. - * The official client library to rippled, [ripple-lib](https://github.com/ripple/ripple-lib) is available for JavaScript, and provides extended convenience features. -* [Ripple-REST](ripple-rest.html) provides an easy-to-use RESTful API on top of `rippled`. In particular, Ripple-REST is designed to be easier to use from statically-typed languages. +* [RippleAPI](rippleapi.html) provides a simple API for JavaScript applications. ## Tool Security ## Any time you submit a Ripple transaction, it must be signed using your secret. However, having your secret means having full control over your account. Therefore, you should never transmit your secret to a server operated by someone else. Instead, use your own server or client application to sign the transactions before sending them out. -The examples in this document show Ripple-REST API methods that include an account secret. This is only safe if you control the Ripple-REST server yourself, *and* you connect to it over a connection that is secure from outside listeners. (For example, you could connect over a loopback (localhost) network, a private subnet, or an encrypted VPN.) Alternatively, you could operate your own `rippled` server; or you can use a client application such as `ripple-lib` to perform local signing before submitting your transactions to a third-party server. +The examples in this document show API methods that include an account secret. This is only safe if you control `rippled` server yourself, *and* you connect to it over a connection that is secure from outside listeners. (For example, you could connect over a loopback (localhost) network, a private subnet, or an encrypted VPN.) Alternatively, you could use [RippleAPI](rippleapi.html) to perform local signing before submitting your transactions to a third-party server. ## DefaultRipple ## @@ -301,9 +300,7 @@ The DefaultRipple flag controls whether the balances held in an account's trust Before asking users to trust its issuing account, a gateway should enable the DefaultRipple flag on that account. Otherwise, the gateway must individually disable the NoRipple flag for each trust line that other accounts extend to it. -*Note:* Ripple-REST (as of version 1.4.0) does not yet support retrieving or setting the DefaultRipple flag. - -The following is an example of using a local [`rippled` JSON-RPC API](ripple-rest.html#update-account-settings) to enable the DefaultRipple flag: +The following is an example of using a locally-hosted `rippled`'s [`submit` command](rippled-apis.html#submit) submitting an AccountSet transaction to enable the DefaultRipple flag: Request: @@ -371,47 +368,35 @@ Enable the [RequireDest](#requiredest) flag on your hot and cold wallet accounts ## DisallowXRP ## -The DisallowXRP flag (`disallow_xrp` in Ripple-REST) is designed to discourage users from sending XRP to an account by accident. This reduces the costs and effort of bouncing undesired payments, if you operate a gateway that does not trade XRP. The DisallowXRP flag is not strictly enforced, because doing so could allow accounts to become permanently unusable if they run out of XRP. Client applications should honor the DisallowXRP flag, but it is intentionally possible to work around. +The DisallowXRP flag is designed to discourage users from sending XRP to an account by accident. This reduces the costs and effort of bouncing undesired payments, if you operate a gateway that does not trade XRP. The DisallowXRP flag is not strictly enforced, because doing so could allow accounts to become permanently unusable if they run out of XRP. Client applications should honor the DisallowXRP flag, but it is intentionally possible to work around. An issuing gateway that does not trade XRP should enable the DisallowXRP flag on all gateway hot and cold wallets. A private exchange that trades in XRP should only enable the DisallowXRP flag on accounts that are not expected to receive XRP. -The following is an example of a [Ripple-REST Update Account Settings request](ripple-rest.html#update-account-settings) to enable the DisallowXRP flag: +The following is an example of using a locally-hosted `rippled`'s [`submit` command](rippled-apis.html#submit) submitting an AccountSet transaction to enable the DisallowXRP flag: Request: ``` -POST /v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/settings?validated=true - +POST http://localhost:8088/ { - "secret": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9", - "settings": { - "disallow_xrp": true - } + "method": "submit", + "params": [ + { + "secret": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9", + "tx_json": { + "Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", + "Fee": "15000", + "Flags": 0, + "SetFlag": 3, + "TransactionType": "AccountSet" + } + } + ] } ``` _(**Reminder:** Don't send your secret to a server you do not control.)_ -Response: - -``` -200 OK - -{ - "success": true, - "settings": { - "hash": "AC0F7D7735CDDC6D859D0EC4E96A571F71F7481750F4C6C975FC8075801A6FB5", - "ledger": "10560577", - "state": "validated", - "require_destination_tag": false, - "require_authorization": false, - "disallow_xrp": true - } -} -``` - -The value `"disallow_xrp": true` indicates that the DisallowXRP flag is enabled. A successful response shows `"state": "validated"` when the change has been accepted into a validated Ripple ledger. - ## RequireDest ## @@ -419,42 +404,31 @@ The `RequireDest` flag (`require_destination_tag` in Ripple-REST) is designed to We recommend enabling the RequireDest flag on all gateway hot and cold wallets. -The following is an example of a [Ripple-REST Update Account Settings request](ripple-rest.html#update-account-settings) to enable the RequireDest flag. +The following is an example of using a locally-hosted `rippled`'s [`submit` command](rippled-apis.html#submit) submitting an AccountSet transaction to enable the RequireDest flag: Request: ``` -POST /v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/settings?validated=true - +POST http://localhost:8088/ { - "secret": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9", - "settings": { - "require_destination_tag": true - } + "method": "submit", + "params": [ + { + "secret": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9", + "tx_json": { + "Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", + "Fee": "15000", + "Flags": 0, + "SetFlag": 1, + "TransactionType": "AccountSet" + } + } + ] } ``` + _(**Reminder:** Don't send your secret to a server you do not control.)_ -Response: - -``` -200 OK - -{ - "success": true, - "settings": { - "hash": "F3D2EE87D597BA50EA3A94027583110925E8BAAFE41511F937D65423B18BC2A3", - "ledger": "10560755", - "state": "validated", - "require_destination_tag": true, - "require_authorization": false, - "disallow_xrp": false - } -} -``` - -The value `"require_destination_tag": true` indicates that the RequireDest flag has been enabled. A successful response shows `"state": "validated"` when the change has been accepted into a validated Ripple ledger. - ## RequireAuth ## @@ -468,37 +442,30 @@ You can only enable RequireAuth if the account owns no trust lines and no offers We recommend enabling `RequireAuth` for all hot wallet accounts, and then never approving any accounts, in order to prevent hot wallets from creating issuances even by accident. This is a purely precuationary measure, and does not impede the ability of those accounts to transfer issuances created by the cold wallet, as they are intended to do. -The following is an example of a [Ripple-REST Update Account Settings request](ripple-rest.html#update-account-settings) to enable the RequireDest flag. (This method works the same way regardless of whether the account is used as a hot wallet or cold wallet.) +The following is an example of using a locally-hosted `rippled`'s [`submit` command](rippled-apis.html#submit) submitting an AccountSet transaction to enable the RequireAuth flag: (This method works the same way regardless of whether the account is used as a hot wallet or cold wallet.) Request: ``` -POST /v1/accounts/rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW/settings?validated=true - +POST http://localhost:8088/ { - "secret": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9", - "settings": { - "require_authorization": true - } + "method": "submit", + "params": [ + { + "secret": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9", + "tx_json": { + "Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", + "Fee": "15000", + "Flags": 0, + "SetFlag": 2, + "TransactionType": "AccountSet" + } + } + ] } ``` -_(**Reminder:** Don't send your secret to a server you do not control.)_ -Response: - -``` -{ - "success": true, - "settings": { - "hash": "687702E0C3952E2227B2F7A0B34933EAADD72A572B234D31360AD83D3F193A78", - "ledger": "10596929", - "state": "validated", - "require_destination_tag": false, - "require_authorization": true, - "disallow_xrp": false - } -} -``` +_(**Reminder:** Don't send your secret to a server you do not control.)_ ### With Cold Wallets ### @@ -506,46 +473,37 @@ You may also enable `RequireAuth` for your cold wallet in order to use the [Auth If ACME decides to use Authorized Accounts, ACME creates an interface for users to get their Ripple trust lines authorized by ACME's cold account. After Alice has extended a trust line to ACME from her Ripple account, she goes through the interface on ACME's website to require ACME authorize her trust line. ACME confirms that it has validated Alice's identity information, and then sends a TrustSet transaction to authorize Alice's trust line. -The following is an example of using the [Ripple-REST Grant Trustline method](ripple-rest.html#grant-trustline) to authorize the (customer) account rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn to hold issuances of USD from the (cold wallet) account rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW: + + +The following is an example of using a locally-hosted `rippled`'s [`submit` command](rippled-apis.html#submit) to send a TrustSet transaction authorizing the (customer) account rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn to hold issuances of USD from the (cold wallet) account rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW: Request: ``` -POST /v1/accounts/rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW/trustlines?validated=true +POST http://localhost:8088/ { - "secret": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9", - "trustline": { - "limit": "0", - "currency": "USD", - "counterparty": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", - "authorized": true - } -} -``` -_(**Reminder:** Don't send your secret to a server you do not control.)_ - -Response: - -``` -201 Created -{ - "success": true, - "trustline": { - "account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW", - "limit": "0", - "currency": "USD", - "counterparty": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", - "account_allows_rippling": true, - "account_trustline_frozen": false, - "authorized": true - }, - "hash": "4509288EE17F01C83FC7D45850EB066A795EE5DBA17BB4DC98DD4023D31EEE5B", - "ledger": "11158585", - "state": "validated" + "method": "submit", + "params": [ + { + "secret": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9", + "tx_json": { + "Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW", + "Fee": "15000", + "TransactionType": "TrustSet", + "LimitAmount": { + "currency": "USD", + "issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", + "value": 0 + }, + "Flags": 65536 + } + } + ] } ``` -A successful response shows `"state": "validated"` when the change has been accepted into a validated Ripple ledger. +_(**Reminder:** Don't send your secret to a server you do not control.)_ + ## Robustly Monitoring for Payments ## @@ -699,22 +657,6 @@ POST /v1/accounts/rBEXjfD3MuXKATePRwrk4AqgqzuD9JjQqv/payments?validated=true } ``` _(**Reminder:** Don't send your secret to a server you do not control.)_ - - -## Setting Trust Lines in Ripple Trade ## - -As part of the [Hot and Cold Wallets](#hot-and-cold-wallets) model, each hot or warm wallet must have a trust line to the cold wallet. You can manually set up those trust lines by following these steps in the Ripple Trade client. - -1. Log in and go to the **Fund** tab: - ![Fund tab](img/connectgateway_01.png) -2. Click **Gateways** in the sidebar: - ![Gateways](img/connectgateway_02.png) -3. Enter the Ripple Name or Ripple Address of the Gateway's **cold wallet**, and click **Save**. - ![Enter gateway's name or address, then save](img/connectgateway_03.png) -4. Enter the Ripple Trade password, and click **Submit**. (This allows access to send a transaction to the Ripple Network to create the trust line.) - ![Enter password and submit](img/connectgateway_04.png) -5. When the page shows a green "Gateway connected" box, the transaction to create the trust line has succeeded and the Ripple Network has validated it. - ![Gateway connected](img/connectgateway_05.png) ## Reliable Transaction Submission ## @@ -727,16 +669,15 @@ The goal of reliably submitting transactions is to achieve the following two pro In order to achieve this, there are several steps you can take when submitting transactions: * Persist details of the transaction before submitting it. -* Use the `LastLedgerSequence` parameter. (Ripple-REST and ripple-lib do this by default.) +* Use the `LastLedgerSequence` parameter. (RippleAPI does this by default.) * Resubmit a transaction if it has not appeared in a validated ledger whose sequence number is less than or equal to the transaction's `LastLedgerSequence` parameter. For additional information, consult the [Reliable Transaction Submission](reliable_tx.html) guide. -## ripple.txt and host-meta ## +## ripple.txt ## -The [ripple.txt](https://wiki.ripple.com/Ripple.txt) and host-meta standards provide a way to publish information about your gateway so that automated tools and applications can read and understand it. +The [ripple.txt](https://wiki.ripple.com/Ripple.txt) standard provides a way to publish information about your gateway so that automated tools and applications can read and understand it. For example, if you run a validating `rippled` server, you can use ripple.txt to publish the public key of your validating server. You can also publish information about what currencies your gateway issues, and which Ripple account addresses you control, to protect against impostors or confusion. -We recommend implementing one or both of ripple.txt and host-meta. (In the future, we expect ripple.txt to become obsolete, but not yet.) diff --git a/content/intro.md b/content/intro.md deleted file mode 100644 index 7bed02ccb0..0000000000 --- a/content/intro.md +++ /dev/null @@ -1,30 +0,0 @@ -# Introduction # - -Ripple is a decentralized, peer-to-peer network for moving value using cryptographic technology. For more on the big picture, consult [ripple.com](https://ripple.com/) and check out [our blog](https://ripple.com/blog/). - -# Ripple Client Applications # - -The official web client for the Ripple Network is available at [https://rippletrade.com/](). There is also an official downloadable client at [http://download.ripple.com/](). - -In order to activate your account, you must fund it with enough XRP to meet the account reserve (currently 20 XRP). You can do this in a few different ways: - -* You can buy XRP with Bitcoins in the Ripple Trade client, under the [Fund](https://www.rippletrade.com/#/fund) tab. -* You can have someone who is already on the network send a payment to your account's address. -* Keep an eye out for promotions that give away free XRP to developers. - -# Ripple APIs # - -If you intend to act as a gateway, or if you are a developer with great ideas of how to use the Ripple Network, you will probably want to build a custom client application that you or your customers can use to send, receive, or observe funds on the Ripple Network. - -Connecting to the Ripple Network generally means communicating with the Ripple Server software, [`rippled`](https://github.com/ripple/rippled) (pronounced "ripple-dee"). To get started, you can try running a few calls to retrieve information from public servers using the [Ripple API Tool](https://ripple.com/tools/api) or you try downloading and running your own instance of `rippled`. - -If you are building your own client, you have several options of interfaces that you can use to interact with the Ripple Network: - -| Tool | Summary | Interface | Abstraction Level | Pros | Cons | -|------|---------|-----------------------|-------------------|------|------| -| [gatewayd](https://github.com/ripple/gatewayd) | Skeleton for implementing gateway functionality as a Node.js application | HTTP interface | Very high abstraction | ✓ Most functionality needed to operate a gateway is already implemented | ✗ Only intended for gateways
✗ Requires Node.js | -| [Ripple-REST](?p=ripple-rest-api) | RESTful interface to `rippled` as a Node.js application | HTTP interface | High abstraction | ✓ Simple robust transaction submission
✓ Broad HTTP-client support | ✗ Lacks access to a few features like viewing currency exchange offers
✗ Requires Node.js | -| [ripple-lib](https://github.com/ripple/ripple-lib) | Reference implementation for accessing the WebSocket API | Javascript library | Moderate abstraction | ✓ Simple robust transaction submission
✓ Good balance of simplicity and power | ✗ Javascript only (Clients for other languages are in progress) | -| [rippled WebSocket API](?p=web-sockets-api) | Powerful, asynchronous API built on the WebSocket protocol | [WebSocket](http://en.wikipedia.org/wiki/Websocket) interface | Low abstraction | ✓ Access to all Ripple functionality
✓ Can be pushed ordered stream data | ✗ Fewer convenient abstractions
✗ WebSocket clients are rare outside of Javascript | -| [rippled JSON-RPC API](?p=web-sockets-api) | Powerful, synchronous API built on the [JSON-RPC convention](http://json-rpc.org/) | HTTP interface | Low abstraction | ✓ Access to almost all Ripple functionality
✓ Broad HTTP-client support | ✗ Fewer convenient abstractions
✗ Callbacks may arrive out of order
✗ No incremental pathfinding | - diff --git a/content/reliable_tx.md b/content/reliable_tx.md index 976eae0870..58871b5232 100644 --- a/content/reliable_tx.md +++ b/content/reliable_tx.md @@ -1,6 +1,6 @@ # Reliable Transaction Submission -Gateways and back-end applications should use the best practices described here to ensure that transactions are validated or rejected in a verifiable and timely fashion. Transactions should be submitted to trusted (locally operated) rippled servers. +Gateways and back-end applications should use the best practices described here to ensure that transactions are validated or rejected in a verifiable and timely fashion. You should submit transactions to trusted (locally operated) `rippled` servers. The best practices detailed in this document allow applications to submit transactions to the Ripple network while achieving: @@ -17,7 +17,7 @@ These types of errors can potentially lead to serious problems. For example, an ## Background -The Ripple protocol provides a ledger shared across all nodes in the network. Through a process of consensus and validation, the network agrees on order in which transactions are applied to (or omitted from) the ledger. +The Ripple protocol provides a ledger shared across all nodes in the network. Through a process of consensus and validation, the network agrees on order in which transactions are applied to (or omitted from) the ledger. Well-formed transactions submitted to trusted Ripple network nodes are usually validated or rejected in a matter of seconds. There are cases, however, in which a well-formed transaction is neither validated nor rejected this quickly. One specific case can occur if the global [transaction cost](tx-cost.html) increases after an application sends a transaction. If the transaction cost increases above what has been specified in the transaction, the transaction will not be included in the next validated ledger. If at some later date the global transaction cost decreases, the transaction may become viable again. If the transaction does not include expiration, there is no limit to how much later this can occur. @@ -28,33 +28,37 @@ Applications face additional challenges, in the event of power or network loss, ### Transaction Timeline -Ripple provides several APIs for submitting transactions ([rippled](rippled-apis.html), ripple-lib, [Ripple-REST](ripple-rest.html)). Regardless of the API used, the transaction is applied to the ledger as follows. +Ripple provides several APIs for submitting transactions, including [`rippled`](rippled-apis.html), and [RippleAPI](rippleapi.html). Regardless of the API used, the transaction is applied to the ledger as follows. -1. A transaction is created and signed by account owner. -2. That transaction is submitted to the network as a candidate transaction. +1. An account owner creates and signs a transaction. +2. The owner submits the transaction to the network as a candidate transaction. - Malformed or nonsensical transactions are rejected immediately. - - Well formed transactions may provisionally succeed, then later fail. - - Well formed transactions may provisionally fail, then later succeed. -3. Through consensus and validation, the transaction is applied to the ledger. Even some failed transactions are applied in order to enforce a cost for being propagated through the network. + - Well-formed transactions may provisionally succeed, then later fail. + - Well-formed transactions may provisionally fail, then later succeed. + - Well-formed transactions may provisionally succeed, and then later succeed in a slightly different way. (For example, by consuming a different offer and achieving a better or worse exchange rate than the provisional execution.) +3. Through consensus and validation, the transaction is applied to the ledger. Even some failed transactions are applied, in order to enforce a cost for being propagated through the network. 4. The validated ledger includes the transaction, and its effects are reflected in the ledger state. - Transaction results are no longer provisional, success or failure is now final and immutable. -*Note:* When submitting a transaction via rippled or ripple-lib, a successful status code returned from a submit command indicates the rippled server has received the candidate transaction, and does not indicate the transaction will be finally applied to the ledger. +*Note:* When submitting a transaction via `rippled`, a successful status code returned from a submit command indicates the `rippled` server has received the candidate transaction, and does not indicate the transaction will be finally applied to the ledger. -Ripple APIs may return provisional results based on candidate transactions. Applications must not confuse these with the final, *immutable*, results of a transaction. Immutable results are found only in validated ledgers. Applications may need to query the status of a transaction repeatedly, until the ledger containing the transaction results is validated. +APIs may return provisional results based on the result of applying candidate transactions to the current, in-progress ledger. Applications must not confuse these with the final, *immutable*, results of a transaction. Immutable results are found only in validated ledgers. Applications may need to query the status of a transaction repeatedly, until the ledger containing the transaction results is validated. -While applying transactions, Ripple network nodes work with the *last validated ledger*, a snapshot of the ledger state based on transactions the entire network has validated. The process of consensus and validation apply a set of new transactions to the last validated ledger, resulting in a new validated ledger. This new validated ledger instance and the ones that preceded it comprise the ledger history. Each of these validated ledger instances has a sequence number, which is one greater than the sequence number of the preceding instance. +While applying transactions, `rippled` servers use the *last validated ledger*, a snapshot of the ledger state based on transactions the entire network has validated. The process of consensus and validation apply a set of new transactions to the last validated ledger in canonical order, resulting in a new validated ledger. This new validated ledger instance and the ones that preceded it comprise the ledger history. +Each validated ledger instances has a sequence number, which is one greater than the sequence number of the preceding instance. Each ledger also has an identifying hash value, which is uniquely determined from its contents. There may be many different versions of in-progress ledgers, which have the same sequence number, but different hash values. Only one version can ever be validated. + +Each validated ledger has a canonical order in which transactions apply. This order is deterministic based on the final transaction set of the ledger. In contrast, each `rippled` server's in-progress ledger is calculated incrementally, as transactions are received. The order in which transactions execute provisionally is usually not the same as the order in which transactions execute to build a new validated ledger. This is one reason why the provisional outcome of a transaction may be different than the final result. For example, a payment may achieve a different final exchange rate depending on whether it executes before or after another payment that would consume the same offer. ### LastLedgerSequence -[`LastLedgerSequence`](transactions.html#lastledgersequence) is an optional parameter of all transactions. This instructs the Ripple network that a transaction must be validated on or before a specific ledger instance. The transaction will never be included in a ledger instance with a higher sequence number. +[`LastLedgerSequence`](transactions.html#lastledgersequence) is an optional parameter of all transactions. This instructs the Ripple Consensus Ledger that a transaction must be validated on or before a specific ledger instance. The Ripple Consensus Ledger never includes a transaction in a ledger instance whose sequence number is higher than the transaction's `LastLedgerSequence` parameter. Use the `LastLedgerSequence` parameter to prevent undesirable cases where a transaction is not promptly validated yet could become viable at some point in the future. Gateways and other back-end applications should specify the `LastLedgerSequence` parameter on every transaction. Automated processes should use a value of 4 greater than the sequence number of the last validated ledger[1] to ensure that a transaction is validated or rejected in a predictable and timely fashion. -Applications using rippled APIs should explicitly specify a `LastLedgerSequence` when submitting transactions. When using ripple-lib or Ripple-REST, a `LastLedgerSequence` is automatically included. Applications using those APIs are recommended to use the `LastLedgerSequence` calculated by the API. +Applications using rippled APIs should explicitly specify a `LastLedgerSequence` when submitting transactions. RippleAPI uses the `maxLedgerVersion` field of [Transaction Instructions](rippleapi.html#transaction-instructions) to specify the `LastLedgerSequence`. RippleAPI automatically provides an appropriate value by default. You can specify `maxLedgerVersion` as `null` to intentionally omit `LastLedgerSequence`, in case you want a transaction that can be executed after an unlimited amount of time. @@ -121,31 +125,31 @@ For each persisted transaction without validated result: In order to implement the transaction submission and verification best practices, applications need to perform the following actions. -* Determine the signing account's next sequence number - * Each transaction has an account-specific sequence number. This guarantees the order in which transactions signed by an account are executed and makes it safe to resubmit a transaction without danger of the transaction being applied to the ledger more than once. -* Decide on a `LastLedgerSequence` - * A transaction's `LastLedgerSequence` is calculated from the last validated ledger sequence number. -* Construct and sign the transaction - * The details of a signed transaction are persisted before submission. -* Submit the transaction - * Initial results are provisional and subject to change. -* Determine the final result of a transaction - * Final results are an immutable part of the ledger history. +1. Determine the signing account's next sequence number + * Each transaction has an account-specific sequence number. This guarantees the order in which transactions signed by an account are executed and makes it safe to resubmit a transaction without danger of the transaction being applied to the ledger more than once. +3. Decide on a `LastLedgerSequence` + * A transaction's `LastLedgerSequence` is calculated from the last validated ledger sequence number. +3. Construct and sign the transaction + * Persist the details of a signed transaction before submission. +4. Submit the transaction + * Initial results are provisional and subject to change. +5. Determine the final result of a transaction + * Final results are an immutable part of the ledger history. -An application's means of performing these actions depends on the ripple API the application uses. These interfaces may be any of: +An application's means of performing these actions depends on the API the application uses. These interfaces may be any of: -1. [rippled](rippled-apis.html) -2. [ripple-rest](ripple-rest.html) -3. [ripple-lib](https://github.com/ripple/ripple-lib/) +1. [`rippled`'s internal APIs](rippled-apis.html) +2. [RippleAPI](rippleapi.html) +3. Any number of other software APIs layered on top of `rippled` ### rippled - Submitting and Verifying Transactions #### Determine the Account Sequence -rippled provides the [account_info](rippled-apis.html#account-info) method to learn an account's sequence number in the last validated ledger. +`rippled` provides the [account_info](rippled-apis.html#account-info) method to learn an account's sequence number in the last validated ledger. -Request: +JSON-RPC Request: ``` { @@ -159,7 +163,7 @@ Request: } ``` -Response: +Response body: ``` { @@ -184,7 +188,7 @@ Response: In this example, the account's sequence is **4** (note `"Sequence": 4`, in `"account_data"`) as of the last validated ledger (note `"ledger": "validated"` in the request, and `"validated": "true"` in the response). -If an application were to submit three transactions signed by this account, they would use sequence numbers 4, 5, and 6. An application should keep a running account sequence number in order to submit multiple transactions without waiting for validation of each one. +If an application were to submit three transactions signed by this account, they would use sequence numbers 4, 5, and 6. In order to submit multiple transactions without waiting for validation of each, an application should keep a running account sequence number. #### Determine the Last Validated Ledger @@ -240,7 +244,7 @@ In this example the last validated ledger sequence number is 10268596 (found und #### Construct the Transaction -`rippled` provides the [RPC sign](rippled-apis.html#sign) to prepare a transaction for submission. This method requires an account secret, which should only be passed to trusted rippled instances. This example issues 10 FOO (a made-up currency) from a gateway to another ripple account. +`rippled` provides the [sign method](rippled-apis.html#sign) to prepare a transaction for submission. This method requires an account secret, which should only be passed to trusted `rippled` instances. This example issues 10 FOO (a made-up currency) from a gateway to another Ripple account. Request: @@ -307,7 +311,7 @@ Applications should persist the transaction's hash before submitting. The resul #### Submit the transaction -`rippled` provides the [`submit` method](rippled-apis.html#submit), allowing us to submit the signed transaction. The `tx_blob` parameter was returned from the `sign` method. +`rippled` provides the [`submit` method](rippled-apis.html#submit), allowing us to submit the signed transaction. This uses the `tx_blob` parameter that was returned by the `sign` method. Request: @@ -468,557 +472,13 @@ The [`server_state` method](rippled-apis.html#server-state) (used earlier to det } ``` -Our example transaction specified `LastLedgerSequence` 10268600, based on the last validated ledger at the time, plus four. So to determine whether our missing transaction has permanently failed, our rippled server must have ledgers 10268597 through 10268600. If the server has those validated ledgers in its history, **and** `tx` returns `txnNotFound`, then the transaction has failed and will never be included in any ledger. in this case, application logic may dictate building and submitting a replacement transaction with the same account sequence and updated `LastLedgerSequence`. +Our example transaction specified `LastLedgerSequence` 10268600, based on the last validated ledger at the time, plus four. So to determine whether our missing transaction has permanently failed, our `rippled` server must have ledgers 10268597 through 10268600. If the server has those validated ledgers in its history, **and** `tx` returns `txnNotFound`, then the transaction has failed and will never be included in any ledger. In this case, application logic may dictate building and submitting a replacement transaction with the same account sequence and updated `LastLedgerSequence`. The server state may indicate a last validated ledger sequence number less than the specified `LastLedgerSequence`. If so, the `txnNotFound` indicates either (a) the submitted transaction failed to be distributed to the network, or (b) the transaction has been distributed to the network but has not yet been processed. To handle the former case, applications may submit again the same signed transaction. Because the transaction has a unique account sequence number, it will be processed at most once. Finally the server state might indicate one or more gaps in the transaction history. The `completed_ledgers` field shown in the response above indicates that ledgers 10256383 through 10256411 are missing from this rippled instance. Our example transaction can only appear in ledgers 10268597 - 10268600 (based on when it was submitted and `LastLedgerSequence`), so the gap shown here is not relevant. However, if the gap indicated a ledger in that range was missing, then an application would need to query another rippled server (or wait for this one to retrieve the missing ledgers) in order to determine that a `txnNotFound` result is immutable. -### Ripple-REST - Submitting and Verifying Payments - - -The [Ripple-REST API](ripple-rest.html) provides an interface to Ripple via a [RESTful API](https://en.wikipedia.org/wiki/Representational_state_transfer). It provides robust payment submission features, which include referencing payments by client provided identifiers, re-submitting payments in response to some errors, and automatically calculating transaction parameters such as account sequence, `LastLedgerSequence`, and transaction cost. - -This examples that follow refer to Ripple-REST API for *payments*. The REST methods for setting trust lines and modifying account settings does not follow the same pattern. See [RLJS-126](https://ripplelabs.atlassian.net/browse/RLJS-126) for additional details. - - -#### Construct the Transaction - -In Ripple-REST, a GET request retrieves the path options for a payment. The following example issues 10 FOO (a made-up currency) from one account to another. - -``` -GET /v1/accounts/rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W/payments/paths/rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM/10+FOO+rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W -``` - -The response (below) indicates one payment path exists. (The `payments[0].paths` is present, and empty, when issuing currency directly.) - -``` -{ - "payments": [ - { - "no_direct_ripple": false, - "partial_payment": false, - "paths": "[]", - "invoice_id": "", - "destination_amount": { - "issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W", - "currency": "FOO", - "value": "10" - }, - "destination_tag": "", - "destination_account": "rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM", - "source_slippage": "0", - "source_amount": { - "issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W", - "currency": "FOO", - "value": "10" - }, - "source_tag": "", - "source_account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W" - } - ], - "success": true -} -``` - - - -#### Submit the Payment Transaction - -Applications should persist a record of a transaction before submitting it, in order to recover from a catastrophic failure such as a power outage. Ripple-REST accepts a `client_resource_id` which allows an application to look up a transaction. For this example, let's say the application saves the details of the transaction to its payments table with ID 42, so the application creates `client_resource_id` "payment-42". - -Before submitting, applications should persist the `client_resource_id`, transaction type, and source account. - -Request: - -``` -POST /v1/accounts/:usGate/payments -Content-Type: application/json - -{ - "secret": "sssssssssssssssssssssss", - "client_resource_id": "payment-42", - "max_fee": ".1", - "payment": { - "no_direct_ripple": false, - "partial_payment": false, - "paths": "[]", - "invoice_id": "", - "destination_amount": { - "issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W", - "currency": "FOO", - "value": "10" - }, - "destination_tag": "", - "destination_account": "rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM", - "source_slippage": "0", - "source_amount": { - "issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W", - "currency": "FOO", - "value": "10" - }, - "source_tag": "", - "source_account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W" - } -} -``` - -***Note: only submit your account secret to a trusted Ripple-REST server.*** - -Response: - -``` -{ - success: true, - client_resource_id: 'payment-42', - status_url: 'http://127.0.0.1:5990/v1/accounts/rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W/payments/payment-42' } -``` - -The payment result remains provisional at this point. Ripple-REST returns a `status_url` where we can eventually learn the final result of the transaction. The `status_url` is based on the `client_resource_id` persisted by the application before submission, so the application can construct the `status_url` even in the event of a power failure before this response is received. - - -#### Verify the Payment Transaction - -A GET request to the transaction's `status_url` retrieves the result. - -Request: - -``` -GET /v1/accounts/rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W/payments/payment-42 -``` - -Response: - -``` -{ - "payment": { - "destination_balance_changes": [ - { - "issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W", - "currency": "FOO", - "value": "10" - } - ], - "source_balance_changes": [ - { - "issuer": "", - "currency": "XRP", - "value": "-0.012" - }, - { - "issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W", - "currency": "FOO", - "value": "-10" - } - ], - "fee": "0.012", - "timestamp": "2014-12-02T23:10:10.000Z", - "hash": "DDF9F6E4DC64A1CB056570170FC06B2CBC2701CB500E44AC730BF8C868F6AA15", - "ledger": "10286112", - "result": "tesSUCCESS", - "state": "validated", - "direction": "outgoing", - "partial_payment": false, - "no_direct_ripple": false, - "paths": "[]", - "invoice_id": "", - "destination_amount": { - "value": "10", - "issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W", - "currency": "FOO" - }, - "destination_tag": "", - "destination_account": "rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM", - "source_slippage": "0", - "source_amount": { - "value": "10", - "issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W", - "currency": "FOO" - }, - "source_tag": "", - "source_account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W" - }, - "success": true -} -``` - -In this example, `payment.state: "validated"` indicates the transaction is in a validated ledger. Therefore the results are final and immutable. Any other value for `payment.state` indicates provisional results, an application must check again later to determine final results. - -In the preceeding example, `payment.result: "tesSUCCESS"` (along with the `"validated"` state) indicates the payment has been delivered. Any other result code indicates the transaction did not succeed, and application logic may dictate constructing and submitting a new transaction to perform the desired operation. - - -#### Verify Missing or Failed Payment Transaction - -When a GET request to the transaction's `status_url` returns an error, an application must determine whether the final result of a transaction is failure. - -Request: - -``` -GET /v1/accounts/rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W/payments/payment-42 -``` - -Response: - -``` -{ - "message": "Transaction not found.", - "error": "txnNotFound", - "error_type": "transaction", - "success": false -} -``` - -*Note:* The `txnNotFound` error shown above is the current behavior of ripple-REST, but will change in order to make it easier to determine the status of transactions in this case. Follow [RLJS-163](https://ripplelabs.atlassian.net/browse/RLJS-163) for updates regarding this behavior. - -The `txnNotFound` error in this example indicates the transaction was received by Ripple-REST, but has failed to appear in a validated ledger. This could be caused certain transaction errors, or possibly because Ripple-REST lost power or network before submitting the transaction to the network. Application logic may dictate constructing and submitting a replacement transaction. - -Another error response: - -``` -{ - "message": "A transaction hash was not supplied and there were no entries matching the client_resource_id.", - "error": "Transaction not found", - "error_type": "invalid_request", - "success": false -} -``` - -This `"Transaction not found"` error indicates the transaction was not received by Ripple-REST, and therefore never sent to the network. Again, application logic may dictate constructing and submitting a replacement transaction. - - - - -### ripple-lib - Submitting and Verifying Transactions - -[ripple-lib](https://github.com/ripple/ripple-lib) provides a Javascript API for Ripple in Node.js and web browsers. It provides features for robust transaction submission which including automatically calculating account sequence numbers and `LastLedgerSequence`. - - -#### Construct the Transaction - -ripple-lib provides a high level API for creating transactions. In this example, a payment: - - var tx = remote.createTransaction('Payment', { - account: ‘rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W', - destination: ‘rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM', - amount: ‘10/FOO/rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W' - }); - -Note that ripple-lib will automatically provide additional details before the transaction is signed and submitted. These details include an account transaction Sequence, `LastLedgerSequence` and transaction cost. - -Before submitting, applications should persist the transaction details, so that status may be verified in the event of a failure. Applications have an opportunity to do this by implementing [transaction event handlers](https://github.com/ripple/ripple-lib/blob/61afca2337927a4f331ae02770ccdad5d9bdef17/docs/REFERENCE.md#transaction-events). The `presubmit` event handler is appropriate for saving data before a transaction is submitted to the network. During normal operation, a `state` event is emitted whenever the transaction status changes, including final validation. - -The example implementation (below) of a these event handlers simply logs some information about the transaction, in order to show some of the data available to applications. Live applications should implement handlers to **synchronously** persist transactions details, and should throw an error if unable to save the data. - - // The 'presubmit' handler receives events before the transaction - // is submitted to the network; also before re-submit attempts. - tx.on('presubmit', function(data) { - console.log('- Presubmit Event Handler -'); - // Log information about the transaction. - console.log(this.summary()); - - // Applications should persist transaction data syncronously, - // before returning from this event handler. - - }); - - // The 'state' handler receives events after any state change, including... - tx.on('state', function(state) { - console.log('- State Event Hander: ' + state + ' -'); - // Log information about the transaction. - console.log(this.summary()); - - // Applications should persist updated transaction state. - }); - - - - -#### Submit the Transaction - -ripple-lib provides `Transaction.submit()` to both sign and submit a transaction. In order to sign, an application must first call `Remote.setSecret(, )`. Take care to configure ripple-lib to use local signing, as secrets should only be shared with trusted ripple servers. - - tx.submit(function(err, res) { - if (err) { - console.log('- Transaction Submit Callback Error -'); - console.log(err); - } - else { - console.log('- Transaction Submit Callback -'); - console.log(util.inspect(res)); - } - }); - -ripple-lib emits events as it processes the transaction. The presubmit event allows application to persist the transaction hash and other details before it is sent to the network. - -``` -- Presubmit Event Handler - -{ tx_json: - { Flags: 2147483648, - TransactionType: 'Payment', - Account: 'rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W', - Amount: - { value: '10', - currency: 'FOO', - issuer: 'rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W' }, - Destination: 'rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM', - Fee: '10000', - Sequence: 11, - SigningPubKey: '0267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC5', - LastLedgerSequence: 10320276, - TxnSignature: '3045022100A61FA3AF1569BC4B1D2161F0055CF9760F8AC473ED374A98FE7E77099B8C63AD02200FF2A59CE4722FC246652125D3A13928392E7D0C5AC073314A573E93BF594856' }, - clientID: undefined, - submittedIDs: [ '2120732F77002A9138DE110408EA06C2064F032BC9D44A28C46267C607594203' ], - submissionAttempts: 0, - submitIndex: 10320268, - initialSubmitIndex: 10320268, - lastLedgerSequence: 10320276, - state: 'unsubmitted', - server: undefined, - finalized: false } -``` - -Note in the preceeding example log output, `tx.state: 'unsubmitted'` indicates the transaction is not yet sent to the network. `tx.submittedIDs` includes the transaction hash, a unique identifier that applications should persist in order to later verify the status of the transaction. ripple-lib has automatically calculated `tx.tx_json.Sequence` and `tx.tx_json.LastLedgerSequence`. - -ripple-lib will re-submit a transaction in response to certain errors. Prior to each submission the `presubmit` event provides up-to-date information about the transaction, which applications should persist. - -``` -- Presubmit Event Handler - -{ tx_json: - { Flags: 2147483648, - TransactionType: 'Payment', - Account: 'rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W', - Amount: - { value: '10', - currency: 'FOO', - issuer: 'rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W' }, - Destination: 'rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM', - Fee: '10000', - Sequence: 11, - SigningPubKey: '0267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC5', - LastLedgerSequence: 10320278, - TxnSignature: '3045022100D5AC197A9EB35E86B70B4A02C19EC0120C1D6A539B1FE58C364322067E040AE102205EFE429FF40FAFAAAC58B653DCD25642D8A50E222C2D244105F43CEBAAC7DC89' }, - clientID: undefined, - submittedIDs: - [ 'AD070F312DE0EB8AB64DDA0C512A4A1E9ED1ACE0AEFBBE6AA1418A2D6F137D13', - '2120732F77002A9138DE110408EA06C2064F032BC9D44A28C46267C607594203' ], - submissionAttempts: 1, - submitIndex: 10320270, - initialSubmitIndex: 10320268, - lastLedgerSequence: 10320278, - state: 'submitted', - server: undefined, - finalized: false, - result: - { engine_result: 'telINSUF_FEE_P', - engine_result_message: 'Fee insufficient.', - ledger_hash: undefined, - ledger_index: undefined, - transaction_hash: '2120732F77002A9138DE110408EA06C2064F032BC9D44A28C46267C607594203' } } -``` - - -The example above shows the transaction after 1 failed attempts, before a second attempt is submitted. Note that `tx.submittedIDs[0]` is the updated hash which applications should persist. - -The `tx.result` is the **provisional** result of the **prior** submission attempt. In this example the initial submit failed with `telINSUF_FEE_P`, which could happen if the network adjusts the transaction cost calculated by ripple-lib immediately before the transaction is processed. - - - - -#### Verify the Transaction - -During normal operation, events emitted by ripple-lib inform an application of the result of a transaction. The `state` event will emit with `tx.state: 'pending'` with a provisional result; and finally if successful with `tx.state: 'validated'` and `tx.finalized: true`. - -``` -- State Event Hander: validated - -{ tx_json: - { Flags: 2147483648, - TransactionType: 'Payment', - Account: 'rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W', - Amount: - { value: '10', - currency: 'FOO', - issuer: 'rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W' }, - Destination: 'rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM', - Sequence: 11, - SigningPubKey: '0267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC5', - Fee: '12000', - LastLedgerSequence: 10320625, - TxnSignature: '3045022100DEFA085B88834F3C27200714AB40F3A67E7E86E726DE630A2955843F6D53010D02202592D709D5F90F9E852CEFB0D5A7F6D39AC0A99BC97A3589BF9FA47018C2CB2C' }, - clientID: undefined, - submittedIDs: [ '0E066642EC28DA3C9840202AF4F3CD281A5A2733F2D9BEF38C69DFDC14407E12' ], - submissionAttempts: 1, - submitIndex: 10320617, - initialSubmitIndex: 10320617, - lastLedgerSequence: 10320625, - state: 'validated', - server: undefined, - finalized: true, - result: - { engine_result: 'tesSUCCESS', - engine_result_message: 'The transaction was applied.', - ledger_hash: '7F936E0F37611982A434B76270C819FDA8240649D7592BDC995FC9AEE2D436AA', - ledger_index: 10320618, - transaction_hash: '0E066642EC28DA3C9840202AF4F3CD281A5A2733F2D9BEF38C69DFDC14407E12' } } -``` - -If the final state of a transaction is an error, the state event indicates `tx.state: 'failed'` and `tx.finalized: 'true'`: - -``` -- State Event Hander: failed - -{ tx_json: - { Flags: 2147483648, - TransactionType: 'Payment', - Account: 'rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W', - Amount: - { value: '10', - currency: 'FOO', - issuer: 'rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W' }, - Destination: 'rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM', - Fee: '10000', - Sequence: 11, - SigningPubKey: '0267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC5', - LastLedgerSequence: 10320296, - TxnSignature: '304402201E3D376CF7C1C99EAC19027EA3EDE15F24D8FA59D4EA90067A09267F8D927ABB0220084B8BFF7D9308CD00A5DA265776DC9BAB9F553A9E6A4ED1A75DD76DCB3B40A9' }, - clientID: undefined, - submittedIDs: - [ '895DA495779D51F84E4B79258AAF9A8E51404A79747DD936EE6468FE9A974AEE', - 'F14AE631317D11184DEC7066814539E9BB50AB46DF770E3F2367430810C0AE7C', - '80F7460AD3F8172F9CDD69B638E4EA7ED9466A4D495EF8530FE98B8A0909E897', - '23F59C223701D73C2477963E4D1FA3460DAD5A64D813FB9591AF45C4C68A339B', - 'B929D9018E842A56FFCA8EB295EDA81C62AE37804F759A19E0B1292C888C8586', - 'EC9B4D869B8B9C27F644859F203D54023B01F6C2E9FA12CD34AC8373F9BA67A5', - '47FD42A6604D74A89E006352FBC656843A270EF46B47A3EB1D1098A31A01BC3D', - 'BD3D13C57A5FDBB9B1F88C287EC158AA92BF9B75078273678F3124C84F504ABA', - '0B2CC389D5553FB232E4EF45EC67D149B8CD65E17C4BE7A41B5142A0D4A935BD', - 'AD070F312DE0EB8AB64DDA0C512A4A1E9ED1ACE0AEFBBE6AA1418A2D6F137D13', - '2120732F77002A9138DE110408EA06C2064F032BC9D44A28C46267C607594203' ], - submissionAttempts: 11, - submitIndex: 10320288, - initialSubmitIndex: 10320268, - lastLedgerSequence: 10320296, - state: 'failed', - server: undefined, - finalized: true, - result: - { engine_result: 'telINSUF_FEE_P', - engine_result_message: 'Fee insufficient.', - ledger_hash: undefined, - ledger_index: undefined, - transaction_hash: '895DA495779D51F84E4B79258AAF9A8E51404A79747DD936EE6468FE9A974AEE' } } -``` - - -In the event of a power or network failure, an application may be interrupted before these `state` events are emitted. In these cases, applications should retrieve the status of a transaction by its `hash`, one of the details persisted during an earlier `presubmit` event. - - var hash = 'C3306CA3ED1B372EAC8A84A84B52752A4E4912BB1A26AB883E969BC987E4D20E'; - remote.requestTransaction(hash, function(err, result) { - if (err) { - console.log(err); - } - else { - console.log(result); - } - }); - -Result of `remote.requestTransaction()`: - -``` -{ Account: 'rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W', - Amount: - { currency: 'FOO', - issuer: 'rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W', - value: '10' }, - Destination: 'rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM', - Fee: '10000', - Flags: 2147483648, - LastLedgerSequence: 10303055, - Sequence: 10, - SigningPubKey: '0267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC5', - TransactionType: 'Payment', - TxnSignature: '304402200C65A9FD9EA7000DCD87688BA92C219074858D530E9A75F32EF2DA1A9C07844E02203A72B2688412CF855306E70D9B9ED541B67BEA8A8EDB90D47B7B227B295CED9B', - date: 470953270, - hash: 'C3306CA3ED1B372EAC8A84A84B52752A4E4912BB1A26AB883E969BC987E4D20E', - inLedger: 10303048, - ledger_index: 10303048, - meta: - { AffectedNodes: [ [Object], [Object] ], - TransactionIndex: 23, - TransactionResult: 'tesSUCCESS' }, - validated: true } -``` - -Note the response from `requestTransaction` includes **`validated: true`**, indicating the result is in a validated ledger and is final. Without `validated: true`, results are *provisional* and may change. This example shows `meta.TransactionResult: 'tesSUCCESS'`, indicating the transaction was successful. - - -#### Verify Missing Transaction - -`Remote.requestTransaction` may return `txNotFound`: - -``` -{ [RippleError: Remote reported an error.] - error: 'remoteError', - error_message: 'Remote reported an error.', - remote: - { error: 'txnNotFound', - error_code: 24, - error_message: 'Transaction not found.', - id: 1, - request: - { command: 'tx', - id: 1, - transaction: 'F85D840B152328A1A6C11910A6FBF57E1340B6285E3602A1258B7A41EC814119' }, - status: 'error', - type: 'response' }, - result: 'remoteError', - engine_result: 'remoteError', - result_message: 'Remote reported an error.', - engine_result_message: 'Remote reported an error.', - message: 'Remote reported an error.' } -``` - -In these cases an application must distinguish between a provisional result and a final result. For this, an application needs the transaction's `initialSubmitIndex` and `LastLedgerSequence`. This information was persisted earlier by the application's `presubmit` event handler. In this example, `initialSubmitIndex` is 10301323 and `LastLedgerSequence` is 10301337. - -A call to `Remote.requestServerInfo()` determines whether the server has final, immutable results about the transaction. - - remote.requestServerInfo(function(err, result) { - if (err) { - console.log(err); - } - else { - console.log(result); - } - }); - -Result of `remote.requestServerInfo()`: - -``` -{ info: - { build_version: '0.26.4-sp3-private', - complete_ledgers: '32570-10302948', - hostid: 'KNOW', - io_latency_ms: 1, - last_close: { converge_time_s: 2.001, proposers: 5 }, - load_factor: 1000, - peers: 44, - pubkey_node: 'n9MADAXTbCnaBYoUcvDzHkTqoTSjVd8VHgJE2KwMBbwRV4pM3j2a', - server_state: 'full', - validated_ledger: - { age: 4, - base_fee_xrp: 0.00001, - hash: '47EE6EC414FC0B648869CE7108143D916DE38DAC167DADEF541F9A8CED475909', - reserve_base_xrp: 20, - reserve_inc_xrp: 5, - seq: 10302948 }, - validation_quorum: 3 } } -``` - -In this example, `info.complete_ledgers` indicates the server has continuous ledger history up to ledger sequence 10302948. This history includes the span of ledger where the transaction may appear, from 10301323 to 10301337. Therefore, the `txNotFound` result is final, and the transaction has failed immutably. - -If the ledger history were not complete through the `LastLedgerSequence`, the application must wait for that ledger to become validated, or the server to sync a more complete history with the network. - - - ## Additional Resources - [Transaction Format](transactions.html) diff --git a/content/rippled.md b/content/rippled.md index 76ad3a5ec5..e89943e8c3 100644 --- a/content/rippled.md +++ b/content/rippled.md @@ -8,7 +8,7 @@ The core peer-to-peer server that operates the Ripple Network is called `rippled * Client Library - [Javascript](https://github.com/ripple/ripple-lib) # WebSocket and JSON-RPC APIs # -If you want to communicate directly with the `rippled` server, you can use either the WebSocket API or the JSON-RPC API. Both APIs use the same list of commands, with almost entirely the same parameters in each command. Whereas the [Ripple-REST API](ripple-rest.html) provides a simplified interface on top of the WebSocket API for easier integration, these APIs provide the full power of Ripple but require slightly more complexity: +If you want to communicate directly with the `rippled` server, you can use either the WebSocket API or the JSON-RPC API. Both APIs use the same list of commands, with almost entirely the same parameters in each command. * The WebSocket API uses the [WebSocket protocol](http://www.html5rocks.com/en/tutorials/websockets/basics/), available in most browsers and Javascript implementations, to achieve persistent two-way communication. There is not a 1:1 correlation between requests and responses. Some requests prompt the server to send multiple messages back asynchronously; other times, responses may arrive in a different order than the requests that prompted them. The `rippled` server can be configured to accept secured (wss:), unsecured (ws:) WebSocket connections, or both. * The JSON-RPC API relies on simple request-response communication via HTTP or HTTPS. (The `rippled` server can be configured to accept HTTP, HTTPS, or both.) For commands that prompt multiple responses, you can provide a callback URL. diff --git a/content/ripplerest_api.md b/content/ripplerest_api.md deleted file mode 100644 index 0eaf2b06a4..0000000000 --- a/content/ripplerest_api.md +++ /dev/null @@ -1,2511 +0,0 @@ -# Ripple-REST API # - -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. - -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. - - -## Available API Routes ## - -#### Accounts #### - -* [Generate Wallet - `GET /v1/wallet/new`](#generate-wallet) -* [Get Account Balances - `GET /v1/accounts/{:address}/balances`](#get-account-balances) -* [Get Account Settings - `GET /v1/accounts/{:address}/settings`](#get-account-settings) -* [Update Account Settings - `POST /v1/accounts/{:address}/settings`](#update-account-settings) - -#### Payments #### - -* [Prepare Payment - `GET /v1/accounts/{:source_address}/payments/paths/{:destination_address}/{:amount}`](#prepare-payment) -* [Submit Payment - `POST /v1/accounts/{:source_address}/payments`](#submit-payment) -* [Confirm Payment - `GET /v1/accounts/{:address}/payments/{:id}`](#confirm-payment) -* [Get Payment History - `GET /v1/accounts/{:address}/payments`](#get-payment-history) - -#### Orders #### - -* [Place Order - `POST /v1/accounts/{:address}/orders`](#place-order) -* [Cancel Order - `DELETE /v1/accounts/{:address}/orders/{:sequence}`](#cancel-order) -* [Get Account Orders - `GET /v1/accounts/{:address}/orders`](#get-account-orders) -* [Get Order Book - `GET /v1/accounts/{:address}/order_book/{:base}/{:counter}`](#get-order-book) -* [Get Order Transaction - `GET /v1/accounts{:address}/orders/{:hash}`](#get-order-transaction) - -#### Trustlines #### - -* [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/{:id}`](#check-notifications) - -#### Status #### - -* [Check Connection - `GET /v1/server/connected`](#check-connection) -* [Get Server Status - `GET /v1/server`](#get-server-status) - -#### Utilities #### - -* [Retrieve Ripple Transaction - `GET /v1/transactions/{:id}`](#retrieve-ripple-transaction) -* [Retrieve Transaction Cost - `GET /v1/transaction-fee`](#retrieve-transaction-cost) -* [Generate UUID - `GET /v1/uuid`](#create-client-resource-id) - - - -## API Overview ## - -### Ripple Concepts ### - -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 [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. - -Payments are made between two accounts, by specifying the ___source___ and ___destination___ address for those accounts. A payment also involves an ___amount___, which includes both the numeric amount and the currency, for example: `100+XRP`. - -When you make a payment in a currency other than XRP, you also need to include the Ripple address of the ___counterparty___. The counterparty is the gateway or other entity who holds the funds on your behalf. For non-XRP payments, the amount looks something like this: `100+USD+rNsJKf3kaxvFvR8RrDi9P3LBk2Zp6VL8mp`. - -Although the Ripple-REST API provides a high-level interface to Ripple, there are also API methods for checking the status of the `rippled` server and retrieving a Ripple transaction in its native format. - -### Sending Payments ### - -Sending a payment involves three steps: - -1. Generate the payment object with the [Prepare Payment method](#prepare-payment). If the payment is not a direct send of XRP from one account to another, the Ripple system identifies the chain of trust, or ___path___, that connects the source and destination accounts, and includes it in the payment object. -2. Modify the payment object if desired, and then [submit it](#submit-payment) to the API for processing. *Caution:* Making many changes to the payment object increases the chances of causing an error. -3. Finally, ___confirm___ that the payment has completed, using the [Confirm Payment method](#confirm-payment). Payment submission is an asynchronous process, so payments can fail even after they have been submitted successfully. - -When you submit a payment for processing, you assign a unique `client resource identifier` to that payment. This is a string which uniquely identifies the payment, and ensures that you do not accidentally submit the same payment twice. You can also use the `client_resource_id` to retrieve a payment once it has been submitted. - -### Transaction Types ### - -The Ripple protocol supports multiple types of transactions, not 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#trustset)) - * 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#accountset)) - -### Client Resource IDs ### - -All Ripple transactions are identified by a unique hash, which is generated with the fields of the transaction. Ripple-REST uses an additional type of identifier, called a Client Resource ID, which is an arbitrary string provided at the time a transaction is submitted. - -A client resource ID generally maps to one Ripple transaction. However, if Ripple-REST re-submits a failed transaction, the client resource ID can become associated with the new transaction, which may have slightly different properties (such as the deadline for it to succeed) and therefore a different transaction hash. - -You can create client resource IDs using any method you like, so long as you follow some simple rules: - -* Do not reuse identifiers. -* A client resource ID cannot be a 256-bit hex string, because that is ambiguous with Ripple transaction hashes. -* Client resource IDs must be properly [encoded](http://tools.ietf.org/html/rfc3986#section-2.1) when provided as part of a URL. - -You can use the [Create Client Resource ID](#create-client-resource-id) method in order to generate new Client Resource IDs. - - -## Using Ripple-REST ## - -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: - -`https://api.ripple.com` - -If you want to run your own Ripple-REST server, see the [installation instructions](#running-ripple-rest). - -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/). - -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 that allows you to make secure HTTP (`HTTPS`) GET and POST requests. For testing, 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 ### - -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: - -https://api.ripple.com/v1/server - -The response should be a page with content similar to the following: - -```js -{ - "rippled_server_url": "wss://s-west.ripple.com:443", - "rippled_server_status": { - "build_version": "0.23.0", - "complete_ledgers": "5526705-6142138", - "fetch_pack": 2004, - "hostid": "NEAT", - "last_close": { - "converge_time_s": 2.005, - "proposers": 5 - }, - "load_factor": 1, - "peers": 55, - "pubkey_node": "n9KmrBnGoyVf89WYdiAnvGnKFaVqjLdAYjKrBuvg2r8pMxGPp6MF", - "server_state": "full", - "validated_ledger": { - "age": 1, - "base_fee_xrp": 0.00001, - "hash": "BADDAB671EF21E8ED56B21253123D2C74139FE34E12DBE4B1F5527772EC88494", - "reserve_base_xrp": 20, - "reserve_inc_xrp": 5, - "seq": 6142138 - }, - "validation_quorum": 3 - }, - "success": true, - "api_documentation_url": "https://github.com/ripple/ripple-rest" -} -``` - -If you want to connect to your own server, just replace the hostname and port with the location of your instance. For example, if you are running Ripple-REST locally on port 5990, you can access the same information at the following URL: - -http://localhost:5990/v1/server - -Since the hostname depends on where your chosen Ripple-REST instance is, the methods in this document are identified using only the part of the path that comes after the hostname. - - - -# Running Ripple-REST # - -## Quick Start ## - -Ripple-REST requires [Node.js](http://nodejs.org/) and [sqlite 3](http://www.sqlite.org/). Before starting, you should make sure that you have both installed. - -Following that, use these instructions to get Ripple-REST installed and running: - -1. Clone the Ripple-REST repository with git: - `git clone https://github.com/ripple/ripple-rest.git` -2. Switch to the `ripple-rest` directory: - `cd ripple-rest` -3. Use *npm* to install additional dependencies: - `npm install` -4. Copy the example config file to `config.json`: - `cp config-example.json config.json` -5. Start the server: - `npm start` -6. Visit `http://localhost:5990` in a browser to view available endpoints and get started - - -## Configuring `ripple-rest` ## - -The Ripple-REST server uses [nconf](https://github.com/flatiron/nconf) to load configuration options from several sources. Settings from sources earlier in the following hierarchy override settings from the later levels: - -1. Command line arguments -2. Environment variables -3. The `config.json` file - -The path to the `config.json` file can be specified as a command line argument (`node server.js --config /path/to/config.json`). If no path is specified, the default location for that file is Ripple-REST's root directory. - -Available configuration options are outlined in the [__Server Configuration__](https://github.com/ripple/ripple-rest/blob/develop/docs/server-configuration.md) document. The `config-example.json` file in the root directory contains a sample configuration. - - -## Debug mode ## -You can run the server in Debug Mode with the following command: - - node server.js --debug - - -## Running Ripple-REST securely over SSL ## - -We highly recommend running Ripple-REST securely over SSL. Doing so requires a certificate. For development and internal-only deployments, you can use a self-signed certificate. For production servers that are accessed over untrusted network connections, you should purchase a cert from a proper authority. - -You can perform the following steps to generate a self-signed cert with [OpenSSL](https://www.openssl.org/) and configure Ripple-REST to use it: - -1. Generate the SSL certificate: - -```bash -openssl genrsa -out /etc/ssl/private/server.key 2048 -openssl req -utf8 -new -key /etc/ssl/private/server.key -out /etc/ssl/server.csr -sha512 --batch -openssl x509 -req -days 730 -in /etc/ssl/server.csr -signkey /etc/ssl/private/server.key --out /etc/ssl/certs/server.crt -sha512 -``` - -2. Modify the `config.json` to enable SSL and specify the paths to the `certificate` and `key` files - -``` - "ssl_enabled": true, - "ssl": { - "key_path": "./certs/server.key", - "cert_path": "./certs/server.crt" - }, - -``` - -## Deployment Tips ## - -### Keeping the service running ### - -Monitor `ripple-rest` using [`monit`](http://mmonit.com/monit/). On Ubuntu you can install `monit` using `sudo apt-get install monit`. - -Here is an example of a monit script that will restart the server if: - -- memory usage surpasses 25% of the server's available memory -- the server fails responding to server status - -``` -set httpd port 2812 and allow localhost - -check process ripple-rest with pidfile /var/run/ripple-rest/ripple-rest.pid - start program = "/etc/init.d/ripple-rest start" - stop program = "/etc/init.d/ripple-rest stop" - if memory > 25% then restart - if failed port 5990 protocol HTTP - and request "/v1/server" - then restart -``` - - - -# Formatting Conventions # - -The `ripple-rest` API conforms to the following general behavior for [RESTful API](http://en.wikipedia.org/wiki/Representational_state_transfer): - -* 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.) -* 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. -* If more complicated information needs to be sent, it will be included as JSON-formatted data within the body of the HTTP POST request. - * This means that you must set `Content-Type: application/json` in the headers when sending POST requests with a body. -* 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. - -As an additional convention, all responses from Ripple-REST contain a `"success"` field with a boolean value indicating whether or not the success - -## Errors ## - -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. - -In general, the HTTP status code is indicative of where the problem occurred: - -* Codes in the 200-299 range indicate success. (*Note:* This behavior is new in [Ripple-REST v1.3.0](https://github.com/ripple/ripple-rest/releases/tag/1.3.0). Previous versions sometimes return 200 OK for some types of errors.) - * Unless otherwise specified, methods are expected to return `200 OK` on success. -* 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: - * `500 Internal Server Error` occurs when the server does not catch an error. This is always a bug. If you can reproduce the error, file it at [our bug tracker](https://ripplelabs.atlassian.net/browse/RA/). - * `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. - -When possible, the server provides a JSON response body with more information about the error. These responses contain the following fields: - -| Field | Type | Description | -|-------|------|-------------| -| success | Boolean | `false` indicates that an error occurred. | -| error_type | String | A short code identifying a general category for the error that occurred. | -| error | String | A human-readable summary of the error that occurred. | -| message | String | (May be omitted) A longer human-readable explanation for the error. | - -Example error: - -```js -{ - "success": false, - "error_type": "invalid_request", - "error": "Invalid parameter: destination_amount", - "message": "Non-XRP payment must have an issuer" -} -``` - - -## 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. - -## Currency Amounts ## - -There are two kinds of currency on the Ripple network: XRP, and issuances. XRP is the native cryptocurrency that only exists in the network, and can be held by accounts and sent directly to other accounts with no trust necessary. - -All other currencies take the form of *issuances*, which are held in the *trust lines* that link accounts. Issuances are identified by a `counterparty` on the other end of the trust line, sometimes also called the `issuer`. Sending and trading issuances actually means debiting the balance of a trust line and crediting the balance of another trust line linked to the same account. Ripple ensures this operation happens atomically. - -Issuances are typically created by Gateway accounts in exchange for assets in the outside world. In most cases, the `counterparty` of a currency refers to the gateway that created the issuances. XRP never has a counterparty. - -You can read more about [XRP](https://ripple.com/knowledge_categories/xrp/) and [Gateways](https://ripple.com/knowledge_center/gateways/) in the Knowledge Center. - - -### Amounts in JSON ### - -When an amount of currency is specified as part of a JSON body, it is encoded as an object with three fields: - -| Field | Type | 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. Alternatively, a 160-bit hex value. (Some advanced features, like [demurrage](https://ripple.com/wiki/Gateway_demurrage), require the hex version.) | -| counterparty | String | (New in [v1.4.0](https://github.com/ripple/ripple-rest/releases/tag/1.4.0)) The Ripple address of the account that is a counterparty to this currency. This is usually an [issuing gateway](https://ripple.com/knowledge_center/gateways/). Always omitted, or an empty string, for XRP. | -| issuer | String | (Prior to 1.4.0) **DEPRECATED** alias for `counterparty`. Some methods may still return this instead. | - - -Example Amount Object: - -```js -{ - "value": "1.0", - "currency": "USD", - "counterparty": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" -} -``` - -or for XRP: - -```js -{ - "value": "1.0", - "currency": "XRP", - "counterparty": "" -} -``` - -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 counterparty -- but concatenate them with `+` symbols in that order. - -Example Amount: - -`1.0+USD+rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q` - -When specifying an amount of XRP, you must omit the counterparty entirely. For example: - -`1.0+XRP` - -### Counterparties in Payments ### - -Most of the time, the `counterparty` field of a non-XRP currency indicates the account of the gateway that issues that currency. However, when describing payments, there are a few nuances that are important: - -* There is only ever one balance for the same currency between two accounts. This means that, sometimes, the `counterparty` field of an amount actually refers to a counterparty that is redeeming issuances, instead of the account that created the issuances. -* You can omit the counterparty from the `destination_amount` of a payment to mean "any counterparty that the destination accepts". This includes all accounts to which the destination has extended trust lines, as well as issuances created by the destination which may be held on other trust lines. - * For compatibility with `rippled`, setting the `counterparty` of the `destination_amount` to be the destination account's address means the same thing. -* You can omit the counterparty from the `source_amount` of a payment to mean "any counterparty the source can use". This includes creating new issuances on trust lines that other accounts have extended to the source account, as well as issuances from other accounts that the source account possesses. - * Similarly, setting the `counterparty` of the `source_amount` to be the source account's address means the same thing. - - -## 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. - -An example Payment object looks like this: - -```js -{ - - "source_address": "rKXCummUHnenhYudNb9UoJ4mGBR75vFcgz", - "source_tag": "", - "source_amount": { - "value": "0.001", - "currency": "XRP", - "issuer": "" - }, - "source_slippage": "0", - "destination_address": "rNw4ozCG514KEjPs5cDrqEcdsi31Jtfm5r", - "destination_tag": "", - "destination_amount": { - "value": "0.001", - "currency": "XRP", - "issuer": "" - }, - "invoice_id": "", - "paths": "[]", - "flag_no_direct_ripple": false, - "flag_partial_payment": false -} -``` - -The fields of a Payment object are defined as follows: - -| Field | Type | Description | -|-------|------|-------------| -| `source_account` | String | The Ripple address of the account sending the payment | -| `source_amount` | [Amount Object](#amount_object) | The amount to deduct from the account sending the payment. | -| `destination_account` | String | The Ripple address of the account receiving the payment | -| `destination_amount` | [Amount Object](#amount_object) | The amount that should be deposited into the account receiving the payment. | -| `source_tag` | String (Quoted unsigned integer) | (Optional) A quoted 32-bit unsigned integer (0-4294967294, inclusive) to indicate a sub-category of the source account. Typically, it identifies a hosted wallet at a gateway as the sender of the payment. | -| `destination_tag` | String (Quoted unsigned integer) | (Optional) A quoted 32-bit unsigned integer (0-4294967294, inclusive) to indicate a particular sub-category of the destination account. Typically, it identifies a hosted wallet at a gateway as the recipient of the payment. | -| `source_slippage` | String (Quoted decimal) | (Optional) Provides the `source_amount` a cushion to 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) Arbitrary 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. | -| `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. | -| `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) | -| `memos` | Array | (Optional) Array of [memo objects](#memo-objects), where each object is an arbitrary note to send with this payment. | - -Submitted transactions can have additional fields reflecting the current status and outcome of the transaction, including: - -[[Source]
](https://github.com/ripple/ripple-rest/blob/59ea02d634ac4a308db2ba21781efbc02f5ccf53/lib/tx-to-rest-converter.js#L25 "Source") - -| Field | Type | Description | -|-------|------|-------------| -| direction | String | The direction of the payment relative to the account from the URL, either `"outgoing"` (sent by the account in the URL) or `"incoming"` (received by the account in the URL) | -| result | String | The [Ripple transaction status code](transactions.html#transaction-results) for the transaction. A value of `"tesSUCCESS"` indicates a successful transaction. | -| timestamp | String | The time the ledger containing this transaction was validated, as a [ISO8601 extended format](http://en.wikipedia.org/wiki/ISO_8601) string in the form `YYYY-MM-DDTHH:mm:ss.sssZ`. | -| fee | String (Quoted decimal) | The amount of XRP charged as a transaction fee. | -| source_balance_changes | Array | Array of [Amount objects](#amount_object) indicating changes in balances held by the account sending the transaction as a result of the transaction. | -| destination_balance_changes | Array | Array of [Amount objects](#amount_object) indicating changes in balances held by the account receiving the transaction as a result of the transaction. | -| order\_changes | Array | Array of [Amount objects](#amount_object) indicating changes to orders caused by the Payment. | -| source_amount_submitted | Object | An [Amount object](#amount_object) indicating the source amount submitted (useful when `payment.partial_payment` flag is set to *true* | - - -### Memo Objects ### - -_(New in [Ripple-REST v1.3.0](https://github.com/ripple/ripple-rest/releases/tag/1.3.0))_ - -Memo objects represent arbitrary data that can be included in a transaction. The overall size of the `memos` field cannot exceed 1KB after serialization. - -Each Memo object must have at least one of the following fields: - -| Field | Type | Description | -|-------|------|-------------| -| MemoType | String | A string using URL-safe characters, conventionally a unique relation type (according to [RFC 5988](http://tools.ietf.org/html/rfc5988#section-4)) that defines the format of this memo. | -| MemoFormat | String | A string using URL-safe characters, conventionally containing information on how the memo is encoded, for example as a [MIME type](http://www.iana.org/assignments/media-types/media-types.xhtml) | -| MemoData | String | Arbitrary UTF-8 string representing the content of the memo. | - -The MemoType and MemoFormat fields should only consist of the following characters: `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=%` - -Example of the memos field: - -```js - "memos": [ - { - "MemoType": "http://example.com/unique/memo/relation", - "MemoData": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum是指一篇常用於排版設計領域的拉丁文文章,主要的目的為測試文章或文字在不同字型、版型下看起來的效果。Lorem ipsum es el texto que se usa habitualmente en diseño gráfico en demostraciones de tipografías o de borradores de diseño para probar el diseño visual antes de insertar el texto final." - }, - { - "MemoData": "Fusce est est, malesuada in tincidunt mattis, auctor eu magna." - } - ] -``` - -## Order Objects ## - -_(New in [Ripple-REST 1.4.0](https://github.com/ripple/ripple-rest/releases/tag/1.4.0))_ - -An order object describes an offer to exchange two currencies. Order objects are used when creating or looking up individual orders. - -| Field | Value | Description | -|-------|-------|-------------| -| type | String (`buy` or `sell`) | Whether the order is to buy or sell. | -| taker\_pays | String ([Amount Object](#amount_object)) | The amount the taker must pay to consume this order. | -| taker\_gets | String ([Amount Object](#amount_object)) | The amount the taker will get once the order is consumed. | -| sequence | Number | The sequence number of the transaction that created the order. Used in combination with account to uniquely identify the order. | -| passive | Boolean | Whether the order should be [passive](transactions.html#offercreate-flags). | -| sell | Boolean | Whether the order should be [sell](transactions.html#offercreate-flags). | -| immediate\_or\_cancel | Boolean | Whether the order should be [immediate or cancel](transactions.html#offercreate-flags). | -| fill\_or\_kill | Boolean | Whether the order should be [fill or kill](transactions.html#offercreate-flags). | - -## Order Change Objects ## - -An order change object describes the changes to to a Ripple account's open order due to a transaction. - -| Field | Value | Description | -|-------|-------|-------------| -| type | String (`buy` or `sell`) | Whether the order is to buy or sell. | -| taker\_pays | String ([Amount Object](#amount_object)) | The `value` of the amount is expressed as the difference between the final amount and original amount. | -| taker\_gets | String ([Amount Object](#amount_object)) | The `value` of the amount is expressed as the difference between the final amount and original amount. | -| sequence | Number | The sequence number of the transaction that created the order. Used in combination with account to uniquely identify the order. | -| status | String(`created`, `closed`, `canceled`, `open`) | The status of the order on the ledger. An order that is partially filled has the status `open`. | - - -## Bid Objects ## - -An bid object describes an offer to exchange two currencies, including the current funding status of the offer. Bid objects are used to describe bids and asks when retrieving an order book. - -| Field | Value | Description | -|-------|-------|-------------| -| type | String (`buy` or `sell`) | Whether the order is to buy or sell. | -| price | String ([Amount Object](#amount_object)) | The quoted price, denominated in total units of the counter currency per unit of the base currency | -| taker\_pays\_total | String ([Amount Object](#amount_object)) | The total amount the taker must pay to consume this order. | -| taker\_pays\_funded | String ([Amount Object](#amount_object)) | The actual amount the taker must pay to consume this order, if the order is [partially funded](transactions.html#lifecycle-of-an-offer). | -| taker\_gets\_total | String ([Amount Object](#amount_object)) | The total amount the taker will get once the order is consumed. | -| taker\_gets\_funded | String ([Amount Object](#amount_object)) | The actual amount the taker will get once the order is consumed, if the order is [partially funded](transactions.html#lifecycle-of-an-offer). | -| order\_maker | String | The Ripple address of the account that placed the bid or ask on the order book. | -| sequence | Number | The sequence number of the transaction that created the order. Used in combination with account to uniquely identify the order. | -| sell | Boolean | Whether the order should be [sell](https://ripple.com/build/transactions/#offercreate-flags). | -| passive | Boolean | Whether the order should be [passive](https://ripple.com/build/transactions/#offercreate-flags). | - -## Trustline Objects ## - -A trustline object describes a link between two accounts that allows one to hold the other's issuances. A trustline can also be two-way, meaning that each can hold balances issued by the other, but that case is less common. In other words, a trustline tracks money owed. - -A trustline with a positive limit indicates an account accepts issuances from the other account (typically an issuing gateway) as payment, up to the limit. An account cannot receive a payment that increases its balance over that trust limit. It is possible, however, to go over a limit by either by trading currencies or by decreasing the limit while already holding a balance. - -From the perspective of an account on one side of the trustline, the trustline has the following fields: - -| Field | Value | Description | -|-------|-------|-------------| -| account | String (Address) | This account | -| counterparty | String (Address) | The account at the other end of the trustline | -| currency | String | Currency code for the type of currency that is held on this trustline. | -| limit | String (Quoted decimal) | The maximum amount of currency issued by the counterparty account that this account should hold. | -| reciprocated_limit | String (Quoted decimal) | (Read-only) The maximum amount of currency issued by this account that the counterparty account should hold. | -| account\_allows\_rippling | Boolean | If set to false on two trustlines from the same account, payments cannot ripple between them. (See the [NoRipple flag](https://ripple.com/knowledge_center/understanding-the-noripple-flag/) for details.) | -| counterparty\_allows\_rippling | Boolean | (Read-only) If false, the counterparty account has the [NoRipple flag](https://ripple.com/knowledge_center/understanding-the-noripple-flag/) enabled. | -| account\_trustline\_frozen | Boolean | Indicates whether this account has [frozen](https://wiki.ripple.com/Freeze) the trustline. (`account_froze_trustline` prior to [v1.4.0](https://github.com/ripple/ripple-rest/releases/tag/1.4.0)) | -| counterparty\_trustline\_frozen | Boolean | (Read-only) Indicates whether the counterparty account has [frozen](https://wiki.ripple.com/Freeze) the trustline. (`counterparty_froze_line` prior to [v1.4.0](https://github.com/ripple/ripple-rest/releases/tag/1.4.0)) | - -The read-only fields indicate portions of the trustline that pertain to the counterparty, and can only be changed by that account. (The `counterparty` field is technically part of the identity of the trustline. If you "change" it, that just means that you are referring to a different trustline object.) - -A trust line with a limit *and* a balance of 0 is equivalent to no trust line. - - -# ACCOUNTS # - -Accounts are the core unit of authentication in the Ripple Network. Each account can hold balances in multiple currencies, and all transactions must be signed by an account’s secret key. In order for an account to exist in a validated ledger version, it must hold a minimum reserve amount of XRP. (The [account reserve](reserves.html) increases with the amount of data it is responsible for in the shared ledger.) It is expected that accounts will correspond loosely to individual users. - - - -## Generate Wallet ## - -(New in [Ripple-REST v1.3.0](https://github.com/ripple/ripple-rest/releases/tag/1.3.0)) - -Randomly generate keys for a potential new Ripple account. - -
- -*REST* - -``` -GET /v1/wallet/new -``` - -
- -[Try it! >](rest-api-tool.html#generate-wallet) - -There are two steps to making a new account on the Ripple network: randomly creating the keys for that account, and sending it enough XRP to meet the account reserve. - -Generating the keys can be done offline, since it does not affect the network at all. To make it easy, Ripple-REST can generate account keys for you. - -*Caution:* Ripple account keys are very sensitive, since they give full control over that account's money on the Ripple network. Do not transmit them to untrusted servers, or unencrypted over the internet (for example, through HTTP instead of HTTPS). There *are* bad actors who are sniffing around for account keys so they can steal your money! - -#### Response #### - -The response is an object with the address and the secret for a potential new account: - -```js -{ - "success": true, - "account": { - "address": "raqFu9wswvHYS4q5hZqZxVSYei73DQnKL8", - "secret": "shUzHiYxoXX2FgA54j42cXCZ9dTVT" - } -} -``` - -The second step is [making a payment](#payments) of XRP to the new account address. (Ripple lets you send XRP to any mathematically possible account address, which creates the account if necessary.) The generated account does not exist in the ledger until it receives enough XRP to meet the account reserve. - - - -## Get Account Balances ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/a268d7058b9bf20d48a1b61d86093756e5274512/api/balances.js#L34 "Source") - -Retrieve the current balances for the given Ripple account. - -
- -*REST* - -``` -GET /v1/accounts/{:address}/balances -``` - -
- -[Try it! >](rest-api-tool.html#get-account-balances) - -The following URL parameters are required by this API endpoint: - -| Field | Type | Description | -|-------|------|-------------| -| address | String | The Ripple account address of the account whose balances to retrieve. | - -Optionally, you can also include any of the following query parameters: - -| Field | Type | Description | -|-------|------|-------------| -| currency | String ([ISO 4217 Currency Code](http://www.xe.com/iso4217.php)) | If provided, only include balances in the given currency. | -| counterparty | String (Address) | If provided, only include balances issued by the provided address (usually a gateway). | -| marker | String | Server-provided value that marks where to resume pagination. | -| limit | String (Integer or `all`) | (Defaults to 200) Max results per response. Cannot be less than 10. Cannot be greater than 400. Use `all` to return all results | -| ledger | String (ledger hash or sequence, or 'validated', 'current', or 'closed') | (Defaults to 'validated') Identifying ledger version to pull results from. | - -*Note:* Pagination using `limit` and `marker` requires a consistent ledger version, so you must also provide the `ledger` hash or sequence query parameter to use pagination. - -*Caution:* When an account holds balances on a very large number of trust lines, specifying `limit=all` may take a long time or even time out. If you experience timeouts, try again later, or specify a smaller limit. - -#### Response #### - -```js -{ - "success": true, - "marker": "0C812C919D343EAE789B29E8027C62C5792C22172D37EA2B2C0121D2381F80E1", - "limit": 200, - "ledger": 10478339, - "validated": true, - "balances": [ - { - "currency": "XRP", - "amount": "1046.29877312", - "counterparty": "" - }, - { - "currency": "USD", - "amount": "512.79", - "counterparty": "r...", - } - ... - ] -} -``` - -*Note:* `marker` will be present in the response when there are additional pages to page through. - -There is one entry in the `balances` array for the account's XRP balance, and additional entries for each combination of currency code and counterparty. - - - -## Get Account Settings ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/master/api/settings.js#L53 "Source") - -Retrieve the current settings for a given account. - -
- -*REST* - -``` -GET /v1/accounts/{:address}/settings -``` - -
- -[Try it! >](rest-api-tool.html#get-account-settings) - -The following URL parameters are required by this API endpoint: - -| Field | Value | Description | -|---------|-------|-------------| -| address | String | The Ripple account address of the account whose settings to retrieve. | - -#### Response #### - -```js -{ - "success": true, - "settings": { - "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", - "transfer_rate": 1004999999, - "password_spent": false, - "require_destination_tag": true, - "require_authorization": false, - "disallow_xrp": true, - "disable_master": false, - "no_freeze": false, - "global_freeze": false, - "default_ripple": true, - "transaction_sequence": "330", - "email_hash": "98B4375E1D753E5B91627516F6D70977", - "wallet_locator": "", - "wallet_size": "", - "message_key": "0000000000000000000000070000000300", - "domain": "mduo13.com", - "signers": "" - } -} -``` - -The response contains a `settings` object, with the following fields: - -| Field | Value | Description | -|-------|-------|-------------| -| account | String | The Ripple address of this account | -| transfer\_rate | String (Quoted decimal number) | If set, imposes a fee for transferring balances issued by this account. Must be between 1 and 2, with up to 9 decimal places of precision. See [TransferRate](transactions.html#transferrate) for details. | -| password\_spent | Boolean | If false, then this account can submit a special [SetRegularKey transaction](transactions.html#setregularkey) without a transaction fee. | -| require\_destination\_tag | Boolean | If true, require a destination tag to send payments to this account. (This is intended to protect users from accidentally omitting the destination tag in a payment to a gateway's hosted wallet.) | -| require\_authorization | Boolean | If true, require authorization for users to hold balances issued by this account. (This prevents users unknown to a gateway from holding funds issued by that gateway.) | -| disallow\_xrp | Boolean | If true, XRP should not be sent to this account. (Enforced in clients but not in the server, because it could cause accounts to become unusable if all their XRP were spent.) | -| disable\_master | Boolean | If true, the master secret key cannot be used to sign transactions for this account. Can only be set to true if a Regular Key is defined for the account. | -| no_freeze | Boolean | If true, the account has permanently given up the ability to [freeze](https://ripple.com/files/GB-2014-02.pdf) its trust lines. | -| global_freeze | Boolean | If true, all trust lines connected to the account are [frozen](https://ripple.com/files/GB-2014-02.pdf). | -| default\_ripple | Boolean | If true, enables [rippling](https://ripple.com/knowledge_center/understanding-the-noripple-flag/) on this account's trustlines by default. _(New in [Ripple-REST v1.5.0](https://github.com/ripple/ripple-rest/releases/tag/1.5.0-rc1))_ | -| transaction\_sequence | String (Quoted integer) | The sequence number of the next valid transaction for this account. (Each account starts with Sequence = 1 and increases each time a transaction is made.) | -| email_hash | String | Hash of an email address to be used for generating an avatar image. Conventionally, clients use [Gravatar](http://en.gravatar.com/site/implement/hash/) to display this image. | -| wallet\_locator | String | (Not used) | -| wallet\_size | String | (Not used) | -| message\_key | String | A [secp256k1](https://en.bitcoin.it/wiki/Secp256k1) public key that should be used to encrypt secret messages to this account. | -| domain | String | The domain that holds this account. Clients can use this to verify the account in the [ripple.txt](https://wiki.ripple.com/Ripple.txt) of the domain. | -| signers | (Undefined) | (To be used for [Multi-sign](https://wiki.ripple.com/M_of_N)) | - - - -## Update Account Settings ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/a268d7058b9bf20d48a1b61d86093756e5274512/api/settings.js#L135 "Source") - -Modify the existing settings for an account. - -
- -*REST* - -``` -POST /v1/accounts/{:address}/settings?validated=true - -{ - "secret": "sssssssssssssssssssssssssssss", - "settings": { - "transfer_rate": 1.02, - "require_destination_tag": false, - "require_authorization": false, - "disallow_xrp": false, - "disable_master": false, - "default_ripple": false - } -} -``` - -
- -[Try it! >](rest-api-tool.html#update-account-settings) - -The following URL parameters are required by this API endpoint: - -| Field | Value | Description | -|-------|-------|-------------| -| address | String | The Ripple account address of the account whose settings to retrieve. | - -The request body must be a JSON object with the following fields: - -| Field | Value | Description | -|-------|-------|-------------| -| secret | String | A secret key for your Ripple account. This is either the master secret, or a regular secret, if your account has one configured. | -| settings | Object | A map of settings to change for this account. Any settings not included are left unchanged. | - -Optionally, you can include the following as a URL query parameter: - -| Field | Type | Description | -|-----------|---------|-------------| -| validated | Boolean | If `true`, the server waits to respond until the account transaction has been successfully validated by the network. A validated transaction has `state` field of the response set to `"validated"`. | - -__DO NOT SUBMIT YOUR SECRET TO AN UNTRUSTED REST API SERVER__ -- The secret key can be used to send transactions from your account, including spending all the balances it holds. For the public server, only use test accounts. - -The `settings` object can contain any of the following fields (any omitted fields are left unchanged): - -| Field | Value | Description | -|-------|-------|-------------| -| transfer_rate | String (Quoted decimal number) | If set, imposes a fee for transferring balances issued by this account. Must be between 1 and 2, with up to 9 decimal places of precision. | -| require\_destination\_tag | Boolean | If true, require a destination tag to send payments to this account. (This is intended to protect users from accidentally omitting the destination tag in a payment to a gateway's hosted wallet.) | -| require\_authorization | Boolean | If true, require authorization for users to hold balances issued by this account. (This prevents users unknown to a gateway from holding funds issued by that gateway.) | -| disallow\_xrp | Boolean | If true, XRP should not be sent to this account. (Enforced in clients but not in the server, because it could cause accounts to become unusable if all their XRP were spent.) | -| disable_master | Boolean | If true, the master secret key cannot be used to sign transactions for this account. Can only be set to true if a Regular Key is defined for the account. | -| no_freeze | Boolean | If true, the account has permanently given up the ability to [freeze](https://ripple.com/files/GB-2014-02.pdf) its trust lines. Cannot be set to false after being true. | -| global_freeze | Boolean | If true, [freeze](https://ripple.com/files/GB-2014-02.pdf) all trust lines connected to the account. | -| default\_ripple | Boolean | If true, enables [rippling](https://ripple.com/knowledge_center/understanding-the-noripple-flag/) on this account's trustlines by default. _(New in [Ripple-REST v1.5.0](https://github.com/ripple/ripple-rest/releases/tag/1.5.0-rc1))_ | -| email_hash | String | Hash of an email address to be used for generating an avatar image. Conventionally, clients use [Gravatar](http://en.gravatar.com/site/implement/hash/) to display this image. | -| message\_key | String | A [secp256k1](https://en.bitcoin.it/wiki/Secp256k1) public key that should be used to encrypt secret messages to this account, as hex. | -| domain | String | The domain that holds this account, as lowercase ASCII. Clients can use this to verify the account in the [ripple.txt](https://wiki.ripple.com/Ripple.txt). | - -*Note:* Some of the account setting fields cannot be modified by this method. For example, the `password_spent` flag is only enabled when the account uses a free SetRegularKey transaction, and only disabled when the account receives a transmission of XRP. - -#### Response #### - -```js -{ - "success": true, - "settings": { - "require_destination_tag": false, - "require_authorization": false, - "disallow_xrp": false, - "email_hash": "98b4375e1d753e5b91627516f6d70977", - "state": "pending", - "ledger": "9248628", - "hash": "81FA244915767DAF65B0ACF262C88ABC60E9437A4A1B728F7A9F932E727B82C6" - } -} -``` - -The response is a JSON object containing the following fields: - -| Field | Value | Description | -|-------|-------|-------------| -| hash | String | A unique hash that identifies the Ripple transaction to change settings | -| ledger | String (Quoted integer) | The sequence number of the ledger version where the settings-change transaction was applied. | -| settings | Object | The settings that were changed, as provided in the request. | - - - - -# PAYMENTS # - -`ripple-rest` provides access to `ripple-lib`'s robust transaction submission processes. This means that it automatically manages the transaction cost and sequence number, signs the transaction with your secret, and resubmits the transaction up to 10 times if `rippled` reports an initial error that can be solved automatically. - - -## Prepare Payment ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/a268d7058b9bf20d48a1b61d86093756e5274512/api/payments.js#L484 "Source") - -Get quotes for possible ways to make a particular payment. - -
- -*REST* - -``` -GET /v1/accounts/{:source_address}/payments/paths/{:destination_address}/{:amount} -``` - -
- -[Try it! >](rest-api-tool.html#prepare-payment) - -The following URL parameters are required by this API endpoint: - -| Field | Type | 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. | - -Optionally, you can also include the following as a query parameter: - -| Field | Type | 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}+{:counterparty}` string. | Filters possible payments to include only ones that spend the source account's balances in the specified currencies. If a counterparty is not specified, include all issuances of that currency held by the sending account. | - -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. This method effectively performs a [ripple_path_find](rippled-apis.html#ripple-path-find) and constructs payment objects for the paths it finds. - -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. - -#### Response #### - -```js -{ - "success": true, - "payments": [ - { - "source_account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", - "source_tag": "", - "source_amount": { - "value": "1.008413509923106", - "currency": "USD", - "issuer": "" - }, - "source_slippage": "0", - "destination_account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH", - "destination_tag": "", - "destination_amount": { - "value": "1", - "currency": "USD", - "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" - }, - "invoice_id": "", - "paths": "[[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\",\"type\":1,\"type_hex\":\"0000000000000001\"},{\"currency\":\"USD\",\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"type\":48,\"type_hex\":\"0000000000000030\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"type\":1,\"type_hex\":\"0000000000000001\"}],[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\",\"type\":1,\"type_hex\":\"0000000000000001\"},{\"currency\":\"XRP\",\"type\":16,\"type_hex\":\"0000000000000010\"},{\"currency\":\"USD\",\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"type\":48,\"type_hex\":\"0000000000000030\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"type\":1,\"type_hex\":\"0000000000000001\"}]]", - "partial_payment": false, - "no_direct_ripple": false - }, - { - "source_account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", - "source_tag": "", - "source_amount": { - "value": "61.06103", - "currency": "XRP", - "issuer": "" - }, - "source_slippage": "0", - "destination_account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH", - "destination_tag": "", - "destination_amount": { - "value": "1", - "currency": "USD", - "issuer": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q" - }, - "invoice_id": "", - "paths": "[[{\"currency\":\"USD\",\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"type\":48,\"type_hex\":\"0000000000000030\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"type\":1,\"type_hex\":\"0000000000000001\"}],[{\"currency\":\"USD\",\"issuer\":\"rpDMez6pm6dBve2TJsmDpv7Yae6V5Pyvy2\",\"type\":48,\"type_hex\":\"0000000000000030\"},{\"account\":\"rpDMez6pm6dBve2TJsmDpv7Yae6V5Pyvy2\",\"type\":1,\"type_hex\":\"0000000000000001\"},{\"account\":\"rHAwwozJw6FHfnJfRQaFXrkGHocGoaNYSy\",\"type\":1,\"type_hex\":\"0000000000000001\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"type\":1,\"type_hex\":\"0000000000000001\"}],[{\"currency\":\"USD\",\"issuer\":\"rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc\",\"type\":48,\"type_hex\":\"0000000000000030\"},{\"account\":\"rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc\",\"type\":1,\"type_hex\":\"0000000000000001\"},{\"account\":\"rEtr3Kzh5MmhPbeNu6PDtQZsKBpgFEEEo5\",\"type\":1,\"type_hex\":\"0000000000000001\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"type\":1,\"type_hex\":\"0000000000000001\"}],[{\"currency\":\"USD\",\"issuer\":\"rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc\",\"type\":48,\"type_hex\":\"0000000000000030\"},{\"account\":\"rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc\",\"type\":1,\"type_hex\":\"0000000000000001\"},{\"account\":\"rKvPTQrD8ap1Y8TSmKjcK6G7q7Kvx7RAqQ\",\"type\":1,\"type_hex\":\"0000000000000001\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"type\":1,\"type_hex\":\"0000000000000001\"}]]", - "partial_payment": false, - "no_direct_ripple": false - } - ] -} -``` - -You can then select the desired payment, modify it if necessary, and submit the payment object to the [`POST /v1/accounts/{address}/payments`](#submit-payment) endpoint for processing. - -__NOTE:__ This command may be quite slow. If the command times out, please try it again. - - - -## Submit Payment ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/a268d7058b9bf20d48a1b61d86093756e5274512/api/payments.js#L52 "Source") - -Submit a payment object to be processed and executed. - -
- -*REST* - -``` -POST /v1/accounts/{address}/payments?validated=true - -{ - "secret": "s...", - "client_resource_id": "123", - "last_ledger_sequence": "1...", - "max_fee": "0.1", - "fixed_fee": "0.01", - "payment": { - "source_account": "rBEXjfD3MuXKATePRwrk4AqgqzuD9JjQqv", - "source_tag": "", - "source_amount": { - "value": "5.01", - "currency": "USD", - "issuer": "" - }, - "source_slippage": "0", - "destination_account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59", - "destination_tag": "", - "destination_amount": { - "value": "5", - "currency": "USD", - "issuer": "" - }, - "invoice_id": "", - "paths": "[[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\",\"type\":1,\"type_hex\":\"0000000000000001\"}]]", - "partial_payment": false, - "no_direct_ripple": false - } -} -``` - -
- -[Try it! >](rest-api-tool.html#submit-payment) - -The JSON body of the request includes the following parameters: - -| Field | Type | Description | -|-------|------|-------------| -| payment | [Payment object](#payment_object) | The payment to send. You can generate a payment object using the [Prepare Payment](#prepare-payment) method. | -| client\_resource\_id | String | A unique identifier for this payment. You can generate one using the [`GET /v1/uuid`](#create-client-resource-id) method. | -| secret | String | A secret key for your Ripple account. This is either the master secret, or a regular secret, if your account has one configured. | -| last\_ledger\_sequence | String | (Optional) A string representation of a ledger sequence number. If this parameter is not set, it defaults to the current ledger sequence plus an appropriate buffer. | -| max\_fee | String | (Optional) The maximum [transaction cost](tx-cost.html) to allow, as a decimal amount of XRP. | -| fixed\_fee | String | (Optional) The exact [transaction cost](tx-cost.html) to pay, as a decimal amount of XRP. | - -__DO NOT SUBMIT YOUR SECRET TO AN UNTRUSTED REST API SERVER__ -- The secret key can be used to send transactions from your account, including spending all the balances it holds. For the public server, only use test accounts. - -*Note:* The [transaction cost](tx-cost.html) is determined as follows: - -1. If `fixed_fee` is included, that exact value is used for the transaction cost. Otherwise, the transaction cost is set dynamically based on the server's current cost. -2. If `max_fee` is included and the server requires a transaction cost that is higher than `max_fee`, then the transaction is rejected without being submitted. This is true regardless of whether the transaction cost was fixed or dynamically set. Otherwise, the transaction is submitted to the `rippled` server with the specified transaction cost. -3. If the transaction succeeds, the sending account loses the whole amount of the transaction cost, even if it was higher than the server's current requirement. -4. If the transaction fails because the transaction cost was not high enough, Ripple-REST automatically resubmits it later. In this case, return to step 1. - -Consequently, you can use `max_fee` as a "set-it-and-forget-it" safeguard on the transaction cost you are willing to pay. - -Optionally, you can include the following as a URL query parameter: - -| Field | Type | Description | -|-------|------|-------------| -| validated | Boolean | If `true`, the server waits to respond until the payment has been successfully validated by the network and returns the payment object. Otherwise, the server responds immediately with a message indicating that the transaction was received for processing. | - - -#### Response #### - -The response can take two formats, depending on the `validated` query parameter: - -* If `validated` is set to `true`, then the response matches the format from [Confirm Payment](#confirm-payment). -* If `validated` is omitted or set to `false`, then the response is a JSON object as follows: - -```js -{ - "success": true, - "client_resource_id": "123", - "status_url": ".../v1/accounts/r1.../payments/123" -} -``` - -| Field | Type | Description | -|-------|------|-------------| -| success | Boolean | A value of `true` only indicates that the request was received, not that the transaction was processed. | -| client_resource_id | String | The client resource ID provided in the request | -| status_url | String | A URL that you can GET to check the status of the request. This refers to the [Confirm Payment](#confirm-payment) method. | - - - -## Confirm Payment ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/a268d7058b9bf20d48a1b61d86093756e5274512/api/payments.js#L270 "Source") - -Retrieve the details of a payment, including the current state of the transaction and the result of transaction processing. - -
- -*REST* - -``` -GET /v1/accounts/{:address}/payments/{:id} -``` - -
- -[Try it! >](rest-api-tool.html#confirm-payment) - -The following URL parameters are required by this API endpoint: - -| Field | Type | Description | -|-------|------|-------------| -| address | String | The Ripple account address of an account involved in the transaction. | -| id | String | A unique identifier for the transaction: either a client resource ID or a transaction hash. | - -#### Response #### - -```js -{ - "success": true, - "payment": { - "source_account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", - "source_tag": "", - "source_amount": { - "value": "0.00001", - "currency": "XRP", - "issuer": "" - }, - "source_slippage": "0", - "destination_account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", - "destination_tag": "", - "destination_amount": { - "value": "0.00000005080000000000001", - "currency": "USD", - "issuer": "rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc" - }, - "invoice_id": "", - "paths": "[]", - "no_direct_ripple": false, - "partial_payment": true, - "direction": "outgoing", - "result": "tesSUCCESS", - "timestamp": "2014-09-17T21:47:00.000Z", - "fee": "0.00001", - "source_balance_changes": [ - { - "currency": "XRP", - "value": "-0.00002", - "issuer": "" - } - ], - "destination_balance_changes": [ - { - "currency": "USD", - "value": "5.08e-8", - "issuer": "rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc" - } - ], - "order_changes": [], - "destination_amount_submitted": { - "value": "0.01", - "currency": "USD", - "issuer": "rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc" - }, - "source_amount_submitted": { - "value": "0.00001", - "currency": "XRP", - "issuer": "" - } - }, - "client_resource_id": "", - "hash": "9D591B18EDDD34F0B6CF4223A2940AEA2C3CC778925BABF289E0011CD8FA056E", - "ledger": "8924146", - "state": "validated" -} -``` - -| Field | Type | Description | -|-------|------|-------------| -| payment | Object | A [payment object](#payment-objects) for the transaction. | -| client\_resource\_id | String | The [client resource identifier](#client-resource-ids) used for this payment. | -| hash | String (Transaction Hash) | A hash value that uniquely identifies this transaction in the Ripple network. | -| ledger | String (Ledger Index) | (May be omitted) The sequence number of the ledger that includes this transaction, if this transaction is in a ledger. | -| state | String | Whether or not the transaction is included in a ledger that has been validated by consensus. | - -_New in [v1.4.0](https://github.com/ripple/ripple-rest/releases/tag/1.4.0) - The `hash`, `ledger`, and `state` fields have been moved to the top level. Previously, they were included as part of the Payment object._ - -If the `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 `result` field of the Payment 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. - -Processing a payment can take several seconds to complete, depending on the [consensus process](https://ripple.com/consensus-whitepaper/). If the payment does not exist yet, or has not been validated, you should wait a few seconds before checking again. - - - -## Get Payment History ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/a268d7058b9bf20d48a1b61d86093756e5274512/api/payments.js#L394 "Source") - -Retrieve a selection of payments that affected the specified account. - -
- -*REST* - -``` -GET /v1/accounts/{:address}/payments -``` - -
- -[Try it! >](rest-api-tool.html#get-payment-history) - -The following URL parameters are required by this API endpoint: - -| Field | Type | Description | -|-------|------|-------------| -| address | String | The Ripple account address of an account involved in the transaction. | - -Optionally, you can also include the following query parameters: - -| Field | Type | Description | -|-------|------|-------------| -| source_account | String (Address) | If provided, only include payments sent by a given account. | -| destination_account | String (Address) | If provided, only include payments received by a given account. | -| exclude_failed | Boolean | If true, only include successful transactions. Defaults to false. | -| direction | String | If provided, only include payments of the given type. Valid values include `"incoming"` (payments received by this account) and `"outgoing"` (payments sent by this account). | -| earliest_first | Boolean | If true, sort results with the oldest payments first. Defaults to false (sort with the most recent payments first). | -| start\_ledger | Integer (Ledger sequence number) | If provided, exclude payments from ledger versions older than the given ledger. | -| end\_ledger | Integer (Ledger sequence number) | If provided, exclude payments from ledger versions newer than the given ledger. | -| results\_per\_page | Integer | The maximum number of payments to be returned at once. Defaults to 10. | -| page | Integer | The page number for the results to return, if more than `results_per_page` are available. The first page of results is page `1`, the second page is number `2`, and so on. Defaults to `1`. | - -#### Response #### - -```js -{ - "success": true, - "payments": [ - { - "payment": { - "source_account": "rBvktWhzs4MQDaFYScsqPCB5YufRDXwKDC", - "source_tag": "", - "source_amount": { - "value": "1166313.057", - "currency": "JPY", - "issuer": "r94s8px6kSw1uZ1MV98dhSRTvc6VMPoPcN" - }, - "source_slippage": "0", - "destination_account": "rBvktWhzs4MQDaFYScsqPCB5YufRDXwKDC", - "destination_tag": "", - "destination_amount": { - "value": "600000", - "currency": "XRP", - "issuer": "" - }, - "invoice_id": "", - "paths": "[[{\"currency\":\"XRP\",\"type\":16,\"type_hex\":\"0000000000000010\"}]]", - "no_direct_ripple": false, - "partial_payment": false, - "direction": "passthrough", - "result": "tesSUCCESS", - "timestamp": "2015-02-06T03:59:30.000Z", - "fee": "0.012", - "source_balance_changes": [ - { - "currency": "JPY", - "value": "-1164533.852420654", - "issuer": "r94s8px6kSw1uZ1MV98dhSRTvc6VMPoPcN" - }, - { - "currency": "XRP", - "value": "599999.988", - "issuer": "" - } - ], - "destination_balance_changes": [ - { - "currency": "JPY", - "value": "-1164533.852420654", - "issuer": "r94s8px6kSw1uZ1MV98dhSRTvc6VMPoPcN" - }, - { - "currency": "XRP", - "value": "599999.988", - "issuer": "" - } - ], - "order_changes": [ - { - "taker_pays": { - "currency": "JPY", - "counterparty": "r94s8px6kSw1uZ1MV98dhSRTvc6VMPoPcN", - "value": "-67605.3" - }, - "taker_gets": { - "currency": "XRP", - "counterparty": "", - "value": "-34300" - }, - "sequence": 3751, - "status": "closed" - } - ], - "memos": [ - { - "MemoType": "636C69656E74", - "MemoFormat": "7274312E332E31", - "parsed_memo_type": "client", - "parsed_memo_format": "rt1.3.1" - } - ] - }, - "client_resource_id": "", - "hash": "E485D1E18D946ACD410AD79F51E2C57E887CC206286E6CE0A1CA80FC75C24643", - "ledger": "11547185", - "state": "validated" - } - ] -} -``` - -If the length of the `payments` array is equal to `results_per_page`, then there may be more results. To get them, increment the `page` query paramter and run the request again. - -*Note:* It is not more efficient to specify more filter values, because Ripple-REST has to retrieve the full list of payments from the `rippled` before it can filter them. - -# ORDERS # - -## Place Order ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/59ea02d634ac4a308db2ba21781efbc02f5ccf53/api/orders.js#L161 "Source") - -(New in [Ripple-REST v1.3.2](https://github.com/ripple/ripple-rest/releases/tag/1.3.2-rc4)) - -Places an order to exchange currencies. - -
- -*REST* - -``` -POST /v1/accounts/{:address}/orders?validated=true -{ - "secret": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9", - "order": { - "type": "sell", - "taker_pays": { - "currency": "JPY", - "counterparty": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "value": "4000" - }, - "taker_gets": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": ".25" - } - } -} -``` - -
- -[Try it! >](rest-api-tool.html#place-order) - -The following URL parameters are required by this API endpoint: - -| Field | Type | Description | -|-------|------|-------------| -| address | String | The Ripple account address the account creating the order. | - -The following parameters are required in the JSON body of the request: - -| Field | Value | Description | -|-------|-------|-------------| -| secret | String | A secret key for your Ripple account. This is either the master secret, or a regular secret, if your account has one configured. | -| order | Object ([Order](#order-objects)) | The order to place. | - -Optionally, you can include the following as a URL query parameter: - -| Field | Type | Description | -|-------|------|-------------| -| validated | String | `true` or `false`. When set to `true`, will force the request to wait until the trustline transaction has been successfully validated by the server. A validated transaction will have the `state` attribute set to `"validated"` in the response. | - -__DO NOT SUBMIT YOUR SECRET TO AN UNTRUSTED REST API SERVER__ -- The secret key can be used to send transactions from your account, including spending all the balances it holds. For the public server, only use test accounts. - -#### Response #### - -```js -{ - "success": true, - "order": { - "hash": "71AE74B03DE3B9A06C559AD4D173A362D96B7D2A5AA35F56B9EF21543D627F34", - "ledger": "9592219", - "state": "validated", - "account": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9", - "taker_pays": { - "currency": "JPY", - "counterparty": "rMAz5ZnK73nyNUL4foAvaxdreczCkG3vA6", - "value": "4000" - }, - "taker_gets": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": ".25" - }, - "fee": "0.012", - "type": "sell", - "sequence": 99 - } -} -``` - -## Cancel Order ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/59ea02d634ac4a308db2ba21781efbc02f5ccf53/api/orders.js#L250 "Source") - -Deletes a previous order to exchange currencies. - -
- -*REST* - -``` -DELETE /v1/accounts/{:address}/orders/{:order}?validated=true -{ - "secret": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9" -} -``` - -
- -[Try it! >](rest-api-tool.html#cancel-order) - -The following URL parameters are required by this API endpoint: - -| Field | Type | Description | -|-------|------|-------------| -| address | String | The Ripple account address of an account involved in the transaction. | -| order | Integer | The `sequence` number of the order to cancel. | - -The following parameters are required in the JSON body of the request: - -| Field | Value | Description | -|-------|-------|-------------| -| secret | String | A secret key for your Ripple account. This is either the master secret, or a regular secret, if your account has one configured. | - -*Note:* Some older client libraries do not support a body for the DELETE method. If this is a problem for you, please [file an issue in Ripple Labs' bug tracker](https://ripplelabs.atlassian.net/browse/RLJS). - -Optionally, you can include the following as a URL query parameter: - -| Field | Type | Description | -|-------|------|-------------| -| validated | String | `true` or `false`. When set to `true`, will force the request to wait until the trustline transaction has been successfully validated by the server. A validated transaction will have the `state` attribute set to `"validated"` in the response. | - -__DO NOT SUBMIT YOUR SECRET TO AN UNTRUSTED REST API SERVER__ -- The secret key can be used to send transactions from your account, including spending all the balances it holds. For the public server, only use test accounts. - -#### Response #### - -```js -{ - "success": true, - "order": { - "hash": "71AE74B03DE3B9A06C559AD4D173A362D96B7D2A5AA35F56B9EF21543D627F34", - "ledger": "9592219", - "state": "validated", - "account": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9", - "fee": "0.012", - "offer_sequence": 99, - "sequence": 100 - } -} -``` - -## Get Account Orders ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/59ea02d634ac4a308db2ba21781efbc02f5ccf53/api/orders.js#L38 "Source") - -Retrieves all open currency-exchange orders associated with the Ripple address. - -
- -*REST* - -``` -GET /v1/accounts/{:address}/orders -``` - -
- -[Try it! >](rest-api-tool.html#get-account-orders) - -The following URL parameters are required by this API endpoint: - -| Field | Value | Description | -|-------|-------|-------------| -| address | String | The Ripple account address whose orders to look up. | - -Optionally, you can also include the following query parameters: - -| Field | Value | Description | -|-------|-------|-------------| -| marker | String | Start position in response paging. | -| limit | String (Integer) | (Defaults to 200) Max results per response. Cannot be less than 10. Cannot be greater than 400. | -| ledger | String | Ledger to request paged results from. Use the ledger's hash. | - -*Note:* Pagination using `limit` and `marker` requires a consistent ledger version, so you must also provide the `ledger` query parameter to use pagination. `marker` will be present in the response when there are additional pages to page through. - -#### Response #### - -The response is an object with a `orders` array, where each member is a [order object](#order-objects). - -```js -{ - "success": true, - "ledger": 11561783, - "validated": true, - "orders": [ - { - "type": "buy", - "taker_gets": { - "currency": "CAD", - "counterparty": "rLr7umFScvEZnj3AJzzZjm25yCZYh3tMwc", - "value": "11205.2494363431" - }, - "taker_pays": { - "currency": "USD", - "counterparty": "rDZBotqkN4MywSxm9HDtX4m7V6SRkFo7By", - "value": "9933.731769807718" - }, - "sequence": 11, - "passive": false - }, - { - "type": "sell", - "taker_gets": { - "currency": "USD", - "counterparty": "rDZBotqkN4MywSxm9HDtX4m7V6SRkFo7By", - "value": "9229.29" - }, - "taker_pays": { - "currency": "CAD", - "counterparty": "rLr7umFScvEZnj3AJzzZjm25yCZYh3tMwc", - "value": "10447.55628" - }, - "sequence": 12, - "passive": false - }, - { - "type": "buy", - "taker_gets": { - "currency": "CAD", - "counterparty": "rLr7umFScvEZnj3AJzzZjm25yCZYh3tMwc", - "value": "5600" - }, - "taker_pays": { - "currency": "USD", - "counterparty": "rDZBotqkN4MywSxm9HDtX4m7V6SRkFo7By", - "value": "5000" - }, - "sequence": 13, - "passive": false - }, - { - "type": "buy", - "taker_gets": { - "currency": "USD", - "counterparty": "rDZBotqkN4MywSxm9HDtX4m7V6SRkFo7By", - "value": "4.7" - }, - "taker_pays": { - "currency": "XRP", - "counterparty": "", - "value": "997.876857" - }, - "sequence": 14, - "passive": false - }, - { - "type": "sell", - "taker_gets": { - "currency": "XRP", - "counterparty": "", - "value": "999" - }, - "taker_pays": { - "currency": "USD", - "counterparty": "rDZBotqkN4MywSxm9HDtX4m7V6SRkFo7By", - "value": "4.74525" - }, - "sequence": 15, - "passive": false - }, - { - "type": "buy", - "taker_gets": { - "currency": "CAD", - "counterparty": "rLr7umFScvEZnj3AJzzZjm25yCZYh3tMwc", - "value": "5.35" - }, - "taker_pays": { - "currency": "XRP", - "counterparty": "", - "value": "998.134328" - }, - "sequence": 16, - "passive": false - }, - { - "type": "sell", - "taker_gets": { - "currency": "XRP", - "counterparty": "", - "value": "999" - }, - "taker_pays": { - "currency": "CAD", - "counterparty": "rLr7umFScvEZnj3AJzzZjm25yCZYh3tMwc", - "value": "5.96403" - }, - "sequence": 17, - "passive": false - }, - { - "type": "buy", - "taker_gets": { - "currency": "CAD", - "counterparty": "rLr7umFScvEZnj3AJzzZjm25yCZYh3tMwc", - "value": "1103.64" - }, - "taker_pays": { - "currency": "USD", - "counterparty": "rDZBotqkN4MywSxm9HDtX4m7V6SRkFo7By", - "value": "976.6725663716827" - }, - "sequence": 18, - "passive": false - }, - { - "type": "sell", - "taker_gets": { - "currency": "USD", - "counterparty": "rDZBotqkN4MywSxm9HDtX4m7V6SRkFo7By", - "value": "986.89" - }, - "taker_pays": { - "currency": "CAD", - "counterparty": "rLr7umFScvEZnj3AJzzZjm25yCZYh3tMwc", - "value": "1116.17259" - }, - "sequence": 19, - "passive": false - }, - { - "type": "sell", - "taker_gets": { - "currency": "USD", - "counterparty": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "value": "2" - }, - "taker_pays": { - "currency": "CAD", - "counterparty": "rLr7umFScvEZnj3AJzzZjm25yCZYh3tMwc", - "value": "2" - }, - "sequence": 21, - "passive": false - } - ] -} - -``` - -## Get Order Transaction ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/59ea02d634ac4a308db2ba21781efbc02f5ccf53/api/orders.js#L505 "Source") - -Get the details of an order transaction. An order transaction either [places an order](#place-order) or [cancels an order](#cancel-order). - - -
- -*REST* - -``` -GET /v1/accounts/{:address}/orders/{:hash} -``` - -
- -[Try it! >](rest-api-tool.html#get-order-transaction) - -The following URL parameters are required by this API endpoint: - -| Field | Value | Description | -|-------|-------|-------------| -| address | String | The Ripple account address whose orders to look up. | -| hash | String | The transaction hash for the order | - - -#### Response #### - -An example response for an order transaction to place an order: - -```js -{ - "success": true, - "hash": "D53A3B99AC0C3CAF35D72178390ACA94CD42479A98CEA438EEAFF338E5FEB76D", - "ledger": 11349675, - "validated": true, - "timestamp": "2015-01-26T17:49:30.000Z", - "fee": "0.012", - "action": "order_create", - "direction": "outgoing", - "order": { - "account": "rEQWVz1qN4DWw5J17s3DgXQzUuVYDSpK6M", - "taker_pays": { - "currency": "XRP", - "counterparty": "", - "value": "10000000" - }, - "taker_gets": { - "currency": "JPY", - "counterparty": "r94s8px6kSw1uZ1MV98dhSRTvc6VMPoPcN", - "value": "0.0001" - }, - "passive": false, - "immediate_or_cancel": false, - "fill_or_kill": false, - "type": "buy", - "sequence": 26 - }, - "balance_changes": [ - { - "counterparty": "", - "currency": "XRP", - "value": "-0.012" - } - ], - "order_changes": [ - { - "taker_pays": { - "currency": "XRP", - "counterparty": "", - "value": "10000000" - }, - "taker_gets": { - "currency": "JPY", - "counterparty": "r94s8px6kSw1uZ1MV98dhSRTvc6VMPoPcN", - "value": "0.0001" - }, - "sequence": 26, - "status": "created" - } - ] -} - -``` - -An example response for an order transaction that cancels an order: - -```js -{ - "success": true, - "hash": "3D948699072B40312AE313E7E8297EED83080C9A4D5B564BCACF0951ABF00AC5", - "ledger": 11236693, - "validated": true, - "timestamp": "2015-01-20T21:46:00.000Z", - "fee": "0.012", - "action": "order_cancel", - "direction": "outgoing", - "order": { - "account": "rEQWVz1qN4DWw5J17s3DgXQzUuVYDSpK6M", - "type": "cancel", - "sequence": 22, - "cancel_sequence": 20 - }, - "balance_changes": [{ - "counterparty": "", - "currency": "XRP", - "value": "-0.012" - }], - "order_changes": [{ - "taker_pays": { - "currency": "XRP", - "counterparty": "", - "value": "0" - }, - "taker_gets": { - "currency": "JPY", - "counterparty": "r94s8px6kSw1uZ1MV98dhSRTvc6VMPoPcN", - "value": "0" - }, - "sequence": 20, - "status": "canceled" - }] -} -``` - -The response includes the original [`order`](#order-objects), if the `action` is `order_create`. - -For transactions that cancel orders, the `order` object describes the transaction that canceled the original order. - -The response also includes `balance_changes` and [`order changes`](#order-change-objects) -for the perspective account (e.g., the Ripple account address used in the URI). - -The `direction` of the transaction is either `incoming`, `outgoing` or `unaffected`. Outgoing transactions are made by the perspective account. Incoming transactions affect the perspective account. - -## Get Order Book ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/59ea02d634ac4a308db2ba21781efbc02f5ccf53/api/orders.js#L38 "Source") - -Retrieves the top of the order book for a currency pair. - -
- -*REST* - -``` -GET /v1/accounts/{:address}/order_book/{:base}/{:counter} -``` - -
- -[Try it! >](rest-api-tool.html#get-order-book) - -The following URL parameters are required by this API endpoint: - -| Field | Value | Description | -|-------|-------|-------------| -| address | String | The Ripple account address whose orders to look up. | -| base | String | The base currency as `currency+counterparty` (e.g., `USD+`)| -| counter | String | The counter currency as `currency+counterparty` (e.g., `BTC+`)| - -Optionally, you can also include the following query parameters: - -| Field | Value | Description | -|-------|-------|-------------| -| limit | String (Integer) | (Defaults to 200) Max results per response. Cannot be less than 10. Cannot be greater than 400. | - - -#### Response #### - -The response includes `bids` and `asks` arrays that contain [bid objects](#bid-objects) - -```js -{ - "success": true, - "order_book": "BTC+rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B/USD+rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "ledger": "11082710", - "validated": true, - "bids": [{ - "price": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "265.60000000000017358109" - }, - "taker_gets_funded": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "610.8241466511631" - }, - "taker_gets_total": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "610.8241466511631" - }, - "taker_pays_funded": { - "currency": "BTC", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "2.299789708776968" - }, - "taker_pays_total": { - "currency": "BTC", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "2.299789708776968" - }, - "order_maker": "r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ", - "sequence": 550, - "passive": false, - "sell": false - }, { - "price": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "265.53485133502987091805" - }, - "taker_gets_funded": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "57.55101250864556" - }, - "taker_gets_total": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "57.55101250864556" - }, - "taker_pays_funded": { - "currency": "BTC", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "0.2167361919510613" - }, - "taker_pays_total": { - "currency": "BTC", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "0.2167361919510613" - }, - "order_maker": "rQE5Z3FgVnRMbVfS6xiVQFgB4J3X162FVD", - "sequence": 114646, - "passive": false, - "sell": false - }], - "asks": [{ - "price": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "267.73999242396369106028" - }, - "taker_gets_funded": { - "currency": "BTC", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "1.112931117688904" - }, - "taker_gets_total": { - "currency": "BTC", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "1.112931117688904" - }, - "taker_pays_funded": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "297.9761690184206" - }, - "taker_pays_total": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "297.9761690184206" - }, - "order_maker": "rwmnMXpRXFqHLYzwyeggJQ8fu5bPyxqup1", - "sequence": 145474, - "passive": false, - "sell": false - }, { - "price": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "269.5405478403477" - }, - "taker_gets_funded": { - "currency": "BTC", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "5205797604790419e-26" - }, - "taker_gets_total": { - "currency": "BTC", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "1" - }, - "taker_pays_funded": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "0.00000001403173538341179" - }, - "taker_pays_total": { - "currency": "USD", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", - "value": "269.5405478403477" - }, - "order_maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE", - "sequence": 52688, - "passive": false, - "sell": true - }] -} -``` - - - - -# TRUSTLINES # - - -## Get Trustlines ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/develop/api/trustlines.js#L18 "Source") - -Retrieves all trustlines associated with the Ripple address. - -
- -*REST* - -``` -GET /v1/accounts/{:address}/trustlines -``` - -
- -[Try it! >](rest-api-tool.html#get-trustlines) - -The following URL parameters are required by this API endpoint: - -| Field | Value | Description | -|-------|-------|-------------| -| address | String | The Ripple account address whose trustlines to look up. | - -Optionally, you can also include the following query parameters: - -| Field | Value | Description | -|-------|-------|-------------| -| currency | String ([ISO4217 currency code](http://www.xe.com/iso4217.php)) | Filter results to include only trustlines for the given currency. | -| counterparty | String (Address) | Filter results to include only trustlines to the given account. | -| marker | String | Start position in response paging. | -| limit | String (Integer or 'all') | (Defaults to 200) Max results per response. Cannot be less than 10. Cannot be greater than 400. Use 'all' to return all results | -| ledger | String (ledger hash or sequence, or 'validated', 'current', or 'closed') | (Defaults to 'validated') Identifying ledger version to pull results from. | - -*Note:* Pagination using `limit` and `marker` requires a consistent ledger version, so you must also provide the `ledger` query parameter to use pagination. - -#### Response #### - -The response is an object with a `lines` array, where each member is a [trustline object](#trustline-objects). - -```js -{ - "success": true, - "marker": "0C812C919D343EAE789B29E8027C62C5792C22172D37EA2B2C0121D2381F80E1", - "limit": 200, - "ledger": 10478339, - "validated": true, - "lines": [ - { - "account": "rPs7nVbSops6xm4v77wpoPFf549cqjzUy9", - "counterparty": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "currency": "USD", - "trust_limit": "100", - "reciprocated_trust_limit": "0", - "account_allows_rippling": false, - "counterparty_allows_rippling": true - }, - { - "account": "rPs7nVbSops6xm4v77wpoPFf549cqjzUy9", - "counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs58B", - "currency": "BTC", - "trust_limit": "5", - "reciprocated_trust_limit": "0", - "account_allows_rippling": false, - "counterparty_allows_rippling": true - } - ] -} -``` - -*Note:* `marker` will be present in the response when there are additional pages to page through. - -## Grant Trustline ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/develop/api/trustlines.js#L88 "Source") - -Creates or modifies a trustline. - -
- -*REST* - -``` -POST /v1/accounts/{:address}/trustlines?validated=true -{ - "secret": "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9", - "trustline": { - "limit": "110", - "currency": "USD", - "counterparty": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "account_allows_rippling": false - } -} -``` - -
- -[Try it! >](rest-api-tool.html#grant-trustline) - -The following parameters are required in the JSON body of the request: - -| Field | Value | Description | -|-------|-------|-------------| -| secret | String | A secret key for your Ripple account. This is either the master secret, or a regular secret, if your account has one configured. | -| trustline | Object ([Trustline](#trustline-objects)) | The trustline object to set. Ignores fields not controlled by this account. Any fields that are omitted are unchanged. | - -Optionally, you can include the following as a URL query parameter: - -| Field | Type | Description | -|-------|------|-------------| -| validated | String | `true` or `false`. When set to `true`, will force the request to wait until the trustline transaction has been successfully validated by the server. A validated transaction will have the `state` attribute set to `"validated"` in the response. | - -__DO NOT SUBMIT YOUR SECRET TO AN UNTRUSTED REST API SERVER__ -- The secret key can be used to send transactions from your account, including spending all the balances it holds. For the public server, only use test accounts. - -*Note:* Since a trustline occupies space in the ledger, [a trustline increases the XRP the account must hold in reserve](reserves.html). You cannot create more trustlines if you do not have sufficient XRP to pay the reserve. This applies to the account extending trust, not to the account receiving it. A trustline with a limit *and* a balance of 0 is equivalent to no trust line. - -#### Response #### - -A successful response uses the `201 Created` HTTP response code, and provides a JSON object that includes the trustline fields as saved, an identifying hash for the transaction that modified the trustline, and the sequence number of the ledger version that included the transaction. - -```js -{ - "success": true, - "trustline": { - "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", - "limit": "5", - "currency": "USD", - "counterparty": "rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q", - "account_allows_rippling": false, - "account_trustline_frozen": false, - "state": "pending", - "ledger": "9302926", - "hash": "57695598CD32333F67A70DC6EBC3501D71569CE11C9803162CBA61990D89C1EE" - } -} -``` - - - - -# NOTIFICATIONS # - -Notifications provide a mechanism to monitor for any kind of transactions that modify your Ripple account. Unlike the [Get Payment History](#get-payment-history) method, notifications include _all_ types of transactions, but each is described in less detail. - -Notifications are sorted in order of when they occurred, so you can save the most recently-known transaction and easily iterate forward to find any notifications that are newer than that. - - -## Check Notifications ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/develop/api/notifications.js "Source") - -Get a notification for the specific transaction hash, along with links to previous and next notifications, if available. - -
- -*REST* - -``` -GET /v1/accounts/{:address}/notifications/{:id} -``` - -
- -[Try it! >](rest-api-tool.html#check-notifications) - -The following URL parameters are required by this API endpoint: - -| Field | Value | Description | -|-------|-------|-------------| -| address | String | The Ripple account address of an account involved in the transaction. | -| id | String | A unique identifier for the transaction this notification describes -- either a client resource ID or a Ripple transaction hash | - -You can find a transaction `hash` in a few places: - -* From the response when you submit a transaction (via [Submit Payment](#submit-payment), [Update Account Settings](#update-account-settings), or [Grant Trustline](#grant-trustline) -* From objects in the [payment history](#get-payment-history). -* From the `previous_hash` or `next_hash` fields of another Check Notifications response. - -#### Response #### - -A successful response contains a notification object, for example: - -```js -{ - "success": true, - "notification": { - "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", - "type": "payment", - "direction": "outgoing", - "state": "validated", - "result": "tesSUCCESS", - "ledger": "8924146", - "hash": "9D591B18EDDD34F0B6CF4223A2940AEA2C3CC778925BABF289E0011CD8FA056E", - "timestamp": "2014-09-17T21:47:00.000Z", - "transaction_url": "http://api.ripple.com:5990/v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/payments/9D591B18EDDD34F0B6CF4223A2940AEA2C3CC778925BABF289E0011CD8FA056E", - "previous_hash": "8496C20AEB453803CB80474B59AB1E8FAA26725561EFF5AF41BD588B325AFBA8", - "previous_notification_url": "http://api.ripple.com:5990/v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/notifications/8496C20AEB453803CB80474B59AB1E8FAA26725561EFF5AF41BD588B325AFBA8", - "next_hash": "AE79DE34230403EA2769B4DA21A0D4D2FD7A18518DBA0A4C5B6352AFD844D22A", - "next_notification_url": "http://api.ripple.com:5990/v1/accounts/rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn/notifications/AE79DE34230403EA2769B4DA21A0D4D2FD7A18518DBA0A4C5B6352AFD844D22A" - } -} -``` - -If the server has any notifications that are older than this one, the `previous_hash` field contains a hash you can use to call this method again to get the previous one. The `previous_notification_url` contains the same information, but already formatted into a URL you can perform a GET request on. If no older notifications are available, both fields are either omitted, or provided as an empty string. - -The `next_hash` and `next_notification_url` fields work the same way, but they provide information on newer notifications instead. - -*Caution:* If you are accessing the REST API through a proxy, you may not be able to access the URLs as provided. (See [RA-129](https://ripplelabs.atlassian.net/browse/RA-129) for status and details.) - - - - -# RIPPLED SERVER STATUS # - -The following two endpoints can be used to check if the `ripple-rest` API is currently connected to a `rippled` server, and to retrieve information about the current status of the API. - -## Check Connection ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/develop/api/info.js#L33 "Source") - -Perform a simple ping to make sure that the server is working properly. - -
- -*REST* - -``` -GET /v1/server/connected -``` - -
- -[Try it! >](rest-api-tool.html#check-connection) - -#### Response #### - -```js -{ - "success": true, - "connected": true -} -``` - -If the server has any problems, for example with connecting to the `rippled` server, it returns an error message instead. - -## Get Server Status ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/develop/api/info.js#L14 "Source") - -Retrieve information about the current status of the Ripple-REST API and the `rippled` server it is connected to. - -
- -*REST* - -``` -GET /v1/server -``` - -
- -[Try it! >](rest-api-tool.html#get-server-status) - -#### Response #### - -```js -{ - "success": true, - "api_documentation_url": "https://github.com/ripple/ripple-rest", - "rippled_server_url": "wss://s1.ripple.com:443", - "rippled_server_status": { - "build_version": "0.26.3-sp2", - "complete_ledgers": "32570-9306249", - "hostid": "MERT", - "io_latency_ms": 1, - "last_close": { - "converge_time_s": 3.021, - "proposers": 5 - }, - "load_factor": 1, - "peers": 49, - "pubkey_node": "n9LpPSgwfihQDRX68dykxtNCm4gi2dBEJCga7uwV7uztoRSswms8", - "server_state": "full", - "validated_ledger": { - "age": 9, - "base_fee_xrp": 0.00001, - "hash": "7C3F4489091BAE5DCADE3B1A8A2C1E7E5C938FA4483660FD1A4098C4EC4805CD", - "reserve_base_xrp": 20, - "reserve_inc_xrp": 5, - "seq": 9306249 - }, - "validation_quorum": 3 - } -} -``` - -The parameters in a successful response are as follows: - -| Field | Value | Description | -|-------|-------|-------------| -| api\_documentation\_url | String | A URL that contains more information about the software, typically the [Ripple-REST Github Project](https://github.com/ripple/ripple-rest). | -| rippled_server_url | String | The URL of the `rippled` server that Ripple-REST is using to interface with the Ripple Network | -| rippled\_server\_status | Object | Various information about the `rippled` server | - -The `rippled_server_status` object may have any of the following fields: - -| Field | Value | Description | -|-------|-------|-------------| -| build_version | String | The `rippled` software version number | -| complete_ledgers | String | A range (possibly a disjointed range) of ledger versions that the server has on hand | -| hostid | String | The hostname of the machine running the `rippled` server | -| io\_latency\_ms | Number | The number of milliseconds spent waiting for I/O operations to complete. A high number indicates too much load on the server, which can be improved with more RAM and faster hard disks. | -| last\_close | Object | Some information about the most recently-closed ledger | -| last\_close.converge\_time\_s | Number | How many seconds it took to reach consensus on the this ledger version | -| last\_close.proposers | Number | How many trusted validators were involved in the consensus process for this ledger version | -| load\_factor | Number | The load factor the server is currently enforcing, as a multiplier for the base [transaction cost](tx-cost.html). The load factor is determined by the highest of the individual server’s load factor, cluster’s load factor, and the overall network’s load factor. | -| peers | Number | How many other `rippled` servers this server is connected to | -| pubkey_node | String | Public key used to verify this node for internal communications; this key is automatically generated by the server the first time it starts up. (If deleted, the node can just create a new pair of keys.) | -| server_state | String | A string indicating to what extent the server is participating in the network. See [Possible Server States in the rippled documentation](rippled-apis.html#possible-server-states) for more details. | -| validated_ledger | Object | Information about the fully-validated ledger with the highest sequence number (the most recent) | -| validated_ledger.age | Unsigned Integer | The time since the ledger was closed, in seconds | -| validated_ledger.base_fee_xrp | Number | Base [transaction cost](tx-cost.html), in XRP. This may be represented in scientific notation such as 1e-05 for 0.00005 | -| validated_ledger.hash | String | Unique hash for the ledger, as hex | -| validated_ledger.reserve_base_xrp | Unsigned Integer | Minimum amount of XRP (not drops) necessary for every account to keep in reserve | -| validated_ledger.reserve_inc_xrp | Unsigned Integer | Amount of XRP (not drops) added to the account reserve for each object an account is responsible for in the ledger | -| validated_ledger.seq | Unsigned Integer | Identifying sequence number of this ledger version | -| validation_quorum | Number | Minimum number of trusted validations required in order to validate a ledger version. Some circumstances may cause the server to require more validations. | - - - - - - -# UTILITIES # - -## Retrieve Ripple Transaction ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/develop/api/transactions.js#L118 "Source") - -Returns a Ripple transaction, in its complete, original format. - -
- -*REST* - -``` -GET /v1/transactions/{:id} -``` - -
- -[Try it! >](rest-api-tool.html#retrieve-ripple-transaction) - -The following URL parameters are required by this API endpoint: - -| Field | Value | Description | -|-------|-------|-------------| -| hash | String | A unique identifier for the Ripple transaction to retrieve -- either a client resource ID or a Ripple transaction hash. | - -#### Response #### - -The result is a JSON object, whose `transaction` field has the requested transaction. See the [Transaction format documentation](transactions.html) for a complete explanation of the fields of a transaction. - -```js -{ - "success": true, - "transaction": { - "Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", - "Amount": { - "currency": "USD", - "issuer": "rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc", - "value": "0.01" - }, - "Destination": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", - "Fee": "10", - "Flags": 131072, - "SendMax": "10", - "Sequence": 11, - "SigningPubKey": "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB", - "TransactionType": "Payment", - "TxnSignature": "304402206B62F24BA371DF6E8F2F5A4D0C006F4081494B8ED49F9B2C453FF50B58AB170702200886487FFD272799E5C88547692AD7DD48B04E10070F7A1F36D7AF73CCFB708D", - "hash": "9D591B18EDDD34F0B6CF4223A2940AEA2C3CC778925BABF289E0011CD8FA056E", - "inLedger": 8924146, - "ledger_index": 8924146, - "meta": { - "AffectedNodes": [ - { - "ModifiedNode": { - "FinalFields": { - "Account": "rUrgXPxenRbjnFDXKWUhH8mBJcQ2CyPfkG", - "Balance": "20357167562", - "Flags": 0, - "OwnerCount": 44, - "Sequence": 709 - }, - "LedgerEntryType": "AccountRoot", - "LedgerIndex": "0193CB8318BDB270B775835373E8789F5357CEF712DF3275F92A8CEE97E352FE", - "PreviousFields": { - "Balance": "20357167552" - }, - "PreviousTxnID": "41F8D5612778AC1318599217E53198940EF16063A3F4B73DECE33EA0901FA96A", - "PreviousTxnLgrSeq": 8924070 - } - }, - { - "ModifiedNode": { - "FinalFields": { - "Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", - "Balance": "230999889", - "Domain": "6D64756F31332E636F6D", - "Flags": 0, - "MessageKey": "0000000000000000000000070000000300", - "OwnerCount": 0, - "Sequence": 12 - }, - "LedgerEntryType": "AccountRoot", - "LedgerIndex": "13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8", - "PreviousFields": { - "Balance": "230999909", - "Sequence": 11 - }, - "PreviousTxnID": "8496C20AEB453803CB80474B59AB1E8FAA26725561EFF5AF41BD588B325AFBA8", - "PreviousTxnLgrSeq": 8889845 - } - }, - { - "ModifiedNode": { - "FinalFields": { - "Balance": { - "currency": "USD", - "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", - "value": "-19.84529319487081" - }, - "Flags": 2228224, - "HighLimit": { - "currency": "USD", - "issuer": "rUrgXPxenRbjnFDXKWUhH8mBJcQ2CyPfkG", - "value": "0" - }, - "HighNode": "0000000000000002", - "LowLimit": { - "currency": "USD", - "issuer": "rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc", - "value": "0" - }, - "LowNode": "0000000000000010" - }, - "LedgerEntryType": "RippleState", - "LedgerIndex": "2E103526973EF8CCE3340125DD66D6BF84DD8473EF693EC5E06B2ACBF2BAC155", - "PreviousFields": { - "Balance": { - "currency": "USD", - "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", - "value": "-19.84529324567081" - } - }, - "PreviousTxnID": "41F8D5612778AC1318599217E53198940EF16063A3F4B73DECE33EA0901FA96A", - "PreviousTxnLgrSeq": 8924070 - } - }, - { - "ModifiedNode": { - "FinalFields": { - "Account": "rUrgXPxenRbjnFDXKWUhH8mBJcQ2CyPfkG", - "BookDirectory": "3A574D1E645D05EA27A5D011AECF6C78FFB028AA9B584C245D06FE5809E78102", - "BookNode": "0000000000000000", - "Flags": 0, - "OwnerNode": "0000000000000003", - "Sequence": 696, - "TakerGets": { - "currency": "USD", - "issuer": "rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc", - "value": "15.2299999492" - }, - "TakerPays": "2998031486" - }, - "LedgerEntryType": "Offer", - "LedgerIndex": "350327BB97B7707F4E7B8670C42F886E29B9C9615D4A8D93FC730DD17770D9B4", - "PreviousFields": { - "TakerGets": { - "currency": "USD", - "issuer": "rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc", - "value": "15.23" - }, - "TakerPays": "2998031496" - }, - "PreviousTxnID": "41F8D5612778AC1318599217E53198940EF16063A3F4B73DECE33EA0901FA96A", - "PreviousTxnLgrSeq": 8924070 - } - }, - { - "ModifiedNode": { - "FinalFields": { - "Balance": { - "currency": "USD", - "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", - "value": "-0.0100000508" - }, - "Flags": 131072, - "HighLimit": { - "currency": "USD", - "issuer": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX", - "value": "100" - }, - "HighNode": "0000000000000000", - "LowLimit": { - "currency": "USD", - "issuer": "rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc", - "value": "0" - }, - "LowNode": "000000000000000B" - }, - "LedgerEntryType": "RippleState", - "LedgerIndex": "E3DC31319B6C121387EAE05253AF71CAF98360BF1419249DD1A218A9B4C121A9", - "PreviousFields": { - "Balance": { - "currency": "USD", - "issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji", - "value": "-0.01" - } - }, - "PreviousTxnID": "41F8D5612778AC1318599217E53198940EF16063A3F4B73DECE33EA0901FA96A", - "PreviousTxnLgrSeq": 8924070 - } - } - ], - "DeliveredAmount": { - "currency": "USD", - "issuer": "rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc", - "value": "0.00000005080000000000001" - }, - "TransactionIndex": 5, - "TransactionResult": "tesSUCCESS" - }, - "validated": true, - "date": 464305620 - } -} -``` - - -## Retrieve Transaction Cost ## -[[Source]
](https://github.com/ripple/ripple-rest/blob/develop/api/info.js#L42 "Source") - -(New in [Ripple-REST v1.3.1](https://github.com/ripple/ripple-rest/releases/tag/1.3.1-rc1)) - -Retrieve the current [transaction cost](tx-cost.html), in XRP, for the `rippled` server Ripple-REST is connected to. If Ripple-REST is connected to multiple rippled servers, returns the median transaction cost among the connected servers. - -
- -*REST* - -``` -GET /v1/transaction-fee -``` - -
- -[Try it! >](rest-api-tool.html#retrieve-transaction-fee) - -#### Response #### - -The response is a JSON object, whose `fee` field is a string containing a decimal amount of XRP that the `rippled` server requires to be destroyed in order to process and relay the transaction to the network. - -```js -{ - "success": true, - "fee": "0.012" -} -``` - - -## Create Client Resource ID ## - -Generate a universally-unique identifier suitable for use as the Client Resource ID for a payment. - -
- -*REST* - -``` -GET /v1/uuid -``` - -
- -[Try it! >](rest-api-tool.html#generate-uuid) - -#### Response #### - -```js -{ - "success": true, - "uuid": "a5a8fe40-3795-4b10-b2b6-f05f3ca31db9" -} -``` diff --git a/content/transferrate.md b/content/transferrate.md index 2a5866f63c..2dcbf935d7 100644 --- a/content/transferrate.md +++ b/content/transferrate.md @@ -26,19 +26,19 @@ In this scenario, Salazar (the sender) holds EUR issued by ACME, and wants to de The transfer fee is represented by a setting on the issuing (**cold wallet**) account. The transfer fee has a maximum precision of 9 digits, and cannot be less than 0% or greater than 100%. The TransferRate setting applies to all currencies issued by the same account. If you want to have different transfer fee percentages for different currencies, use different cold wallets to issue each currency. -## Ripple-REST ## +## RippleAPI ## -In Ripple-REST, the transfer fee is specified in the `transfer_rate` field, as a decimal which represents the amount you must send in order for the recipient to get 1 unit of the same currency. A `transfer_rate` of `1.005` is equivalent to a transfer fee of 0.5%. By default, the `transfer_rate` is set at `1.0`, indicating no fee. The value of `transfer_rate` cannot be less than `1.0` or more than `2.0`. However, the value `0` is special: it is equivalent to `1.0`, meaning no fee. +In RippleAPI, the transfer fee is specified in the `transferRate` field, as an integer which represents the amount you must send in order for the recipient to get 1 billion units of the same currency. A `transferRate` of `1005000000` is equivalent to a transfer fee of 0.5%. By default, the `transferRate` is set to no fee. The value of `transferRate` cannot be less than `1000000000` or more than `2000000000`. The value `null` is special: it is equivalent to `1000000000`, meaning no fee. -A gateway can use the [Update Account Settings method](https://ripple.com/build/ripple-rest/#update-account-settings) with its cold wallet to change the `transfer_rate` for its issuances. +A gateway can send a [Settings transaction](rippleapi.html#settings) with its cold wallet to change the `transferRate` for its issuances. -You can check an account's `transfer_rate` with the [Get Account Settings method](https://ripple.com/build/ripple-rest/#get-account-settings). +You can check an account's `transferRate` with the [getSettings method](rippleapi.html#getsettings). ## rippled ## -In `rippled`'s JSON-RPC and WebSocket APIs, the transfer fee is specified in the `TransferRate` field, as an integer which represents the amount you must send in order for the recipient to get 1 billion units of the same currency. A `TransferRate` of `1005000000` is equivalent to a transfer fee of 0.5%. By default, the `transfer_rate` is set at `1000000000`, indicating no fee. The value of `TransferRate` cannot be less than `1000000000` or more than `2000000000`. However, value `0` is special: it is equivalent to `1000000000`, meaning no fee. +In `rippled`'s JSON-RPC and WebSocket APIs, the transfer fee is specified in the `TransferRate` field, as an integer which represents the amount you must send in order for the recipient to get 1 billion units of the same currency. A `TransferRate` of `1005000000` is equivalent to a transfer fee of 0.5%. By default, the `TransferRate` is set at `1000000000`, indicating no fee. The value of `TransferRate` cannot be less than `1000000000` or more than `2000000000`. However, value `0` is special: it is equivalent to `1000000000`, meaning no fee. -A gateway can submit an [AccountSet transaction](https://ripple.com/build/transactions/#accountset) from its cold wallet to change the `TransferRate` for its issuances. +A gateway can submit an [AccountSet transaction](transactions.html#accountset) from its cold wallet to change the `TransferRate` for its issuances. -You can check an account's `TransferRate` with the [account_info command](https://ripple.com/build/rippled-apis/#account-info). If the `TransferRate` is omitted, then that indicates no fee. +You can check an account's `TransferRate` with the [`account_info` command](rippled-apis.html#account-info). If the `TransferRate` is omitted, then that indicates no fee. diff --git a/content/whitepapers.md b/content/whitepapers.md deleted file mode 100644 index dfa9c10c45..0000000000 --- a/content/whitepapers.md +++ /dev/null @@ -1,13 +0,0 @@ -Ripple Whitepapers -================== - -Ripple has published several whitepapers on the benefits and workings of the Ripple technology stack. The following is a brief selection of useful papers: - -* [Ripple Primer](https://ripple.com/ripple_primer.pdf) (PDF) -* [Gateway whitepaper](https://ripple.com/ripple-gateways.pdf) (PDF) -* [Market makers whitepaper](https://ripple.com/ripple-mm.pdf) (PDF) -* [Financial institutions whitepaper](https://ripple.com/ripple-FIs.pdf) (PDF) -* [The Ripple Protocol: A Deep Dive for Finance Professionals](https://ripple.com/files/ripple_deep_dive_final.pdf) (PDF) -* [The Ripple Protocol Consensus Algorithm](https://ripple.com/files/ripple_consensus_whitepaper.pdf) (PDF) - -You can find further information about Ripple in the [Knowledge Center](https://ripple.com/knowledge-center/). diff --git a/data-api-v2-tool.html b/data-api-v2-tool.html index 584583c9b6..009a6517de 100644 --- a/data-api-v2-tool.html +++ b/data-api-v2-tool.html @@ -60,7 +60,6 @@ References