mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-04 21:15:47 +00:00
Compare commits
58 Commits
0.13.0-rc1
...
0.15.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfc21fde8c | ||
|
|
5c06ef547b | ||
|
|
0990ad4a6f | ||
|
|
d8f967d2b8 | ||
|
|
fe1c3e7130 | ||
|
|
062148674c | ||
|
|
11320693fd | ||
|
|
7af7eaccb4 | ||
|
|
5d5cf868a2 | ||
|
|
ddf8fe5b1a | ||
|
|
dc24f6afe0 | ||
|
|
f7dac6ab25 | ||
|
|
4b4fc36ebd | ||
|
|
7626ea5ed8 | ||
|
|
7061e9afe4 | ||
|
|
a124635c2c | ||
|
|
c9704137b7 | ||
|
|
ab8d75d3cc | ||
|
|
5e720891f5 | ||
|
|
27ed1aadd5 | ||
|
|
001f203983 | ||
|
|
515047d2dc | ||
|
|
995606b1e6 | ||
|
|
b5081344da | ||
|
|
4f86691fb8 | ||
|
|
45aca016d4 | ||
|
|
7f33d8a71e | ||
|
|
af620755c5 | ||
|
|
a76b554cad | ||
|
|
ef1e9e1b70 | ||
|
|
fdbac63f46 | ||
|
|
377f1dbfa1 | ||
|
|
14b840f3fe | ||
|
|
beb1cc0cde | ||
|
|
ef2515507d | ||
|
|
a271b9e816 | ||
|
|
8a3d4a64db | ||
|
|
9cd8beb778 | ||
|
|
aaa165a0f3 | ||
|
|
7514213918 | ||
|
|
849ba999cb | ||
|
|
10eb08095a | ||
|
|
23eb4c90fd | ||
|
|
12e5765c64 | ||
|
|
8a53abc32f | ||
|
|
25d1ac0c5f | ||
|
|
f534bafb79 | ||
|
|
f5fa1e6c2a | ||
|
|
60842540cb | ||
|
|
0fb04cdcb4 | ||
|
|
5fb8d9214f | ||
|
|
f7f2de291f | ||
|
|
0c27a13a00 | ||
|
|
02a887776f | ||
|
|
786c371acd | ||
|
|
c4920f474d | ||
|
|
61afca2337 | ||
|
|
47251bd38b |
55
HISTORY.md
55
HISTORY.md
@@ -1,12 +1,57 @@
|
||||
##0.13.0 (release candidate)
|
||||
##0.15.2
|
||||
**Changes**
|
||||
+ [Fix support for proxy credentials in proxy URL and fix error when there are more than 10 outstanding requests](https://github.com/ripple/ripple-lib/commit/0990ad4a6f1d59ca9d2cb859b4e2d71693f3fc4b)
|
||||
|
||||
##0.15.1
|
||||
**Changes**
|
||||
+ [Fix babel-polyfill require](https://github.com/ripple/ripple-lib/commit/062148674c3b1293ab82c28e25615ddd530339fa)
|
||||
+ [Fix samples](https://github.com/ripple/ripple-lib/commit/5d5cf868a2ddb1b1cd40e4a4f0a782d0066c2055)
|
||||
+ [add unit tests for RippleAPIBroadcast](https://github.com/ripple/ripple-lib/commit/ddf8fe5b1a9c750490dca98fb9ffaaf8017f87e0)
|
||||
|
||||
##0.15.0
|
||||
**Breaking Changes**
|
||||
+ ["servers" parameter changed to single "server"](https://github.com/ripple/ripple-lib/commit/7061e9afe46f0682254d098adeff3dd7157521a1)
|
||||
|
||||
**Changes**
|
||||
+ [fix handling memos in prepareSettings](https://github.com/ripple/ripple-lib/commit/c9704137b7b538e8dbf31c483bcdcf2dcfd7cd75)
|
||||
+ [Docs: SusPay warnings, offline mode, and other tweaks](https://github.com/ripple/ripple-lib/commit/4b4fc36ebd93f1360781a65f2869bd2c4f0a5093)
|
||||
+ [Fix prepareOrderCancellation documentation](https://github.com/ripple/ripple-lib/commit/5e720891f579fd73d43c64e5ec519d9121023c10)
|
||||
|
||||
##0.14.0
|
||||
**Breaking Changes**
|
||||
+ [prepareOrderCancellation now takes orderCancellation specification](https://github.com/ripple/ripple-lib/commit/7f33d8a71e56289e5a5e0ead1c74f75ebcde72bc)
|
||||
+ [Rename "ledgerClosed" event to "ledger" and change format](https://github.com/ripple/ripple-lib/commit/8a3d4a64db5fbf560ebf87dc62e0212513c5e18a)
|
||||
|
||||
**Changes**
|
||||
+ [Fix proxy support and add support for proxy authorization](https://github.com/ripple/ripple-lib/commit/14b840f3feca758e0384b746c94e36d8bf59b8c2)
|
||||
+ [Fix trace option](https://github.com/ripple/ripple-lib/commit/af620755c53556c55eed12de4b0013ef5a349ce2)
|
||||
+ [Allow memos on all transaction types](https://github.com/ripple/ripple-lib/commit/b5081344da8e66fbd3a5113cc3313325ef72a494)
|
||||
+ [Add documentation for RippleAPI options](https://github.com/ripple/ripple-lib/commit/a76b554cadb9f9f918b06f8386bc29355682a1a4)
|
||||
+ [Docs: more on basic types, tx types](https://github.com/ripple/ripple-lib/commit/fdbac63f466b4fd3be701d4878800d856692e26e)
|
||||
+ [Docs: revised introductory material](https://github.com/ripple/ripple-lib/commit/ef2515507dbd3c6a426ab5b31332a1bdf72d5b2d)
|
||||
+ [boost coverage to almost 100%](https://github.com/ripple/ripple-lib/commit/995606b1e6f3643af34d9fd442ccd31f320b03eb)
|
||||
|
||||
##0.13.2
|
||||
|
||||
**Changes**
|
||||
+ [Fix: Specify send_max when pathfinding with a source amount](https://github.com/ripple/ripple-lib/commit/75142139184625c8b9fcc480b1825d9985337813)
|
||||
|
||||
##0.13.1
|
||||
+ [Add documentation for API events](https://github.com/ripple/ripple-lib/commit/25d1ac0c5f95cad32ea4ceebb))
|
||||
|
||||
**Changes**
|
||||
+ [Fix: Add babel-polyfill](https://github.com/ripple/ripple-lib/commit/8a53abc32f6ec6c7d50cd182492d6fb511b86704)
|
||||
+ [Fix: Bump version on ripple-hashes](https://github.com/ripple/ripple-lib/commit/12e5765c64aea31b3c2fb65ff989cf01e6368f58)
|
||||
|
||||
##0.13.0
|
||||
|
||||
**Breaking Changes**
|
||||
+ [Removed timeout method of Request and added default timeout](https://github.com/ripple/ripple-lib/commit/634fe5683a9082e57682ff7d5c4fb9483b4af818)
|
||||
+ Add new RippleAPI interface
|
||||
+ Add new RippleAPI interface and delete old API
|
||||
- [RippleAPI README and samples](https://github.com/ripple/ripple-lib/tree/develop/docs/samples)
|
||||
- [Method documentation](https://rawgit.com/ripple/ripple-lib/develop/docs/api.html)
|
||||
|
||||
**Changes**
|
||||
+ [Removed timeout method of Request and added default timeout](https://github.com/ripple/ripple-lib/commit/634fe5683a9082e57682ff7d5c4fb9483b4af818)
|
||||
+ [Add Remote.closeCurrentPathFind function, so current pathfind can be properly closed](https://github.com/ripple/ripple-lib/commit/e99010f363fc7cbe7fd547d3ca5b32ea083c44e6)
|
||||
+ [Implement Balance Sheet API](https://github.com/ripple/ripple-lib/pull/579)
|
||||
+ [Fix bugs in orderbook subscription](https://github.com/ripple/ripple-lib/commit/7404795dc64a85216148de7bc3ca7da7b33f4490)
|
||||
@@ -18,6 +63,10 @@
|
||||
+ [Fix bug where the paths would be set with an empty array](https://github.com/ripple/ripple-lib/commit/83874ec0962da311b76f2385623e51c68bc39035)
|
||||
+ [Fix reserve calculation](https://github.com/ripple/ripple-lib/commit/52879febb92d876f01f2e4d70871baa07af631fb)
|
||||
|
||||
##0.12.9
|
||||
|
||||
+ [OrderBook performance optimizations](https://github.com/ripple/ripple-lib/commit/3e17d91edf36745f6b6c09b0ad88971b7775f6ab)
|
||||
|
||||
##0.12.7 and 0.12.8
|
||||
|
||||
+ [Improve performance of orderbook](https://github.com/ripple/ripple-lib/commit/c745faaaf0956ca98448a754b4fe97fb50574fc7)
|
||||
|
||||
@@ -20,7 +20,7 @@ Install `ripple-lib` using npm:
|
||||
$ npm install ripple-lib
|
||||
```
|
||||
|
||||
Then see the sample code in `docs/samples`.
|
||||
Then see the [documentation](https://github.com/ripple/ripple-lib/blob/develop/docs/index.md) and [code samples](https://github.com/ripple/ripple-lib/tree/develop/docs/samples)
|
||||
|
||||
##Running tests
|
||||
|
||||
@@ -28,6 +28,10 @@ Then see the sample code in `docs/samples`.
|
||||
2. `cd` into the repository and install dependencies with `npm install`
|
||||
3. `npm test` or `npm test --coverage` (`istanbul` will create coverage reports in coverage/lcov-report/`)
|
||||
|
||||
##Generating Documentation
|
||||
|
||||
The continuous integration tests require that the documentation stays up-to-date. If you make changes the the JSON schemas, fixtures, or documentation sources, you must update the documentation by running `npm run docgen`.
|
||||
|
||||
##More Information
|
||||
|
||||
+ [Ripple Dev Portal](https://ripple.com/build/)
|
||||
|
||||
358
docs/api.html
358
docs/api.html
@@ -1,358 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.method {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.details {
|
||||
font-family: "Courier New", monospace;
|
||||
white-space: pre;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function toggle(element) {
|
||||
var results = element.parentElement.getElementsByClassName('details');
|
||||
if (results.length > 0) {
|
||||
var style = results[0].style;
|
||||
style.display = (style.display === 'block') ? 'none' : 'block';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2><a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/index.js">RippleAPI</a></h2>
|
||||
|
||||
<div class="method">
|
||||
connect()
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
disconnect()
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
isConnected()
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
getServerInfo()
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
getFee()
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
getLedgerVersion()
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/get-transaction.json">getTransaction</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/hash256.json">identifier</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/transaction-options.json">options</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
identifier: txhash
|
||||
options: {minLedgerVersion: int, maxLedgerVersion: int}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/get-transactions.json">getTransactions</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/address.json">account</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/transactions-options.json">options</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
options: {
|
||||
start: txhash,
|
||||
limit: int,
|
||||
minLedgerVersion: int,
|
||||
maxLedgerVersion: int,
|
||||
earliestFirst: bool,
|
||||
excludeFailures: bool,
|
||||
initiated: bool,
|
||||
counterparty: address,
|
||||
types: [string],
|
||||
binary: bool
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/get-trustlines.json">getTrustlines</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/address.json">account</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/trustlines-options.json">options</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
options: {counterparty: address, currency: string, limit: int, ledgerVersion: int}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/get-balances.json">getBalances</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/address.json">account</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/trustlines-options.json">options</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
options: {counterparty: address, currency: string, limit: int, ledgerVersion: int}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/get-paths.json">getPaths</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/pathfind.json">pathfind</a>
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
pathfind: {
|
||||
source: {
|
||||
address: address,
|
||||
currencies: [{
|
||||
currency: string,
|
||||
counterparty: address
|
||||
}]
|
||||
},
|
||||
destination: adjustment
|
||||
}
|
||||
|
||||
adjustment = {address: address, amount: amount, tag?: int}
|
||||
amount = {currency: string, counterparty: address, value: floatstr}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/get-orders.json">getOrders</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/address.json">account</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/orders-options.json">options</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
options: {limit: int, ledverVersion: int}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/get-orderbook.json">getOrderbook</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/address.json">account</a>,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/orderbook.json">orderbook</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/orders-options.json">options</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
orderbook: {
|
||||
base: {
|
||||
currency,
|
||||
counterparty
|
||||
},
|
||||
counter: {
|
||||
currency,
|
||||
counterparty
|
||||
}
|
||||
}
|
||||
options: {limit: int, ledverVersion: int}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/get-settings.json">getSettings</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/address.json">account</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/settings-options.json">options</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
options: {ledgerVersion: int}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/get-account-info.json">getAccountInfo</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/address.json">account</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/settings-options.json">options</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
options: {ledgerVersion: int}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/tx.json">preparePayment</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/address.json">account</a>,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/payment.json">payment</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/instructions.json">instructions</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
payment: {
|
||||
source: adjustment,
|
||||
destination: adjustment,
|
||||
paths?: string,
|
||||
slippage?: strfloat,
|
||||
memos?: [{
|
||||
type: string,
|
||||
format: string,
|
||||
data: string
|
||||
}],
|
||||
invoiceID?: hash256,
|
||||
allowPartialPayment?: bool,
|
||||
noDirectRipple?: bool,
|
||||
limitQuality?: bool
|
||||
}
|
||||
|
||||
adjustment = {address: address, amount: amount, tag?: int}
|
||||
amount = {currency: string, counterparty: address, value: floatstr}
|
||||
|
||||
instructions: {
|
||||
sequence: int,
|
||||
fee: floatstr,
|
||||
maxFee: floatstr,
|
||||
maxLedgerVersion: int,
|
||||
maxLedgerVersionOffset: int
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/tx.json">prepareTrustline</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/address.json">account</a>,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/trustline.json">trustline</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/instructions.json">instructions</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
trustline: {
|
||||
currency: string,
|
||||
counterparty: address,
|
||||
limit: strfloat,
|
||||
qualityIn?: float,
|
||||
qualityOut?: float,
|
||||
allowRippling?: bool,
|
||||
authorized?: bool,
|
||||
frozen?: bool
|
||||
}
|
||||
|
||||
instructions: {
|
||||
sequence: int,
|
||||
fee: floatstr,
|
||||
maxFee: floatstr,
|
||||
maxLedgerVersion: int,
|
||||
maxLedgerVersionOffset: int
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/tx.json">prepareOrder</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/address.json">account</a>,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/order.json">order</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/instructions.json">instructions</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
order: {
|
||||
direction: ("buy"|"sell"),
|
||||
quantity: amount,
|
||||
totalPrice: amount,
|
||||
immediateOrCancel?: bool,
|
||||
fillOrKill?: bool,
|
||||
passive?: bool
|
||||
}
|
||||
|
||||
amount = {currency: string, counterparty: address, value: floatstr}
|
||||
|
||||
instructions: {
|
||||
sequence: int,
|
||||
fee: floatstr,
|
||||
maxFee: floatstr,
|
||||
maxLedgerVersion: int,
|
||||
maxLedgerVersionOffset: int
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/tx.json">prepareOrderCancellation</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/address.json">account</a>,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/sequence.json">sequence</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/instructions.json">instructions</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
sequence: int
|
||||
|
||||
instructions: {
|
||||
sequence: int,
|
||||
fee: floatstr,
|
||||
maxFee: floatstr,
|
||||
maxLedgerVersion: int,
|
||||
maxLedgerVersionOffset: int
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/tx.json">prepareSettings</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/address.json">account</a>,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/settings.json">settings</a>[,
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/instructions.json">instructions</a>]
|
||||
)
|
||||
<a href="#" onclick="javascript:toggle(this)">+</a>
|
||||
<div class="details">
|
||||
settings: {
|
||||
passwordSpent: bool,
|
||||
requireDestinationTag: bool,
|
||||
requireAuthorization: bool,
|
||||
disallowIncomingXRP: bool,
|
||||
disableMasterKey: bool,
|
||||
enableTransactionIDTracking: bool,
|
||||
noFreeze: bool,
|
||||
globalFreeze: bool,
|
||||
defaultRipple: bool,
|
||||
emailHash: hash128,
|
||||
walletLocator: hash256,
|
||||
walletSize: int,
|
||||
messageKey: string,
|
||||
domain: string,
|
||||
transferRate: float,
|
||||
signers: string,
|
||||
regularKey: address
|
||||
}
|
||||
|
||||
instructions: {
|
||||
sequence: int,
|
||||
fee: floatstr,
|
||||
maxFee: floatstr,
|
||||
maxLedgerVersion: int,
|
||||
maxLedgerVersionOffset: int
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/sign.json">sign</a>(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/tx.json">txJSON</a>,
|
||||
secret)
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
submit(
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/schemas/blob.json">txBlob</a>
|
||||
)
|
||||
</div>
|
||||
|
||||
<div class="method">
|
||||
generateWallet()
|
||||
</div>
|
||||
|
||||
<a href="https://github.com/ripple/ripple-lib/blob/develop/src/api/common/errors.js">errors</a>
|
||||
</body>
|
||||
</html>
|
||||
3502
docs/index.md
Normal file
3502
docs/index.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
const RippleAPI = require('../../src').RippleAPI; // require('ripple-lib')
|
||||
|
||||
const api = new RippleAPI({servers: ['wss://s1.ripple.com:443']});
|
||||
const api = new RippleAPI({server: 'wss://s1.ripple.com:443'});
|
||||
const address = 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV';
|
||||
|
||||
api.connect().then(() => {
|
||||
|
||||
@@ -4,13 +4,13 @@ const RippleAPI = require('../../src').RippleAPI; // require('ripple-lib')
|
||||
const address = 'INSERT ADDRESS HERE';
|
||||
const secret = 'INSERT SECRET HERE';
|
||||
|
||||
const api = new RippleAPI({servers: ['wss://s1.ripple.com:443']});
|
||||
const api = new RippleAPI({server: 'wss://s1.ripple.com:443'});
|
||||
const instructions = {maxLedgerVersionOffset: 5};
|
||||
|
||||
const payment = {
|
||||
source: {
|
||||
address: address,
|
||||
amount: {
|
||||
maxAmount: {
|
||||
value: '0.01',
|
||||
currency: 'XRP'
|
||||
}
|
||||
|
||||
55
docs/src/basictypes.md.ejs
Normal file
55
docs/src/basictypes.md.ejs
Normal file
@@ -0,0 +1,55 @@
|
||||
# Basic Types
|
||||
|
||||
## Ripple Address
|
||||
|
||||
```json
|
||||
"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59"
|
||||
```
|
||||
|
||||
Every Ripple account has an *address*, which is a base58-encoding of a hash of the account's public key. Ripple addresses always start with the lowercase letter `r`.
|
||||
|
||||
## Account Sequence Number
|
||||
|
||||
Every Ripple account has a *sequence number* that is used to keep transactions in order. Every transaction must have a sequence number. A transaction can only be executed if it has the next sequence number in order, of the account sending it. This prevents one transaction from executing twice and transactions executing out of order. The sequence number starts at `1` and increments for each transaction that the account makes.
|
||||
|
||||
## Currency
|
||||
|
||||
Currencies are represented as either 3-character currency codes or 40-character uppercase hexadecimal strings. We recommend using uppercase [ISO 4217 Currency Codes](http://www.xe.com/iso4217.php) only. The string "XRP" is disallowed on trustlines because it is reserved for the Ripple native currency. The following characters are permitted: all uppercase and lowercase letters, digits, as well as the symbols `?`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `<`, `>`, `(`, `)`, `{`, `}`, `[`, `]`, and `|`.
|
||||
|
||||
## Value
|
||||
A *value* is a quantity of a currency represented as a decimal string. Be careful: JavaScript's native number format does not have sufficient precision to represent all values. XRP has different precision from other currencies.
|
||||
|
||||
**XRP** has 6 significant digits past the decimal point. In other words, XRP cannot be divided into positive values smaller than `0.000001` (1e-6). XRP has a maximum value of `100000000000` (1e11).
|
||||
|
||||
**Non-XRP values** have 15 decimal digits of precision, with a maximum value of `9999999999999999e80`. The smallest positive non-XRP value is `1e-81`.
|
||||
|
||||
|
||||
## Amount
|
||||
|
||||
Example amount:
|
||||
|
||||
```json
|
||||
{
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM",
|
||||
"value": "100"
|
||||
}
|
||||
```
|
||||
|
||||
Example XRP amount:
|
||||
```json
|
||||
{
|
||||
"currency": "XRP",
|
||||
"value": "2000"
|
||||
}
|
||||
```
|
||||
|
||||
An *amount* is data structure representing a currency, a quantity of that currency, and the counterparty on the trustline that holds the value. For XRP, there is no counterparty.
|
||||
|
||||
A *lax amount* allows the counterparty to be omitted for all currencies. If the counterparty is not specified in an amount within a transaction specification, then any counterparty may be used for that amount.
|
||||
|
||||
A *lax lax amount* allows either or both the counterparty and value to be omitted.
|
||||
|
||||
A *balance* is an amount than can have a negative value.
|
||||
|
||||
<%- renderSchema('objects/amount-base.json') %>
|
||||
53
docs/src/boilerplate.md.ejs
Normal file
53
docs/src/boilerplate.md.ejs
Normal file
@@ -0,0 +1,53 @@
|
||||
## Boilerplate
|
||||
|
||||
Use the following [boilerplate code](https://en.wikipedia.org/wiki/Boilerplate_code) to wrap your custom code using RippleAPI.
|
||||
|
||||
```javascript
|
||||
const {RippleAPI} = require('ripple-lib');
|
||||
|
||||
const api = new RippleAPI({
|
||||
server: 'wss://s1.ripple.com' // Public rippled server hosted by Ripple, Inc.
|
||||
});
|
||||
api.connect().then(() => {
|
||||
/* insert code here */
|
||||
}).then(() => {
|
||||
return api.disconnect();
|
||||
}).catch(console.error);
|
||||
```
|
||||
|
||||
RippleAPI is designed to work in [NodeJS](https://nodejs.org) (version `0.12.0` or greater) using [Babel](https://babeljs.io/) for [ECMAScript 6](https://babeljs.io/docs/learn-es2015/) support.
|
||||
|
||||
The code samples in this documentation are written in ES6, but `RippleAPI` will work with ES5 also. Regardless of whether you use ES5 or ES6, the methods that return promises will return [ES6-style promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
|
||||
|
||||
<aside class="notice">
|
||||
All the code snippets in this documentation assume that you have surrounded them with this boilerplate.
|
||||
</aside>
|
||||
|
||||
<aside class="notice">
|
||||
If you omit the "catch" section, errors may not be visible.
|
||||
</aside>
|
||||
|
||||
### Parameters
|
||||
|
||||
The RippleAPI constructor optionally takes one argument, an object with the following options:
|
||||
|
||||
<%- renderSchema('input/api-options.json') %>
|
||||
|
||||
If you omit the `server` parameter, RippleAPI operates [offline](#offline-functionality).
|
||||
|
||||
|
||||
### Installation ###
|
||||
|
||||
1. Install [NodeJS](https://nodejs.org) and the Node Package Manager (npm). Most Linux distros have a package for NodeJS, but make sure you have version `0.12.0` or higher.
|
||||
2. Use npm to install [Babel](https://babeljs.io/) globally:
|
||||
`npm install -g babel`
|
||||
3. Use npm to install RippleAPI:
|
||||
`npm install ripple-lib`
|
||||
|
||||
After you have installed ripple-lib, you can create scripts using the [boilerplate](#boilerplate) and run them using babel-node:
|
||||
`babel-node script.js`
|
||||
|
||||
<aside class="notice">
|
||||
Instead of using babel-node in production, we recommend using Babel to transpile to ECMAScript 5 first.
|
||||
</aside>
|
||||
|
||||
28
docs/src/computeLedgerHash.md.ejs
Normal file
28
docs/src/computeLedgerHash.md.ejs
Normal file
@@ -0,0 +1,28 @@
|
||||
## computeLedgerHash
|
||||
|
||||
`computeLedgerHash(ledger: Object): string`
|
||||
|
||||
Compute the hash of a ledger.
|
||||
|
||||
### Parameters
|
||||
|
||||
<aside class="notice">
|
||||
The parameter to this method has the same structure as the return value of getLedger.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('input/compute-ledger-hash.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns an uppercase hexadecimal string representing the hash of the ledger.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const ledger = <%- importFile('test/fixtures/requests/compute-ledger-hash.json') %>;
|
||||
return api.computeLedgerHash(ledger);
|
||||
```
|
||||
|
||||
```json
|
||||
"F4D865D83EB88C1A1911B9E90641919A1314F36E1B099F8E95FE3B7C77BE3349"
|
||||
```
|
||||
17
docs/src/connect.md.ejs
Normal file
17
docs/src/connect.md.ejs
Normal file
@@ -0,0 +1,17 @@
|
||||
## connect
|
||||
|
||||
`connect(): Promise<void>`
|
||||
|
||||
Tells the RippleAPI instance to connect to its rippled server.
|
||||
|
||||
### Parameters
|
||||
|
||||
This method has no parameters.
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with a void value when a connection is established.
|
||||
|
||||
### Example
|
||||
|
||||
See [Boilerplate](#boilerplate) for code sample.
|
||||
17
docs/src/disconnect.md.ejs
Normal file
17
docs/src/disconnect.md.ejs
Normal file
@@ -0,0 +1,17 @@
|
||||
## disconnect
|
||||
|
||||
`disconnect(): Promise<void>`
|
||||
|
||||
Tells the RippleAPI instance to disconnect from its rippled server.
|
||||
|
||||
### Parameters
|
||||
|
||||
This method has no parameters.
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with a void value when a connection is destroyed.
|
||||
|
||||
### Example
|
||||
|
||||
See [Boilerplate](#boilerplate) for code sample
|
||||
39
docs/src/events.md.ejs
Normal file
39
docs/src/events.md.ejs
Normal file
@@ -0,0 +1,39 @@
|
||||
# API Events
|
||||
|
||||
## ledger
|
||||
|
||||
This event is emitted whenever a new ledger version is validated on the connected server.
|
||||
|
||||
### Return Value
|
||||
|
||||
<%- renderSchema('output/ledger-event.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
api.on('ledger', ledger => {
|
||||
console.log(JSON.stringify(ledger, null, 2));
|
||||
});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/ledger-event.json') %>
|
||||
|
||||
## error
|
||||
|
||||
This event is emitted when there is an error on the connection to the server.
|
||||
|
||||
### Return Value
|
||||
|
||||
The first parameter is a string indicating the error type, which may be `badMessage` (meaning that rippled returned a malformed message), or one of the [rippled Universal Errors](https://ripple.com/build/rippled-apis/#universal-errors). The second parameter is a message explaining the error, or the message that caused the error in the case of `badMessage`.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
api.on('error', (errorCode, errorMessage) => {
|
||||
console.log(errorCode + ': ' + errorMessage);
|
||||
});
|
||||
```
|
||||
|
||||
```
|
||||
tooBusy: The server is too busy to help you now.
|
||||
```
|
||||
24
docs/src/generateAddress.md.ejs
Normal file
24
docs/src/generateAddress.md.ejs
Normal file
@@ -0,0 +1,24 @@
|
||||
## generateAddress
|
||||
|
||||
`generateAddress(): {address: string, secret: string}`
|
||||
|
||||
Generate a new Ripple address and corresponding secret.
|
||||
|
||||
### Parameters
|
||||
|
||||
This method has no parameters.
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns an object with the following structure:
|
||||
|
||||
<%- renderSchema('output/generate-address.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
return api.generateAddress()
|
||||
.then(result => {/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/generate-address.json') %>
|
||||
25
docs/src/getAccountInfo.md.ejs
Normal file
25
docs/src/getAccountInfo.md.ejs
Normal file
@@ -0,0 +1,25 @@
|
||||
## getAccountInfo
|
||||
|
||||
`getAccountInfo(address: string, options: Object): Promise<Object>`
|
||||
|
||||
Returns information for the specified account. Note: For account data that is modifiable by the user, see [getSettings](#getsettings).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/get-account-info.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<%- renderSchema('output/get-account-info.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
return api.getAccountInfo(address).then(info =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/get-account-info.json') %>
|
||||
25
docs/src/getBalanceSheet.md.ejs
Normal file
25
docs/src/getBalanceSheet.md.ejs
Normal file
@@ -0,0 +1,25 @@
|
||||
## getBalanceSheet
|
||||
|
||||
`getBalanceSheet(address: string, options: Object): Promise<Object>`
|
||||
|
||||
Returns aggregate balances by currency plus a breakdown of assets and obligations for a specified account.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/get-balance-sheet.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an array of objects with the following structure:
|
||||
|
||||
<%- renderSchema('output/get-balance-sheet.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
return api.getBalanceSheet(address).then(balanceSheet =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/get-balance-sheet.json') %>
|
||||
25
docs/src/getBalances.md.ejs
Normal file
25
docs/src/getBalances.md.ejs
Normal file
@@ -0,0 +1,25 @@
|
||||
## getBalances
|
||||
|
||||
`getBalances(address: string, options: Object): Promise<Array<Object>>`
|
||||
|
||||
Returns balances for a specified account.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/get-balances.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an array of objects with the following structure:
|
||||
|
||||
<%- renderSchema('output/get-balances.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
return api.getBalances(address).then(balances =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/get-balances.json') %>
|
||||
23
docs/src/getFee.md.ejs
Normal file
23
docs/src/getFee.md.ejs
Normal file
@@ -0,0 +1,23 @@
|
||||
## getFee
|
||||
|
||||
`getFee(): Promise<number>`
|
||||
|
||||
Returns the estimated transaction fee for the rippled server the RippleAPI instance is connected to.
|
||||
|
||||
### Parameters
|
||||
|
||||
This method has no parameters.
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with a floating point value representing the estimated fee to submit a transaction, expressed in XRP.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
return api.getFee().then(fee => {/* ... */});
|
||||
```
|
||||
|
||||
```json
|
||||
0.012
|
||||
```
|
||||
24
docs/src/getLedger.md.ejs
Normal file
24
docs/src/getLedger.md.ejs
Normal file
@@ -0,0 +1,24 @@
|
||||
## getLedger
|
||||
|
||||
`getLedger(options: Object): Promise<Object>`
|
||||
|
||||
Returns header information for the specified ledger (or the most recent validated ledger if no ledger is specified). Optionally, all the transactions that were validated in the ledger or the account state information can be returned with the ledger header.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/get-ledger.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<%- renderSchema('output/get-ledger.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
return api.getLedger()
|
||||
.then(ledger => {/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/get-ledger.json') %>
|
||||
26
docs/src/getLedgerVersion.md.ejs
Normal file
26
docs/src/getLedgerVersion.md.ejs
Normal file
@@ -0,0 +1,26 @@
|
||||
## getLedgerVersion
|
||||
|
||||
`getLedgerVersion(): Promise<number>`
|
||||
|
||||
Returns the most recent validated ledger version number known to the connected server.
|
||||
|
||||
### Parameters
|
||||
|
||||
This method has no parameters.
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with a positive integer representing the most recent validated ledger version number known to the connected server.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
return api.getLedgerVersion().then(ledgerVersion => {
|
||||
/* ... */
|
||||
});
|
||||
```
|
||||
|
||||
```json
|
||||
16869039
|
||||
```
|
||||
|
||||
26
docs/src/getOrderbook.md.ejs
Normal file
26
docs/src/getOrderbook.md.ejs
Normal file
@@ -0,0 +1,26 @@
|
||||
## getOrderbook
|
||||
|
||||
`getOrderbook(address: string, orderbook: Object, options: Object): Promise<Object>`
|
||||
|
||||
Returns open orders for the specified account. Open orders are orders that have not yet been fully executed and are still in the order book.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/get-orderbook.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure (Note: the structures of `bids` and `asks` are identical):
|
||||
|
||||
<%- renderSchema('output/get-orderbook.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const orderbook = <%- importFile('test/fixtures/requests/get-orderbook.json') %>;
|
||||
return api.getOrderbook(address, orderbook)
|
||||
.then(orderbook => {/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/get-orderbook.json') %>
|
||||
25
docs/src/getOrders.md.ejs
Normal file
25
docs/src/getOrders.md.ejs
Normal file
@@ -0,0 +1,25 @@
|
||||
## getOrders
|
||||
|
||||
`getOrders(address: string, options: Object): Promise<Array<Object>>`
|
||||
|
||||
Returns open orders for the specified account. Open orders are orders that have not yet been fully executed and are still in the order book.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/get-orders.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an array of objects with the following structure:
|
||||
|
||||
<%- renderSchema('output/get-orders.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
return api.getOrders(address).then(orders =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/get-orders.json') %>
|
||||
25
docs/src/getPaths.md.ejs
Normal file
25
docs/src/getPaths.md.ejs
Normal file
@@ -0,0 +1,25 @@
|
||||
## getPaths
|
||||
|
||||
`getPaths(pathfind: Object): Promise<Array<Object>>`
|
||||
|
||||
Finds paths to send a payment. Paths are options for how to route a payment.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema("input/get-paths.json") %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an array of objects with the following structure:
|
||||
|
||||
<%- renderSchema("output/get-paths.json") %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const pathfind = <%- importFile('test/fixtures/requests/getpaths/normal.json') %>;
|
||||
return api.getPaths(pathfind)
|
||||
.then(paths => {/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture("responses/get-paths.json") %>
|
||||
23
docs/src/getServerInfo.md.ejs
Normal file
23
docs/src/getServerInfo.md.ejs
Normal file
@@ -0,0 +1,23 @@
|
||||
## getServerInfo
|
||||
|
||||
`getServerInfo(): Promise<object>`
|
||||
|
||||
Get status information about the server that the RippleAPI instance is connected to.
|
||||
|
||||
### Parameters
|
||||
|
||||
This method has no parameters.
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<%- renderSchema('output/get-server-info.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
return api.getServerInfo().then(info => {/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/get-server-info.json') %>
|
||||
25
docs/src/getSettings.md.ejs
Normal file
25
docs/src/getSettings.md.ejs
Normal file
@@ -0,0 +1,25 @@
|
||||
## getSettings
|
||||
|
||||
`getSettings(address: string, options: Object): Promise<Object>`
|
||||
|
||||
Returns settings for the specified account. Note: For account data that is not modifiable by the user, see [getAccountInfo](#getaccountinfo).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/get-settings.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an array of objects with the following structure (Note: all fields are optional as they will not be shown if they are set to their default value):
|
||||
|
||||
<%- renderSchema('output/get-settings.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
return api.getSettings(address).then(settings =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/get-settings.json') %>
|
||||
26
docs/src/getTransaction.md.ejs
Normal file
26
docs/src/getTransaction.md.ejs
Normal file
@@ -0,0 +1,26 @@
|
||||
## getTransaction
|
||||
|
||||
`getTransaction(id: string, options: Object): Promise<Object>`
|
||||
|
||||
Retrieves a transaction by its [Transaction ID](#transaction-id).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/get-transaction.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with a transaction object containing the following fields.
|
||||
|
||||
<%- renderSchema('output/get-transaction.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const id = '01CDEAA89BF99D97DFD47F79A0477E1DCC0989D39F70E8AACBFE68CC83BD1E94';
|
||||
return api.getTransaction(id).then(transaction => {
|
||||
/* ... */
|
||||
});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/get-transaction-payment.json') %>
|
||||
24
docs/src/getTransactions.md.ejs
Normal file
24
docs/src/getTransactions.md.ejs
Normal file
@@ -0,0 +1,24 @@
|
||||
## getTransactions
|
||||
|
||||
`getTransactions(address: string, options: Object): Promise<Array<Object>>`
|
||||
|
||||
Retrieves historical transactions of an account.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/get-transactions.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an array of transaction object in the same format as [getTransaction](#gettransaction).
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
return api.getTransactions(address).then(transaction => {
|
||||
/* ... */
|
||||
});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/get-transactions.json') %>
|
||||
25
docs/src/getTrustlines.md.ejs
Normal file
25
docs/src/getTrustlines.md.ejs
Normal file
@@ -0,0 +1,25 @@
|
||||
## getTrustlines
|
||||
|
||||
`getTrustlines(address: string, options: Object): Promise<Array<Object>>`
|
||||
|
||||
Returns trustlines for a specified account.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema("input/get-trustlines.json") %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an array of objects with the following structure.
|
||||
|
||||
<%- renderSchema("output/get-trustlines.json") %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
return api.getTrustlines(address).then(trustlines =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture("responses/get-trustlines.json") %>
|
||||
37
docs/src/index.md.ejs
Normal file
37
docs/src/index.md.ejs
Normal file
@@ -0,0 +1,37 @@
|
||||
<% include introduction.md.ejs %>
|
||||
<% include boilerplate.md.ejs %>
|
||||
<% include offline.md.ejs %>
|
||||
<% include basictypes.md.ejs %>
|
||||
<% include transactions.md.ejs %>
|
||||
<% include specifications.md.ejs %>
|
||||
<% include methods.md.ejs %>
|
||||
<% include connect.md.ejs %>
|
||||
<% include disconnect.md.ejs %>
|
||||
<% include isConnected.md.ejs %>
|
||||
<% include getServerInfo.md.ejs %>
|
||||
<% include getFee.md.ejs %>
|
||||
<% include getLedgerVersion.md.ejs %>
|
||||
<% include getTransaction.md.ejs %>
|
||||
<% include getTransactions.md.ejs %>
|
||||
<% include getTrustlines.md.ejs %>
|
||||
<% include getBalances.md.ejs %>
|
||||
<% include getBalanceSheet.md.ejs %>
|
||||
<% include getPaths.md.ejs %>
|
||||
<% include getOrders.md.ejs %>
|
||||
<% include getOrderbook.md.ejs %>
|
||||
<% include getSettings.md.ejs %>
|
||||
<% include getAccountInfo.md.ejs %>
|
||||
<% include getLedger.md.ejs %>
|
||||
<% include preparePayment.md.ejs %>
|
||||
<% include prepareTrustline.md.ejs %>
|
||||
<% include prepareOrder.md.ejs %>
|
||||
<% include prepareOrderCancellation.md.ejs %>
|
||||
<% include prepareSettings.md.ejs %>
|
||||
<% include prepareSuspendedPaymentCreation.md.ejs %>
|
||||
<% include prepareSuspendedPaymentCancellation.md.ejs %>
|
||||
<% include prepareSuspendedPaymentExecution.md.ejs %>
|
||||
<% include sign.md.ejs %>
|
||||
<% include submit.md.ejs %>
|
||||
<% include generateAddress.md.ejs %>
|
||||
<% include computeLedgerHash.md.ejs %>
|
||||
<% include events.md.ejs %>
|
||||
12
docs/src/introduction.md.ejs
Normal file
12
docs/src/introduction.md.ejs
Normal file
@@ -0,0 +1,12 @@
|
||||
# Introduction
|
||||
|
||||
RippleAPI is the official client library to the Ripple Consensus Ledger. Currently, RippleAPI is only available in JavaScript.
|
||||
Using RippleAPI, you can:
|
||||
|
||||
* [Query transactions from the network](#gettransaction)
|
||||
* [Sign](#sign) transactions securely without connecting to any server
|
||||
* [Submit](#submit) transactions to the Ripple Consensus Ledger, including [Payments](#payment), [Orders](#order), [Settings changes](#settings), and [other types](#transaction-types)
|
||||
* [Generate a new Ripple Address](#generateaddress)
|
||||
* ... and [much more](#api-methods).
|
||||
|
||||
RippleAPI only provides access to *validated*, *immutable* transaction data.
|
||||
23
docs/src/isConnected.md.ejs
Normal file
23
docs/src/isConnected.md.ejs
Normal file
@@ -0,0 +1,23 @@
|
||||
## isConnected
|
||||
|
||||
`isConnected(): boolean`
|
||||
|
||||
Checks if the RippleAPI instance is connected to its rippled server.
|
||||
|
||||
### Parameters
|
||||
|
||||
This method has no parameters.
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns `true` if connected and `false` if not connected.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
return api.isConnected();
|
||||
```
|
||||
|
||||
```json
|
||||
true
|
||||
```
|
||||
1
docs/src/methods.md.ejs
Normal file
1
docs/src/methods.md.ejs
Normal file
@@ -0,0 +1 @@
|
||||
# API Methods
|
||||
27
docs/src/offline.md.ejs
Normal file
27
docs/src/offline.md.ejs
Normal file
@@ -0,0 +1,27 @@
|
||||
## Offline functionality
|
||||
|
||||
RippleAPI can also function without internet connectivity. This can be useful in order to generate secrets and sign transactions from a secure, isolated machine.
|
||||
|
||||
To instantiate RippleAPI in offline mode, use the following boilerplate code:
|
||||
|
||||
```javascript
|
||||
const {RippleAPI} = require('ripple-lib');
|
||||
|
||||
const api = new RippleAPI();
|
||||
/* insert code here */
|
||||
```
|
||||
|
||||
Methods that depend on the state of the Ripple Consensus Ledger are unavailable in offline mode. To prepare transactions offline, you **must** specify the `fee`, `sequence`, and `maxLedgerVersion` parameters in the [transaction instructions](#transaction-instructions). The following methods should work offline:
|
||||
|
||||
* [preparePayment](#preparepayment)
|
||||
* [prepareTrustline](#preparetrustline)
|
||||
* [prepareOrder](#prepareorder)
|
||||
* [prepareOrderCancellation](#prepareordercancellation)
|
||||
* [prepareSettings](#preparesettings)
|
||||
* [prepareSuspendedPaymentCreation](#preparesuspendedpaymentcreation)
|
||||
* [prepareSuspendedPaymentCancellation](#preparesuspendedpaymentcancellation)
|
||||
* [prepareSuspendedPaymentExecution](#preparesuspendedpaymentexecution)
|
||||
* [sign](#sign)
|
||||
* [generateAddress](#generateaddress)
|
||||
* [computeLedgerHash](#computeledgerhash)
|
||||
|
||||
30
docs/src/prepareOrder.md.ejs
Normal file
30
docs/src/prepareOrder.md.ejs
Normal file
@@ -0,0 +1,30 @@
|
||||
## prepareOrder
|
||||
|
||||
`prepareOrder(address: string, order: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare an order transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-order.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const order = <%- importFile('test/fixtures/requests/prepare-order.json') %>;
|
||||
return api.prepareOrder(address, order)
|
||||
.then(prepared => {/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-order.json') %>
|
||||
30
docs/src/prepareOrderCancellation.md.ejs
Normal file
30
docs/src/prepareOrderCancellation.md.ejs
Normal file
@@ -0,0 +1,30 @@
|
||||
## prepareOrderCancellation
|
||||
|
||||
`prepareOrderCancellation(address: string, orderCancellation: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare an order cancellation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema("input/prepare-order-cancellation.json") %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema("output/prepare.json") %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const orderCancellation = {orderSequence: 123};
|
||||
return api.prepareOrderCancellation(address, sequence)
|
||||
.then(prepared => {/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture("responses/prepare-order-cancellation.json") %>
|
||||
30
docs/src/preparePayment.md.ejs
Normal file
30
docs/src/preparePayment.md.ejs
Normal file
@@ -0,0 +1,30 @@
|
||||
## preparePayment
|
||||
|
||||
`preparePayment(address: string, payment: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a payment transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema("input/prepare-payment.json") %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema("output/prepare.json") %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const payment = <%- importFile('test/fixtures/requests/prepare-payment.json') %>;
|
||||
return api.preparePayment(address, payment).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture("responses/prepare-payment.json") %>
|
||||
30
docs/src/prepareSettings.md.ejs
Normal file
30
docs/src/prepareSettings.md.ejs
Normal file
@@ -0,0 +1,30 @@
|
||||
## prepareSettings
|
||||
|
||||
`prepareSettings(address: string, settings: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a settings transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-settings.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const settings = <%- importFile('test/fixtures/requests/prepare-settings.json') %>;
|
||||
return api.prepareSettings(address, settings)
|
||||
.then(prepared => {/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('requests/prepare-settings.json') %>
|
||||
32
docs/src/prepareSuspendedPaymentCancellation.md.ejs
Normal file
32
docs/src/prepareSuspendedPaymentCancellation.md.ejs
Normal file
@@ -0,0 +1,32 @@
|
||||
## prepareSuspendedPaymentCancellation
|
||||
|
||||
`prepareSuspendedPaymentCancellation(address: string, suspendedPaymentCancellation: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a suspended payment cancellation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
**Caution:** Suspended Payments are currently available on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) only.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-suspended-payment-cancellation.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const suspendedPaymentCancellation = <%- importFile('test/fixtures/requests/prepare-suspended-payment-cancellation.json') %>;
|
||||
return api.prepareSuspendedPaymentCancellation(address, suspendedPaymentCancellation).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-suspended-payment-cancellation.json') %>
|
||||
32
docs/src/prepareSuspendedPaymentCreation.md.ejs
Normal file
32
docs/src/prepareSuspendedPaymentCreation.md.ejs
Normal file
@@ -0,0 +1,32 @@
|
||||
## prepareSuspendedPaymentCreation
|
||||
|
||||
`prepareSuspendedPaymentCreation(address: string, suspendedPaymentCreation: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a suspended payment creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
**Caution:** Suspended Payments are currently available on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) only.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-suspended-payment-creation.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const suspendedPaymentCreation = <%- importFile('test/fixtures/requests/prepare-suspended-payment-creation.json') %>;
|
||||
return api.prepareSuspendedPaymentCreation(address, suspendedPaymentCreation).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-suspended-payment-creation.json') %>
|
||||
32
docs/src/prepareSuspendedPaymentExecution.md.ejs
Normal file
32
docs/src/prepareSuspendedPaymentExecution.md.ejs
Normal file
@@ -0,0 +1,32 @@
|
||||
## prepareSuspendedPaymentExecution
|
||||
|
||||
`prepareSuspendedPaymentExecution(address: string, suspendedPaymentExecution: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a suspended payment execution transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
**Caution:** Suspended Payments are currently available on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) only.
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/prepare-suspended-payment-execution.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema('output/prepare.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const suspendedPaymentExecution = <%- importFile('test/fixtures/requests/prepare-suspended-payment-execution.json') %>;
|
||||
return api.prepareSuspendedPaymentExecution(address, suspendedPaymentExecution).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/prepare-suspended-payment-execution.json') %>
|
||||
30
docs/src/prepareTrustline.md.ejs
Normal file
30
docs/src/prepareTrustline.md.ejs
Normal file
@@ -0,0 +1,30 @@
|
||||
## prepareTrustline
|
||||
|
||||
`prepareTrustline(address: string, trustline: Object, instructions: Object): Promise<Object>`
|
||||
|
||||
Prepare a trustline transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema("input/prepare-trustline.json") %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with an object with the following structure:
|
||||
|
||||
<aside class="notice">
|
||||
All "prepare*" methods have the same return type.
|
||||
</aside>
|
||||
|
||||
<%- renderSchema("output/prepare.json") %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const trustline = <%- importFile('test/fixtures/requests/prepare-trustline.json') %>;
|
||||
return api.preparePayment(address, trustline).then(prepared =>
|
||||
{/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture("responses/prepare-trustline.json") %>
|
||||
25
docs/src/sign.md.ejs
Normal file
25
docs/src/sign.md.ejs
Normal file
@@ -0,0 +1,25 @@
|
||||
## sign
|
||||
|
||||
`sign(txJSON: string, secret: string): {signedTransaction: string, id: string}`
|
||||
|
||||
Sign a prepared transaction. The signed transaction must subsequently be [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema("input/sign.json") %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns an object with the following structure:
|
||||
|
||||
<%- renderSchema("output/sign.json") %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const txJSON = '{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Domain":"726970706C652E636F6D","LastLedgerSequence":8820051,"Fee":"12","Sequence":23}';
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV';
|
||||
return api.sign(txJSON, secret);
|
||||
```
|
||||
|
||||
<%- renderFixture("responses/sign.json") %>
|
||||
83
docs/src/specifications.md.ejs
Normal file
83
docs/src/specifications.md.ejs
Normal file
@@ -0,0 +1,83 @@
|
||||
# Transaction Specifications
|
||||
|
||||
A *transaction specification* specifies what a transaction should do. Each [Transaction Type](#transaction-types) has its own type of specification.
|
||||
|
||||
## Payment
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/payment.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-payment.json') %>
|
||||
|
||||
## Trustline
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/trustline.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-trustline.json') %>
|
||||
|
||||
## Order
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/order.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-order.json') %>
|
||||
|
||||
## Order Cancellation
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/order-cancellation.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-order-cancellation.json') %>
|
||||
|
||||
## Settings
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('output/get-settings.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-settings.json') %>
|
||||
|
||||
## Suspended Payment Creation
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/suspended-payment-creation.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-suspended-payment-creation.json') %>
|
||||
|
||||
## Suspended Payment Cancellation
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/suspended-payment-cancellation.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-suspended-payment-cancellation.json') %>
|
||||
|
||||
## Suspended Payment Execution
|
||||
|
||||
See [Transaction Types](#transaction-types) for a description.
|
||||
|
||||
<%- renderSchema('specifications/suspended-payment-execution.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
<%- renderFixture('requests/prepare-suspended-payment-execution.json') %>
|
||||
25
docs/src/submit.md.ejs
Normal file
25
docs/src/submit.md.ejs
Normal file
@@ -0,0 +1,25 @@
|
||||
## submit
|
||||
|
||||
`submit(signedTransaction: string): Promise<Object>`
|
||||
|
||||
Submits a signed transaction. The transaction is not guaranteed to succeed; it must be verified with [getTransaction](#gettransaction).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema('input/submit.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns an object with the following structure:
|
||||
|
||||
<%- renderSchema('output/submit.json') %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const signedTransaction = '12000322800000002400000017201B0086955368400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D874473045022100BDE09A1F6670403F341C21A77CF35BA47E45CDE974096E1AA5FC39811D8269E702203D60291B9A27F1DCABA9CF5DED307B4F23223E0B6F156991DB601DFB9C41CE1C770A726970706C652E636F6D81145E7B112523F68D2F5E879DB4EAC51C6698A69304';
|
||||
return api.submit(signedTransaction)
|
||||
.then(result => {/* ... */});
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/submit.json') %>
|
||||
65
docs/src/transactions.md.ejs
Normal file
65
docs/src/transactions.md.ejs
Normal file
@@ -0,0 +1,65 @@
|
||||
# Transaction Overview
|
||||
|
||||
## Transaction Types
|
||||
|
||||
A transaction type is specified by the strings in the first column in the table below.
|
||||
|
||||
Type | Description
|
||||
---- | -----------
|
||||
[payment](#payment) | A `payment` transaction represents a transfer of value from one account to another. Depending on the [path](https://ripple.com/build/paths/) taken, additional exchanges of value may occur atomically to facilitate the payment.
|
||||
[order](#order) | An `order` transaction creates a limit order. It defines an intent to exchange currencies, and creates an order in the Ripple Consensus Ledger's order book if not completely fulfilled when placed. Orders can be partially fulfilled.
|
||||
[orderCancellation](#order-cancellation) | An `orderCancellation` transaction cancels an order in the Ripple Consensus Ledger's order book.
|
||||
[trustline](#trustline) | A `trustline` transactions creates or modifies a trust line between two accounts.
|
||||
[settings](#settings) | A `settings` transaction modifies the settings of an account in the Ripple Consensus Ledger.
|
||||
[suspendedPaymentCreation](#suspended-payment-creation) | A `suspendedPaymentCreation` transaction creates a suspended payment on the ledger, which locks XRP until a cryptographic condition is met or it expires. It is like an escrow service where the Ripple network acts as the escrow agent.
|
||||
[suspendedPaymentCancellation](#suspended-payment-cancellation) | A `suspendedPaymentCancellation` transaction unlocks the funds in a suspended payment and sends them back to the creator of the suspended payment, but it will only work after the suspended payment expires.
|
||||
[suspendedPaymentExecution](#suspended-payment-execution) | A `suspendedPaymentExecution` transaction unlocks the funds in a suspended payment and sends them to the destination of the suspended payment, but it will only work if the cryptographic condition is provided.
|
||||
|
||||
The three "suspended payment" transaction types are not supported by the production Ripple peer-to-peer network at this time. They are available for testing purposes if you [configure RippleAPI](#boilerplate) to connect to the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) instead.
|
||||
|
||||
## Transaction Flow
|
||||
|
||||
Executing a transaction with `RippleAPI` requires the following four steps:
|
||||
|
||||
1. Prepare - Create an unsigned transaction based on a [specification](#transaction-specifications) and [instructions](#transaction-instructions). There is a method to prepare each type of transaction:
|
||||
* [preparePayment](#preparepayment)
|
||||
* [prepareTrustline](#preparetrustline)
|
||||
* [prepareOrder](#prepareorder)
|
||||
* [prepareOrderCancellation](#prepareordercancellation)
|
||||
* [prepareSettings](#preparesettings)
|
||||
* [prepareSuspendedPaymentCreation](#preparesuspendedpaymentcreation)
|
||||
* [prepareSuspendedPaymentCancellation](#preparesuspendedpaymentcancellation)
|
||||
* [prepareSuspendedPaymentExecution](#preparesuspendedpaymentexecution)
|
||||
2. [Sign](#sign) - Cryptographically sign the transaction locally and save the [transaction ID](#transaction-id). Signing is how the owner of an account authorizes a transaction to take place.
|
||||
3. [Submit](#submit) - Submit the transaction to the connected server.
|
||||
4. Verify - Verify that the transaction got validated by querying with [getTransaction](#gettransaction). This is necessary because transactions may fail even if they were successfully submitted.
|
||||
|
||||
## Transaction Fees
|
||||
|
||||
Every transaction must destroy a small amount of XRP as a cost to send the transaction. This is also called a *transaction fee*. The transaction cost is designed to increase along with the load on the Ripple network, making it very expensive to deliberately or inadvertently overload the network.
|
||||
|
||||
You can choose the size of the fee you want to pay or let a default be used. You can get an estimate of the fee required to be included in the next ledger closing with the [getFee](#getfee) method.
|
||||
|
||||
## Transaction Instructions
|
||||
|
||||
Transaction instructions indicate how to execute a transaction, complementary with the [transaction specification](#transaction-specifications).
|
||||
|
||||
<%- renderSchema("objects/instructions.json") %>
|
||||
|
||||
We recommended that you specify a `maxLedgerVersion` so that you can quickly determine that a failed transaction will never succeeed in the future. It is impossible for a transaction to succeed after the network ledger version exceeds the transaction's `maxLedgerVersion`. If you omit `maxLedgerVersion`, the "prepare*" method automatically supplies a `maxLedgerVersion` equal to the current ledger plus 3, which it includes in the return value from the "prepare*" method.
|
||||
|
||||
## Transaction ID
|
||||
|
||||
```json
|
||||
"F4AB442A6D4CBB935D66E1DA7309A5FC71C7143ED4049053EC14E3875B0CF9BF"
|
||||
```
|
||||
|
||||
A transaction ID is a 64-bit hexadecimal string that uniquely identifies the transaction. The transaction ID is derived from the transaction instruction and specifications, using a strong hash function.
|
||||
|
||||
You can look up a transaction by ID using the [getTransaction](#gettransaction) method.
|
||||
|
||||
## Transaction Memos
|
||||
|
||||
Every transaction can optionally have an array of memos for user applications. The `memos` field in each [transaction specification](#transaction-specifications) is an array of objects with the following structure:
|
||||
|
||||
<%- renderSchema('objects/memos.json') %>
|
||||
140
npm-shrinkwrap.json
generated
140
npm-shrinkwrap.json
generated
@@ -1,93 +1,126 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "0.13.0-rc16",
|
||||
"npm-shrinkwrap-version": "5.4.0",
|
||||
"node-version": "v0.12.7",
|
||||
"version": "0.15.2",
|
||||
"dependencies": {
|
||||
"ajv": {
|
||||
"version": "1.4.8",
|
||||
"from": "https://registry.npmjs.org/ajv/-/ajv-1.4.8.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-1.4.8.tgz",
|
||||
"dependencies": {
|
||||
"json-stable-stringify": {
|
||||
"version": "1.0.0",
|
||||
"from": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.0.tgz",
|
||||
"dependencies": {
|
||||
"jsonify": {
|
||||
"version": "0.0.0",
|
||||
"from": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"babel-polyfill": {
|
||||
"version": "6.2.0",
|
||||
"from": "babel-polyfill@*",
|
||||
"resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.2.0.tgz",
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "1.2.6",
|
||||
"from": "core-js@>=1.0.1 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz"
|
||||
},
|
||||
"babel-regenerator-runtime": {
|
||||
"version": "6.2.0",
|
||||
"from": "babel-regenerator-runtime@>=6.2.0 <7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-regenerator-runtime/-/babel-regenerator-runtime-6.2.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"babel-runtime": {
|
||||
"version": "5.8.29",
|
||||
"from": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.29.tgz",
|
||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.29.tgz",
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "1.2.3",
|
||||
"from": "https://registry.npmjs.org/core-js/-/core-js-1.2.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.3.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bignumber.js": {
|
||||
"version": "2.1.0",
|
||||
"from": "bignumber.js@>=2.0.3 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.1.0.tgz"
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "1.0.0",
|
||||
"from": "https-proxy-agent@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
|
||||
"dependencies": {
|
||||
"agent-base": {
|
||||
"version": "2.0.1",
|
||||
"from": "agent-base@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz",
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.0.3",
|
||||
"from": "semver@>=5.0.1 <5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.2.0",
|
||||
"from": "debug@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "0.7.1",
|
||||
"from": "ms@0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.0",
|
||||
"from": "extend@>=3.0.0 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "3.10.1",
|
||||
"from": "lodash@>=3.1.0 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz"
|
||||
},
|
||||
"ripple-address-codec": {
|
||||
"version": "2.0.1",
|
||||
"from": "ripple-address-codec@>=2.0.1 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-2.0.1.tgz",
|
||||
"dependencies": {
|
||||
"hash.js": {
|
||||
"version": "1.0.3",
|
||||
"from": "hash.js@>=1.0.3 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz",
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@>=2.0.1 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-address-codec": {
|
||||
"version": "0.7.2",
|
||||
"from": "x-address-codec@>=0.7.0 <0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/x-address-codec/-/x-address-codec-0.7.2.tgz",
|
||||
"dependencies": {
|
||||
"base-x": {
|
||||
"version": "1.0.1",
|
||||
"from": "base-x@>=1.0.1 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/base-x/-/base-x-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
@@ -95,97 +128,77 @@
|
||||
}
|
||||
},
|
||||
"ripple-binary-codec": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.0.7.tgz",
|
||||
"version": "0.1.0",
|
||||
"from": "ripple-binary-codec@0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.1.0.tgz",
|
||||
"dependencies": {
|
||||
"babel-runtime": {
|
||||
"version": "5.8.34",
|
||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.34.tgz",
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bn.js": {
|
||||
"version": "3.3.0",
|
||||
"from": "bn.js@>=3.2.0 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-3.3.0.tgz"
|
||||
},
|
||||
"create-hash": {
|
||||
"version": "1.1.2",
|
||||
"from": "create-hash@>=1.1.2 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz",
|
||||
"dependencies": {
|
||||
"cipher-base": {
|
||||
"version": "1.0.2",
|
||||
"from": "cipher-base@>=1.0.1 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.2.tgz"
|
||||
},
|
||||
"ripemd160": {
|
||||
"version": "1.0.1",
|
||||
"from": "ripemd160@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz"
|
||||
},
|
||||
"sha.js": {
|
||||
"version": "2.4.4",
|
||||
"from": "sha.js@>=2.3.6 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.4.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"decimal.js": {
|
||||
"version": "4.0.3",
|
||||
"from": "decimal.js@>=4.0.2 <5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-4.0.3.tgz"
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@>=2.0.1 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
},
|
||||
"lodash": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz"
|
||||
},
|
||||
"ripple-address-codec": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-2.0.1.tgz",
|
||||
"dependencies": {
|
||||
"hash.js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz"
|
||||
},
|
||||
"x-address-codec": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/x-address-codec/-/x-address-codec-0.7.2.tgz",
|
||||
"dependencies": {
|
||||
"base-x": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/base-x/-/base-x-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ripple-hashes": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ripple-hashes/-/ripple-hashes-0.0.1.tgz",
|
||||
"version": "0.1.0",
|
||||
"from": "ripple-hashes@0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-hashes/-/ripple-hashes-0.1.0.tgz",
|
||||
"dependencies": {
|
||||
"create-hash": {
|
||||
"version": "1.1.2",
|
||||
"from": "create-hash@>=1.1.2 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz",
|
||||
"dependencies": {
|
||||
"cipher-base": {
|
||||
"version": "1.0.2",
|
||||
"from": "cipher-base@>=1.0.1 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.2.tgz"
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@>=2.0.1 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
},
|
||||
"ripemd160": {
|
||||
"version": "1.0.1",
|
||||
"from": "ripemd160@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz"
|
||||
},
|
||||
"sha.js": {
|
||||
"version": "2.4.4",
|
||||
"from": "sha.js@>=2.3.6 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.4.tgz"
|
||||
}
|
||||
}
|
||||
@@ -194,32 +207,39 @@
|
||||
},
|
||||
"ripple-keypairs": {
|
||||
"version": "0.10.0",
|
||||
"from": "ripple-keypairs@>=0.10.0 <0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-0.10.0.tgz",
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "3.3.0",
|
||||
"from": "bn.js@>=3.1.1 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-3.3.0.tgz"
|
||||
},
|
||||
"brorand": {
|
||||
"version": "1.0.5",
|
||||
"from": "brorand@>=1.0.5 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.0.5.tgz"
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "5.2.1",
|
||||
"from": "elliptic@>=5.1.0 <6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-5.2.1.tgz",
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@>=2.0.1 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hash.js": {
|
||||
"version": "1.0.3",
|
||||
"from": "hash.js@>=1.0.3 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz",
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@>=2.0.1 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
@@ -228,19 +248,57 @@
|
||||
},
|
||||
"ripple-lib-transactionparser": {
|
||||
"version": "0.6.0",
|
||||
"from": "ripple-lib-transactionparser@>=0.6.0 <0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-lib-transactionparser/-/ripple-lib-transactionparser-0.6.0.tgz"
|
||||
},
|
||||
"ws": {
|
||||
"version": "0.7.2",
|
||||
"from": "ws@>=0.7.1 <0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-0.7.2.tgz",
|
||||
"dependencies": {
|
||||
"options": {
|
||||
"version": "0.0.6",
|
||||
"from": "options@>=0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz"
|
||||
},
|
||||
"ultron": {
|
||||
"version": "1.0.2",
|
||||
"from": "ultron@>=1.0.0 <1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz"
|
||||
},
|
||||
"bufferutil": {
|
||||
"version": "1.1.0",
|
||||
"from": "bufferutil@>=1.1.0 <1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-1.1.0.tgz",
|
||||
"dependencies": {
|
||||
"bindings": {
|
||||
"version": "1.2.1",
|
||||
"from": "bindings@>=1.2.0 <1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
|
||||
},
|
||||
"nan": {
|
||||
"version": "1.8.4",
|
||||
"from": "nan@>=1.8.0 <1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-1.8.4.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"version": "1.1.0",
|
||||
"from": "utf-8-validate@>=1.1.0 <1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-1.1.0.tgz",
|
||||
"dependencies": {
|
||||
"bindings": {
|
||||
"version": "1.2.1",
|
||||
"from": "bindings@>=1.2.0 <1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
|
||||
},
|
||||
"nan": {
|
||||
"version": "1.8.4",
|
||||
"from": "nan@>=1.8.0 <1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-1.8.4.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
32
package.json
32
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "0.13.0-rc16",
|
||||
"version": "0.15.2",
|
||||
"license": "ISC",
|
||||
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
|
||||
"files": [
|
||||
@@ -16,16 +16,17 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": "^1.4.8",
|
||||
"babel-polyfill": "^6.2.0",
|
||||
"babel-runtime": "^5.5.4",
|
||||
"bignumber.js": "^2.0.3",
|
||||
"https-proxy-agent": "^1.0.0",
|
||||
"lodash": "^3.1.0",
|
||||
"ripple-address-codec": "^2.0.1",
|
||||
"ripple-binary-codec": "^0.0.7",
|
||||
"ripple-hashes": "^0.0.1",
|
||||
"ripple-binary-codec": "^0.1.0",
|
||||
"ripple-hashes": "^0.1.0",
|
||||
"ripple-keypairs": "^0.10.0",
|
||||
"ripple-lib-transactionparser": "^0.6.0",
|
||||
"ws": "~0.7.1"
|
||||
"ws": "^0.7.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"assert-diff": "^1.0.1",
|
||||
@@ -33,23 +34,28 @@
|
||||
"babel-core": "^5.8.22",
|
||||
"babel-eslint": "^4.1.3",
|
||||
"babel-loader": "^5.3.2",
|
||||
"coveralls": "~2.10.0",
|
||||
"coveralls": "^2.10.0",
|
||||
"doctoc": "^0.15.0",
|
||||
"ejs": "^2.3.4",
|
||||
"eslint": "^1.3.0",
|
||||
"eslint-plugin-flowtype": "^1.0.0",
|
||||
"eventemitter2": "^0.4.14",
|
||||
"flow-bin": "^0.14",
|
||||
"gulp": "~3.8.10",
|
||||
"gulp-bump": "~0.1.13",
|
||||
"gulp-rename": "~1.2.0",
|
||||
"gulp-uglify": "~1.1.0",
|
||||
"istanbul": "~0.3.5",
|
||||
"gulp": "^3.8.10",
|
||||
"gulp-bump": "^0.1.13",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"gulp-uglify": "^1.1.0",
|
||||
"istanbul": "^0.3.5",
|
||||
"json-loader": "^0.5.2",
|
||||
"mocha": "~2.1.0",
|
||||
"webpack": "~1.5.3",
|
||||
"yargs": "~1.3.1"
|
||||
"json-schema-to-markdown-table": "^0.4.0",
|
||||
"mocha": "^2.1.0",
|
||||
"webpack": "^1.5.3",
|
||||
"yargs": "^1.3.1"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp",
|
||||
"doctoc": "doctoc docs/index.md --title '# RippleAPI Reference' --github --maxlevel 2",
|
||||
"docgen": "node --harmony scripts/build_docs.js",
|
||||
"clean": "rm -rf dist/npm && rm -rf build/flow",
|
||||
"typecheck": "babel --optional runtime --blacklist flow -d build/flow/ src/ && flow check",
|
||||
"compile": "babel -D --optional runtime -d dist/npm/ src/",
|
||||
|
||||
51
scripts/build_docs.js
Normal file
51
scripts/build_docs.js
Normal file
@@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const execSync = require('child_process').execSync;
|
||||
const ejs = require('ejs');
|
||||
const renderFromPaths =
|
||||
require('json-schema-to-markdown-table').renderFromPaths;
|
||||
const ROOT = path.dirname(path.normalize(__dirname));
|
||||
|
||||
function strip(string) {
|
||||
return string.replace(/^\s+|\s+$/g, '');
|
||||
}
|
||||
|
||||
function importFile(relativePath) {
|
||||
const absolutePath = path.join(ROOT, relativePath);
|
||||
return strip(fs.readFileSync(absolutePath).toString('utf-8'));
|
||||
}
|
||||
|
||||
function renderFixture(fixtureRelativePath) {
|
||||
const json = importFile(path.join('test', 'fixtures', fixtureRelativePath));
|
||||
return '\n```json\n' + json + '\n```\n';
|
||||
}
|
||||
|
||||
function renderSchema(schemaRelativePath) {
|
||||
const schemasPath = path.join(ROOT, 'src', 'common', 'schemas');
|
||||
const schemaPath = path.join(schemasPath, schemaRelativePath);
|
||||
return renderFromPaths(schemaPath, schemasPath);
|
||||
}
|
||||
|
||||
function main() {
|
||||
const locals = {
|
||||
importFile: importFile,
|
||||
renderFixture: renderFixture,
|
||||
renderSchema: renderSchema
|
||||
};
|
||||
|
||||
const indexPath = path.join(ROOT, 'docs', 'src', 'index.md.ejs');
|
||||
ejs.renderFile(indexPath, locals, function(error, output) {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
} else {
|
||||
const outputPath = path.join(ROOT, 'docs', 'index.md');
|
||||
fs.writeFileSync(outputPath, output);
|
||||
execSync('npm run doctoc', {cwd: ROOT});
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -36,7 +36,17 @@ integrationtest() {
|
||||
mocha test/integration/integration-test.js
|
||||
}
|
||||
|
||||
doctest() {
|
||||
mv docs/index.md docs/index.md.save
|
||||
npm run docgen
|
||||
mv docs/index.md docs/index.md.test
|
||||
mv docs/index.md.save docs/index.md
|
||||
cmp docs/index.md docs/index.md.test
|
||||
rm docs/index.md.test
|
||||
}
|
||||
|
||||
oneNode() {
|
||||
doctest
|
||||
lint
|
||||
typecheck
|
||||
unittest
|
||||
@@ -45,15 +55,15 @@ oneNode() {
|
||||
|
||||
twoNodes() {
|
||||
case "$NODE_INDEX" in
|
||||
0) lint && integrationtest;;
|
||||
1) typecheck && unittest;;
|
||||
0) doctest; lint; integrationtest;;
|
||||
1) typecheck; unittest;;
|
||||
*) echo "ERROR: invalid usage"; exit 2;;
|
||||
esac
|
||||
}
|
||||
|
||||
threeNodes() {
|
||||
case "$NODE_INDEX" in
|
||||
0) lint && integrationtest;;
|
||||
0) doctest; lint; integrationtest;;
|
||||
1) typecheck;;
|
||||
2) unittest;;
|
||||
*) echo "ERROR: invalid usage"; exit 2;;
|
||||
|
||||
144
src/api.js
Normal file
144
src/api.js
Normal file
@@ -0,0 +1,144 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
/* eslint-disable max-len */
|
||||
// Enable core-js polyfills. This allows use of ES6/7 extensions listed here:
|
||||
// https://github.com/zloirock/core-js/blob/fb0890f32dabe8d4d88a4350d1b268446127132e/shim.js#L1-L103
|
||||
/* eslint-enable max-len */
|
||||
|
||||
// In node.js env, polyfill might be already loaded (from any npm package),
|
||||
// that's why we do this check.
|
||||
if (!global._babelPolyfill) {
|
||||
require('babel-polyfill');
|
||||
}
|
||||
|
||||
const _ = require('lodash');
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const common = require('./common');
|
||||
const server = require('./server/server');
|
||||
const connect = server.connect;
|
||||
const disconnect = server.disconnect;
|
||||
const getServerInfo = server.getServerInfo;
|
||||
const getFee = server.getFee;
|
||||
const isConnected = server.isConnected;
|
||||
const getLedgerVersion = server.getLedgerVersion;
|
||||
const getTransaction = require('./ledger/transaction');
|
||||
const getTransactions = require('./ledger/transactions');
|
||||
const getTrustlines = require('./ledger/trustlines');
|
||||
const getBalances = require('./ledger/balances');
|
||||
const getBalanceSheet = require('./ledger/balance-sheet');
|
||||
const getPaths = require('./ledger/pathfind');
|
||||
const getOrders = require('./ledger/orders');
|
||||
const getOrderbook = require('./ledger/orderbook');
|
||||
const getSettings = require('./ledger/settings');
|
||||
const getAccountInfo = require('./ledger/accountinfo');
|
||||
const preparePayment = require('./transaction/payment');
|
||||
const prepareTrustline = require('./transaction/trustline');
|
||||
const prepareOrder = require('./transaction/order');
|
||||
const prepareOrderCancellation = require('./transaction/ordercancellation');
|
||||
const prepareSuspendedPaymentCreation =
|
||||
require('./transaction/suspended-payment-creation');
|
||||
const prepareSuspendedPaymentExecution =
|
||||
require('./transaction/suspended-payment-execution');
|
||||
const prepareSuspendedPaymentCancellation =
|
||||
require('./transaction/suspended-payment-cancellation');
|
||||
const prepareSettings = require('./transaction/settings');
|
||||
const sign = require('./transaction/sign');
|
||||
const submit = require('./transaction/submit');
|
||||
const errors = require('./common').errors;
|
||||
const generateAddress = common.generateAddressAPI;
|
||||
const computeLedgerHash = require('./offline/ledgerhash');
|
||||
const getLedger = require('./ledger/ledger');
|
||||
|
||||
type APIOptions = {
|
||||
server?: string,
|
||||
feeCushion?: number,
|
||||
trace?: boolean,
|
||||
proxy?: string,
|
||||
timeout?: number
|
||||
}
|
||||
|
||||
// prevent access to non-validated ledger versions
|
||||
class RestrictedConnection extends common.Connection {
|
||||
request(request, timeout) {
|
||||
const ledger_index = request.ledger_index;
|
||||
if (ledger_index !== undefined && ledger_index !== 'validated') {
|
||||
if (!_.isNumber(ledger_index) || ledger_index > this._ledgerVersion) {
|
||||
return Promise.reject(new errors.LedgerVersionError(
|
||||
`ledgerVersion ${ledger_index} is greater than server\'s ` +
|
||||
`most recent validated ledger: ${this._ledgerVersion}`));
|
||||
}
|
||||
}
|
||||
return super.request(request, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
class RippleAPI extends EventEmitter {
|
||||
constructor(options: APIOptions = {}) {
|
||||
common.validate.apiOptions(options);
|
||||
super();
|
||||
this._feeCushion = options.feeCushion || 1.2;
|
||||
const serverURL = options.server;
|
||||
if (serverURL !== undefined) {
|
||||
this.connection = new RestrictedConnection(serverURL, options);
|
||||
this.connection.on('ledgerClosed', message => {
|
||||
this.emit('ledger', server.formatLedgerClose(message));
|
||||
});
|
||||
this.connection.on('error', (type, info) => {
|
||||
this.emit('error', type, info);
|
||||
});
|
||||
} else {
|
||||
// use null object pattern to provide better error message if user
|
||||
// tries to call a method that requires a connection
|
||||
this.connection = new RestrictedConnection(null, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_.assign(RippleAPI.prototype, {
|
||||
connect,
|
||||
disconnect,
|
||||
isConnected,
|
||||
getServerInfo,
|
||||
getFee,
|
||||
getLedgerVersion,
|
||||
|
||||
getTransaction,
|
||||
getTransactions,
|
||||
getTrustlines,
|
||||
getBalances,
|
||||
getBalanceSheet,
|
||||
getPaths,
|
||||
getOrders,
|
||||
getOrderbook,
|
||||
getSettings,
|
||||
getAccountInfo,
|
||||
getLedger,
|
||||
|
||||
preparePayment,
|
||||
prepareTrustline,
|
||||
prepareOrder,
|
||||
prepareOrderCancellation,
|
||||
prepareSuspendedPaymentCreation,
|
||||
prepareSuspendedPaymentExecution,
|
||||
prepareSuspendedPaymentCancellation,
|
||||
prepareSettings,
|
||||
sign,
|
||||
submit,
|
||||
|
||||
generateAddress,
|
||||
computeLedgerHash,
|
||||
errors
|
||||
});
|
||||
|
||||
// these are exposed only for use by unit tests; they are not part of the API
|
||||
RippleAPI._PRIVATE = {
|
||||
validate: common.validate,
|
||||
RangeSet: require('./common/rangeset').RangeSet,
|
||||
ledgerUtils: require('./ledger/utils'),
|
||||
schemaValidator: require('./common/schema-validator')
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
RippleAPI
|
||||
};
|
||||
66
src/broadcast.js
Normal file
66
src/broadcast.js
Normal file
@@ -0,0 +1,66 @@
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const RippleAPI = require('./api').RippleAPI;
|
||||
|
||||
class RippleAPIBroadcast extends RippleAPI {
|
||||
constructor(servers, options) {
|
||||
super(options);
|
||||
this.ledgerVersion = 0;
|
||||
|
||||
const apis = servers.map(server => new RippleAPI(
|
||||
_.assign({}, options, {server})
|
||||
));
|
||||
|
||||
this.getMethodNames().forEach(name => {
|
||||
this[name] = function() { // eslint-disable-line no-loop-func
|
||||
return Promise.race(apis.map(api => api[name].apply(api, arguments)));
|
||||
};
|
||||
});
|
||||
|
||||
// connection methods must be overridden to apply to all api instances
|
||||
this.connect = function() {
|
||||
return Promise.all(apis.map(api => api.connect()));
|
||||
};
|
||||
this.disconnect = function() {
|
||||
return Promise.all(apis.map(api => api.disconnect()));
|
||||
};
|
||||
this.isConnected = function() {
|
||||
return _.every(apis.map(api => api.isConnected()));
|
||||
};
|
||||
|
||||
// synchronous methods are all passed directly to the first api instance
|
||||
const defaultAPI = apis[0];
|
||||
const syncMethods = ['sign', 'generateAddress', 'computeLedgerHash'];
|
||||
syncMethods.forEach(name => {
|
||||
this[name] = defaultAPI[name].bind(defaultAPI);
|
||||
});
|
||||
|
||||
apis.forEach(api => {
|
||||
api.on('ledger', this.onLedgerEvent.bind(this));
|
||||
api.on('error', (type, info) => this.emit('error', type, info));
|
||||
});
|
||||
}
|
||||
|
||||
onLedgerEvent(ledger) {
|
||||
if (ledger.ledgerVersion > this.ledgerVersion) {
|
||||
this.ledgerVersion = ledger.ledgerVersion;
|
||||
this.emit('ledger', ledger);
|
||||
}
|
||||
}
|
||||
|
||||
getMethodNames() {
|
||||
const methodNames = [];
|
||||
for (const name in RippleAPI.prototype) {
|
||||
if (RippleAPI.prototype.hasOwnProperty(name)) {
|
||||
if (typeof RippleAPI.prototype[name] === 'function') {
|
||||
methodNames.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return methodNames;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
RippleAPIBroadcast
|
||||
};
|
||||
@@ -15,9 +15,17 @@ function isStreamMessageType(type) {
|
||||
class Connection extends EventEmitter {
|
||||
constructor(url, options = {}) {
|
||||
super();
|
||||
this.setMaxListeners(Infinity);
|
||||
this._url = url;
|
||||
this._proxyURL = options.proxyURL;
|
||||
this._trace = options.trace;
|
||||
if (this._trace) {
|
||||
// for easier unit testing
|
||||
this._console = console;
|
||||
}
|
||||
this._proxyURL = options.proxy;
|
||||
this._proxyAuthorization = options.proxyAuthorization;
|
||||
this._authorization = options.authorization;
|
||||
this._trustedCertificates = options.trustedCertificates;
|
||||
this._timeout = options.timeout || (20 * 1000);
|
||||
this._isReady = false;
|
||||
this._ws = null;
|
||||
@@ -50,6 +58,9 @@ class Connection extends EventEmitter {
|
||||
|
||||
_onMessage(message) {
|
||||
let parameters;
|
||||
if (this._trace) {
|
||||
this._console.log(message);
|
||||
}
|
||||
try {
|
||||
parameters = this._parseMessage(message);
|
||||
} catch (error) {
|
||||
@@ -74,6 +85,7 @@ class Connection extends EventEmitter {
|
||||
}
|
||||
|
||||
_onUnexpectedClose() {
|
||||
this._ws = null;
|
||||
this._isReady = false;
|
||||
this.connect().then();
|
||||
}
|
||||
@@ -92,12 +104,20 @@ class Connection extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
_createWebSocket(url, proxyURL, authorization) {
|
||||
_createWebSocket(url, proxyURL, proxyAuthorization, authorization,
|
||||
trustedCertificates) {
|
||||
const options = {};
|
||||
if (proxyURL !== undefined) {
|
||||
const parsedURL = parseURL(url);
|
||||
const proxyOptions = parseURL(proxyURL);
|
||||
proxyOptions.secureEndpoint = (parsedURL.protocol === 'wss:');
|
||||
proxyOptions.secureProxy = (proxyOptions.protocol === 'https:');
|
||||
if (proxyAuthorization !== undefined) {
|
||||
proxyOptions.auth = proxyAuthorization;
|
||||
}
|
||||
if (trustedCertificates !== undefined) {
|
||||
proxyOptions.ca = trustedCertificates;
|
||||
}
|
||||
let HttpsProxyAgent;
|
||||
try {
|
||||
HttpsProxyAgent = require('https-proxy-agent');
|
||||
@@ -110,7 +130,11 @@ class Connection extends EventEmitter {
|
||||
const base64 = new Buffer(authorization).toString('base64');
|
||||
options.headers = {Authorization: `Basic ${base64}`};
|
||||
}
|
||||
return new WebSocket(url, options);
|
||||
const websocket = new WebSocket(url, options);
|
||||
// we will have a listener for each outstanding request,
|
||||
// so we have to raise the limit (the default is 10)
|
||||
websocket.setMaxListeners(Infinity);
|
||||
return websocket;
|
||||
}
|
||||
|
||||
connect() {
|
||||
@@ -125,9 +149,11 @@ class Connection extends EventEmitter {
|
||||
this._ws.once('open', resolve);
|
||||
} else {
|
||||
this._ws = this._createWebSocket(this._url, this._proxyURL,
|
||||
this._authorization);
|
||||
this._proxyAuthorization, this._authorization,
|
||||
this._trustedCertificates);
|
||||
this._ws.on('message', this._onMessage.bind(this));
|
||||
this._ws.once('close', () => this._onUnexpectedClose);
|
||||
this._onUnexpectedCloseBound = this._onUnexpectedClose.bind(this);
|
||||
this._ws.once('close', this._onUnexpectedCloseBound);
|
||||
this._ws.once('open', () => this._onOpen().then(resolve, reject));
|
||||
}
|
||||
});
|
||||
@@ -140,7 +166,7 @@ class Connection extends EventEmitter {
|
||||
} else if (this._state === WebSocket.CLOSING) {
|
||||
this._ws.once('close', resolve);
|
||||
} else {
|
||||
this._ws.removeListener('close', this._onUnexpectedClose);
|
||||
this._ws.removeListener('close', this._onUnexpectedCloseBound);
|
||||
this._ws.once('close', () => {
|
||||
this._ws = null;
|
||||
this._isReady = false;
|
||||
@@ -182,6 +208,9 @@ class Connection extends EventEmitter {
|
||||
}
|
||||
|
||||
_send(message) {
|
||||
if (this._trace) {
|
||||
this._console.log(message);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this._ws.send(message, undefined, (error, result) => {
|
||||
if (error) {
|
||||
|
||||
@@ -43,6 +43,7 @@ function loadSchemas() {
|
||||
require('./schemas/objects/signed-value.json'),
|
||||
require('./schemas/objects/orderbook.json'),
|
||||
require('./schemas/objects/instructions.json'),
|
||||
require('./schemas/objects/settings.json'),
|
||||
require('./schemas/specifications/settings.json'),
|
||||
require('./schemas/specifications/payment.json'),
|
||||
require('./schemas/specifications/suspended-payment-cancellation.json'),
|
||||
@@ -61,7 +62,7 @@ function loadSchemas() {
|
||||
require('./schemas/output/get-orders.json'),
|
||||
require('./schemas/output/order-change.json'),
|
||||
require('./schemas/output/prepare.json'),
|
||||
require('./schemas/output/ledger-closed.json'),
|
||||
require('./schemas/output/ledger-event.json'),
|
||||
require('./schemas/output/get-paths.json'),
|
||||
require('./schemas/output/get-server-info.json'),
|
||||
require('./schemas/output/get-settings.json'),
|
||||
|
||||
@@ -3,21 +3,45 @@
|
||||
"title": "api-options",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"trace": {"type": "boolean"},
|
||||
"feeCushion": {"$ref": "value"},
|
||||
"servers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"pattern": "^wss?://"
|
||||
}
|
||||
"trace": {
|
||||
"type": "boolean",
|
||||
"description": "If true, log rippled requests and responses to stdout."
|
||||
},
|
||||
"feeCushion": {
|
||||
"type": "number",
|
||||
"minimum": 1,
|
||||
"description": "Factor to multiply estimated fee by to provide a cushion in case the required fee rises during submission of a transaction. Defaults to `1.2`."
|
||||
},
|
||||
"server": {
|
||||
"type": "string",
|
||||
"description": "URI for rippled websocket port to connect to. Must start with `wss://` or `ws://`.",
|
||||
"format": "uri",
|
||||
"pattern": "^wss?://"
|
||||
},
|
||||
"proxy": {
|
||||
"format": "uri"
|
||||
"format": "uri",
|
||||
"description": "URI for HTTP/HTTPS proxy to use to connect to the rippled server."
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "Timeout in milliseconds before considering a request to have failed.",
|
||||
"minimum": 1
|
||||
},
|
||||
"proxyAuthorization": {
|
||||
"type": "string",
|
||||
"description": "Username and password for HTTP basic authentication to the proxy in the format **username:password**."
|
||||
},
|
||||
"authorization": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"description": "Username and password for HTTP basic authentication to the rippled server in the format **username:password**."
|
||||
},
|
||||
"trustedCertificates": {
|
||||
"type": "array",
|
||||
"description": "Array of PEM-formatted SSL certificates to trust when connecting to a proxy. This is useful if you want to use a self-signed certificate on the proxy server. Note: Each element must contain a single certificate; concatenated certificates are not valid.",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"description": "A PEM-formatted SSL certificate to trust when connecting to a proxy."
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
"$ref": "address",
|
||||
"description": "The address of the account that is creating the transaction."
|
||||
},
|
||||
"sequence": {
|
||||
"$ref": "sequence",
|
||||
"description": "The account sequence number of the transaction that created the order to cancel."
|
||||
"orderCancellation": {
|
||||
"$ref": "orderCancellation",
|
||||
"description": "The specification of the order cancellation to prepare."
|
||||
},
|
||||
"instructions": {"$ref": "instructions"}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["address", "sequence"]
|
||||
"required": ["address", "orderCancellation"]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "memos",
|
||||
"link": "transaction-memos",
|
||||
"description": "Array of memos to attach to the transaction.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
||||
74
src/common/schemas/objects/settings.json
Normal file
74
src/common/schemas/objects/settings.json
Normal file
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "settingsPlusMemos",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"passwordSpent": {
|
||||
"type": "boolean",
|
||||
"description": "Indicates that the account has used its free SetRegularKey transaction."
|
||||
},
|
||||
"requireDestinationTag": {
|
||||
"type": "boolean",
|
||||
"description": "Requires incoming payments to specify a destination tag."
|
||||
},
|
||||
"requireAuthorization": {
|
||||
"type": "boolean",
|
||||
"description": "If set, this account must individually approve other users in order for those users to hold this account’s issuances."
|
||||
},
|
||||
"disallowIncomingXRP": {
|
||||
"type": "boolean",
|
||||
"description": "Indicates that client applications should not send XRP to this account. Not enforced by rippled."
|
||||
},
|
||||
"disableMasterKey": {
|
||||
"type": "boolean",
|
||||
"description": "Disallows use of the master key to sign transactions for this account."
|
||||
},
|
||||
"enableTransactionIDTracking": {
|
||||
"type": "boolean",
|
||||
"description": "Track the ID of this account’s most recent transaction."
|
||||
},
|
||||
"noFreeze": {
|
||||
"type": "boolean",
|
||||
"description": "Permanently give up the ability to freeze individual trust lines. This flag can never be disabled after being enabled."
|
||||
},
|
||||
"globalFreeze": {
|
||||
"type": "boolean",
|
||||
"description": "Freeze all assets issued by this account."
|
||||
},
|
||||
"defaultRipple": {
|
||||
"type": "boolean",
|
||||
"description": "Enable [rippling](https://ripple.com/knowledge_center/understanding-the-noripple-flag/) on this account’s trust lines by default. (New in [rippled 0.27.3](https://github.com/ripple/rippled/releases/tag/0.27.3))"
|
||||
},
|
||||
"emailHash": {
|
||||
"description": "Hash of an email address to be used for generating an avatar image. Conventionally, clients use Gravatar to display this image. Use `null` to clear.",
|
||||
"oneOf": [
|
||||
{"type": "null"},
|
||||
{"$ref": "hash128"}
|
||||
]
|
||||
},
|
||||
"messageKey": {
|
||||
"type": "string",
|
||||
"description": "Public key for sending encrypted messages to this account. Conventionally, it should be a secp256k1 key, the same encryption that is used by the rest of Ripple."
|
||||
},
|
||||
"domain": {
|
||||
"type": "string",
|
||||
"description": " The domain that owns this account, as a hexadecimal string representing the ASCII for the domain in lowercase."
|
||||
},
|
||||
"transferRate": {
|
||||
"description": " The fee to charge when users transfer this account’s issuances, represented as billionths of a unit. Use `null` to set no fee.",
|
||||
"oneOf": [
|
||||
{"type": "null"},
|
||||
{"type": "number", "minimum": 1, "maximum": 4.294967295}
|
||||
]
|
||||
},
|
||||
"regularKey": {
|
||||
"oneOf": [
|
||||
{"$ref": "address"},
|
||||
{"type": "null"}
|
||||
],
|
||||
"description": "The public key of a new keypair, to use as the regular key to this account, as a base-58-encoded string in the same format as an account address. Use `null` to remove the regular key."
|
||||
},
|
||||
"memos": {"$ref": "memos"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "tag",
|
||||
"description": "An arbitrary unsigned 32-bit integer most commonly used to identify a non-Ripple account.",
|
||||
"description": "An arbitrary unsigned 32-bit integer that identifies a reason for payment or a non-Ripple account.",
|
||||
"type": "integer",
|
||||
"$ref": "uint32"
|
||||
}
|
||||
|
||||
@@ -93,12 +93,12 @@
|
||||
"reserveBaseXRP": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "Minimum amount of XRP (not drops) necessary for every account to keep in reserve."
|
||||
"description": "Minimum amount of XRP necessary for every account to keep in reserve."
|
||||
},
|
||||
"reserveIncrementXRP": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "Amount of XRP (not drops) added to the account reserve for each object an account is responsible for in the ledger."
|
||||
"description": "Amount of XRP added to the account reserve for each object an account is responsible for in the ledger."
|
||||
},
|
||||
"ledgerVersion": {
|
||||
"type": "integer",
|
||||
|
||||
@@ -1,73 +1,8 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getSettings",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"passwordSpent": {
|
||||
"type": "boolean",
|
||||
"description": "Indicates that the account has used its free SetRegularKey transaction."
|
||||
},
|
||||
"requireDestinationTag": {
|
||||
"type": "boolean",
|
||||
"description": "Requires incoming payments to specify a destination tag."
|
||||
},
|
||||
"requireAuthorization": {
|
||||
"type": "boolean",
|
||||
"description": "If set, this account must individually approve other users in order for those users to hold this account’s issuances."
|
||||
},
|
||||
"disallowIncomingXRP": {
|
||||
"type": "boolean",
|
||||
"description": "Indicates that client applications should not send XRP to this account. Not enforced by rippled."
|
||||
},
|
||||
"disableMasterKey": {
|
||||
"type": "boolean",
|
||||
"description": "Disallows use of the master key to sign transactions for this account."
|
||||
},
|
||||
"enableTransactionIDTracking": {
|
||||
"type": "boolean",
|
||||
"description": "Track the ID of this account’s most recent transaction."
|
||||
},
|
||||
"noFreeze": {
|
||||
"type": "boolean",
|
||||
"description": "Permanently give up the ability to freeze individual trust lines. This flag can never be disabled after being enabled."
|
||||
},
|
||||
"globalFreeze": {
|
||||
"type": "boolean",
|
||||
"description": "Freeze all assets issued by this account."
|
||||
},
|
||||
"defaultRipple": {
|
||||
"type": "boolean",
|
||||
"description": "Enable [rippling](https://ripple.com/knowledge_center/understanding-the-noripple-flag/) on this account’s trust lines by default. (New in [rippled 0.27.3](https://github.com/ripple/rippled/releases/tag/0.27.3))"
|
||||
},
|
||||
"emailHash": {
|
||||
"description": "Hash of an email address to be used for generating an avatar image. Conventionally, clients use Gravatar to display this image. Use `null` to clear.",
|
||||
"oneOf": [
|
||||
{"type": "null"},
|
||||
{"$ref": "hash128"}
|
||||
]
|
||||
},
|
||||
"messageKey": {
|
||||
"type": "string",
|
||||
"description": "Public key for sending encrypted messages to this account. Conventionally, it should be a secp256k1 key, the same encryption that is used by the rest of Ripple."
|
||||
},
|
||||
"domain": {
|
||||
"type": "string",
|
||||
"description": " The domain that owns this account, as a hexadecimal string representing the ASCII for the domain in lowercase."
|
||||
},
|
||||
"transferRate": {
|
||||
"description": " The fee to charge when users transfer this account’s issuances, represented as billionths of a unit. Use `null` to set no fee.",
|
||||
"oneOf": [
|
||||
{"type": "null"},
|
||||
{"type": "number", "minimum": 1, "maximum": 4.294967295}
|
||||
]
|
||||
},
|
||||
"regularKey": {
|
||||
"oneOf": [
|
||||
{"$ref": "address"},
|
||||
{"type": "null"}
|
||||
],
|
||||
"description": "The public key of a new keypair, to use as the regular key to this account, as a base-58-encoded string in the same format as an account address. Use `null` to remove the regular key."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
"$ref": "settingsPlusMemos",
|
||||
"not": {
|
||||
"required": ["memos"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"state": {
|
||||
"properties": {
|
||||
"balance": {
|
||||
"$ref": "value",
|
||||
"$ref": "signedValue",
|
||||
"description": "The balance on the trustline, representing which party owes the other and by how much."
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "ledgerClosed",
|
||||
"description": "A ledgerClosed event message",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"feeBase": {"type": "integer", "minimum": 0},
|
||||
"feeReference": {"type": "integer", "minimum": 0},
|
||||
"ledgerHash": {"$ref": "hash256"},
|
||||
"ledgerVersion": {"$ref": "ledgerVersion"},
|
||||
"ledgerTimestamp": {"type": "string", "format": "date-time"},
|
||||
"reserveBase": {"type": "integer", "minimum": 0},
|
||||
"reserveIncrement": {"type": "integer", "minimum": 0},
|
||||
"transactionCount": {"type": "integer", "minimum": 0},
|
||||
"validatedLedgerVersions": {"type": "string"}
|
||||
},
|
||||
"addtionalProperties": false,
|
||||
"required": ["feeBase", "feeReference", "ledgerHash", "ledgerTimestamp",
|
||||
"reserveBase", "reserveIncrement", "transactionCount",
|
||||
"ledgerVersion", "validatedLedgerVersions"]
|
||||
}
|
||||
46
src/common/schemas/output/ledger-event.json
Normal file
46
src/common/schemas/output/ledger-event.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "ledgerEvent",
|
||||
"description": "A ledger event message",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"baseFeeXRP": {
|
||||
"$ref": "value",
|
||||
"description": "Base fee, in XRP."
|
||||
},
|
||||
"ledgerHash": {
|
||||
"$ref": "hash256",
|
||||
"description": "Unique hash of the ledger that was closed, as hex."
|
||||
},
|
||||
"ledgerVersion": {
|
||||
"$ref": "ledgerVersion",
|
||||
"description": "Ledger version of the ledger that closed."
|
||||
},
|
||||
"ledgerTimestamp": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The time at which this ledger closed."
|
||||
},
|
||||
"reserveBaseXRP": {
|
||||
"$ref": "value",
|
||||
"description": "The minimum reserve, in drops of XRP, that is required for an account."
|
||||
},
|
||||
"reserveIncrementXRP": {
|
||||
"$ref": "value",
|
||||
"description": "The increase in account reserve that is added for each item the account owns, such as offers or trust lines."
|
||||
},
|
||||
"transactionCount": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "Number of new transactions included in this ledger."
|
||||
},
|
||||
"validatedLedgerVersions": {
|
||||
"type": "string",
|
||||
"description": "Range of ledgers that the server has available. This may be discontiguous."
|
||||
}
|
||||
},
|
||||
"addtionalProperties": false,
|
||||
"required": ["baseFeeXRP", "ledgerHash", "ledgerTimestamp",
|
||||
"reserveBaseXRP", "reserveIncrementXRP", "transactionCount",
|
||||
"ledgerVersion", "validatedLedgerVersions"]
|
||||
}
|
||||
@@ -7,7 +7,8 @@
|
||||
"orderSequence": {
|
||||
"$ref": "sequence",
|
||||
"description": "The [account sequence number](#account-sequence-number) of the order to cancel."
|
||||
}
|
||||
},
|
||||
"memos": {"$ref": "memos"}
|
||||
},
|
||||
"required": ["orderSequence"],
|
||||
"additionalProperties": false
|
||||
|
||||
@@ -33,7 +33,8 @@
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Time after which the offer is no longer active, as an [ISO 8601 date-time](https://en.wikipedia.org/wiki/ISO_8601)."
|
||||
}
|
||||
},
|
||||
"memos": {"$ref": "memos"}
|
||||
},
|
||||
"required": ["direction", "quantity", "totalPrice"],
|
||||
"additionalProperties": false,
|
||||
|
||||
@@ -2,11 +2,17 @@
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "settings",
|
||||
"link": "settings",
|
||||
"allOf": [
|
||||
"$ref": "settingsPlusMemos",
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "getSettings"
|
||||
"required": ["memos"],
|
||||
"minProperties": 2,
|
||||
"maxProperties": 2
|
||||
},
|
||||
{
|
||||
"not": {
|
||||
"required": ["memos"]
|
||||
},
|
||||
"minProperties": 1,
|
||||
"maxProperties": 1
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
},
|
||||
"digest": {
|
||||
"$ref": "hash256",
|
||||
"description": "The original `digest` from the suspended payment creation transaction. This is sha256 hash of `proof` string."
|
||||
"description": "The original `digest` from the suspended payment creation transaction. This is sha256 hash of `proof` string. It is replicated here so that the relatively expensive hashing operation can be delegated to a server without ledger history and the server with ledger history only has to do a quick comparison of the old digest with the new digest."
|
||||
},
|
||||
"proof": {
|
||||
"type": "string",
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
"frozen": {
|
||||
"type": "boolean",
|
||||
"description": "If true, the trustline is frozen, which means that funds can only be sent to the owner."
|
||||
}
|
||||
},
|
||||
"memos": {"$ref": "memos"}
|
||||
},
|
||||
"required": ["currency", "counterparty", "limit"],
|
||||
"additionalProperties": false
|
||||
|
||||
145
src/index.js
145
src/index.js
@@ -1,145 +1,6 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
/* eslint-disable max-len */
|
||||
// Enable core-js polyfills. This allows use of ES6/7 extensions listed here:
|
||||
// https://github.com/zloirock/core-js/blob/fb0890f32dabe8d4d88a4350d1b268446127132e/shim.js#L1-L103
|
||||
/* eslint-enable max-len */
|
||||
|
||||
// In node.js env, polyfill might be already loaded (from any npm package),
|
||||
// that's why we do this check.
|
||||
if (!global._babelPolyfill) {
|
||||
require('babel-core/polyfill');
|
||||
}
|
||||
|
||||
const _ = require('lodash');
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const common = require('./common');
|
||||
const server = require('./server/server');
|
||||
const connect = server.connect;
|
||||
const disconnect = server.disconnect;
|
||||
const getServerInfo = server.getServerInfo;
|
||||
const getFee = server.getFee;
|
||||
const isConnected = server.isConnected;
|
||||
const getLedgerVersion = server.getLedgerVersion;
|
||||
const getTransaction = require('./ledger/transaction');
|
||||
const getTransactions = require('./ledger/transactions');
|
||||
const getTrustlines = require('./ledger/trustlines');
|
||||
const getBalances = require('./ledger/balances');
|
||||
const getBalanceSheet = require('./ledger/balance-sheet');
|
||||
const getPaths = require('./ledger/pathfind');
|
||||
const getOrders = require('./ledger/orders');
|
||||
const getOrderbook = require('./ledger/orderbook');
|
||||
const getSettings = require('./ledger/settings');
|
||||
const getAccountInfo = require('./ledger/accountinfo');
|
||||
const preparePayment = require('./transaction/payment');
|
||||
const prepareTrustline = require('./transaction/trustline');
|
||||
const prepareOrder = require('./transaction/order');
|
||||
const prepareOrderCancellation = require('./transaction/ordercancellation');
|
||||
const prepareSuspendedPaymentCreation =
|
||||
require('./transaction/suspended-payment-creation');
|
||||
const prepareSuspendedPaymentExecution =
|
||||
require('./transaction/suspended-payment-execution');
|
||||
const prepareSuspendedPaymentCancellation =
|
||||
require('./transaction/suspended-payment-cancellation');
|
||||
const prepareSettings = require('./transaction/settings');
|
||||
const sign = require('./transaction/sign');
|
||||
const submit = require('./transaction/submit');
|
||||
const errors = require('./common').errors;
|
||||
const generateAddress = common.generateAddressAPI;
|
||||
const computeLedgerHash = require('./offline/ledgerhash');
|
||||
const getLedger = require('./ledger/ledger');
|
||||
|
||||
type APIOptions = {
|
||||
servers?: Array<string>,
|
||||
feeCushion?: number,
|
||||
trace?: boolean,
|
||||
proxy?: string
|
||||
}
|
||||
|
||||
// prevent access to non-validated ledger versions
|
||||
class RestrictedConnection extends common.Connection {
|
||||
request(request, timeout) {
|
||||
const ledger_index = request.ledger_index;
|
||||
if (ledger_index !== undefined && ledger_index !== 'validated') {
|
||||
if (!_.isNumber(ledger_index) || ledger_index > this._ledgerVersion) {
|
||||
return Promise.reject(new errors.LedgerVersionError(
|
||||
`ledgerVersion ${ledger_index} is greater than server\'s ` +
|
||||
`most recent validated ledger: ${this._ledgerVersion}`));
|
||||
}
|
||||
}
|
||||
return super.request(request, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
class RippleAPI extends EventEmitter {
|
||||
constructor(options: APIOptions = {}) {
|
||||
common.validate.apiOptions(options);
|
||||
super();
|
||||
this._feeCushion = options.feeCushion || 1.2;
|
||||
if (options.servers !== undefined) {
|
||||
const servers: Array<string> = options.servers;
|
||||
if (servers.length === 1) {
|
||||
this.connection = new RestrictedConnection(servers[0], options);
|
||||
this.connection.on('ledgerClosed', message => {
|
||||
this.emit('ledgerClosed', server.formatLedgerClose(message));
|
||||
});
|
||||
this.connection.on('error', (type, info) => {
|
||||
this.emit('error', type, info);
|
||||
});
|
||||
} else {
|
||||
throw new errors.RippleError('Multi-server not implemented');
|
||||
}
|
||||
} else {
|
||||
// use null object pattern to provide better error message if user
|
||||
// tries to call a method that requires a connection
|
||||
this.connection = new RestrictedConnection(null, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_.assign(RippleAPI.prototype, {
|
||||
connect,
|
||||
disconnect,
|
||||
isConnected,
|
||||
getServerInfo,
|
||||
getFee,
|
||||
getLedgerVersion,
|
||||
|
||||
getTransaction,
|
||||
getTransactions,
|
||||
getTrustlines,
|
||||
getBalances,
|
||||
getBalanceSheet,
|
||||
getPaths,
|
||||
getOrders,
|
||||
getOrderbook,
|
||||
getSettings,
|
||||
getAccountInfo,
|
||||
getLedger,
|
||||
|
||||
preparePayment,
|
||||
prepareTrustline,
|
||||
prepareOrder,
|
||||
prepareOrderCancellation,
|
||||
prepareSuspendedPaymentCreation,
|
||||
prepareSuspendedPaymentExecution,
|
||||
prepareSuspendedPaymentCancellation,
|
||||
prepareSettings,
|
||||
sign,
|
||||
submit,
|
||||
|
||||
generateAddress,
|
||||
computeLedgerHash,
|
||||
errors
|
||||
});
|
||||
|
||||
// these are exposed only for use by unit tests; they are not part of the API
|
||||
RippleAPI._PRIVATE = {
|
||||
validate: common.validate,
|
||||
RangeSet: require('./common/rangeset').RangeSet,
|
||||
ledgerUtils: require('./ledger/utils'),
|
||||
schemaValidator: require('./common/schema-validator')
|
||||
module.exports = {
|
||||
RippleAPI: require('./api').RippleAPI,
|
||||
RippleAPIBroadcast: require('./broadcast').RippleAPIBroadcast
|
||||
};
|
||||
|
||||
module.exports.RippleAPI = RippleAPI;
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
import type {Amount, LaxLaxAmount, RippledAmount, Adjustment, MaxAdjustment,
|
||||
MinAdjustment} from '../common/types.js';
|
||||
|
||||
|
||||
type Path = {
|
||||
source: Adjustment | MaxAdjustment,
|
||||
destination: Adjustment | MinAdjustment,
|
||||
paths: string
|
||||
}
|
||||
|
||||
export type GetPaths = Array<Path>
|
||||
|
||||
export type PathFind = {
|
||||
source: {
|
||||
address: string,
|
||||
amount?: Amount,
|
||||
currencies?: Array<{currency: string, counterparty?:string}>
|
||||
},
|
||||
destination: {
|
||||
address: string,
|
||||
amount: LaxLaxAmount
|
||||
}
|
||||
}
|
||||
|
||||
export type PathFindRequest = {
|
||||
command: string,
|
||||
source_account: string,
|
||||
destination_amount: RippledAmount,
|
||||
destination_account: string,
|
||||
source_amount?: RippledAmount,
|
||||
source_currencies?: Array<string>
|
||||
}
|
||||
|
||||
export type RippledPathsResponse = {
|
||||
alternatives: Array<{
|
||||
paths_computed: Array<Array<{
|
||||
type: number,
|
||||
type_hex: string,
|
||||
account?: string,
|
||||
issuer?: string,
|
||||
currency?: string
|
||||
}>>,
|
||||
source_amount: RippledAmount
|
||||
}>,
|
||||
type: string,
|
||||
destination_account: string,
|
||||
destination_amount: RippledAmount,
|
||||
destination_currencies?: Array<string>,
|
||||
source_account?: string,
|
||||
source_currencies?: Array<{currency: string}>,
|
||||
full_reply?: boolean
|
||||
}
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
import type {Amount, LaxLaxAmount, RippledAmount, Adjustment, MaxAdjustment,
|
||||
MinAdjustment} from '../common/types.js';
|
||||
|
||||
|
||||
type Path = {
|
||||
source: Adjustment | MaxAdjustment,
|
||||
destination: Adjustment | MinAdjustment,
|
||||
paths: string
|
||||
}
|
||||
|
||||
export type GetPaths = Array<Path>
|
||||
|
||||
export type PathFind = {
|
||||
source: {
|
||||
address: string,
|
||||
amount?: Amount,
|
||||
currencies?: Array<{currency: string, counterparty?:string}>
|
||||
},
|
||||
destination: {
|
||||
address: string,
|
||||
amount: LaxLaxAmount
|
||||
}
|
||||
}
|
||||
|
||||
export type PathFindRequest = {
|
||||
command: string,
|
||||
source_account: string,
|
||||
destination_amount: RippledAmount,
|
||||
destination_account: string,
|
||||
source_currencies?: Array<string>,
|
||||
send_max?: RippledAmount
|
||||
}
|
||||
|
||||
export type RippledPathsResponse = {
|
||||
alternatives: Array<{
|
||||
paths_computed: Array<Array<{
|
||||
type: number,
|
||||
type_hex: string,
|
||||
account?: string,
|
||||
issuer?: string,
|
||||
currency?: string
|
||||
}>>,
|
||||
source_amount: RippledAmount
|
||||
}>,
|
||||
type: string,
|
||||
destination_account: string,
|
||||
destination_amount: RippledAmount,
|
||||
destination_currencies?: Array<string>,
|
||||
source_account?: string,
|
||||
source_currencies?: Array<{currency: string}>,
|
||||
full_reply?: boolean
|
||||
}
|
||||
|
||||
@@ -46,9 +46,9 @@ function requestPathFind(connection: Connection, pathfind: PathFind): Promise {
|
||||
throw new ValidationError('Cannot specify both source.amount'
|
||||
+ ' and destination.amount.value in getPaths');
|
||||
}
|
||||
request.source_amount = toRippledAmount(pathfind.source.amount);
|
||||
if (request.source_amount.currency && !request.source_amount.issuer) {
|
||||
request.source_amount.issuer = pathfind.source.address;
|
||||
request.send_max = toRippledAmount(pathfind.source.amount);
|
||||
if (request.send_max.currency && !request.send_max.issuer) {
|
||||
request.send_max.issuer = pathfind.source.address;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,9 +47,6 @@ function parseAccountTxTransaction(tx) {
|
||||
}
|
||||
|
||||
function counterpartyFilter(filters, tx: TransactionType) {
|
||||
if (!filters.counterparty) {
|
||||
return true;
|
||||
}
|
||||
if (tx.address === filters.counterparty || (
|
||||
tx.specification && (
|
||||
(tx.specification.destination &&
|
||||
|
||||
@@ -30,13 +30,12 @@ function getFee(): Promise<number> {
|
||||
|
||||
function formatLedgerClose(ledgerClose: Object): Object {
|
||||
return {
|
||||
feeBase: ledgerClose.fee_base,
|
||||
feeReference: ledgerClose.fee_ref,
|
||||
baseFeeXRP: common.dropsToXrp(ledgerClose.fee_base),
|
||||
ledgerHash: ledgerClose.ledger_hash,
|
||||
ledgerVersion: ledgerClose.ledger_index,
|
||||
ledgerTimestamp: common.rippleTimeToISO8601(ledgerClose.ledger_time),
|
||||
reserveBase: ledgerClose.reserve_base,
|
||||
reserveIncrement: ledgerClose.reserve_inc,
|
||||
reserveBaseXRP: common.dropsToXrp(ledgerClose.reserve_base),
|
||||
reserveIncrementXRP: common.dropsToXrp(ledgerClose.reserve_inc),
|
||||
transactionCount: ledgerClose.txn_count,
|
||||
validatedLedgerVersions: ledgerClose.validated_ledgers
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const offerFlags = utils.common.txFlags.OfferCreate;
|
||||
const {validate, iso8601ToRippleTime} = utils.common;
|
||||
@@ -34,6 +35,9 @@ function createOrderTransaction(account: string, order: Order): Object {
|
||||
if (order.expirationTime !== undefined) {
|
||||
txJSON.Expiration = iso8601ToRippleTime(order.expirationTime);
|
||||
}
|
||||
if (order.memos !== undefined) {
|
||||
txJSON.Memos = _.map(order.memos, utils.convertMemo);
|
||||
}
|
||||
return txJSON;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
import type {Instructions, Prepare} from './types.js';
|
||||
|
||||
function createOrderCancellationTransaction(account: string,
|
||||
sequence: number
|
||||
orderCancellation: Object
|
||||
): Object {
|
||||
return {
|
||||
const txJSON: Object = {
|
||||
TransactionType: 'OfferCancel',
|
||||
Account: account,
|
||||
OfferSequence: sequence
|
||||
OfferSequence: orderCancellation.orderSequence
|
||||
};
|
||||
if (orderCancellation.memos !== undefined) {
|
||||
txJSON.Memos = _.map(orderCancellation.memos, utils.convertMemo);
|
||||
}
|
||||
return txJSON;
|
||||
}
|
||||
|
||||
function prepareOrderCancellation(address: string, sequence: number,
|
||||
function prepareOrderCancellation(address: string, orderCancellation: Object,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareOrderCancellation({address, sequence, instructions});
|
||||
const txJSON = createOrderCancellationTransaction(address, sequence);
|
||||
validate.prepareOrderCancellation({address, orderCancellation, instructions});
|
||||
const txJSON = createOrderCancellationTransaction(address, orderCancellation);
|
||||
return utils.prepareTransaction(txJSON, this, instructions);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,10 @@ type Payment = {
|
||||
}
|
||||
|
||||
function isXRPToXRPPayment(payment: Payment): boolean {
|
||||
const sourceCurrency = _.get(payment, 'source.maxAmount.currency');
|
||||
const destinationCurrency = _.get(payment, 'destination.amount.currency');
|
||||
const sourceCurrency = _.get(payment, 'source.maxAmount.currency',
|
||||
_.get(payment, 'source.amount.currency'));
|
||||
const destinationCurrency = _.get(payment, 'destination.amount.currency',
|
||||
_.get(payment, 'destination.minAmount.currency'));
|
||||
return sourceCurrency === 'XRP' && destinationCurrency === 'XRP';
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,12 @@ function createSettingsTransaction(account: string, settings: Settings
|
||||
TransactionType: 'AccountSet',
|
||||
Account: account
|
||||
};
|
||||
setTransactionFlags(txJSON, settings);
|
||||
|
||||
if (settings.memos !== undefined) {
|
||||
txJSON.Memos = _.map(settings.memos, utils.convertMemo);
|
||||
}
|
||||
|
||||
setTransactionFlags(txJSON, _.omit(settings, 'memos'));
|
||||
setTransactionFields(txJSON, settings);
|
||||
|
||||
if (txJSON.TransferRate !== undefined) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
const trustlineFlags = utils.common.txFlags.TrustSet;
|
||||
@@ -8,8 +9,7 @@ import type {Instructions, Prepare} from './types.js';
|
||||
import type {TrustLineSpecification} from '../ledger/trustlines-types.js';
|
||||
|
||||
function convertQuality(quality) {
|
||||
return quality === undefined ? undefined :
|
||||
(new BigNumber(quality)).shift(9).truncated().toNumber();
|
||||
return (new BigNumber(quality)).shift(9).truncated().toNumber();
|
||||
}
|
||||
|
||||
function createTrustlineTransaction(account: string,
|
||||
@@ -44,6 +44,9 @@ function createTrustlineTransaction(account: string,
|
||||
txJSON.Flags |= trustline.frozen ?
|
||||
trustlineFlags.SetFreeze : trustlineFlags.ClearFreeze;
|
||||
}
|
||||
if (trustline.memos !== undefined) {
|
||||
txJSON.Memos = _.map(trustline.memos, utils.convertMemo);
|
||||
}
|
||||
return txJSON;
|
||||
}
|
||||
|
||||
|
||||
517
test/api-test.js
517
test/api-test.js
@@ -15,6 +15,9 @@ const utils = RippleAPI._PRIVATE.ledgerUtils;
|
||||
const ledgerClosed = require('./fixtures/rippled/ledger-close-newer');
|
||||
const schemaValidator = RippleAPI._PRIVATE.schemaValidator;
|
||||
|
||||
function unused() {
|
||||
}
|
||||
|
||||
function closeLedger(connection) {
|
||||
connection._ws.emit('message', JSON.stringify(ledgerClosed));
|
||||
}
|
||||
@@ -31,49 +34,95 @@ function checkResult(expected, schemaName, response) {
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
describe('RippleAPI', function() {
|
||||
const instructions = {maxLedgerVersionOffset: 100};
|
||||
beforeEach(setupAPI.setup);
|
||||
afterEach(setupAPI.teardown);
|
||||
|
||||
it('preparePayment', function() {
|
||||
const localInstructions = _.defaults({
|
||||
maxFee: '0.000012'
|
||||
}, instructions);
|
||||
return this.api.preparePayment(
|
||||
address, requests.preparePayment, localInstructions).then(
|
||||
_.partial(checkResult, responses.preparePayment.normal, 'prepare'));
|
||||
it('error inspect', function() {
|
||||
const error = new this.api.errors.RippleError('mess', {data: 1});
|
||||
assert.strictEqual(error.inspect(), '[RippleError(mess, { data: 1 })]');
|
||||
});
|
||||
|
||||
it('preparePayment with all options specified', function() {
|
||||
return this.api.getLedgerVersion().then((ver) => {
|
||||
const localInstructions = {
|
||||
maxLedgerVersion: ver + 100,
|
||||
fee: '0.000012'
|
||||
};
|
||||
describe('preparePayment', function() {
|
||||
|
||||
it('normal', function() {
|
||||
const localInstructions = _.defaults({
|
||||
maxFee: '0.000012'
|
||||
}, instructions);
|
||||
return this.api.preparePayment(
|
||||
address, requests.preparePaymentAllOptions, localInstructions).then(
|
||||
_.partial(checkResult, responses.preparePayment.allOptions, 'prepare'));
|
||||
address, requests.preparePayment.normal, localInstructions).then(
|
||||
_.partial(checkResult, responses.preparePayment.normal, 'prepare'));
|
||||
});
|
||||
});
|
||||
|
||||
it('preparePayment without counterparty set', function() {
|
||||
const localInstructions = _.defaults({sequence: 23}, instructions);
|
||||
return this.api.preparePayment(
|
||||
address, requests.preparePaymentNoCounterparty, localInstructions).then(
|
||||
_.partial(checkResult, responses.preparePayment.noCounterparty,
|
||||
'prepare'));
|
||||
});
|
||||
it('preparePayment - min amount xrp', function() {
|
||||
const localInstructions = _.defaults({
|
||||
maxFee: '0.000012'
|
||||
}, instructions);
|
||||
return this.api.preparePayment(
|
||||
address, requests.preparePayment.minAmountXRP, localInstructions).then(
|
||||
_.partial(checkResult,
|
||||
responses.preparePayment.minAmountXRP, 'prepare'));
|
||||
});
|
||||
|
||||
it('preparePayment - destination.minAmount', function() {
|
||||
return this.api.preparePayment(address, responses.getPaths.sendAll[0],
|
||||
instructions).then(_.partial(checkResult,
|
||||
responses.preparePayment.minAmount, 'prepare'));
|
||||
it('preparePayment - min amount xrp2xrp', function() {
|
||||
return this.api.preparePayment(
|
||||
address, requests.preparePayment.minAmount, instructions).then(
|
||||
_.partial(checkResult,
|
||||
responses.preparePayment.minAmountXRPXRP, 'prepare'));
|
||||
});
|
||||
|
||||
it('preparePayment - XRP to XRP no partial', function() {
|
||||
assert.throws(() => {
|
||||
this.api.preparePayment(address, requests.preparePayment.wrongPartial);
|
||||
}, /XRP to XRP payments cannot be partial payments/);
|
||||
});
|
||||
|
||||
it('preparePayment - address must match payment.source.address', function(
|
||||
) {
|
||||
assert.throws(() => {
|
||||
this.api.preparePayment(address, requests.preparePayment.wrongAddress);
|
||||
}, /address must match payment.source.address/);
|
||||
});
|
||||
|
||||
it('preparePayment - wrong amount', function() {
|
||||
assert.throws(() => {
|
||||
this.api.preparePayment(address, requests.preparePayment.wrongAmount);
|
||||
}, this.api.errors.ValidationError);
|
||||
});
|
||||
|
||||
it('preparePayment with all options specified', function() {
|
||||
return this.api.getLedgerVersion().then((ver) => {
|
||||
const localInstructions = {
|
||||
maxLedgerVersion: ver + 100,
|
||||
fee: '0.000012'
|
||||
};
|
||||
return this.api.preparePayment(
|
||||
address, requests.preparePayment.allOptions, localInstructions).then(
|
||||
_.partial(checkResult,
|
||||
responses.preparePayment.allOptions, 'prepare'));
|
||||
});
|
||||
});
|
||||
|
||||
it('preparePayment without counterparty set', function() {
|
||||
const localInstructions = _.defaults({sequence: 23}, instructions);
|
||||
return this.api.preparePayment(
|
||||
address, requests.preparePayment.noCounterparty, localInstructions)
|
||||
.then(_.partial(checkResult, responses.preparePayment.noCounterparty,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('preparePayment - destination.minAmount', function() {
|
||||
return this.api.preparePayment(address, responses.getPaths.sendAll[0],
|
||||
instructions).then(_.partial(checkResult,
|
||||
responses.preparePayment.minAmount, 'prepare'));
|
||||
});
|
||||
});
|
||||
|
||||
it('prepareOrder - buy order', function() {
|
||||
const request = requests.prepareOrder.buy;
|
||||
return this.api.prepareOrder(address, request, instructions)
|
||||
return this.api.prepareOrder(address, request)
|
||||
.then(_.partial(checkResult, responses.prepareOrder.buy, 'prepare'));
|
||||
});
|
||||
|
||||
@@ -91,9 +140,25 @@ describe('RippleAPI', function() {
|
||||
});
|
||||
|
||||
it('prepareOrderCancellation', function() {
|
||||
const request = requests.prepareOrderCancellation;
|
||||
const request = requests.prepareOrderCancellation.simple;
|
||||
return this.api.prepareOrderCancellation(address, request, instructions)
|
||||
.then(_.partial(checkResult, responses.prepareOrderCancellation,
|
||||
.then(_.partial(checkResult, responses.prepareOrderCancellation.normal,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareOrderCancellation - no instructions', function() {
|
||||
const request = requests.prepareOrderCancellation.simple;
|
||||
return this.api.prepareOrderCancellation(address, request)
|
||||
.then(_.partial(checkResult,
|
||||
responses.prepareOrderCancellation.noInstructions,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareOrderCancellation - with memos', function() {
|
||||
const request = requests.prepareOrderCancellation.withMemos;
|
||||
return this.api.prepareOrderCancellation(address, request)
|
||||
.then(_.partial(checkResult,
|
||||
responses.prepareOrderCancellation.withMemos,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
@@ -103,6 +168,12 @@ describe('RippleAPI', function() {
|
||||
_.partial(checkResult, responses.prepareTrustline.simple, 'prepare'));
|
||||
});
|
||||
|
||||
it('prepareTrustline - frozen', function() {
|
||||
return this.api.prepareTrustline(
|
||||
address, requests.prepareTrustline.frozen).then(
|
||||
_.partial(checkResult, responses.prepareTrustline.frozen, 'prepare'));
|
||||
});
|
||||
|
||||
it('prepareTrustline - complex', function() {
|
||||
return this.api.prepareTrustline(
|
||||
address, requests.prepareTrustline.complex, instructions).then(
|
||||
@@ -115,6 +186,15 @@ describe('RippleAPI', function() {
|
||||
_.partial(checkResult, responses.prepareSettings.flags, 'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSettings - no instructions', function() {
|
||||
return this.api.prepareSettings(
|
||||
address, requests.prepareSettings).then(
|
||||
_.partial(
|
||||
checkResult,
|
||||
responses.prepareSettings.noInstructions,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSettings - regularKey', function() {
|
||||
const regularKey = {regularKey: 'rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD'};
|
||||
return this.api.prepareSettings(address, regularKey, instructions).then(
|
||||
@@ -161,42 +241,71 @@ describe('RippleAPI', function() {
|
||||
maxFee: '0.000012'
|
||||
}, instructions);
|
||||
return this.api.prepareSuspendedPaymentCreation(
|
||||
address, requests.prepareSuspendedPaymentCreation,
|
||||
address, requests.prepareSuspendedPaymentCreation.normal,
|
||||
localInstructions).then(
|
||||
_.partial(checkResult, responses.prepareSuspendedPaymentCreation,
|
||||
_.partial(checkResult, responses.prepareSuspendedPaymentCreation.normal,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSuspendedPaymentCreation full', function() {
|
||||
return this.api.prepareSuspendedPaymentCreation(
|
||||
address, requests.prepareSuspendedPaymentCreation.full).then(
|
||||
_.partial(checkResult, responses.prepareSuspendedPaymentCreation.full,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSuspendedPaymentExecution', function() {
|
||||
return this.api.prepareSuspendedPaymentExecution(
|
||||
address, requests.prepareSuspendedPaymentExecution, instructions).then(
|
||||
_.partial(checkResult, responses.prepareSuspendedPaymentExecution,
|
||||
'prepare'));
|
||||
address,
|
||||
requests.prepareSuspendedPaymentExecution.normal, instructions).then(
|
||||
_.partial(checkResult,
|
||||
responses.prepareSuspendedPaymentExecution.normal,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSuspendedPaymentExecution - simple', function() {
|
||||
return this.api.prepareSuspendedPaymentExecution(
|
||||
address,
|
||||
requests.prepareSuspendedPaymentExecution.simple).then(
|
||||
_.partial(checkResult,
|
||||
responses.prepareSuspendedPaymentExecution.simple,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSuspendedPaymentCancellation', function() {
|
||||
return this.api.prepareSuspendedPaymentCancellation(
|
||||
address, requests.prepareSuspendedPaymentCancellation, instructions).then(
|
||||
_.partial(checkResult, responses.prepareSuspendedPaymentCancellation,
|
||||
'prepare'));
|
||||
address,
|
||||
requests.prepareSuspendedPaymentCancellation.normal, instructions).then(
|
||||
_.partial(checkResult,
|
||||
responses.prepareSuspendedPaymentCancellation.normal,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSuspendedPaymentCancellation with memos', function() {
|
||||
return this.api.prepareSuspendedPaymentCancellation(
|
||||
address,
|
||||
requests.prepareSuspendedPaymentCancellation.memos).then(
|
||||
_.partial(checkResult,
|
||||
responses.prepareSuspendedPaymentCancellation.memos,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('sign', function() {
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV';
|
||||
const result = this.api.sign(requests.sign.txJSON, secret);
|
||||
assert.deepEqual(result, responses.sign);
|
||||
const result = this.api.sign(requests.sign.normal.txJSON, secret);
|
||||
assert.deepEqual(result, responses.sign.normal);
|
||||
schemaValidator.schemaValidate('sign', result);
|
||||
});
|
||||
|
||||
it('sign - SuspendedPaymentExecution', function() {
|
||||
const secret = 'snoPBrXtMeMyMHUVTgbuqAfg1SUTb';
|
||||
const result = this.api.sign(requests.signSuspended.txJSON, secret);
|
||||
assert.deepEqual(result, responses.signSuspended);
|
||||
const result = this.api.sign(requests.sign.suspended.txJSON, secret);
|
||||
assert.deepEqual(result, responses.sign.suspended);
|
||||
schemaValidator.schemaValidate('sign', result);
|
||||
});
|
||||
|
||||
it('submit', function() {
|
||||
return this.api.submit(responses.sign.signedTransaction).then(
|
||||
return this.api.submit(responses.sign.normal.signedTransaction).then(
|
||||
_.partial(checkResult, responses.submit, 'submit'));
|
||||
});
|
||||
|
||||
@@ -218,7 +327,8 @@ describe('RippleAPI', function() {
|
||||
|
||||
it('getBalances - limit', function() {
|
||||
const options = {
|
||||
limit: 3
|
||||
limit: 3,
|
||||
ledgerVersion: 123456
|
||||
};
|
||||
const expectedResponse = responses.getBalances.slice(0, 3);
|
||||
return this.api.getBalances(address, options).then(
|
||||
@@ -255,6 +365,18 @@ describe('RippleAPI', function() {
|
||||
_.partial(checkResult, responses.getBalanceSheet, 'getBalanceSheet'));
|
||||
});
|
||||
|
||||
it('getBalanceSheet - invalid options', function() {
|
||||
assert.throws(() => {
|
||||
this.api.getBalanceSheet(address, {invalid: 'options'});
|
||||
}, this.api.errors.ValidationError);
|
||||
});
|
||||
|
||||
it('getBalanceSheet - empty', function() {
|
||||
const options = {ledgerVersion: 123456};
|
||||
return this.api.getBalanceSheet(address, options).then(
|
||||
_.partial(checkResult, {}, 'getBalanceSheet'));
|
||||
});
|
||||
|
||||
describe('getTransaction', () => {
|
||||
it('getTransaction - payment', function() {
|
||||
return this.api.getTransaction(hashes.VALID_TRANSACTION_HASH).then(
|
||||
@@ -279,6 +401,15 @@ describe('RippleAPI', function() {
|
||||
'getTransaction'));
|
||||
});
|
||||
|
||||
it('getTransaction - sell order', function() {
|
||||
const hash =
|
||||
'458101D51051230B1D56E9ACAFAA34451BF65FA000F95DF6F0FF5B3A62D83FC2';
|
||||
closeLedger(this.api.connection);
|
||||
return this.api.getTransaction(hash).then(
|
||||
_.partial(checkResult, responses.getTransaction.orderSell,
|
||||
'getTransaction'));
|
||||
});
|
||||
|
||||
it('getTransaction - order cancellation', function() {
|
||||
const hash =
|
||||
'809335DD3B0B333865096217AA2F55A4DF168E0198080B3A090D12D88880FF0E';
|
||||
@@ -456,6 +587,15 @@ describe('RippleAPI', function() {
|
||||
'getTransaction'));
|
||||
});
|
||||
|
||||
it('getTransaction - SuspendedPaymentCreation iou', function() {
|
||||
const hash =
|
||||
'144F272380BDB4F1BD92329A2178BABB70C20F59042C495E10BF72EBFB408EE2';
|
||||
return this.api.getTransaction(hash).then(
|
||||
_.partial(checkResult,
|
||||
responses.getTransaction.SuspendedPaymentCreationIOU,
|
||||
'getTransaction'));
|
||||
});
|
||||
|
||||
it('getTransaction - SuspendedPaymentCancellation', function() {
|
||||
const hash =
|
||||
'F346E542FFB7A8398C30A87B952668DAB48B7D421094F8B71776DA19775A3B22';
|
||||
@@ -466,20 +606,52 @@ describe('RippleAPI', function() {
|
||||
});
|
||||
|
||||
it('getTransaction - SuspendedPaymentExecution', function() {
|
||||
const options = {
|
||||
minLedgerVersion: 10,
|
||||
maxLedgerVersion: 15
|
||||
};
|
||||
const hash =
|
||||
'CC5277137B3F25EE8B86259C83CB0EAADE818505E4E9BCBF19B1AC6FD136993B';
|
||||
return this.api.getTransaction(hash).then(
|
||||
return this.api.getTransaction(hash, options).then(
|
||||
_.partial(checkResult,
|
||||
responses.getTransaction.suspendedPaymentExecution,
|
||||
'getTransaction'));
|
||||
});
|
||||
|
||||
it('getTransaction - SuspendedPaymentExecution simple', function() {
|
||||
const hash =
|
||||
'CC5277137B3F25EE8B86259C83CB0EAADE818505E4E9BCBF19B1AC6FD1369931';
|
||||
return this.api.getTransaction(hash).then(
|
||||
_.partial(checkResult,
|
||||
responses.getTransaction.suspendedPaymentExecutionSimple,
|
||||
'getTransaction'));
|
||||
});
|
||||
|
||||
it('getTransaction - no Meta', function() {
|
||||
const hash =
|
||||
'AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA1B';
|
||||
return this.api.getTransaction(hash).then(result => {
|
||||
assert.deepEqual(result, responses.getTransaction.noMeta);
|
||||
});
|
||||
});
|
||||
|
||||
it('getTransaction - Unrecognized transaction type', function() {
|
||||
const hash =
|
||||
'AFB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA11';
|
||||
closeLedger(this.api.connection);
|
||||
return this.api.getTransaction(hash).then(() => {
|
||||
assert(false, 'Unrecognized transaction type');
|
||||
}).catch(error => {
|
||||
assert.strictEqual(error.message, 'Unrecognized transaction type');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('getTransactions', function() {
|
||||
const options = {types: ['payment', 'order'], initiated: true, limit: 2};
|
||||
return this.api.getTransactions(address, options).then(
|
||||
_.partial(checkResult, responses.getTransactions,
|
||||
_.partial(checkResult, responses.getTransactions.normal,
|
||||
'getTransactions'));
|
||||
});
|
||||
|
||||
@@ -487,12 +659,13 @@ describe('RippleAPI', function() {
|
||||
const options = {types: ['payment', 'order'], initiated: true, limit: 2,
|
||||
earliestFirst: true
|
||||
};
|
||||
const expected = _.cloneDeep(responses.getTransactions)
|
||||
const expected = _.cloneDeep(responses.getTransactions.normal)
|
||||
.sort(utils.compareTransactions);
|
||||
return this.api.getTransactions(address, options).then(
|
||||
_.partial(checkResult, expected, 'getTransactions'));
|
||||
});
|
||||
|
||||
|
||||
it('getTransactions - earliest first with start option', function() {
|
||||
const options = {types: ['payment', 'order'], initiated: true, limit: 2,
|
||||
start: hashes.VALID_TRANSACTION_HASH,
|
||||
@@ -569,13 +742,35 @@ describe('RippleAPI', function() {
|
||||
limit: 2
|
||||
};
|
||||
return this.api.getTransactions(address, options).then(
|
||||
_.partial(checkResult, responses.getTransactions, 'getTransactions'));
|
||||
_.partial(checkResult, responses.getTransactions.normal,
|
||||
'getTransactions'));
|
||||
});
|
||||
|
||||
it('getTrustlines', function() {
|
||||
it('getTransactions - start transaction with zero ledger version', function(
|
||||
) {
|
||||
const options = {
|
||||
start: '4FB3ADF22F3C605E23FAEFAA185F3BD763C4692CAC490D9819D117CD33BFAA13',
|
||||
limit: 1
|
||||
};
|
||||
return this.api.getTransactions(address, options).then(
|
||||
_.partial(checkResult, [], 'getTransactions'));
|
||||
});
|
||||
|
||||
it('getTransactions - no options', function() {
|
||||
return this.api.getTransactions(addresses.OTHER_ACCOUNT).then(
|
||||
_.partial(checkResult, responses.getTransactions.one, 'getTransactions'));
|
||||
});
|
||||
|
||||
it('getTrustlines - filtered', function() {
|
||||
const options = {currency: 'USD'};
|
||||
return this.api.getTrustlines(address, options).then(
|
||||
_.partial(checkResult, responses.getTrustlines, 'getTrustlines'));
|
||||
_.partial(checkResult,
|
||||
responses.getTrustlines.filtered, 'getTrustlines'));
|
||||
});
|
||||
|
||||
it('getTrustlines - no options', function() {
|
||||
return this.api.getTrustlines(address).then(
|
||||
_.partial(checkResult, responses.getTrustlines.all, 'getTrustlines'));
|
||||
});
|
||||
|
||||
it('generateAddress', function() {
|
||||
@@ -586,61 +781,123 @@ describe('RippleAPI', function() {
|
||||
responses.generateAddress);
|
||||
});
|
||||
|
||||
it('generateAddress invalid', function() {
|
||||
assert.throws(() => {
|
||||
function random() {
|
||||
return _.fill(Array(1), 0);
|
||||
}
|
||||
this.api.generateAddress({entropy: random()});
|
||||
}, this.api.errors.UnexpectedError);
|
||||
});
|
||||
|
||||
it('getSettings', function() {
|
||||
return this.api.getSettings(address).then(
|
||||
_.partial(checkResult, responses.getSettings, 'getSettings'));
|
||||
});
|
||||
|
||||
it('getSettings - options undefined', function() {
|
||||
return this.api.getSettings(address, undefined).then(
|
||||
_.partial(checkResult, responses.getSettings, 'getSettings'));
|
||||
});
|
||||
|
||||
it('getSettings - invalid options', function() {
|
||||
assert.throws(() => {
|
||||
this.api.getSettings(address, {invalid: 'options'});
|
||||
}, this.api.errors.ValidationError);
|
||||
});
|
||||
|
||||
it('getAccountInfo', function() {
|
||||
return this.api.getAccountInfo(address).then(
|
||||
_.partial(checkResult, responses.getAccountInfo, 'getAccountInfo'));
|
||||
});
|
||||
|
||||
it('getAccountInfo - options undefined', function() {
|
||||
return this.api.getAccountInfo(address, undefined).then(
|
||||
_.partial(checkResult, responses.getAccountInfo, 'getAccountInfo'));
|
||||
});
|
||||
|
||||
it('getAccountInfo - invalid options', function() {
|
||||
assert.throws(() => {
|
||||
this.api.getAccountInfo(address, {invalid: 'options'});
|
||||
}, this.api.errors.ValidationError);
|
||||
});
|
||||
|
||||
it('getOrders', function() {
|
||||
return this.api.getOrders(address).then(
|
||||
_.partial(checkResult, responses.getOrders, 'getOrders'));
|
||||
});
|
||||
|
||||
it('getOrderbook', function() {
|
||||
return this.api.getOrderbook(address, requests.getOrderbook).then(
|
||||
_.partial(checkResult, responses.getOrderbook, 'getOrderbook'));
|
||||
it('getOrders', function() {
|
||||
return this.api.getOrders(address, undefined).then(
|
||||
_.partial(checkResult, responses.getOrders, 'getOrders'));
|
||||
});
|
||||
|
||||
it('getOrderbook - sorted so that best deals come first', function() {
|
||||
return this.api.getOrderbook(address, requests.getOrderbook)
|
||||
.then(data => {
|
||||
const bidRates = data.bids.map(bid => bid.properties.makerExchangeRate);
|
||||
const askRates = data.asks.map(ask => ask.properties.makerExchangeRate);
|
||||
// makerExchangeRate = quality = takerPays.value/takerGets.value
|
||||
// so the best deal for the taker is the lowest makerExchangeRate
|
||||
// bids and asks should be sorted so that the best deals come first
|
||||
assert.deepEqual(_.sortBy(bidRates, x => Number(x)), bidRates);
|
||||
assert.deepEqual(_.sortBy(askRates, x => Number(x)), askRates);
|
||||
it('getOrders - invalid options', function() {
|
||||
assert.throws(() => {
|
||||
this.api.getOrders(address, {invalid: 'options'});
|
||||
}, this.api.errors.ValidationError);
|
||||
});
|
||||
|
||||
describe('getOrderbook', function() {
|
||||
|
||||
it('normal', function() {
|
||||
return this.api.getOrderbook(address,
|
||||
requests.getOrderbook.normal, undefined).then(
|
||||
_.partial(checkResult,
|
||||
responses.getOrderbook.normal, 'getOrderbook'));
|
||||
});
|
||||
});
|
||||
|
||||
it('getOrderbook - currency & counterparty are correct', function() {
|
||||
return this.api.getOrderbook(address, requests.getOrderbook)
|
||||
.then(data => {
|
||||
const orders = _.flatten([data.bids, data.asks]);
|
||||
_.forEach(orders, order => {
|
||||
const quantity = order.specification.quantity;
|
||||
const totalPrice = order.specification.totalPrice;
|
||||
const {base, counter} = requests.getOrderbook;
|
||||
assert.strictEqual(quantity.currency, base.currency);
|
||||
assert.strictEqual(quantity.counterparty, base.counterparty);
|
||||
assert.strictEqual(totalPrice.currency, counter.currency);
|
||||
assert.strictEqual(totalPrice.counterparty, counter.counterparty);
|
||||
it('invalid options', function() {
|
||||
assert.throws(() => {
|
||||
this.api.getOrderbook(address, requests.getOrderbook.normal,
|
||||
{invalid: 'options'});
|
||||
}, this.api.errors.ValidationError);
|
||||
});
|
||||
|
||||
it('with XRP', function() {
|
||||
return this.api.getOrderbook(address, requests.getOrderbook.withXRP).then(
|
||||
_.partial(checkResult, responses.getOrderbook.withXRP, 'getOrderbook'));
|
||||
});
|
||||
|
||||
it('sorted so that best deals come first', function() {
|
||||
return this.api.getOrderbook(address, requests.getOrderbook.normal)
|
||||
.then(data => {
|
||||
const bidRates = data.bids.map(bid => bid.properties.makerExchangeRate);
|
||||
const askRates = data.asks.map(ask => ask.properties.makerExchangeRate);
|
||||
// makerExchangeRate = quality = takerPays.value/takerGets.value
|
||||
// so the best deal for the taker is the lowest makerExchangeRate
|
||||
// bids and asks should be sorted so that the best deals come first
|
||||
assert.deepEqual(_.sortBy(bidRates, x => Number(x)), bidRates);
|
||||
assert.deepEqual(_.sortBy(askRates, x => Number(x)), askRates);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('getOrderbook - direction is correct for bids and asks', function() {
|
||||
return this.api.getOrderbook(address, requests.getOrderbook)
|
||||
.then(data => {
|
||||
assert(_.every(data.bids, bid => bid.specification.direction === 'buy'));
|
||||
assert(_.every(data.asks, ask => ask.specification.direction === 'sell'));
|
||||
it('currency & counterparty are correct', function() {
|
||||
return this.api.getOrderbook(address, requests.getOrderbook.normal)
|
||||
.then(data => {
|
||||
const orders = _.flatten([data.bids, data.asks]);
|
||||
_.forEach(orders, order => {
|
||||
const quantity = order.specification.quantity;
|
||||
const totalPrice = order.specification.totalPrice;
|
||||
const {base, counter} = requests.getOrderbook.normal;
|
||||
assert.strictEqual(quantity.currency, base.currency);
|
||||
assert.strictEqual(quantity.counterparty, base.counterparty);
|
||||
assert.strictEqual(totalPrice.currency, counter.currency);
|
||||
assert.strictEqual(totalPrice.counterparty, counter.counterparty);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('direction is correct for bids and asks', function() {
|
||||
return this.api.getOrderbook(address, requests.getOrderbook.normal)
|
||||
.then(data => {
|
||||
assert(
|
||||
_.every(data.bids, bid => bid.specification.direction === 'buy'));
|
||||
assert(
|
||||
_.every(data.asks, ask => ask.specification.direction === 'sell'));
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('getServerInfo', function() {
|
||||
@@ -664,6 +921,13 @@ describe('RippleAPI', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('getFee default', function() {
|
||||
this.api._feeCushion = undefined;
|
||||
return this.api.getFee().then(fee => {
|
||||
assert.strictEqual(fee, '0.000012');
|
||||
});
|
||||
});
|
||||
|
||||
it('disconnect & isConnected', function() {
|
||||
assert.strictEqual(this.api.isConnected(), true);
|
||||
return this.api.disconnect().then(() => {
|
||||
@@ -702,6 +966,14 @@ describe('RippleAPI', function() {
|
||||
_.partial(checkResult, responses.getPaths.XrpToXrp, 'getPaths'));
|
||||
});
|
||||
|
||||
it('getPaths - source with issuer', function() {
|
||||
return this.api.getPaths(requests.getPaths.issuer).then(() => {
|
||||
assert(false, 'Should throw NotFoundError');
|
||||
}).catch(error => {
|
||||
assert(error instanceof this.api.errors.NotFoundError);
|
||||
});
|
||||
});
|
||||
|
||||
it('getPaths - XRP 2 XRP - not enough', function() {
|
||||
return this.api.getPaths(requests.getPaths.XrpToXrpNotEnough).then(() => {
|
||||
assert(false, 'Should throw NotFoundError');
|
||||
@@ -710,6 +982,12 @@ describe('RippleAPI', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('getPaths - invalid PathFind', function() {
|
||||
assert.throws(() => {
|
||||
this.api.getPaths(requests.getPaths.invalid);
|
||||
}, /Cannot specify both source.amount/);
|
||||
});
|
||||
|
||||
it('getPaths - does not accept currency', function() {
|
||||
return this.api.getPaths(requests.getPaths.NotAcceptCurrency).then(() => {
|
||||
assert(false, 'Should throw NotFoundError');
|
||||
@@ -768,6 +1046,18 @@ describe('RippleAPI', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('getLedger - with state as hashes', function() {
|
||||
const request = {
|
||||
includeTransactions: true,
|
||||
includeAllData: false,
|
||||
includeState: true,
|
||||
ledgerVersion: 6
|
||||
};
|
||||
return this.api.getLedger(request).then(
|
||||
_.partial(checkResult, responses.getLedger.withStateAsHashes,
|
||||
'getLedger'));
|
||||
});
|
||||
|
||||
it('getLedger - with settings transaction', function() {
|
||||
const request = {
|
||||
includeTransactions: true,
|
||||
@@ -796,7 +1086,55 @@ describe('RippleAPI', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('computeLedgerHash - wrong hash', function() {
|
||||
const request = {
|
||||
includeTransactions: true,
|
||||
includeState: true,
|
||||
includeAllData: true,
|
||||
ledgerVersion: 38129
|
||||
};
|
||||
return this.api.getLedger(request).then(
|
||||
_.partial(checkResult, responses.getLedger.full, 'getLedger'))
|
||||
.then(response => {
|
||||
const ledger = _.assign({}, response, {
|
||||
parentCloseTime: response.closeTime, stateHash:
|
||||
'D9ABF622DA26EEEE48203085D4BC23B0F77DC6F8724AC33D975DA3CA492D2E44'});
|
||||
assert.throws(() => {
|
||||
const hash = this.api.computeLedgerHash(ledger);
|
||||
unused(hash);
|
||||
}, /does not match computed hash of state/);
|
||||
});
|
||||
});
|
||||
|
||||
it('RippleError with data', function() {
|
||||
const error = new this.api.errors.RippleError('_message_', '_data_');
|
||||
assert.strictEqual(error.toString(),
|
||||
'[RippleError(_message_, \'_data_\')]');
|
||||
});
|
||||
|
||||
it('NotFoundError default message', function() {
|
||||
const error = new this.api.errors.NotFoundError();
|
||||
assert.strictEqual(error.toString(),
|
||||
'[NotFoundError(Not found)]');
|
||||
});
|
||||
|
||||
it('common utils - toRippledAmount', function() {
|
||||
const amount = {issuer: 'is', currency: 'c', value: 'v'};
|
||||
|
||||
assert.deepEqual(utils.common.toRippledAmount(amount), {
|
||||
issuer: 'is', currency: 'c', value: 'v'
|
||||
});
|
||||
});
|
||||
|
||||
it('ledger utils - renameCounterpartyToIssuerInOrder', function() {
|
||||
const order = {taker_gets: {issuer: '1'}};
|
||||
const expected = {taker_gets: {issuer: '1'}};
|
||||
|
||||
assert.deepEqual(utils.renameCounterpartyToIssuerInOrder(order), expected);
|
||||
});
|
||||
|
||||
it('ledger utils - compareTransactions', function() {
|
||||
assert.strictEqual(utils.compareTransactions({}, {}), 0);
|
||||
let first = {outcome: {ledgerVersion: 1, indexInLedger: 100}};
|
||||
let second = {outcome: {ledgerVersion: 1, indexInLedger: 200}};
|
||||
|
||||
@@ -896,9 +1234,9 @@ describe('RippleAPI', function() {
|
||||
|
||||
});
|
||||
|
||||
it('ledgerClosed', function(done) {
|
||||
this.api.on('ledgerClosed', message => {
|
||||
checkResult(responses.ledgerClosed, 'ledgerClosed', message);
|
||||
it('ledger event', function(done) {
|
||||
this.api.on('ledger', message => {
|
||||
checkResult(responses.ledgerEvent, 'ledgerEvent', message);
|
||||
done();
|
||||
});
|
||||
closeLedger(this.api.connection);
|
||||
@@ -917,7 +1255,8 @@ describe('RippleAPI - offline', function() {
|
||||
};
|
||||
return api.prepareSettings(address, settings, instructions).then(data => {
|
||||
checkResult(responses.prepareSettings.flags, 'prepare', data);
|
||||
assert.deepEqual(api.sign(data.txJSON, secret), responses.sign);
|
||||
assert.deepEqual(api.sign(data.txJSON, secret),
|
||||
responses.prepareSettings.signed);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -961,7 +1300,7 @@ describe('RippleAPI - offline', function() {
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
it('RippleAPI - implicit server port', function() {
|
||||
const api = new RippleAPI({servers: ['wss://s1.ripple.com']});
|
||||
const api = new RippleAPI({server: 'wss://s1.ripple.com'});
|
||||
});
|
||||
/* eslint-enable no-unused-vars */
|
||||
it('RippleAPI invalid options', function() {
|
||||
@@ -969,12 +1308,12 @@ describe('RippleAPI - offline', function() {
|
||||
});
|
||||
|
||||
it('RippleAPI valid options', function() {
|
||||
const api = new RippleAPI({servers: ['wss://s:1']});
|
||||
const api = new RippleAPI({server: 'wss://s:1'});
|
||||
assert.deepEqual(api.connection._url, 'wss://s:1');
|
||||
});
|
||||
|
||||
it('RippleAPI invalid server uri', function() {
|
||||
assert.throws(() => new RippleAPI({servers: ['wss//s:1']}));
|
||||
assert.throws(() => new RippleAPI({server: 'wss//s:1'}));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
62
test/broadcast-api-test.js
Normal file
62
test/broadcast-api-test.js
Normal file
@@ -0,0 +1,62 @@
|
||||
/* eslint-disable max-nested-callbacks */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert-diff');
|
||||
const setupAPI = require('./setup-api');
|
||||
const responses = require('./fixtures').responses;
|
||||
const ledgerClosed = require('./fixtures/rippled/ledger-close');
|
||||
const RippleAPI = require('ripple-api').RippleAPI;
|
||||
const schemaValidator = RippleAPI._PRIVATE.schemaValidator;
|
||||
|
||||
function checkResult(expected, schemaName, response) {
|
||||
if (expected.txJSON) {
|
||||
assert(response.txJSON);
|
||||
assert.deepEqual(JSON.parse(response.txJSON), JSON.parse(expected.txJSON));
|
||||
}
|
||||
assert.deepEqual(_.omit(response, 'txJSON'), _.omit(expected, 'txJSON'));
|
||||
if (schemaName) {
|
||||
schemaValidator.schemaValidate(schemaName, response);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
describe('RippleAPIBroadcast', function() {
|
||||
beforeEach(setupAPI.setupBroadcast);
|
||||
afterEach(setupAPI.teardown);
|
||||
|
||||
it('base', function() {
|
||||
const expected = {request_server_info: 1};
|
||||
this.mocks.forEach(mock => mock.expect(_.assign({}, expected)));
|
||||
assert(this.api.isConnected());
|
||||
return this.api.getServerInfo().then(
|
||||
_.partial(checkResult, responses.getServerInfo, 'getServerInfo'));
|
||||
});
|
||||
|
||||
it('ledger', function(done) {
|
||||
let gotLedger = 0;
|
||||
this.api.on('ledger', () => {
|
||||
gotLedger++;
|
||||
});
|
||||
const ledgerNext = _.assign({}, ledgerClosed);
|
||||
ledgerNext.ledger_index++;
|
||||
this.mocks.forEach(mock => mock.socket.send(JSON.stringify(ledgerNext)));
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('-- ledgerVersion', this.api.ledgerVersion);
|
||||
assert.strictEqual(gotLedger, 1);
|
||||
done();
|
||||
}, 50);
|
||||
|
||||
});
|
||||
|
||||
it('error propagation', function(done) {
|
||||
this.api.once('error', (type, info) => {
|
||||
assert.strictEqual(type, 'type');
|
||||
assert.strictEqual(info, 'info');
|
||||
done();
|
||||
});
|
||||
this.mocks[1].socket.send(
|
||||
JSON.stringify({error: 'type', error_message: 'info'}));
|
||||
});
|
||||
|
||||
});
|
||||
261
test/connection-test.js
Normal file
261
test/connection-test.js
Normal file
@@ -0,0 +1,261 @@
|
||||
/* eslint-disable max-nested-callbacks */
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const net = require('net');
|
||||
const assert = require('assert-diff');
|
||||
const setupAPI = require('./setup-api');
|
||||
const RippleAPI = require('ripple-api').RippleAPI;
|
||||
const utils = RippleAPI._PRIVATE.ledgerUtils;
|
||||
|
||||
|
||||
function unused() {
|
||||
}
|
||||
|
||||
function createServer() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = net.createServer();
|
||||
server.on('listening', function() {
|
||||
resolve(server);
|
||||
});
|
||||
server.on('error', function(error) {
|
||||
reject(error);
|
||||
});
|
||||
server.listen(0, '0.0.0.0');
|
||||
});
|
||||
}
|
||||
|
||||
describe('Connection', function() {
|
||||
beforeEach(setupAPI.setup);
|
||||
afterEach(setupAPI.teardown);
|
||||
|
||||
it('default options', function() {
|
||||
const connection = new utils.common.Connection('url');
|
||||
assert.strictEqual(connection._url, 'url');
|
||||
assert(_.isUndefined(connection._proxyURL));
|
||||
assert(_.isUndefined(connection._authorization));
|
||||
});
|
||||
|
||||
it('trace', function() {
|
||||
const connection = new utils.common.Connection('url', {trace: true});
|
||||
const message1 = '{"type": "transaction"}';
|
||||
const message2 = '{"type": "path_find"}';
|
||||
const messages = [];
|
||||
connection._console = {
|
||||
log: function(message) {
|
||||
messages.push(message);
|
||||
}
|
||||
};
|
||||
connection._onMessage(message1);
|
||||
connection._send(message2);
|
||||
|
||||
assert.deepEqual(messages, [message1, message2]);
|
||||
});
|
||||
|
||||
it('with proxy', function(done) {
|
||||
createServer().then((server) => {
|
||||
const port = server.address().port;
|
||||
const expect = 'CONNECT localhost';
|
||||
server.on('connection', (socket) => {
|
||||
socket.on('data', (data) => {
|
||||
const got = data.toString('ascii', 0, expect.length);
|
||||
assert.strictEqual(got, expect);
|
||||
server.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
const options = {
|
||||
proxy: 'ws://localhost:' + port,
|
||||
authorization: 'authorization',
|
||||
trustedCertificates: ['path/to/pem']
|
||||
};
|
||||
const connection =
|
||||
new utils.common.Connection(this.api.connection._url, options);
|
||||
connection.connect().catch(done);
|
||||
connection.connect().catch(done);
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('Multiply disconnect calls', function() {
|
||||
this.api.disconnect();
|
||||
return this.api.disconnect();
|
||||
});
|
||||
|
||||
it('reconnect', function() {
|
||||
return this.api.connection.reconnect();
|
||||
});
|
||||
|
||||
it('NotConnectedError', function() {
|
||||
const connection = new utils.common.Connection('url');
|
||||
return connection.getLedgerVersion().then(() => {
|
||||
assert(false, 'Should throw NotConnectedError');
|
||||
}).catch(error => {
|
||||
assert(error instanceof this.api.errors.NotConnectedError);
|
||||
});
|
||||
});
|
||||
|
||||
it('DisconnectedError', function() {
|
||||
this.api.connection._send = function() {
|
||||
this._ws.close();
|
||||
};
|
||||
return this.api.getServerInfo().then(() => {
|
||||
assert(false, 'Should throw DisconnectedError');
|
||||
}).catch(error => {
|
||||
assert(error instanceof this.api.errors.DisconnectedError);
|
||||
});
|
||||
});
|
||||
|
||||
it('TimeoutError', function() {
|
||||
this.api.connection._send = function() {
|
||||
return Promise.resolve({});
|
||||
};
|
||||
const request = {command: 'server_info'};
|
||||
return this.api.connection.request(request, 1).then(() => {
|
||||
assert(false, 'Should throw TimeoutError');
|
||||
}).catch(error => {
|
||||
assert(error instanceof this.api.errors.TimeoutError);
|
||||
});
|
||||
});
|
||||
|
||||
it('DisconnectedError on send', function() {
|
||||
this.api.connection._ws.send = function(message, options, callback) {
|
||||
unused(message, options);
|
||||
callback({message: 'not connected'});
|
||||
};
|
||||
return this.api.getServerInfo().then(() => {
|
||||
assert(false, 'Should throw DisconnectedError');
|
||||
}).catch(error => {
|
||||
assert(error instanceof this.api.errors.DisconnectedError);
|
||||
assert.strictEqual(error.message, 'not connected');
|
||||
});
|
||||
});
|
||||
|
||||
it('ResponseFormatError', function() {
|
||||
this.api.connection._send = function(message) {
|
||||
const parsed = JSON.parse(message);
|
||||
setTimeout(() => {
|
||||
this._ws.emit('message', JSON.stringify({
|
||||
id: parsed.id,
|
||||
type: 'response',
|
||||
status: 'unrecognized'
|
||||
}));
|
||||
}, 2);
|
||||
return new Promise(() => {});
|
||||
};
|
||||
return this.api.getServerInfo().then(() => {
|
||||
assert(false, 'Should throw ResponseFormatError');
|
||||
}).catch(error => {
|
||||
assert(error instanceof this.api.errors.ResponseFormatError);
|
||||
});
|
||||
});
|
||||
|
||||
it('reconnect on unexpected close ', function(done) {
|
||||
this.api.connection.on('connected', () => {
|
||||
done();
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
this.api.connection._ws.close();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
it('Multiply connect calls', function() {
|
||||
return this.api.connect().then(() => {
|
||||
return this.api.connect();
|
||||
});
|
||||
});
|
||||
|
||||
it('hasLedgerVersion', function() {
|
||||
return this.api.connection.hasLedgerVersion(8819951).then((result) => {
|
||||
assert(result);
|
||||
});
|
||||
});
|
||||
|
||||
it('Cannot connect because no server', function() {
|
||||
const connection = new utils.common.Connection();
|
||||
return connection.connect().then(() => {
|
||||
assert(false, 'Should throw ConnectionError');
|
||||
}).catch(error => {
|
||||
assert(error instanceof this.api.errors.ConnectionError);
|
||||
});
|
||||
});
|
||||
|
||||
it('connect multiserver error', function() {
|
||||
const options = {
|
||||
servers: ['wss://server1.com', 'wss://server2.com']
|
||||
};
|
||||
assert.throws(function() {
|
||||
const api = new RippleAPI(options);
|
||||
unused(api);
|
||||
}, this.api.errors.RippleError);
|
||||
});
|
||||
|
||||
it('connect throws error', function(done) {
|
||||
this.api.once('error', (type, info) => {
|
||||
assert.strictEqual(type, 'type');
|
||||
assert.strictEqual(info, 'info');
|
||||
done();
|
||||
});
|
||||
this.api.connection.emit('error', 'type', 'info');
|
||||
});
|
||||
|
||||
it('emit stream messages', function(done) {
|
||||
let transactionCount = 0;
|
||||
let pathFindCount = 0;
|
||||
this.api.connection.on('transaction', () => {
|
||||
transactionCount++;
|
||||
});
|
||||
this.api.connection.on('path_find', () => {
|
||||
pathFindCount++;
|
||||
});
|
||||
this.api.connection.on('1', () => {
|
||||
assert.strictEqual(transactionCount, 1);
|
||||
assert.strictEqual(pathFindCount, 1);
|
||||
done();
|
||||
});
|
||||
|
||||
this.api.connection._onMessage(JSON.stringify({
|
||||
type: 'transaction'
|
||||
}));
|
||||
this.api.connection._onMessage(JSON.stringify({
|
||||
type: 'path_find'
|
||||
}));
|
||||
this.api.connection._onMessage(JSON.stringify({
|
||||
type: 'response', id: 1
|
||||
}));
|
||||
});
|
||||
|
||||
it('invalid message id', function(done) {
|
||||
this.api.on('error', (type, message) => {
|
||||
assert.strictEqual(type, 'badMessage');
|
||||
assert.strictEqual(message,
|
||||
'{"type":"response","id":"must be integer"}');
|
||||
done();
|
||||
});
|
||||
this.api.connection._onMessage(JSON.stringify({
|
||||
type: 'response', id: 'must be integer'
|
||||
}));
|
||||
});
|
||||
|
||||
it('propagate error message', function(done) {
|
||||
this.api.on('error', (type, message) => {
|
||||
assert.strictEqual(type, 'slowDown');
|
||||
assert.strictEqual(message, 'slow down');
|
||||
done();
|
||||
});
|
||||
this.api.connection._onMessage(JSON.stringify({
|
||||
error: 'slowDown', error_message: 'slow down'
|
||||
}));
|
||||
});
|
||||
|
||||
it('unrecognized message type', function(done) {
|
||||
this.api.on('error', (type, message) => {
|
||||
assert.strictEqual(type, 'badMessage');
|
||||
assert.strictEqual(message, '{"type":"unknown"}');
|
||||
done();
|
||||
});
|
||||
|
||||
this.api.connection._onMessage(JSON.stringify({type: 'unknown'}));
|
||||
});
|
||||
});
|
||||
9
test/fixtures/requests/get-orderbook-with-xrp.json
vendored
Normal file
9
test/fixtures/requests/get-orderbook-with-xrp.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"base": {
|
||||
"currency": "USD",
|
||||
"counterparty": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw"
|
||||
},
|
||||
"counter": {
|
||||
"currency": "XRP"
|
||||
}
|
||||
}
|
||||
16
test/fixtures/requests/getpaths/invalid.json
vendored
Normal file
16
test/fixtures/requests/getpaths/invalid.json
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J",
|
||||
"amount": {
|
||||
"value": "1000002",
|
||||
"currency": "USD"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"value": "1000002",
|
||||
"currency": "USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
16
test/fixtures/requests/getpaths/issuer.json
vendored
Normal file
16
test/fixtures/requests/getpaths/issuer.json
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J",
|
||||
"amount": {
|
||||
"value": "1000002",
|
||||
"currency": "USD",
|
||||
"counterparty": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"currency": "USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
54
test/fixtures/requests/index.js
vendored
54
test/fixtures/requests/index.js
vendored
@@ -6,23 +6,42 @@ module.exports = {
|
||||
sell: require('./prepare-order-sell'),
|
||||
expiration: require('./prepare-order-expiration')
|
||||
},
|
||||
prepareOrderCancellation: require('./prepare-order-cancellation'),
|
||||
preparePayment: require('./prepare-payment'),
|
||||
preparePaymentAllOptions: require('./prepare-payment-all-options'),
|
||||
preparePaymentNoCounterparty: require('./prepare-payment-no-counterparty'),
|
||||
prepareOrderCancellation: {
|
||||
simple: require('./prepare-order-cancellation'),
|
||||
withMemos: require('./prepare-order-cancellation-memos')
|
||||
},
|
||||
preparePayment: {
|
||||
normal: require('./prepare-payment'),
|
||||
minAmountXRP: require('./prepare-payment-min-xrp'),
|
||||
minAmount: require('./prepare-payment-min'),
|
||||
wrongAddress: require('./prepare-payment-wrong-address'),
|
||||
wrongAmount: require('./prepare-payment-wrong-amount'),
|
||||
wrongPartial: require('./prepare-payment-wrong-partial'),
|
||||
allOptions: require('./prepare-payment-all-options'),
|
||||
noCounterparty: require('./prepare-payment-no-counterparty')
|
||||
},
|
||||
prepareSettings: require('./prepare-settings'),
|
||||
prepareSuspendedPaymentCreation:
|
||||
require('./prepare-suspended-payment-creation'),
|
||||
prepareSuspendedPaymentExecution:
|
||||
require('./prepare-suspended-payment-execution'),
|
||||
prepareSuspendedPaymentCancellation:
|
||||
require('./prepare-suspended-payment-cancellation'),
|
||||
prepareSuspendedPaymentCreation: {
|
||||
normal: require('./prepare-suspended-payment-creation'),
|
||||
full: require('./prepare-suspended-payment-creation-full')
|
||||
},
|
||||
prepareSuspendedPaymentExecution: {
|
||||
normal: require('./prepare-suspended-payment-execution'),
|
||||
simple: require('./prepare-suspended-payment-execution-simple')
|
||||
},
|
||||
prepareSuspendedPaymentCancellation: {
|
||||
normal: require('./prepare-suspended-payment-cancellation'),
|
||||
memos: require('./prepare-suspended-payment-cancellation-memos')
|
||||
},
|
||||
prepareTrustline: {
|
||||
simple: require('./prepare-trustline-simple'),
|
||||
complex: require('./prepare-trustline')
|
||||
complex: require('./prepare-trustline'),
|
||||
frozen: require('./prepare-trustline-frozen.json')
|
||||
},
|
||||
sign: {
|
||||
normal: require('./sign'),
|
||||
suspended: require('./sign-suspended.json')
|
||||
},
|
||||
sign: require('./sign'),
|
||||
signSuspended: require('./sign-suspended.json'),
|
||||
getPaths: {
|
||||
normal: require('./getpaths/normal'),
|
||||
UsdToUsd: require('./getpaths/usd2usd'),
|
||||
@@ -31,9 +50,14 @@ module.exports = {
|
||||
NotAcceptCurrency: require('./getpaths/not-accept-currency'),
|
||||
NoPaths: require('./getpaths/no-paths'),
|
||||
NoPathsWithCurrencies: require('./getpaths/no-paths-with-currencies'),
|
||||
sendAll: require('./getpaths/send-all')
|
||||
sendAll: require('./getpaths/send-all'),
|
||||
invalid: require('./getpaths/invalid'),
|
||||
issuer: require('./getpaths/issuer')
|
||||
},
|
||||
getOrderbook: {
|
||||
normal: require('./get-orderbook'),
|
||||
withXRP: require('./get-orderbook-with-xrp')
|
||||
},
|
||||
getOrderbook: require('./get-orderbook'),
|
||||
computeLedgerHash: {
|
||||
header: require('./compute-ledger-hash'),
|
||||
transactions: require('./compute-ledger-hash-transactions')
|
||||
|
||||
10
test/fixtures/requests/prepare-order-cancellation-memos.json
vendored
Normal file
10
test/fixtures/requests/prepare-order-cancellation-memos.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"orderSequence": 23,
|
||||
"memos": [
|
||||
{
|
||||
"type": "test",
|
||||
"format": "plain/text",
|
||||
"data": "texted data"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +1,3 @@
|
||||
23
|
||||
{
|
||||
"orderSequence": 23
|
||||
}
|
||||
|
||||
@@ -9,5 +9,12 @@
|
||||
"currency": "XRP",
|
||||
"value": "2"
|
||||
},
|
||||
"immediateOrCancel": true
|
||||
"immediateOrCancel": true,
|
||||
"memos": [
|
||||
{
|
||||
"type": "test",
|
||||
"format": "plain/text",
|
||||
"data": "texted data"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
3
test/fixtures/requests/prepare-order.json
vendored
3
test/fixtures/requests/prepare-order.json
vendored
@@ -9,5 +9,6 @@
|
||||
"currency": "XRP",
|
||||
"value": "2"
|
||||
},
|
||||
"immediateOrCancel": true
|
||||
"passive": true,
|
||||
"fillOrKill": true
|
||||
}
|
||||
|
||||
17
test/fixtures/requests/prepare-payment-min-xrp.json
vendored
Normal file
17
test/fixtures/requests/prepare-payment-min-xrp.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"value": "0.01",
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"minAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP"
|
||||
}
|
||||
}
|
||||
}
|
||||
17
test/fixtures/requests/prepare-payment-min.json
vendored
Normal file
17
test/fixtures/requests/prepare-payment-min.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"minAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP"
|
||||
}
|
||||
}
|
||||
}
|
||||
17
test/fixtures/requests/prepare-payment-wrong-address.json
vendored
Normal file
17
test/fixtures/requests/prepare-payment-wrong-address.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM",
|
||||
"amount": {
|
||||
"value": "0.01",
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"minAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP"
|
||||
}
|
||||
}
|
||||
}
|
||||
17
test/fixtures/requests/prepare-payment-wrong-amount.json
vendored
Normal file
17
test/fixtures/requests/prepare-payment-wrong-amount.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"maxAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"minAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP"
|
||||
}
|
||||
}
|
||||
}
|
||||
17
test/fixtures/requests/prepare-payment-wrong-partial.json
vendored
Normal file
17
test/fixtures/requests/prepare-payment-wrong-partial.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"minAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP"
|
||||
}
|
||||
},
|
||||
"allowPartialPayment": true
|
||||
}
|
||||
9
test/fixtures/requests/prepare-settings.json
vendored
9
test/fixtures/requests/prepare-settings.json
vendored
@@ -1,3 +1,10 @@
|
||||
{
|
||||
"domain": "ripple.com"
|
||||
"domain": "ripple.com",
|
||||
"memos": [
|
||||
{
|
||||
"type": "test",
|
||||
"format": "plain/text",
|
||||
"data": "texted data"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
11
test/fixtures/requests/prepare-suspended-payment-cancellation-memos.json
vendored
Normal file
11
test/fixtures/requests/prepare-suspended-payment-cancellation-memos.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"owner": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"suspensionSequence": 1234,
|
||||
"memos": [
|
||||
{
|
||||
"type": "test",
|
||||
"format": "plain/text",
|
||||
"data": "texted data"
|
||||
}
|
||||
]
|
||||
}
|
||||
28
test/fixtures/requests/prepare-suspended-payment-creation-full.json
vendored
Normal file
28
test/fixtures/requests/prepare-suspended-payment-creation-full.json
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"maxAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||
},
|
||||
"tag": 1
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"amount": {
|
||||
"value": "0.01",
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||
},
|
||||
"tag": 2
|
||||
},
|
||||
"digest": "8F434346648F6B96DF89DDA901C5176B10A6D83961DD3C1AC88B59B2DC327AA4",
|
||||
"allowExecuteAfter": "2014-09-24T21:21:50.000Z",
|
||||
"memos": [
|
||||
{
|
||||
"type": "test",
|
||||
"data": "texted data"
|
||||
}
|
||||
]
|
||||
}
|
||||
11
test/fixtures/requests/prepare-suspended-payment-execution-simple.json
vendored
Normal file
11
test/fixtures/requests/prepare-suspended-payment-execution-simple.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"owner": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"suspensionSequence": 1234,
|
||||
"memos": [
|
||||
{
|
||||
"type": "test",
|
||||
"format": "plain/text",
|
||||
"data": "texted data"
|
||||
}
|
||||
]
|
||||
}
|
||||
8
test/fixtures/requests/prepare-trustline-frozen.json
vendored
Normal file
8
test/fixtures/requests/prepare-trustline-frozen.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"currency": "BTC",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM",
|
||||
"limit": "0.1",
|
||||
"authorized": true,
|
||||
"ripplingDisabled": false,
|
||||
"frozen": true
|
||||
}
|
||||
@@ -5,5 +5,12 @@
|
||||
"qualityIn": 0.91,
|
||||
"qualityOut": 0.87,
|
||||
"ripplingDisabled": true,
|
||||
"frozen": false
|
||||
"frozen": false,
|
||||
"memos": [
|
||||
{
|
||||
"type": "test",
|
||||
"format": "plain/text",
|
||||
"data": "texted data"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
2
test/fixtures/requests/sign.json
vendored
2
test/fixtures/requests/sign.json
vendored
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Domain\":\"726970706C652E636F6D\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Domain\":\"726970706C652E636F6D\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23,\"SigningPubKey\":\"02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8\"}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user