mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-04 21:15:47 +00:00
Compare commits
317 Commits
0.13.0-rc1
...
0.13.0-rc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57ecbc58f8 | ||
|
|
ea4d1007b8 | ||
|
|
16bc7b986b | ||
|
|
115f95fa96 | ||
|
|
b77b76ebb5 | ||
|
|
f516298a84 | ||
|
|
edb31a0c9c | ||
|
|
e99010f363 | ||
|
|
fa865f8409 | ||
|
|
40b613b7a2 | ||
|
|
a79b010572 | ||
|
|
7404795dc6 | ||
|
|
47a9fb5803 | ||
|
|
701d4c5722 | ||
|
|
d8d6f945ec | ||
|
|
a6821bb8ab | ||
|
|
ed40eec711 | ||
|
|
2f163c3b6e | ||
|
|
43488c55f1 | ||
|
|
2f727b553c | ||
|
|
29c37aa6da | ||
|
|
64baef431d | ||
|
|
634fe5683a | ||
|
|
225ca3f852 | ||
|
|
ff2ac6c3cd | ||
|
|
607777f2a3 | ||
|
|
78eeb40322 | ||
|
|
772f79ae21 | ||
|
|
806a4e823f | ||
|
|
323e402e0c | ||
|
|
9ebb59580d | ||
|
|
bafab6eb18 | ||
|
|
35acbb62c3 | ||
|
|
4676ade4ee | ||
|
|
8edc3b1f36 | ||
|
|
8acfb1a537 | ||
|
|
ac78171099 | ||
|
|
d573c5746b | ||
|
|
51e8f9a87a | ||
|
|
bfe590d96d | ||
|
|
60e2d10775 | ||
|
|
2f432cef62 | ||
|
|
5217b66396 | ||
|
|
b8bb191d24 | ||
|
|
8070a52dc7 | ||
|
|
3205f3cf8c | ||
|
|
e0cdd610dd | ||
|
|
ed3b04ed6f | ||
|
|
62a2d2ae39 | ||
|
|
e2c853e40d | ||
|
|
b9b5a71869 | ||
|
|
87fdbc932f | ||
|
|
84838b2e9f | ||
|
|
c2ca37a790 | ||
|
|
c6805b9f0d | ||
|
|
b1dbdc03dd | ||
|
|
88a3f3d43b | ||
|
|
5f8dcd71a5 | ||
|
|
45db95da79 | ||
|
|
c79b12b27f | ||
|
|
135da6108d | ||
|
|
0d6dda579f | ||
|
|
e641a347db | ||
|
|
3e17d91edf | ||
|
|
715c648d52 | ||
|
|
d0ebed9822 | ||
|
|
a3775f18ba | ||
|
|
7b5d6e9fc5 | ||
|
|
368ac0b9e0 | ||
|
|
0448696bd8 | ||
|
|
deb75ed0d7 | ||
|
|
fcc9bacb4e | ||
|
|
9a5e8fd2ba | ||
|
|
1c023c4377 | ||
|
|
c213b98329 | ||
|
|
27d2e6e519 | ||
|
|
7ee368965c | ||
|
|
d8b5b825b3 | ||
|
|
de67570230 | ||
|
|
60c604fbe6 | ||
|
|
2f6d25ed01 | ||
|
|
b134081293 | ||
|
|
a0528d7f9c | ||
|
|
348335ddf0 | ||
|
|
01752e5486 | ||
|
|
3e758e1b86 | ||
|
|
fb0b30a9a7 | ||
|
|
0c9aea454e | ||
|
|
f282585c3f | ||
|
|
ae5ff31c96 | ||
|
|
20fa8bc953 | ||
|
|
778f59b4fd | ||
|
|
49623cb4dd | ||
|
|
90b53002aa | ||
|
|
93c12af305 | ||
|
|
60f2419b5c | ||
|
|
80494ad813 | ||
|
|
b43c4a7ad4 | ||
|
|
3c608de5bb | ||
|
|
fe5bc1d215 | ||
|
|
580bf9a755 | ||
|
|
c7df5df163 | ||
|
|
a08c52af55 | ||
|
|
e11db0f0f3 | ||
|
|
c6e0582729 | ||
|
|
6e98629f9b | ||
|
|
2243760442 | ||
|
|
91dd6877aa | ||
|
|
e73bcd8fc1 | ||
|
|
7e886b3260 | ||
|
|
5c9451d3ed | ||
|
|
c6c2dcc6c0 | ||
|
|
0bdd37090e | ||
|
|
c745faaaf0 | ||
|
|
9ad03ca873 | ||
|
|
138914384e | ||
|
|
77068667e4 | ||
|
|
c57cef4a21 | ||
|
|
50acc4c708 | ||
|
|
b5f8ba4817 | ||
|
|
a53249ccd7 | ||
|
|
0c62fa2112 | ||
|
|
806547dd15 | ||
|
|
fb1669b2b3 | ||
|
|
0cda15f2b5 | ||
|
|
b88e9370c6 | ||
|
|
e343f3beb8 | ||
|
|
a13bfae714 | ||
|
|
877c6bbb2a | ||
|
|
30d5134394 | ||
|
|
fae5c74487 | ||
|
|
255332ea2e | ||
|
|
15c0e6db19 | ||
|
|
2b600a1e4e | ||
|
|
297fb2483d | ||
|
|
5049822415 | ||
|
|
e3787e0f4f | ||
|
|
683199044b | ||
|
|
4f3c3e9f66 | ||
|
|
fc0240c06b | ||
|
|
6bfa284bac | ||
|
|
dfee9bc578 | ||
|
|
0838a0e865 | ||
|
|
5f61d80e2d | ||
|
|
c4fa4c237c | ||
|
|
44d00d5ef4 | ||
|
|
d4d3efcb65 | ||
|
|
f23e105240 | ||
|
|
5a396a7060 | ||
|
|
513632299f | ||
|
|
0d40558f1e | ||
|
|
1ccbaf6776 | ||
|
|
ba6c703163 | ||
|
|
3b9eb02bbb | ||
|
|
bca7382015 | ||
|
|
67672bd389 | ||
|
|
232017d9a2 | ||
|
|
23653f67f0 | ||
|
|
e3b688d1dd | ||
|
|
a94b21ca3c | ||
|
|
9c9be3e6e4 | ||
|
|
062561686e | ||
|
|
761682c206 | ||
|
|
39c48d631c | ||
|
|
a55d26a726 | ||
|
|
597ae157b3 | ||
|
|
c1c7458914 | ||
|
|
0e97f269ab | ||
|
|
bbe4cd63a1 | ||
|
|
2515d17a85 | ||
|
|
d8e95a3c3b | ||
|
|
98f6bed8c9 | ||
|
|
bd000c2662 | ||
|
|
a46141111a | ||
|
|
f57c89c6e9 | ||
|
|
6d4cac948d | ||
|
|
1f54b3a0cf | ||
|
|
2f8655dc23 | ||
|
|
d624923cd8 | ||
|
|
2180c076dd | ||
|
|
0dbdf0a21a | ||
|
|
5cb63a258c | ||
|
|
39ac6caaef | ||
|
|
de4ef8b2b4 | ||
|
|
99cba09a4a | ||
|
|
300967f0f3 | ||
|
|
52879febb9 | ||
|
|
f077a563c4 | ||
|
|
92fbc61f47 | ||
|
|
5ac1bcc414 | ||
|
|
5837aa23ea | ||
|
|
8c431b4ec3 | ||
|
|
25086a7944 | ||
|
|
b0889b4afe | ||
|
|
ed971bc41c | ||
|
|
728595dc96 | ||
|
|
7fc6adb776 | ||
|
|
002102ce62 | ||
|
|
bf9da80d46 | ||
|
|
dda9994869 | ||
|
|
4c76ad159e | ||
|
|
f76a8daca8 | ||
|
|
3263629ebe | ||
|
|
fcbe7d3c98 | ||
|
|
a6662ccdff | ||
|
|
854fe85151 | ||
|
|
2b2fdf1b11 | ||
|
|
cbe44d6a96 | ||
|
|
420346faea | ||
|
|
6220162852 | ||
|
|
37198bde66 | ||
|
|
281c056f6c | ||
|
|
49a513cd07 | ||
|
|
7a95aabbf4 | ||
|
|
83874ec096 | ||
|
|
9270d0a33d | ||
|
|
30295efdb4 | ||
|
|
f1342c1456 | ||
|
|
194b73c293 | ||
|
|
89e5f79bbb | ||
|
|
82d7ce7ac2 | ||
|
|
0cc4c704f8 | ||
|
|
dde762a1d6 | ||
|
|
1c86e246c7 | ||
|
|
2d173c8e69 | ||
|
|
600fd34d30 | ||
|
|
4cb9cf801c | ||
|
|
50fb8789b4 | ||
|
|
fb8dc44ec1 | ||
|
|
0781caa8bc | ||
|
|
2cdb23f0dd | ||
|
|
8e536c00b9 | ||
|
|
8ff154cc2d | ||
|
|
daaae6e01e | ||
|
|
a64a4e697a | ||
|
|
3f51d8cc12 | ||
|
|
9f9e76f8b9 | ||
|
|
5b51db158d | ||
|
|
a4d1509448 | ||
|
|
bbd51a03b6 | ||
|
|
b55b82b2fd | ||
|
|
fdb0f101bd | ||
|
|
0afca5633d | ||
|
|
7c0d9a7172 | ||
|
|
f6b7e27c67 | ||
|
|
b8624bc55f | ||
|
|
2eec30756d | ||
|
|
6b44ce8973 | ||
|
|
ed0b501716 | ||
|
|
0fd391af72 | ||
|
|
fe9c1ada88 | ||
|
|
4c1f4ef58c | ||
|
|
10afc770ff | ||
|
|
8543e60f86 | ||
|
|
116d7e0f29 | ||
|
|
68adaec55b | ||
|
|
03640efef5 | ||
|
|
c6f450842e | ||
|
|
e583eb4592 | ||
|
|
7fffbe0c64 | ||
|
|
63e3b71eb5 | ||
|
|
823ef738fe | ||
|
|
0977ef0ec2 | ||
|
|
cecf3f3d22 | ||
|
|
472fbce23a | ||
|
|
e44aea1767 | ||
|
|
d682d90d86 | ||
|
|
141aa17dfc | ||
|
|
0b09e53479 | ||
|
|
528d8bf25d | ||
|
|
03a2109e24 | ||
|
|
b38b9bced6 | ||
|
|
ea063d0c95 | ||
|
|
7f93929014 | ||
|
|
4cd10ecb87 | ||
|
|
6ef30debd2 | ||
|
|
4766bace4e | ||
|
|
261500a3a4 | ||
|
|
fae22b7023 | ||
|
|
4568b39997 | ||
|
|
4a218cacfa | ||
|
|
34a4dd3077 | ||
|
|
a383bd7e52 | ||
|
|
e76e693bdb | ||
|
|
2c52e4aa69 | ||
|
|
13dee36e93 | ||
|
|
6e180439d1 | ||
|
|
e8d0c1ae95 | ||
|
|
068bda0c95 | ||
|
|
ab694381d5 | ||
|
|
dc2a6c75cf | ||
|
|
98dbba8f27 | ||
|
|
9a1b80d77a | ||
|
|
a655be30d6 | ||
|
|
e5aabc3072 | ||
|
|
2cd32d58ad | ||
|
|
0c02b92717 | ||
|
|
c58a077a2f | ||
|
|
6e7dc9d7d3 | ||
|
|
572c945274 | ||
|
|
c605efab61 | ||
|
|
2695f4302a | ||
|
|
a17011243e | ||
|
|
9a533ab807 | ||
|
|
a037952493 | ||
|
|
dc96795a02 | ||
|
|
8d9746d7b1 | ||
|
|
00342c4239 | ||
|
|
e48df2c1fd | ||
|
|
6ade0f6554 | ||
|
|
a88157bb92 | ||
|
|
00f318284f | ||
|
|
2e12dc6d53 | ||
|
|
34435d4d05 | ||
|
|
a99452b773 | ||
|
|
a05cb39ab0 | ||
|
|
0c69f7f10e |
@@ -26,6 +26,9 @@ function webpackConfig(extension, overrides) {
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'babel-loader?optional=runtime'
|
||||
}, {
|
||||
test: /\.json/,
|
||||
loader: 'json-loader'
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
32
HISTORY.md
32
HISTORY.md
@@ -1,3 +1,35 @@
|
||||
##0.13.0 (release candidate)
|
||||
|
||||
**Breaking Changes**
|
||||
+ [Removed timeout method of Request and added default timeout](https://github.com/ripple/ripple-lib/commit/634fe5683a9082e57682ff7d5c4fb9483b4af818)
|
||||
+ Add new RippleAPI interface
|
||||
- [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**
|
||||
+ [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)
|
||||
+ [Fix crash due to rippled slowDown error](https://github.com/ripple/ripple-lib/commit/84838b2e9f6969b593b8462a62a6b8f516ada937)
|
||||
+ [Fix: Emit error events and return error on pathfind](https://github.com/ripple/ripple-lib/commit/1ccbaf677631a1944eb05d90f7afc5f3690a03dd)
|
||||
+ [Deprecate core and remove snake case method copying](https://github.com/ripple/ripple-lib/commit/fb8dc44ec1d49bb05cd0cdbe6dd4ab211195868a)
|
||||
|
||||
+ [Fix RangeSet for validated_ledger as single ledger](https://github.com/ripple/ripple-lib/commit/9f9e76f8b933201651af59307135f67cfa7d60e8)
|
||||
+ [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.7 and 0.12.8
|
||||
|
||||
+ [Improve performance of orderbook](https://github.com/ripple/ripple-lib/commit/c745faaaf0956ca98448a754b4fe97fb50574fc7)
|
||||
|
||||
+ [Remove Firefox warning about prototype overwrite](https://github.com/ripple/ripple-lib/commit/0c62fa21123b220b066871e1c41a3b4fe6f51885)
|
||||
|
||||
+ [Fix compare bug in Amount class](https://github.com/ripple/ripple-lib/commit/806547dd154e1b0bf252e8a74ad3ac6aa8a97660)
|
||||
|
||||
##0.12.6
|
||||
|
||||
+ [Fix webpack require failure due to "./" notation](https://github.com/ripple/ripple-lib/commit/8d9746d7b10be203ee613df523c2522012ff1baf)
|
||||
|
||||
##0.12.15
|
||||
|
||||
+ [Add offer autobridging](https://github.com/ripple/ripple-lib/commit/c7bbce83719c1e8c6a4fae5ca850e7515db1a4a5)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
A JavaScript API for interacting with Ripple in Node.js and the browser
|
||||
|
||||
[](https://travis-ci.org/ripple/ripple-lib) [](https://coveralls.io/r/ripple/ripple-lib?branch=develop)
|
||||
[](https://circleci.com/gh/ripple/ripple-lib/tree/develop) [](https://coveralls.io/r/ripple/ripple-lib?branch=develop)
|
||||
|
||||
[](https://www.npmjs.org/package/ripple-lib)
|
||||
|
||||
|
||||
17
bin/ci.sh
17
bin/ci.sh
@@ -5,19 +5,32 @@ TOTAL_NODES="$2"
|
||||
|
||||
typecheck() {
|
||||
npm install -g flow-bin
|
||||
flow --version
|
||||
npm run typecheck
|
||||
}
|
||||
|
||||
lint() {
|
||||
echo "eslint $(node_modules/.bin/eslint --version)"
|
||||
npm list babel-eslint | grep babel-eslint
|
||||
REPO_URL="https://raw.githubusercontent.com/ripple/javascript-style-guide"
|
||||
curl "$REPO_URL/es6/eslintrc" > ./eslintrc
|
||||
echo "plugins: [flowtype]" >> ./eslintrc
|
||||
node_modules/.bin/eslint --reset -c ./eslintrc $(git --no-pager diff --name-only -M100% --diff-filter=AM --relative $(git merge-base FETCH_HEAD origin/HEAD) FETCH_HEAD | grep "\.js$")
|
||||
echo "parser: babel-eslint" >> ./eslintrc
|
||||
node_modules/.bin/eslint -c ./eslintrc $(git --no-pager diff --name-only -M100% --diff-filter=AM --relative $(git merge-base FETCH_HEAD origin/HEAD) FETCH_HEAD | grep "\.js$")
|
||||
}
|
||||
|
||||
unittest() {
|
||||
# test "src"
|
||||
npm test --coverage
|
||||
npm run coveralls
|
||||
|
||||
# test compiled version in "dist/npm"
|
||||
babel -D --optional runtime --ignore "**/node_modules/**" -d test-compiled/ test/
|
||||
echo "--reporter spec --timeout 5000 --slow 500" > test-compiled/mocha.opts
|
||||
mkdir -p test-compiled/node_modules
|
||||
ln -nfs ../../dist/npm/core test-compiled/node_modules/ripple-lib
|
||||
ln -nfs ../../dist/npm test-compiled/node_modules/ripple-api
|
||||
mocha --opts test-compiled/mocha.opts test-compiled
|
||||
rm -rf test-compiled
|
||||
}
|
||||
|
||||
oneNode() {
|
||||
|
||||
@@ -14,6 +14,8 @@ __(More examples coming soon!)__
|
||||
+ [Transaction requests](REFERENCE.md#transaction-requests)
|
||||
3. [`Transaction` constructors](REFERENCE.md#transaction-constructors)
|
||||
+ [Transaction events](REFERENCE.md#transaction-events)
|
||||
4. [Subscriptions](REFERENCE.md#subscriptions)
|
||||
+ [Orderbook subscription](REFERENCE.md#orderbook-subscription)
|
||||
|
||||
###Also see:
|
||||
|
||||
@@ -352,3 +354,24 @@ transaction.submit(function(err, res) {
|
||||
#Amount objects
|
||||
|
||||
Coming Soon
|
||||
|
||||
#Subscriptions
|
||||
|
||||
##Orderbook subscription
|
||||
|
||||
Subscribes to an orderbook (including autobridged books). Send the orderbook on subscribe then notifies updates.
|
||||
Available events: ['transaction', 'model', 'trade', 'offer_added', 'offer_removed', 'offer_changed', 'offer_funds_changed']
|
||||
```js
|
||||
parameters = {
|
||||
currency_pays: <string>,
|
||||
issuer_pays: <string>,
|
||||
currency_gets: <string>,
|
||||
issuer_gets: <string>
|
||||
}
|
||||
```
|
||||
Basic subscription:
|
||||
```js
|
||||
var Orderbook = Remote.book(parameters);
|
||||
Orderbook.on('model', handler);
|
||||
|
||||
```
|
||||
|
||||
358
docs/api.html
Normal file
358
docs/api.html
Normal file
@@ -0,0 +1,358 @@
|
||||
<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>
|
||||
3
docs/samples/README
Normal file
3
docs/samples/README
Normal file
@@ -0,0 +1,3 @@
|
||||
Usage:
|
||||
babel-node balances.js
|
||||
babel-node payment.js (requires setting address and secret in source file first)
|
||||
12
docs/samples/balances.js
Normal file
12
docs/samples/balances.js
Normal file
@@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
const RippleAPI = require('../../src').RippleAPI; // require('ripple-lib')
|
||||
|
||||
const api = new RippleAPI({servers: ['wss://s1.ripple.com:443']});
|
||||
const address = 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV';
|
||||
|
||||
api.connect().then(() => {
|
||||
api.getBalances(address).then(balances => {
|
||||
console.log(JSON.stringify(balances, null, 2));
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
41
docs/samples/payment.js
Normal file
41
docs/samples/payment.js
Normal file
@@ -0,0 +1,41 @@
|
||||
'use strict';
|
||||
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 instructions = {maxLedgerVersionOffset: 5};
|
||||
|
||||
const payment = {
|
||||
source: {
|
||||
address: address,
|
||||
amount: {
|
||||
value: '0.01',
|
||||
currency: 'XRP'
|
||||
}
|
||||
},
|
||||
destination: {
|
||||
address: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc',
|
||||
amount: {
|
||||
value: '0.01',
|
||||
currency: 'XRP'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
api.connect().then(() => {
|
||||
console.log('Connected...');
|
||||
api.preparePayment(address, payment, instructions).then(txJSON => {
|
||||
console.log('Payment transaction prepared...');
|
||||
const signedTransaction = api.sign(txJSON, secret).signedTransaction;
|
||||
console.log('Payment transaction signed...');
|
||||
api.submit(signedTransaction).then(response => {
|
||||
console.log(response);
|
||||
process.exit(0);
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
process.exit(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
138
npm-shrinkwrap.json
generated
138
npm-shrinkwrap.json
generated
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "0.13.0-rc1",
|
||||
"version": "0.13.0-rc14",
|
||||
"npm-shrinkwrap-version": "5.4.0",
|
||||
"node-version": "v0.12.6",
|
||||
"node-version": "v0.12.7",
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz"
|
||||
},
|
||||
"babel-runtime": {
|
||||
"version": "5.8.3",
|
||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.3.tgz",
|
||||
"version": "5.8.25",
|
||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.25.tgz",
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "0.9.18",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-0.9.18.tgz"
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.1.4.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -22,21 +22,45 @@
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.0.7.tgz"
|
||||
},
|
||||
"bn.js": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-3.1.2.tgz"
|
||||
},
|
||||
"es6-promisify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-2.0.0.tgz",
|
||||
"dependencies": {
|
||||
"es6-promise": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-1.2.1.tgz"
|
||||
},
|
||||
"hash.js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz",
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
|
||||
"dependencies": {
|
||||
"agent-base": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.0.tgz",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz",
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz"
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -57,8 +81,8 @@
|
||||
}
|
||||
},
|
||||
"is-my-json-valid": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.12.0.tgz",
|
||||
"version": "2.12.2",
|
||||
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.12.2.tgz",
|
||||
"dependencies": {
|
||||
"generate-function": {
|
||||
"version": "2.0.0",
|
||||
@@ -75,8 +99,8 @@
|
||||
}
|
||||
},
|
||||
"jsonpointer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-1.1.0.tgz"
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-2.0.0.tgz"
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.0",
|
||||
@@ -85,40 +109,76 @@
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "3.10.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.0.tgz"
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz"
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.2.tgz"
|
||||
},
|
||||
"ripple-address-codec": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-2.0.1.tgz",
|
||||
"dependencies": {
|
||||
"x-address-codec": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/x-address-codec/-/x-address-codec-0.7.0.tgz",
|
||||
"dependencies": {
|
||||
"base-x": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/base-x/-/base-x-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ripple-keypairs": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-0.9.0.tgz",
|
||||
"dependencies": {
|
||||
"brorand": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.0.5.tgz"
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-5.1.0.tgz",
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ripple-address-codec": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-1.6.0.tgz",
|
||||
"dependencies": {
|
||||
"x-address-codec": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/x-address-codec/-/x-address-codec-0.6.0.tgz",
|
||||
"dependencies": {
|
||||
"base-x": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/base-x/-/base-x-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ripple-lib-transactionparser": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ripple-lib-transactionparser/-/ripple-lib-transactionparser-0.3.2.tgz",
|
||||
"dependencies": {
|
||||
"bignumber.js": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-1.4.1.tgz"
|
||||
}
|
||||
}
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/ripple-lib-transactionparser/-/ripple-lib-transactionparser-0.5.1.tgz"
|
||||
},
|
||||
"ripple-wallet-generator": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ripple-wallet-generator/-/ripple-wallet-generator-1.0.3.tgz"
|
||||
},
|
||||
"simple-asyncify": {
|
||||
"ripple-lib-value": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-asyncify/-/simple-asyncify-0.1.0.tgz"
|
||||
"resolved": "https://registry.npmjs.org/ripple-lib-value/-/ripple-lib-value-0.1.0.tgz"
|
||||
},
|
||||
"sjcl-extended": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "git://github.com/ripple/sjcl-extended.git#d8cf8b22e7d97193c54e1f65113e3edcf200ca17",
|
||||
"dependencies": {
|
||||
"sjcl": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.3.tgz"
|
||||
}
|
||||
}
|
||||
"sjcl-codec": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/sjcl-codec/-/sjcl-codec-0.1.0.tgz"
|
||||
},
|
||||
"ws": {
|
||||
"version": "0.7.2",
|
||||
|
||||
36
package.json
36
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "0.13.0-rc1",
|
||||
"version": "0.13.0-rc14",
|
||||
"license": "ISC",
|
||||
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
|
||||
"files": [
|
||||
@@ -18,33 +18,38 @@
|
||||
"async": "~0.9.0",
|
||||
"babel-runtime": "^5.5.4",
|
||||
"bignumber.js": "^2.0.3",
|
||||
"bn.js": "^3.1.1",
|
||||
"es6-promisify": "^2.0.0",
|
||||
"extend": "~1.2.1",
|
||||
"hash.js": "^1.0.3",
|
||||
"https-proxy-agent": "^1.0.0",
|
||||
"is-my-json-valid": "^2.12.0",
|
||||
"is-my-json-valid": "^2.12.2",
|
||||
"lodash": "^3.1.0",
|
||||
"lru-cache": "~2.5.0",
|
||||
"ripple-lib-transactionparser": "^0.3.2",
|
||||
"ripple-wallet-generator": "^1.0.3",
|
||||
"simple-asyncify": "^0.1.0",
|
||||
"sjcl-extended": "ripple/sjcl-extended#1.0.3",
|
||||
"ripple-address-codec": "^2.0.1",
|
||||
"ripple-keypairs": "^0.9.0",
|
||||
"ripple-lib-transactionparser": "^0.5.1",
|
||||
"ripple-lib-value": "0.1.0",
|
||||
"sjcl-codec": "0.1.0",
|
||||
"ws": "~0.7.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"assert-diff": "^1.0.1",
|
||||
"babel": "^5.5.4",
|
||||
"babel-core": "^5.5.4",
|
||||
"babel-eslint": "^3.1.23",
|
||||
"babel-loader": "^5.0.0",
|
||||
"babel": "^5.8.21",
|
||||
"babel-core": "^5.8.22",
|
||||
"babel-eslint": "^4.0.5",
|
||||
"babel-loader": "^5.3.2",
|
||||
"coveralls": "~2.10.0",
|
||||
"eslint": "^0.24.0",
|
||||
"eslint": "^1.3.0",
|
||||
"eslint-plugin-flowtype": "^1.0.0",
|
||||
"eventemitter2": "^0.4.14",
|
||||
"flow-bin": "^0.13.1",
|
||||
"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",
|
||||
"json-loader": "^0.5.2",
|
||||
"mocha": "~2.1.0",
|
||||
"webpack": "~1.5.3",
|
||||
"yargs": "~1.3.1"
|
||||
@@ -53,12 +58,13 @@
|
||||
"build": "gulp",
|
||||
"clean": "rm -rf dist/npm && rm -rf build/flow",
|
||||
"typecheck": "babel --optional runtime --blacklist flow -d build/flow/ src/ && flow check",
|
||||
"compile": "babel --optional runtime -d dist/npm/ src/ && cp -r src/api/common/schemas/ dist/npm/api/common/schemas/",
|
||||
"compile-with-source-maps": "babel --optional runtime -s -t -d dist/npm/ src/",
|
||||
"compile": "babel -D --optional runtime -d dist/npm/ src/",
|
||||
"watch": "babel -w -D --optional runtime -d dist/npm/ src/",
|
||||
"compile-with-source-maps": "babel -D --optional runtime -s -t -d dist/npm/ src/",
|
||||
"prepublish": "npm run clean && npm run compile",
|
||||
"test": "istanbul test _mocha",
|
||||
"coveralls": "cat ./coverage/lcov.info | coveralls",
|
||||
"lint": "if ! [ -f eslintrc ]; then curl -o eslintrc 'https://raw.githubusercontent.com/ripple/javascript-style-guide/es6/eslintrc'; echo 'plugins:\n - flowtype' >> eslintrc; fi; eslint --reset -c eslintrc src/",
|
||||
"lint": "if ! [ -f eslintrc ]; then curl -o eslintrc 'https://raw.githubusercontent.com/ripple/javascript-style-guide/es6/eslintrc'; echo 'parser: babel-eslint' >> eslintrc; fi; eslint -c eslintrc src/",
|
||||
"perf": "./scripts/perf_test.sh"
|
||||
},
|
||||
"repository": {
|
||||
|
||||
@@ -26,7 +26,7 @@ gulp bower
|
||||
exit_on_error
|
||||
|
||||
cd dist/bower
|
||||
version=$(cat bower.json | grep -Eo '([0-9]\.?)+(-rc[0-9])?')
|
||||
version=$(cat bower.json | grep -Eo '([0-9]\.?)+(-rc([0-9])+)?')
|
||||
echo "version: $version"
|
||||
git add ripple.js ripple-debug.js ripple-min.js bower.json
|
||||
exit_on_error
|
||||
@@ -40,4 +40,4 @@ exit_on_error
|
||||
git push origin master
|
||||
git push --tags origin master
|
||||
|
||||
cd ..
|
||||
cd ../..
|
||||
|
||||
@@ -26,7 +26,7 @@ gulp bower
|
||||
exit_on_error
|
||||
|
||||
cd dist/bower
|
||||
version=$(cat bower.json | grep -Eo '([0-9]\.?)+(-rc[0-9])?')
|
||||
version=$(cat bower.json | grep -Eo '([0-9]\.?)+(-rc([0-9])+)?')
|
||||
echo "version: $version"
|
||||
git add ripple.js ripple-debug.js ripple-min.js bower.json
|
||||
exit_on_error
|
||||
@@ -40,4 +40,4 @@ exit_on_error
|
||||
git push origin master
|
||||
git push --tags origin master
|
||||
|
||||
cd ..
|
||||
cd ../..
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var Amount = require('../dist/npm').Amount;
|
||||
var Ledger = require('../dist/npm').Ledger;
|
||||
var ripple = require('../dist/npm')._DEPRECATED;
|
||||
var Amount = ripple.Amount;
|
||||
var Ledger = ripple.Ledger;
|
||||
|
||||
function parse_options(from, flags) {
|
||||
var argv = from.slice(),
|
||||
opts_ = {argv: argv};
|
||||
var argv = from.slice();
|
||||
var opts_ = {argv: argv};
|
||||
|
||||
flags.forEach(function(f) {
|
||||
// Do we have the flag?
|
||||
|
||||
@@ -33,7 +33,7 @@ const AccountFields = {
|
||||
WalletSize: {name: 'walletSize', defaults: 0},
|
||||
MessageKey: {name: 'messageKey'},
|
||||
Domain: {name: 'domain', encoding: 'hex'},
|
||||
TransferRate: {name: 'transferRate', defaults: 0},
|
||||
TransferRate: {name: 'transferRate', defaults: 0, shift: 9},
|
||||
Signers: {name: 'signers'}
|
||||
};
|
||||
|
||||
|
||||
@@ -58,6 +58,13 @@ function MissingLedgerHistoryError(message) {
|
||||
MissingLedgerHistoryError.prototype = new RippleError();
|
||||
MissingLedgerHistoryError.prototype.name = 'MissingLedgerHistoryError';
|
||||
|
||||
function PendingLedgerVersionError(message) {
|
||||
this.message = message ||
|
||||
'maxLedgerVersion is greater than server\'s most recent validated ledger';
|
||||
}
|
||||
PendingLedgerVersionError.prototype = new RippleError();
|
||||
PendingLedgerVersionError.prototype.name = 'PendingLedgerVersionError';
|
||||
|
||||
/**
|
||||
* Request timed out
|
||||
*/
|
||||
@@ -77,13 +84,14 @@ ApiError.prototype = new RippleError();
|
||||
ApiError.prototype.name = 'ApiError';
|
||||
|
||||
module.exports = {
|
||||
ValidationError: ValidationError,
|
||||
NetworkError: NetworkError,
|
||||
TransactionError: TransactionError,
|
||||
RippledNetworkError: RippledNetworkError,
|
||||
NotFoundError: NotFoundError,
|
||||
MissingLedgerHistoryError: MissingLedgerHistoryError,
|
||||
TimeOutError: TimeOutError,
|
||||
ApiError: ApiError,
|
||||
RippleError: RippleError
|
||||
ValidationError,
|
||||
NetworkError,
|
||||
TransactionError,
|
||||
RippledNetworkError,
|
||||
NotFoundError,
|
||||
PendingLedgerVersionError,
|
||||
MissingLedgerHistoryError,
|
||||
TimeOutError,
|
||||
ApiError,
|
||||
RippleError
|
||||
};
|
||||
|
||||
@@ -9,7 +9,12 @@ module.exports = {
|
||||
dropsToXrp: utils.dropsToXrp,
|
||||
xrpToDrops: utils.xrpToDrops,
|
||||
toRippledAmount: utils.toRippledAmount,
|
||||
wrapCatch: utils.wrapCatch,
|
||||
generateAddress: utils.generateAddress,
|
||||
composeAsync: utils.composeAsync,
|
||||
convertExceptions: utils.convertExceptions
|
||||
wrapCatch: utils.wrapCatch,
|
||||
convertErrors: utils.convertErrors,
|
||||
convertExceptions: utils.convertExceptions,
|
||||
convertKeysFromSnakeCaseToCamelCase:
|
||||
utils.convertKeysFromSnakeCaseToCamelCase,
|
||||
promisify: utils.promisify
|
||||
};
|
||||
|
||||
@@ -1,36 +1,84 @@
|
||||
// flow is disabled for this file until support for requiring json is added:
|
||||
// https://github.com/facebook/flow/issues/167
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const assert = require('assert');
|
||||
const validator = require('is-my-json-valid');
|
||||
const core = require('./utils').core;
|
||||
const ValidationError = require('./errors').ValidationError;
|
||||
const {isValidAddress} = require('ripple-address-codec');
|
||||
|
||||
let SCHEMAS = {};
|
||||
|
||||
function isValidAddress(address) {
|
||||
return core.UInt160.is_valid(address);
|
||||
}
|
||||
|
||||
function isValidLedgerHash(ledgerHash) {
|
||||
return core.UInt256.is_valid(ledgerHash);
|
||||
}
|
||||
|
||||
function loadSchema(filepath) {
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(filepath, 'utf8'));
|
||||
} catch (e) {
|
||||
throw new Error('Failed to parse schema: ' + filepath);
|
||||
}
|
||||
}
|
||||
|
||||
function endsWith(str, suffix) {
|
||||
return str.indexOf(suffix, str.length - suffix.length) !== -1;
|
||||
}
|
||||
|
||||
function loadSchemas(dir) {
|
||||
const filenames = fs.readdirSync(dir).filter(name => endsWith(name, '.json'));
|
||||
const schemas = filenames.map(name => loadSchema(path.join(dir, name)));
|
||||
function loadSchemas() {
|
||||
// listed explicitly for webpack (instead of scanning schemas directory)
|
||||
const schemas = [
|
||||
require('./schemas/address.json'),
|
||||
require('./schemas/adjustment.json'),
|
||||
require('./schemas/amount.json'),
|
||||
require('./schemas/amountbase.json'),
|
||||
require('./schemas/balance.json'),
|
||||
require('./schemas/blob.json'),
|
||||
require('./schemas/currency.json'),
|
||||
require('./schemas/get-account-info.json'),
|
||||
require('./schemas/get-balances.json'),
|
||||
require('./schemas/get-balance-sheet'),
|
||||
require('./schemas/balance-sheet-options.json'),
|
||||
require('./schemas/get-ledger.json'),
|
||||
require('./schemas/get-orderbook.json'),
|
||||
require('./schemas/get-orders.json'),
|
||||
require('./schemas/get-paths.json'),
|
||||
require('./schemas/get-server-info.json'),
|
||||
require('./schemas/get-settings.json'),
|
||||
require('./schemas/get-transaction.json'),
|
||||
require('./schemas/get-transactions.json'),
|
||||
require('./schemas/get-trustlines.json'),
|
||||
require('./schemas/hash128.json'),
|
||||
require('./schemas/hash256.json'),
|
||||
require('./schemas/instructions.json'),
|
||||
require('./schemas/issue.json'),
|
||||
require('./schemas/ledger-options.json'),
|
||||
require('./schemas/ledgerversion.json'),
|
||||
require('./schemas/max-adjustment.json'),
|
||||
require('./schemas/memo.json'),
|
||||
require('./schemas/order-cancellation-transaction.json'),
|
||||
require('./schemas/order-cancellation.json'),
|
||||
require('./schemas/order-change.json'),
|
||||
require('./schemas/order-transaction.json'),
|
||||
require('./schemas/order.json'),
|
||||
require('./schemas/orderbook-orders.json'),
|
||||
require('./schemas/orderbook.json'),
|
||||
require('./schemas/orders-options.json'),
|
||||
require('./schemas/outcome.json'),
|
||||
require('./schemas/pathfind.json'),
|
||||
require('./schemas/payment-transaction.json'),
|
||||
require('./schemas/payment.json'),
|
||||
require('./schemas/quality.json'),
|
||||
require('./schemas/remote-options.json'),
|
||||
require('./schemas/sequence.json'),
|
||||
require('./schemas/settings-options.json'),
|
||||
require('./schemas/settings-transaction.json'),
|
||||
require('./schemas/settings.json'),
|
||||
require('./schemas/sign.json'),
|
||||
require('./schemas/signed-value.json'),
|
||||
require('./schemas/submit.json'),
|
||||
require('./schemas/suspended-payment-cancellation.json'),
|
||||
require('./schemas/suspended-payment-execution.json'),
|
||||
require('./schemas/suspended-payment-creation.json'),
|
||||
require('./schemas/timestamp.json'),
|
||||
require('./schemas/transaction-options.json'),
|
||||
require('./schemas/transactions-options.json'),
|
||||
require('./schemas/trustline-transaction.json'),
|
||||
require('./schemas/trustline.json'),
|
||||
require('./schemas/trustlines-options.json'),
|
||||
require('./schemas/tx.json'),
|
||||
require('./schemas/uint32.json'),
|
||||
require('./schemas/value.json'),
|
||||
require('./schemas/prepare.json'),
|
||||
require('./schemas/ledger-closed.json')
|
||||
];
|
||||
const titles = _.map(schemas, schema => schema.title);
|
||||
const duplicates = _.keys(_.pick(_.countBy(titles), count => count > 1));
|
||||
assert(duplicates.length === 0, 'Duplicate schemas for: ' + duplicates);
|
||||
return _.indexBy(schemas, 'title');
|
||||
}
|
||||
|
||||
@@ -43,9 +91,8 @@ function formatSchemaErrors(errors) {
|
||||
return errors.map(formatSchemaError).join(', ');
|
||||
}
|
||||
|
||||
function schemaValidate(schemaName, object) {
|
||||
const formats = {address: isValidAddress,
|
||||
ledgerHash: isValidLedgerHash};
|
||||
function schemaValidate(schemaName: string, object: any): void {
|
||||
const formats = {address: isValidAddress};
|
||||
const options = {schemas: SCHEMAS, formats: formats,
|
||||
verbose: true, greedy: true};
|
||||
const schema = SCHEMAS[schemaName];
|
||||
@@ -59,5 +106,8 @@ function schemaValidate(schemaName, object) {
|
||||
}
|
||||
}
|
||||
|
||||
SCHEMAS = loadSchemas(path.join(__dirname, './schemas'));
|
||||
module.exports = schemaValidate;
|
||||
SCHEMAS = loadSchemas();
|
||||
module.exports = {
|
||||
schemaValidate: schemaValidate,
|
||||
SCHEMAS: SCHEMAS
|
||||
};
|
||||
|
||||
@@ -5,10 +5,7 @@
|
||||
"properties": {
|
||||
"address": {"$ref": "address"},
|
||||
"amount": {"$ref": "amount"},
|
||||
"tag": {
|
||||
"description": "A string representing an unsigned 32-bit integer most commonly used to refer to a sender's hosted account at a Ripple gateway",
|
||||
"$ref": "uint32"
|
||||
}
|
||||
"tag": {"$ref": "tag"}
|
||||
},
|
||||
"required": ["address", "amount"],
|
||||
"additionalProperties": false
|
||||
|
||||
15
src/api/common/schemas/balance-sheet-options.json
Normal file
15
src/api/common/schemas/balance-sheet-options.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "balance-sheet-options",
|
||||
"description": "Options for getBalanceSheet",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"excludeAddresses": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "address"},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"ledgerVersion": {"$ref": "ledgerVersion"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
44
src/api/common/schemas/balance.json
Normal file
44
src/api/common/schemas/balance.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "balance",
|
||||
"description": "Balance amount",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"value": {
|
||||
"description": "The balance on the trustline",
|
||||
"$ref": "signedValue"
|
||||
},
|
||||
"currency": {
|
||||
"description": "The three-character code or hex string used to denote currencies",
|
||||
"$ref": "currency"
|
||||
},
|
||||
"counterparty": {
|
||||
"description": "The Ripple account address of the currency's issuer or gateway",
|
||||
"$ref": "address"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["currency", "value"],
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"currency": {
|
||||
"not": {
|
||||
"enum": ["XRP"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["counterparty"]
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"currency": {
|
||||
"enum": ["XRP"]
|
||||
}
|
||||
},
|
||||
"not": {
|
||||
"required": ["counterparty"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
9
src/api/common/schemas/destinationAdjustment.json
Normal file
9
src/api/common/schemas/destinationAdjustment.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "destinationAdjustment",
|
||||
"type": "object",
|
||||
"oneOf": [
|
||||
{"$ref": "adjustment"},
|
||||
{"$ref": "minAdjustment"}
|
||||
]
|
||||
}
|
||||
21
src/api/common/schemas/get-account-info.json
Normal file
21
src/api/common/schemas/get-account-info.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getAccountInfo",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"sequence": {"$ref": "sequence"},
|
||||
"xrpBalance": {"$ref": "value"},
|
||||
"ownerCount": {"type": "integer", "minimum": 0},
|
||||
"previousInitiatedTransactionID": {"$ref": "hash256"},
|
||||
"previousAffectingTransactionID": {"$ref": "hash256"},
|
||||
"previousAffectingTransactionLedgerVersion": {"$ref": "ledgerVersion"}
|
||||
},
|
||||
"required": [
|
||||
"sequence",
|
||||
"xrpBalance",
|
||||
"ownerCount",
|
||||
"previousAffectingTransactionID",
|
||||
"previousAffectingTransactionLedgerVersion"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
29
src/api/common/schemas/get-balance-sheet.json
Normal file
29
src/api/common/schemas/get-balance-sheet.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getBalanceSheet",
|
||||
"description": "getBalanceSheet response",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"balances": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "amount"}
|
||||
},
|
||||
"assets": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "amount"}
|
||||
},
|
||||
"obligations": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["currency", "value"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"currency": {"$ref": "currency"},
|
||||
"value": {"$ref": "value"}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
6
src/api/common/schemas/get-balances.json
Normal file
6
src/api/common/schemas/get-balances.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getBalances",
|
||||
"type": "array",
|
||||
"items": {"$ref": "balance"}
|
||||
}
|
||||
39
src/api/common/schemas/get-ledger.json
Normal file
39
src/api/common/schemas/get-ledger.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getLedger",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"accepted": {"type": "boolean"},
|
||||
"closed": {"type": "boolean"},
|
||||
"stateHash": {"$ref": "hash256"},
|
||||
"closeTime": {"type": "integer", "minimum": 0},
|
||||
"closeTimeResolution": {"type": "integer", "minimum": 1},
|
||||
"closeFlags": {"type": "integer", "minimum": 0},
|
||||
"ledgerHash": {"$ref": "hash256"},
|
||||
"ledgerVersion": {"$ref": "ledgerVersion"},
|
||||
"parentLedgerHash": {"$ref": "hash256"},
|
||||
"parentCloseTime": {"type": "integer", "minimum": 0},
|
||||
"totalDrops": {"$ref": "value"},
|
||||
"transactionHash": {"$ref": "hash256"},
|
||||
"transactions": {"type": "array", "items": {"type": "object"}},
|
||||
"rawTransactions": {"type": "string"},
|
||||
"transactionHashes": {"type": "array", "items": {"$ref": "hash256"}},
|
||||
"rawState": {"type": "string"},
|
||||
"stateHashes": {"type": "array", "items": {"$ref": "hash256"}}
|
||||
},
|
||||
"required": [
|
||||
"accepted",
|
||||
"closed",
|
||||
"stateHash",
|
||||
"closeTime",
|
||||
"closeTimeResolution",
|
||||
"closeFlags",
|
||||
"ledgerHash",
|
||||
"ledgerVersion",
|
||||
"parentLedgerHash",
|
||||
"parentCloseTime",
|
||||
"totalDrops",
|
||||
"transactionHash"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
11
src/api/common/schemas/get-orderbook.json
Normal file
11
src/api/common/schemas/get-orderbook.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getOrderbook",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bids": {"$ref": "orderbookOrders"},
|
||||
"asks": {"$ref": "orderbookOrders"}
|
||||
},
|
||||
"required": ["bids", "asks"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
23
src/api/common/schemas/get-orders.json
Normal file
23
src/api/common/schemas/get-orders.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getOrders",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"specification": {"$ref": "order"},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maker": {"$ref": "address"},
|
||||
"sequence": {"$ref": "sequence"},
|
||||
"makerExchangeRate": {"$ref": "value"}
|
||||
},
|
||||
"required": ["maker", "sequence", "makerExchangeRate"],
|
||||
"addtionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": ["specification", "properties"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
15
src/api/common/schemas/get-paths.json
Normal file
15
src/api/common/schemas/get-paths.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getPaths",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"source": {"$ref": "sourceAdjustment"},
|
||||
"destination": {"$ref": "destinationAdjustment"},
|
||||
"paths": {"type": "string"}
|
||||
},
|
||||
"required": ["source", "destination", "paths"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
49
src/api/common/schemas/get-server-info.json
Normal file
49
src/api/common/schemas/get-server-info.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getServerInfo",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"buildVersion": {"type": "string"},
|
||||
"completeLedgers": {"type": "string", "pattern": "[0-9,-]+"},
|
||||
"hostid": {"type": "string"},
|
||||
"ioLatencyMs": {"type": "number"},
|
||||
"load": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"jobTypes": {
|
||||
"type": "array",
|
||||
"items": {"type": "object"}
|
||||
},
|
||||
"threads": {"type": "number"}
|
||||
}
|
||||
},
|
||||
"lastClose": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"convergeTimeS": {"type": "number"},
|
||||
"proposers": {"type": "integer", "minimum": 0}
|
||||
}
|
||||
},
|
||||
"loadFactor": {"type": "number"},
|
||||
"peers": {"type": "integer", "minimum": 0},
|
||||
"pubkeyNode": {"type": "string"},
|
||||
"pubkeyValidator": {"type": "string"},
|
||||
"serverState": {
|
||||
"type": "string",
|
||||
"enum": ["disconnected", "connected", "syncing", "tracking", "full", "validating", "proposing"]
|
||||
},
|
||||
"validatedLedger": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"age": {"type": "integer", "minimum": 0},
|
||||
"baseFeeXrp": {"type": "number"},
|
||||
"hash": {"$ref": "hash256"},
|
||||
"reserveBaseXrp": {"type": "integer", "minimum": 0},
|
||||
"reserveIncXrp": {"type": "integer", "minimum": 0},
|
||||
"seq": {"type": "integer", "minimum": 0}
|
||||
}
|
||||
},
|
||||
"validationQuorum": {"type": "number"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
40
src/api/common/schemas/get-settings.json
Normal file
40
src/api/common/schemas/get-settings.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getSettings",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"passwordSpent": {"type": "boolean"},
|
||||
"requireDestinationTag": {"type": "boolean"},
|
||||
"requireAuthorization": {"type": "boolean"},
|
||||
"disallowIncomingXRP": {"type": "boolean"},
|
||||
"disableMasterKey": {"type": "boolean"},
|
||||
"enableTransactionIDTracking": {"type": "boolean"},
|
||||
"noFreeze": {"type": "boolean"},
|
||||
"globalFreeze": {"type": "boolean"},
|
||||
"defaultRipple": {"type": "boolean"},
|
||||
"emailHash": {
|
||||
"oneOf": [
|
||||
{"type": "null"},
|
||||
{"$ref": "hash128"}
|
||||
]
|
||||
},
|
||||
"walletLocator": {
|
||||
"oneOf": [
|
||||
{"type": "null"},
|
||||
{"$ref": "hash256"}
|
||||
]
|
||||
},
|
||||
"walletSize": {"type": ["integer", "null"]},
|
||||
"messageKey": {"type": "string"},
|
||||
"domain": {"type": "string"},
|
||||
"transferRate": {
|
||||
"oneOf": [
|
||||
{"type": "null"},
|
||||
{"type": "number", "minimum": 1, "maximum": 4.294967295}
|
||||
]
|
||||
},
|
||||
"signers": {"type": "string"},
|
||||
"regularKey": {"$ref": "address"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
11
src/api/common/schemas/get-transaction.json
Normal file
11
src/api/common/schemas/get-transaction.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getTransaction",
|
||||
"oneOf": [
|
||||
{"$ref": "paymentTransaction"},
|
||||
{"$ref": "orderTransaction"},
|
||||
{"$ref": "orderCancellationTransaction"},
|
||||
{"$ref": "trustlineTransaction"},
|
||||
{"$ref": "settingsTransaction"}
|
||||
]
|
||||
}
|
||||
6
src/api/common/schemas/get-transactions.json
Normal file
6
src/api/common/schemas/get-transactions.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getTransactions",
|
||||
"type": "array",
|
||||
"items": {"$ref": "getTransaction"}
|
||||
}
|
||||
29
src/api/common/schemas/get-trustlines.json
Normal file
29
src/api/common/schemas/get-trustlines.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "getTrustlines",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"properties": {
|
||||
"specification": {"$ref": "trustline"},
|
||||
"counterparty": {
|
||||
"properties": {
|
||||
"limit": {"$ref": "value"},
|
||||
"ripplingDisabled": {"type": "boolean"},
|
||||
"frozen": {"type": "boolean"},
|
||||
"authorized": {"type": "boolean"}
|
||||
},
|
||||
"required": ["limit"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"state": {
|
||||
"properties": {
|
||||
"balance": {"$ref": "value"}
|
||||
},
|
||||
"required": ["balance"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": ["specification", "counterparty", "state"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
13
src/api/common/schemas/lax-amount.json
Normal file
13
src/api/common/schemas/lax-amount.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "laxAmount",
|
||||
"description": "Amount where counterparty is optional",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"currency": {"$ref": "currency"},
|
||||
"counterparty": {"$ref": "address"},
|
||||
"value": {"$ref": "value"}
|
||||
},
|
||||
"required": ["currency", "value"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
13
src/api/common/schemas/lax-lax-amount.json
Normal file
13
src/api/common/schemas/lax-lax-amount.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "laxLaxAmount",
|
||||
"description": "Amount where counterparty and value are optional",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"currency": {"$ref": "currency"},
|
||||
"counterparty": {"$ref": "address"},
|
||||
"value": {"$ref": "value"}
|
||||
},
|
||||
"required": ["currency"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
21
src/api/common/schemas/ledger-closed.json
Normal file
21
src/api/common/schemas/ledger-closed.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$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": "ledgerHash"},
|
||||
"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"]
|
||||
}
|
||||
13
src/api/common/schemas/ledger-options.json
Normal file
13
src/api/common/schemas/ledger-options.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "ledger-options",
|
||||
"description": "Options for getLedger",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ledgerVersion": {"$ref": "ledgerVersion"},
|
||||
"includeAllData": {"type": "boolean"},
|
||||
"includeTransactions": {"type": "boolean"},
|
||||
"includeState": {"type": "boolean"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
12
src/api/common/schemas/max-adjustment.json
Normal file
12
src/api/common/schemas/max-adjustment.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "maxAdjustment",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {"$ref": "address"},
|
||||
"maxAmount": {"$ref": "laxAmount"},
|
||||
"tag": {"$ref": "tag"}
|
||||
},
|
||||
"required": ["address", "maxAmount"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
12
src/api/common/schemas/min-adjustment.json
Normal file
12
src/api/common/schemas/min-adjustment.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "minAdjustment",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {"$ref": "address"},
|
||||
"minAmount": {"$ref": "laxAmount"},
|
||||
"tag": {"$ref": "tag"}
|
||||
},
|
||||
"required": ["address", "minAmount"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
15
src/api/common/schemas/order-cancellation-transaction.json
Normal file
15
src/api/common/schemas/order-cancellation-transaction.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "orderCancellationTransaction",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {"enum": ["orderCancellation"]},
|
||||
"specification": {"$ref": "orderCancellation"},
|
||||
"outcome": {"$ref": "outcome"},
|
||||
"id": {"$ref": "hash256"},
|
||||
"address": {"$ref": "address"},
|
||||
"sequence": {"$ref": "sequence"}
|
||||
},
|
||||
"required": ["type", "id", "address", "sequence", "specification", "outcome"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "cancellation",
|
||||
"title": "orderCancellation",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"orderSequence": {"$ref": "sequence"}
|
||||
18
src/api/common/schemas/order-change.json
Normal file
18
src/api/common/schemas/order-change.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "orderChange",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"direction": {
|
||||
"type": "string",
|
||||
"enum": ["buy", "sell"]
|
||||
},
|
||||
"quantity": {"$ref": "balance"},
|
||||
"totalPrice": {"$ref": "balance"},
|
||||
"makerExchangeRate": {"$ref": "value"},
|
||||
"sequence": {"$ref": "sequence"},
|
||||
"status": {"enum": ["created", "open", "closed", "canceled"]}
|
||||
},
|
||||
"required": ["direction", "quantity", "totalPrice", "sequence", "status"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
15
src/api/common/schemas/order-transaction.json
Normal file
15
src/api/common/schemas/order-transaction.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "orderTransaction",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {"enum": ["order"]},
|
||||
"specification": {"$ref": "order"},
|
||||
"outcome": {"$ref": "outcome"},
|
||||
"id": {"$ref": "hash256"},
|
||||
"address": {"$ref": "address"},
|
||||
"sequence": {"$ref": "sequence"}
|
||||
},
|
||||
"required": ["type", "id", "address", "sequence", "specification", "outcome"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
32
src/api/common/schemas/orderbook-orders.json
Normal file
32
src/api/common/schemas/orderbook-orders.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "orderbookOrders",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"specification": {"$ref": "order"},
|
||||
"properties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maker": {"$ref": "address"},
|
||||
"sequence": {"$ref": "sequence"},
|
||||
"makerExchangeRate": {"$ref": "value"}
|
||||
},
|
||||
"required": ["maker", "sequence", "makerExchangeRate"],
|
||||
"addtionalProperties": false
|
||||
},
|
||||
"state": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fundedAmount": {"$ref": "amount"},
|
||||
"priceOfFundedAmount": {"$ref": "amount"}
|
||||
},
|
||||
"required": ["fundedAmount", "priceOfFundedAmount"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": ["specification", "properties"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
31
src/api/common/schemas/outcome.json
Normal file
31
src/api/common/schemas/outcome.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "outcome",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"result": {"type": "string"},
|
||||
"timestamp": {"type": "string", "format": "date-time"},
|
||||
"fee": {"$ref": "value"},
|
||||
"balanceChanges": {
|
||||
"type": "object",
|
||||
"description": "Key is the ripple address; value is an array of changes",
|
||||
"additionalProperties": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "balance"}
|
||||
}
|
||||
},
|
||||
"orderbookChanges": {
|
||||
"type": "object",
|
||||
"description": "Key is the maker's ripple address; value is an array of changes",
|
||||
"additionalProperties": {
|
||||
"type": "array",
|
||||
"items": {"$ref": "orderChange"}
|
||||
}
|
||||
},
|
||||
"ledgerVersion": {"$ref": "ledgerVersion"},
|
||||
"indexInLedger": {"type": "integer", "minimum": 0}
|
||||
},
|
||||
"required": ["result", "fee", "balanceChanges",
|
||||
"orderbookChanges", "ledgerVersion", "indexInLedger"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {"$ref": "address"},
|
||||
"amount": {"$ref": "laxAmount"},
|
||||
"currencies": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@@ -19,12 +20,23 @@
|
||||
"additionalProperties": false
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"not": {
|
||||
"required": ["amount", "currencies"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["address"]
|
||||
},
|
||||
"destination": {"$ref": "adjustment"}
|
||||
"destination": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {"$ref": "address"},
|
||||
"amount": {"$ref": "laxLaxAmount"}
|
||||
},
|
||||
"required": ["address", "amount"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": ["source", "destination"],
|
||||
"additionalProperties": false
|
||||
|
||||
15
src/api/common/schemas/payment-transaction.json
Normal file
15
src/api/common/schemas/payment-transaction.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "paymentTransaction",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {"enum": ["payment"]},
|
||||
"specification": {"$ref": "payment"},
|
||||
"outcome": {"$ref": "outcome"},
|
||||
"id": {"$ref": "hash256"},
|
||||
"address": {"$ref": "address"},
|
||||
"sequence": {"$ref": "sequence"}
|
||||
},
|
||||
"required": ["type", "id", "address", "sequence", "specification", "outcome"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -3,13 +3,9 @@
|
||||
"title": "payment",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"source": {"$ref": "adjustment"},
|
||||
"destination": {"$ref": "adjustment"},
|
||||
"source": {"$ref": "sourceAdjustment"},
|
||||
"destination": {"$ref": "destinationAdjustment"},
|
||||
"paths": {"type": "string"},
|
||||
"slippage": {
|
||||
"description": "An optional cushion for the source_amount to increase the likelihood that the payment will succeed. The source_account will never be charged more than source_amount.value + source_slippage",
|
||||
"$ref": "value"
|
||||
},
|
||||
"memos": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
||||
21
src/api/common/schemas/prepare.json
Normal file
21
src/api/common/schemas/prepare.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "prepare",
|
||||
"description": "Result of prepare function",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"txJSON": {"type": "string"},
|
||||
"instructions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fee": {"$ref": "value"},
|
||||
"sequence": {"$ref": "sequence"},
|
||||
"maxLedgerVersion": {"$ref": "ledgerVersion"}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["fee", "sequence"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["txJSON", "instructions"]
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "quality",
|
||||
"description": "Ratio for incoming/outgoing transit fees represented in billionths. (For example, a value of 500 million represents a 0.5:1 ratio.) As a special case, 0 is treated as a 1:1 ratio.",
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 1000000000
|
||||
"description": "Ratio for incoming/outgoing transit fees.",
|
||||
"type": "number",
|
||||
"minimum": 0.000000001,
|
||||
"maximum": 4.294967295
|
||||
}
|
||||
|
||||
17
src/api/common/schemas/remote-options.json
Normal file
17
src/api/common/schemas/remote-options.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "remote-options",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"trace": {"type": "boolean"},
|
||||
"servers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"pattern": "^wss?://"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
15
src/api/common/schemas/settings-transaction.json
Normal file
15
src/api/common/schemas/settings-transaction.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "settingsTransaction",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {"enum": ["settings"]},
|
||||
"specification": {"$ref": "getSettings"},
|
||||
"outcome": {"$ref": "outcome"},
|
||||
"id": {"$ref": "hash256"},
|
||||
"address": {"$ref": "address"},
|
||||
"sequence": {"$ref": "sequence"}
|
||||
},
|
||||
"required": ["type", "id", "address", "sequence", "specification"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -1,27 +1,13 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "settings",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"passwordSpent": {"type": "boolean"},
|
||||
"requireDestinationTag": {"type": "boolean"},
|
||||
"requireAuthorization": {"type": "boolean"},
|
||||
"disallowIncomingXRP": {"type": "boolean"},
|
||||
"disableMasterKey": {"type": "boolean"},
|
||||
"enableTransactionIDTracking": {"type": "boolean"},
|
||||
"noFreeze": {"type": "boolean"},
|
||||
"globalFreeze": {"type": "boolean"},
|
||||
"defaultRipple": {"type": "boolean"},
|
||||
"emailHash": {"$ref": "hash128"},
|
||||
"walletLocator": {"$ref": "hash256"},
|
||||
"walletSize": {"type": "integer"},
|
||||
"messageKey": {"type": "string"},
|
||||
"domain": {"type": "string"},
|
||||
"transferRate": {"type": "integer"},
|
||||
"signers": {"type": "string"},
|
||||
"regularKey": {"$ref": "address"}
|
||||
},
|
||||
"minProperties": 1,
|
||||
"maxProperties": 1,
|
||||
"additionalProperties": false
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "getSettings"
|
||||
},
|
||||
{
|
||||
"minProperties": 1,
|
||||
"maxProperties": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
14
src/api/common/schemas/sign.json
Normal file
14
src/api/common/schemas/sign.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "sign",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"signedTransaction": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-F0-9]+$"
|
||||
},
|
||||
"id": {"$ref": "hash256"}
|
||||
},
|
||||
"required": ["signedTransaction", "id"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
7
src/api/common/schemas/signed-value.json
Normal file
7
src/api/common/schemas/signed-value.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "signedValue",
|
||||
"description": "A string representation of a floating point number",
|
||||
"type": "string",
|
||||
"pattern": "^[-]?[0-9]*[.]?[0-9]+([eE][-+]?[0-9]+)?$"
|
||||
}
|
||||
9
src/api/common/schemas/sourceAdjustment.json
Normal file
9
src/api/common/schemas/sourceAdjustment.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "sourceAdjustment",
|
||||
"type": "object",
|
||||
"oneOf": [
|
||||
{"$ref": "adjustment"},
|
||||
{"$ref": "maxAdjustment"}
|
||||
]
|
||||
}
|
||||
15
src/api/common/schemas/submit.json
Normal file
15
src/api/common/schemas/submit.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "submit",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": {"type": "boolean"},
|
||||
"engineResult": {"type": "string"},
|
||||
"engineResultCode": {"type": "integer"},
|
||||
"engineResultMessage": {"type": "string"},
|
||||
"txBlob": {"type": "string"},
|
||||
"txJson": {"type": "object"}
|
||||
},
|
||||
"required": ["success", "engineResult", "engineResultCode"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
17
src/api/common/schemas/suspended-payment-cancellation.json
Normal file
17
src/api/common/schemas/suspended-payment-cancellation.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "suspended-payment-cancellation",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"memos": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "memo"
|
||||
}
|
||||
},
|
||||
"owner": {"$ref": "address"},
|
||||
"paymentSequence": {"$ref": "uint32"}
|
||||
},
|
||||
"required": ["owner", "paymentSequence"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
28
src/api/common/schemas/suspended-payment-creation.json
Normal file
28
src/api/common/schemas/suspended-payment-creation.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "suspended-payment-creation",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"source": {"$ref": "maxAdjustment"},
|
||||
"destination": {"$ref": "adjustment"},
|
||||
"memos": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "memo"
|
||||
}
|
||||
},
|
||||
"digest": {"$ref": "hash256"},
|
||||
"allowCancelAfter": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "milliseconds since unix epoch"
|
||||
},
|
||||
"allowExecuteAfter": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "milliseconds since unix epoch"
|
||||
}
|
||||
},
|
||||
"required": ["source", "destination"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
20
src/api/common/schemas/suspended-payment-execution.json
Normal file
20
src/api/common/schemas/suspended-payment-execution.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "suspended-payment-execution",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"memos": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "memo"
|
||||
}
|
||||
},
|
||||
"owner": {"$ref": "address"},
|
||||
"paymentSequence": {"$ref": "uint32"},
|
||||
"method": {"type": "integer", "minimum": 0, "maximum": 255},
|
||||
"digest": {"$ref": "hash256"},
|
||||
"proof": {"type": "string"}
|
||||
},
|
||||
"required": ["owner", "paymentSequence"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
6
src/api/common/schemas/tag.json
Normal file
6
src/api/common/schemas/tag.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "tag",
|
||||
"description": "A string representing an unsigned 32-bit integer most commonly used to refer to a sender's hosted account at a Ripple gateway",
|
||||
"$ref": "uint32"
|
||||
}
|
||||
15
src/api/common/schemas/trustline-transaction.json
Normal file
15
src/api/common/schemas/trustline-transaction.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "trustlineTransaction",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {"enum": ["trustline"]},
|
||||
"specification": {"$ref": "trustline"},
|
||||
"outcome": {"$ref": "outcome"},
|
||||
"id": {"$ref": "hash256"},
|
||||
"address": {"$ref": "address"},
|
||||
"sequence": {"$ref": "sequence"}
|
||||
},
|
||||
"required": ["type", "id", "address", "sequence", "specification", "outcome"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
"limit": {"$ref": "value"},
|
||||
"qualityIn": {"$ref": "quality"},
|
||||
"qualityOut": {"$ref": "quality"},
|
||||
"allowRippling": {"type": "boolean"},
|
||||
"ripplingDisabled": {"type": "boolean"},
|
||||
"authorized": {"type": "boolean"},
|
||||
"frozen": {"type": "boolean"}
|
||||
},
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const BigNumber = require('bignumber.js');
|
||||
const core = require('../../core');
|
||||
const errors = require('./errors');
|
||||
const es6promisify = require('es6-promisify');
|
||||
const keypairs = require('ripple-keypairs');
|
||||
|
||||
function dropsToXrp(drops) {
|
||||
type Amount = {currency: string, issuer: string, value: string}
|
||||
|
||||
function dropsToXrp(drops: string): string {
|
||||
return (new BigNumber(drops)).dividedBy(1000000.0).toString();
|
||||
}
|
||||
|
||||
function xrpToDrops(xrp) {
|
||||
function xrpToDrops(xrp: string): string {
|
||||
return (new BigNumber(xrp)).times(1000000.0).floor().toString();
|
||||
}
|
||||
|
||||
function toRippledAmount(amount) {
|
||||
function toRippledAmount(amount: Amount): string|Amount {
|
||||
if (amount.currency === 'XRP') {
|
||||
return xrpToDrops(amount.value);
|
||||
}
|
||||
@@ -22,7 +28,16 @@ function toRippledAmount(amount) {
|
||||
};
|
||||
}
|
||||
|
||||
function wrapCatch(asyncFunction: () => void): () => void {
|
||||
function generateAddress(options?: Object): Object {
|
||||
const secret = keypairs.generateSeed(options);
|
||||
const keypair = keypairs.deriveKeypair(secret);
|
||||
const address = keypairs.deriveAddress(keypair.publicKey);
|
||||
return {secret, address};
|
||||
}
|
||||
|
||||
type AsyncFunction = (...x: any) => void
|
||||
|
||||
function wrapCatch(asyncFunction: AsyncFunction): AsyncFunction {
|
||||
return function() {
|
||||
try {
|
||||
asyncFunction.apply(this, arguments);
|
||||
@@ -33,10 +48,13 @@ function wrapCatch(asyncFunction: () => void): () => void {
|
||||
};
|
||||
}
|
||||
|
||||
function composeAsync(wrapper, callback) {
|
||||
type Callback = (err: any, data: any) => void
|
||||
type Wrapper = (data: any) => any
|
||||
|
||||
function composeAsync(wrapper: Wrapper, callback: Callback): Callback {
|
||||
return function(error, data) {
|
||||
if (error) {
|
||||
callback(error);
|
||||
callback(error, data);
|
||||
return;
|
||||
}
|
||||
let result;
|
||||
@@ -50,7 +68,23 @@ function composeAsync(wrapper, callback) {
|
||||
};
|
||||
}
|
||||
|
||||
function convertExceptions(f) {
|
||||
function convertErrors(callback: Callback): () => void {
|
||||
return function(error, data) {
|
||||
if (error && !(error instanceof errors.RippleError)) {
|
||||
const message = _.get(error, ['remote', 'error_message'], error.message);
|
||||
const error_ = new errors.RippleError(message);
|
||||
error_.data = data;
|
||||
callback(error_, data);
|
||||
} else if (error) {
|
||||
error.data = data;
|
||||
callback(error, data);
|
||||
} else {
|
||||
callback(error, data);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function convertExceptions<T>(f: () => T): () => T {
|
||||
return function() {
|
||||
try {
|
||||
return f.apply(this, arguments);
|
||||
@@ -60,12 +94,36 @@ function convertExceptions(f) {
|
||||
};
|
||||
}
|
||||
|
||||
const FINDSNAKE = /([a-zA-Z]_[a-zA-Z])/g;
|
||||
function convertKeysFromSnakeCaseToCamelCase(obj: any): any {
|
||||
if (typeof obj === 'object') {
|
||||
let newKey;
|
||||
return _.reduce(obj, (result, value, key) => {
|
||||
newKey = key;
|
||||
if (FINDSNAKE.test(key)) {
|
||||
newKey = key.replace(FINDSNAKE, r => r[0] + r[2].toUpperCase());
|
||||
}
|
||||
result[newKey] = convertKeysFromSnakeCaseToCamelCase(value);
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function promisify(asyncFunction: AsyncFunction): Function {
|
||||
return es6promisify(wrapCatch(asyncFunction));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
core,
|
||||
dropsToXrp,
|
||||
xrpToDrops,
|
||||
toRippledAmount,
|
||||
wrapCatch,
|
||||
generateAddress,
|
||||
composeAsync,
|
||||
convertExceptions
|
||||
wrapCatch,
|
||||
convertExceptions,
|
||||
convertErrors,
|
||||
convertKeysFromSnakeCaseToCamelCase,
|
||||
promisify
|
||||
};
|
||||
|
||||
@@ -1,26 +1,43 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const core = require('./utils').core;
|
||||
const deriveKeypair = require('ripple-keypairs').deriveKeypair;
|
||||
const ValidationError = require('./errors').ValidationError;
|
||||
const schemaValidate = require('./schema-validator');
|
||||
const schemaValidate = require('./schema-validator').schemaValidate;
|
||||
|
||||
function error(text) {
|
||||
return new ValidationError(text);
|
||||
}
|
||||
|
||||
function validateAddressAndSecret(obj) {
|
||||
function isValidSecret(secret) {
|
||||
try {
|
||||
deriveKeypair(secret);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function validateAddressAndSecret(obj: {address: string, secret: string}
|
||||
): void {
|
||||
const address = obj.address;
|
||||
const secret = obj.secret;
|
||||
schemaValidate('address', address);
|
||||
if (!secret) {
|
||||
throw error('Parameter missing: secret');
|
||||
}
|
||||
try {
|
||||
if (!core.Seed.from_json(secret).get_key(address)) {
|
||||
throw error('secret does not match address');
|
||||
}
|
||||
} catch (exception) {
|
||||
throw error('secret does not match address');
|
||||
if (!isValidSecret(secret)) {
|
||||
throw error('Invalid parameter: secret');
|
||||
}
|
||||
}
|
||||
|
||||
function validateSecret(secret: string): void {
|
||||
if (!secret) {
|
||||
throw error('Parameter missing: secret');
|
||||
}
|
||||
if (typeof secret !== 'string' || secret[0] !== 's'
|
||||
|| !isValidSecret(secret)) {
|
||||
throw error('Invalid parameter: secret');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,12 +58,20 @@ function validateOptions(schema, options) {
|
||||
module.exports = {
|
||||
address: _.partial(schemaValidate, 'address'),
|
||||
addressAndSecret: validateAddressAndSecret,
|
||||
secret: validateSecret,
|
||||
currency: _.partial(schemaValidate, 'currency'),
|
||||
identifier: _.partial(schemaValidate, 'hash256'),
|
||||
ledgerVersion: _.partial(schemaValidate, 'ledgerVersion'),
|
||||
sequence: _.partial(schemaValidate, 'sequence'),
|
||||
order: _.partial(schemaValidate, 'order'),
|
||||
orderbook: _.partial(schemaValidate, 'orderbook'),
|
||||
payment: _.partial(schemaValidate, 'payment'),
|
||||
suspendedPaymentCreation:
|
||||
_.partial(schemaValidate, 'suspended-payment-creation'),
|
||||
suspendedPaymentExecution:
|
||||
_.partial(schemaValidate, 'suspended-payment-execution'),
|
||||
suspendedPaymentCancellation:
|
||||
_.partial(schemaValidate, 'suspended-payment-cancellation'),
|
||||
pathfind: _.partial(schemaValidate, 'pathfind'),
|
||||
settings: _.partial(schemaValidate, 'settings'),
|
||||
trustline: _.partial(schemaValidate, 'trustline'),
|
||||
@@ -57,9 +82,12 @@ module.exports = {
|
||||
getAccountInfoOptions: _.partial(validateOptions, 'settings-options'),
|
||||
getTrustlinesOptions: _.partial(validateOptions, 'trustlines-options'),
|
||||
getBalancesOptions: _.partial(validateOptions, 'trustlines-options'),
|
||||
getBalanceSheetOptions: _.partial(validateOptions, 'balance-sheet-options'),
|
||||
getOrdersOptions: _.partial(validateOptions, 'orders-options'),
|
||||
getOrderbookOptions: _.partial(validateOptions, 'orders-options'),
|
||||
getTransactionOptions: _.partial(validateOptions, 'transaction-options'),
|
||||
getLedgerOptions: _.partial(validateOptions, 'ledger-options'),
|
||||
options: _.partial(validateOptions, 'options'),
|
||||
remoteOptions: _.partial(schemaValidate, 'remote-options'),
|
||||
instructions: _.partial(schemaValidate, 'instructions')
|
||||
};
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const core = require('./common').core;
|
||||
const util = require('util');
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const common = require('./common');
|
||||
const server = require('./server/server');
|
||||
const connect = server.connect;
|
||||
const disconnect = server.disconnect;
|
||||
@@ -14,6 +16,7 @@ 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');
|
||||
@@ -23,19 +26,36 @@ 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 convertExceptions = require('./common').convertExceptions;
|
||||
const generateWallet = convertExceptions(core.Wallet.generate);
|
||||
const generateAddress = convertExceptions(common.generateAddress);
|
||||
const computeLedgerHash = require('./offline/ledgerhash');
|
||||
const getLedger = require('./ledger/ledger');
|
||||
|
||||
function RippleAPI(options: {}) {
|
||||
common.validate.remoteOptions(options);
|
||||
if (EventEmitter instanceof Function) { // always true, needed for flow
|
||||
EventEmitter.call(this);
|
||||
}
|
||||
const _options = _.assign({}, options, {automatic_resubmission: false});
|
||||
this.remote = new core.Remote(_options);
|
||||
this.remote = new common.core.Remote(_options);
|
||||
this.remote.on('ledger_closed', message => {
|
||||
this.emit('ledgerClosed', server.formatLedgerClose(message));
|
||||
});
|
||||
}
|
||||
|
||||
RippleAPI.prototype = {
|
||||
util.inherits(RippleAPI, EventEmitter);
|
||||
|
||||
_.assign(RippleAPI.prototype, {
|
||||
connect,
|
||||
disconnect,
|
||||
isConnected,
|
||||
@@ -47,22 +67,35 @@ RippleAPI.prototype = {
|
||||
getTransactions,
|
||||
getTrustlines,
|
||||
getBalances,
|
||||
getBalanceSheet,
|
||||
getPaths,
|
||||
getOrders,
|
||||
getOrderbook,
|
||||
getSettings,
|
||||
getAccountInfo,
|
||||
getLedger,
|
||||
|
||||
preparePayment,
|
||||
prepareTrustline,
|
||||
prepareOrder,
|
||||
prepareOrderCancellation,
|
||||
prepareSuspendedPaymentCreation,
|
||||
prepareSuspendedPaymentExecution,
|
||||
prepareSuspendedPaymentCancellation,
|
||||
prepareSettings,
|
||||
sign,
|
||||
submit,
|
||||
|
||||
generateWallet,
|
||||
generateAddress,
|
||||
errors
|
||||
});
|
||||
|
||||
// these are exposed only for use by unit tests; they are not part of the API
|
||||
RippleAPI._PRIVATE = {
|
||||
common,
|
||||
computeLedgerHash,
|
||||
ledgerUtils: require('./ledger/utils'),
|
||||
schemaValidator: require('./common/schema-validator')
|
||||
};
|
||||
|
||||
module.exports = RippleAPI;
|
||||
|
||||
@@ -5,8 +5,45 @@ const utils = require('./utils');
|
||||
const removeUndefined = require('./parse/utils').removeUndefined;
|
||||
const validate = utils.common.validate;
|
||||
const composeAsync = utils.common.composeAsync;
|
||||
const convertErrors = utils.common.convertErrors;
|
||||
|
||||
function formatAccountInfo(response) {
|
||||
type AccountData = {
|
||||
Sequence: number,
|
||||
Account: string,
|
||||
Balance: string,
|
||||
Flags: number,
|
||||
LedgerEntryType: string,
|
||||
OwnerCount: number,
|
||||
PreviousTxnID: string,
|
||||
AccountTxnID?: string,
|
||||
PreviousTxnLgrSeq: number,
|
||||
index: string
|
||||
}
|
||||
|
||||
type AccountDataResponse = {
|
||||
account_data: AccountData,
|
||||
ledger_current_index?: number,
|
||||
ledger_hash?: string,
|
||||
ledger_index: number,
|
||||
validated: boolean
|
||||
}
|
||||
|
||||
type AccountInfoOptions = {
|
||||
ledgerVersion?: number
|
||||
}
|
||||
|
||||
type AccountInfoCallback = (err: any, data: AccountInfoResponse) => void
|
||||
|
||||
type AccountInfoResponse = {
|
||||
sequence: number,
|
||||
xrpBalance: string,
|
||||
ownerCount: number,
|
||||
previousInitiatedTransactionID: string,
|
||||
previousAffectingTransactionID: string,
|
||||
previousAffectingTransactionLedgerVersion: number
|
||||
}
|
||||
|
||||
function formatAccountInfo(response: AccountDataResponse) {
|
||||
const data = response.account_data;
|
||||
return removeUndefined({
|
||||
sequence: data.Sequence,
|
||||
@@ -18,17 +55,24 @@ function formatAccountInfo(response) {
|
||||
});
|
||||
}
|
||||
|
||||
function getAccountInfo(account, options, callback) {
|
||||
function getAccountInfoAsync(account: string, options: AccountInfoOptions,
|
||||
callback: AccountInfoCallback
|
||||
) {
|
||||
validate.address(account);
|
||||
validate.getAccountInfoOptions(options);
|
||||
|
||||
const request = {
|
||||
account: account,
|
||||
ledger: options.ledgerVersion
|
||||
ledger: options.ledgerVersion || 'validated'
|
||||
};
|
||||
|
||||
this.remote.requestAccountInfo(request,
|
||||
composeAsync(formatAccountInfo, callback));
|
||||
composeAsync(formatAccountInfo, convertErrors(callback)));
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(getAccountInfo);
|
||||
function getAccountInfo(account: string, options: AccountInfoOptions = {}
|
||||
): Promise<AccountInfoResponse> {
|
||||
return utils.promisify(getAccountInfoAsync).call(this, account, options);
|
||||
}
|
||||
|
||||
module.exports = getAccountInfo;
|
||||
|
||||
68
src/api/ledger/balance-sheet.js
Normal file
68
src/api/ledger/balance-sheet.js
Normal file
@@ -0,0 +1,68 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
const composeAsync = utils.common.composeAsync;
|
||||
const convertErrors = utils.common.convertErrors;
|
||||
|
||||
function formatBalanceSheet(balanceSheet) {
|
||||
const result = {};
|
||||
|
||||
if (!_.isUndefined(balanceSheet.balances)) {
|
||||
result.balances = [];
|
||||
_.forEach(balanceSheet.balances, (balances, counterparty) => {
|
||||
_.forEach(balances, (balance) => {
|
||||
result.balances.push(Object.assign({counterparty}, balance));
|
||||
});
|
||||
});
|
||||
}
|
||||
if (!_.isUndefined(balanceSheet.assets)) {
|
||||
result.assets = [];
|
||||
_.forEach(balanceSheet.assets, (assets, counterparty) => {
|
||||
_.forEach(assets, (balance) => {
|
||||
result.assets.push(Object.assign({counterparty}, balance));
|
||||
});
|
||||
});
|
||||
}
|
||||
if (!_.isUndefined(balanceSheet.obligations)) {
|
||||
result.obligations = _.map(balanceSheet.obligations, (value, currency) =>
|
||||
({currency, value}));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getBalanceSheetAsync(address, options, callback) {
|
||||
validate.address(address);
|
||||
validate.getBalanceSheetOptions(options);
|
||||
|
||||
const requestOptions = Object.assign({}, {
|
||||
account: address,
|
||||
strict: true,
|
||||
hotwallet: options.excludeAddresses,
|
||||
ledger: options.ledgerVersion
|
||||
});
|
||||
|
||||
const requestCallback = composeAsync(
|
||||
formatBalanceSheet, convertErrors(callback));
|
||||
|
||||
this.remote.getLedgerSequence((err, ledgerVersion) => {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_.isUndefined(requestOptions.ledger)) {
|
||||
requestOptions.ledger = ledgerVersion;
|
||||
}
|
||||
|
||||
this.remote.requestGatewayBalances(requestOptions, requestCallback);
|
||||
});
|
||||
}
|
||||
|
||||
function getBalanceSheet(address: string, options = {}) {
|
||||
return utils.promisify(getBalanceSheetAsync).call(this, address, options);
|
||||
}
|
||||
|
||||
module.exports = getBalanceSheet;
|
||||
@@ -6,6 +6,10 @@ const utils = require('./utils');
|
||||
const getTrustlines = require('./trustlines');
|
||||
const validate = utils.common.validate;
|
||||
const composeAsync = utils.common.composeAsync;
|
||||
const convertErrors = utils.common.convertErrors;
|
||||
import type {Remote} from '../../core/remote';
|
||||
import type {GetLedgerSequenceCallback} from '../../core/remote';
|
||||
|
||||
|
||||
function getTrustlineBalanceAmount(trustline) {
|
||||
return {
|
||||
@@ -24,16 +28,37 @@ function formatBalances(balances) {
|
||||
balances.trustlines.map(getTrustlineBalanceAmount));
|
||||
}
|
||||
|
||||
function getBalances(account, options, callback) {
|
||||
function getTrustlinesAsync(account, options, callback) {
|
||||
getTrustlines.call(this, account, options)
|
||||
.then(data => callback(null, data))
|
||||
.catch(callback);
|
||||
}
|
||||
|
||||
function getLedgerVersionHelper(remote: Remote, optionValue?: number,
|
||||
callback: GetLedgerSequenceCallback
|
||||
) {
|
||||
if (optionValue !== undefined && optionValue !== null) {
|
||||
callback(null, optionValue);
|
||||
} else {
|
||||
remote.getLedgerSequence(callback);
|
||||
}
|
||||
}
|
||||
|
||||
function getBalancesAsync(account, options, callback) {
|
||||
validate.address(account);
|
||||
validate.getBalancesOptions(options);
|
||||
|
||||
const ledgerVersion = options.ledgerVersion
|
||||
|| this.remote.getLedgerSequence();
|
||||
async.parallel({
|
||||
xrp: _.partial(utils.getXRPBalance, this.remote, account, ledgerVersion),
|
||||
trustlines: _.partial(getTrustlines.bind(this), account, options)
|
||||
}, composeAsync(formatBalances, callback));
|
||||
xrp: async.seq(
|
||||
_.partial(getLedgerVersionHelper, this.remote, options.ledgerVersion),
|
||||
_.partial(utils.getXRPBalance, this.remote, account)
|
||||
),
|
||||
trustlines: _.partial(getTrustlinesAsync.bind(this), account, options)
|
||||
}, composeAsync(formatBalances, convertErrors(callback)));
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(getBalances);
|
||||
function getBalances(account: string, options = {}) {
|
||||
return utils.promisify(getBalancesAsync).call(this, account, options);
|
||||
}
|
||||
|
||||
module.exports = getBalances;
|
||||
|
||||
28
src/api/ledger/ledger.js
Normal file
28
src/api/ledger/ledger.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
const composeAsync = utils.common.composeAsync;
|
||||
const convertErrors = utils.common.convertErrors;
|
||||
const parseLedger = require('./parse/ledger');
|
||||
|
||||
function getLedgerAsync(options, callback) {
|
||||
validate.getLedgerOptions(options);
|
||||
|
||||
const request = {
|
||||
ledger: options.ledgerVersion || 'validated',
|
||||
expand: options.includeAllData,
|
||||
transactions: options.includeTransactions,
|
||||
accounts: options.includeState
|
||||
};
|
||||
|
||||
this.remote.requestLedger(request,
|
||||
composeAsync(response => parseLedger(response.ledger),
|
||||
convertErrors(callback)));
|
||||
}
|
||||
|
||||
function getLedger(options = {}) {
|
||||
return utils.promisify(getLedgerAsync).call(this, options);
|
||||
}
|
||||
|
||||
module.exports = getLedger;
|
||||
@@ -3,21 +3,23 @@
|
||||
const _ = require('lodash');
|
||||
const async = require('async');
|
||||
const utils = require('./utils');
|
||||
const parseOrderbookOrder = require('./parse/orderbook-order');
|
||||
const validate = utils.common.validate;
|
||||
const composeAsync = utils.common.composeAsync;
|
||||
const convertErrors = utils.common.convertErrors;
|
||||
const parseOrderbookOrder = require('./parse/orderbook-order');
|
||||
|
||||
// account is to specify a "perspective", which affects which unfunded offers
|
||||
// are returned
|
||||
function getBookOffers(remote, account, ledgerVersion, limit,
|
||||
takerGets, takerPays, callback) {
|
||||
takerGets, takerPays, callback
|
||||
) {
|
||||
remote.requestBookOffers(utils.renameCounterpartyToIssuerInOrder({
|
||||
taker_gets: takerGets,
|
||||
taker_pays: takerPays,
|
||||
ledger: ledgerVersion || 'validated',
|
||||
limit: limit,
|
||||
taker: account
|
||||
}), composeAsync(data => data.offers, callback));
|
||||
}), composeAsync(data => data.offers, convertErrors(callback)));
|
||||
}
|
||||
|
||||
function isSameIssue(a, b) {
|
||||
@@ -62,7 +64,7 @@ function formatBidsAndAsks(orderbook, offers) {
|
||||
return {bids, asks};
|
||||
}
|
||||
|
||||
function getOrderbook(account, orderbook, options, callback) {
|
||||
function getOrderbookAsync(account, orderbook, options, callback) {
|
||||
validate.address(account);
|
||||
validate.orderbook(orderbook);
|
||||
validate.getOrderbookOptions(options);
|
||||
@@ -76,4 +78,9 @@ function getOrderbook(account, orderbook, options, callback) {
|
||||
callback));
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(getOrderbook);
|
||||
function getOrderbook(account: string, orderbook: Object, options = {}) {
|
||||
return utils.promisify(getOrderbookAsync).call(this,
|
||||
account, orderbook, options);
|
||||
}
|
||||
|
||||
module.exports = getOrderbook;
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const async = require('async');
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
const composeAsync = utils.common.composeAsync;
|
||||
const convertErrors = utils.common.convertErrors;
|
||||
const parseAccountOrder = require('./parse/account-order');
|
||||
|
||||
function requestAccountOffers(remote, address, ledgerVersion, options,
|
||||
marker, limit, callback) {
|
||||
function requestAccountOffers(remote, address, ledgerVersion, marker, limit,
|
||||
callback
|
||||
) {
|
||||
remote.requestAccountOffers({
|
||||
account: address,
|
||||
marker: marker,
|
||||
@@ -17,20 +20,24 @@ function requestAccountOffers(remote, address, ledgerVersion, options,
|
||||
composeAsync((data) => ({
|
||||
marker: data.marker,
|
||||
results: data.offers.map(_.partial(parseAccountOrder, address))
|
||||
}), callback));
|
||||
}), convertErrors(callback)));
|
||||
}
|
||||
|
||||
function getOrders(account, options, callback) {
|
||||
function getOrdersAsync(account, options, callback) {
|
||||
validate.address(account);
|
||||
validate.getOrdersOptions(options);
|
||||
|
||||
const ledgerVersion = options.ledgerVersion
|
||||
|| this.remote.getLedgerSequence();
|
||||
const getter = _.partial(requestAccountOffers, this.remote, account,
|
||||
ledgerVersion, options);
|
||||
options.ledgerVersion);
|
||||
utils.getRecursive(getter, options.limit,
|
||||
composeAsync((orders) => _.sortBy(orders,
|
||||
(order) => order.properties.sequence), callback));
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(getOrders);
|
||||
function getOrders(account: string, options = {}) {
|
||||
return utils.promisify(async.seq(
|
||||
utils.getLedgerOptionsWithLedgerVersion,
|
||||
getOrdersAsync)).call(this, account, options);
|
||||
}
|
||||
|
||||
module.exports = getOrders;
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const BigNumber = require('bignumber.js');
|
||||
const AccountFields = require('./utils').constants.AccountFields;
|
||||
|
||||
function parseField(info, value) {
|
||||
if (info.encoding === 'hex' && !info.length) {
|
||||
return new Buffer(value, 'hex').toString('ascii');
|
||||
}
|
||||
if (info.shift) {
|
||||
return (new BigNumber(value)).shift(-info.shift).toNumber();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
50
src/api/ledger/parse/ledger.js
Normal file
50
src/api/ledger/parse/ledger.js
Normal file
@@ -0,0 +1,50 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const removeUndefined = require('./utils').removeUndefined;
|
||||
const parseTransaction = require('./transaction');
|
||||
|
||||
function parseTransactions(transactions) {
|
||||
if (_.isEmpty(transactions)) {
|
||||
return {};
|
||||
}
|
||||
if (_.isString(transactions[0])) {
|
||||
return {transactionHashes: transactions};
|
||||
}
|
||||
return {
|
||||
transactions: _.map(transactions, parseTransaction),
|
||||
rawTransactions: JSON.stringify(transactions)
|
||||
};
|
||||
}
|
||||
|
||||
function parseState(state) {
|
||||
if (_.isEmpty(state)) {
|
||||
return {};
|
||||
}
|
||||
if (_.isString(state[0])) {
|
||||
return {stateHashes: state};
|
||||
}
|
||||
return {rawState: JSON.stringify(state)};
|
||||
}
|
||||
|
||||
function parseLedger(ledger: Object): Object {
|
||||
return removeUndefined(_.assign({
|
||||
accepted: ledger.accepted,
|
||||
closed: ledger.closed,
|
||||
stateHash: ledger.account_hash,
|
||||
closeTime: ledger.close_time,
|
||||
closeTimeResolution: ledger.close_time_resolution,
|
||||
closeFlags: ledger.close_flags,
|
||||
ledgerHash: ledger.hash || ledger.ledger_hash,
|
||||
ledgerVersion: parseInt(ledger.ledger_index || ledger.seqNum, 10),
|
||||
parentLedgerHash: ledger.parent_hash,
|
||||
parentCloseTime: ledger.parent_close_time,
|
||||
totalDrops: ledger.total_coins || ledger.totalCoins,
|
||||
transactionHash: ledger.transaction_hash
|
||||
},
|
||||
parseTransactions(ledger.transactions),
|
||||
parseState(ledger.accountState)
|
||||
));
|
||||
}
|
||||
|
||||
module.exports = parseLedger;
|
||||
@@ -8,21 +8,42 @@ function parsePaths(paths) {
|
||||
_.omit(step, ['type', 'type_hex'])));
|
||||
}
|
||||
|
||||
function parsePathfind(sourceAddress: string,
|
||||
destinationAmount: Object, pathfindResult: Object): Object {
|
||||
return pathfindResult.alternatives.map(function(alternative) {
|
||||
return {
|
||||
source: {
|
||||
address: sourceAddress,
|
||||
amount: parseAmount(alternative.source_amount)
|
||||
},
|
||||
destination: {
|
||||
address: pathfindResult.destination_account,
|
||||
amount: destinationAmount
|
||||
},
|
||||
paths: JSON.stringify(parsePaths(alternative.paths_computed))
|
||||
};
|
||||
});
|
||||
function removeAnyCounterpartyEncoding(address: string, amount: Object) {
|
||||
return amount.counterparty === address ?
|
||||
_.omit(amount, 'counterparty') : amount;
|
||||
}
|
||||
|
||||
function createAdjustment(address: string, adjustmentWithoutAddress: Object) {
|
||||
const amountKey = _.keys(adjustmentWithoutAddress)[0];
|
||||
const amount = adjustmentWithoutAddress[amountKey];
|
||||
return _.set({address: address}, amountKey,
|
||||
removeAnyCounterpartyEncoding(address, amount));
|
||||
}
|
||||
|
||||
function parseAlternative(sourceAddress: string, destinationAddress: string,
|
||||
destinationAmount: Object, alternative: Object
|
||||
) {
|
||||
// we use "maxAmount"/"minAmount" here so that the result can be passed
|
||||
// directly to preparePayment
|
||||
const amounts = (alternative.destination_amount !== undefined) ?
|
||||
{source: {amount: parseAmount(alternative.source_amount)},
|
||||
destination: {minAmount: parseAmount(alternative.destination_amount)}} :
|
||||
{source: {maxAmount: parseAmount(alternative.source_amount)},
|
||||
destination: {amount: parseAmount(destinationAmount)}};
|
||||
|
||||
return {
|
||||
source: createAdjustment(sourceAddress, amounts.source),
|
||||
destination: createAdjustment(destinationAddress, amounts.destination),
|
||||
paths: JSON.stringify(parsePaths(alternative.paths_computed))
|
||||
};
|
||||
}
|
||||
|
||||
function parsePathfind(pathfindResult: Object): Object {
|
||||
const sourceAddress = pathfindResult.source_account;
|
||||
const destinationAddress = pathfindResult.destination_account;
|
||||
const destinationAmount = pathfindResult.destination_amount;
|
||||
return pathfindResult.alternatives.map(_.partial(parseAlternative,
|
||||
sourceAddress, destinationAddress, destinationAmount));
|
||||
}
|
||||
|
||||
module.exports = parsePathfind;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
const parseAmount = require('./amount');
|
||||
@@ -17,17 +18,9 @@ function isQualityLimited(tx) {
|
||||
return (tx.Flags & Transaction.flags.Payment.LimitQuality) !== 0;
|
||||
}
|
||||
|
||||
function parsePaymentMemos(tx) {
|
||||
if (!Array.isArray(tx.Memos) || tx.Memos.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return tx.Memos.map((m) => {
|
||||
return utils.removeUndefined({
|
||||
type: m.Memo.parsed_memo_type,
|
||||
format: m.Memo.parsed_memo_format,
|
||||
data: m.Memo.parsed_memo_data
|
||||
});
|
||||
});
|
||||
function removeGenericCounterparty(amount, address) {
|
||||
return amount.counterparty === address ?
|
||||
_.omit(amount, 'counterparty') : amount;
|
||||
}
|
||||
|
||||
function parsePayment(tx: Object): Object {
|
||||
@@ -35,20 +28,21 @@ function parsePayment(tx: Object): Object {
|
||||
|
||||
const source = {
|
||||
address: tx.Account,
|
||||
amount: parseAmount(tx.SendMax || tx.Amount),
|
||||
maxAmount: removeGenericCounterparty(
|
||||
parseAmount(tx.SendMax || tx.Amount), tx.Account),
|
||||
tag: tx.SourceTag
|
||||
};
|
||||
|
||||
const destination = {
|
||||
address: tx.Destination,
|
||||
amount: parseAmount(tx.Amount),
|
||||
amount: removeGenericCounterparty(parseAmount(tx.Amount), tx.Destination),
|
||||
tag: tx.DestinationTag
|
||||
};
|
||||
|
||||
return utils.removeUndefined({
|
||||
source: utils.removeUndefined(source),
|
||||
destination: utils.removeUndefined(destination),
|
||||
memos: parsePaymentMemos(tx),
|
||||
memos: utils.parseMemos(tx),
|
||||
invoiceID: tx.InvoiceID,
|
||||
paths: tx.Paths ? JSON.stringify(tx.Paths) : undefined,
|
||||
allowPartialPayment: isPartialPayment(tx) || undefined,
|
||||
|
||||
16
src/api/ledger/parse/suspended-payment-cancellation.js
Normal file
16
src/api/ledger/parse/suspended-payment-cancellation.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
|
||||
function parseSuspendedPaymentCancellation(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'SuspendedPaymentCancel');
|
||||
|
||||
return utils.removeUndefined({
|
||||
memos: utils.parseMemos(tx),
|
||||
owner: tx.Owner,
|
||||
paymentSequence: tx.OfferSequence
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = parseSuspendedPaymentCancellation;
|
||||
39
src/api/ledger/parse/suspended-payment-creation.js
Normal file
39
src/api/ledger/parse/suspended-payment-creation.js
Normal file
@@ -0,0 +1,39 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
const parseAmount = require('./amount');
|
||||
|
||||
function removeGenericCounterparty(amount, address) {
|
||||
return amount.counterparty === address ?
|
||||
_.omit(amount, 'counterparty') : amount;
|
||||
}
|
||||
|
||||
function parseSuspendedPaymentCreation(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'SuspendedPaymentCreate');
|
||||
|
||||
const source = {
|
||||
address: tx.Account,
|
||||
maxAmount: removeGenericCounterparty(
|
||||
parseAmount(tx.SendMax || tx.Amount), tx.Account),
|
||||
tag: tx.SourceTag
|
||||
};
|
||||
|
||||
const destination = {
|
||||
address: tx.Destination,
|
||||
amount: removeGenericCounterparty(parseAmount(tx.Amount), tx.Destination),
|
||||
tag: tx.DestinationTag
|
||||
};
|
||||
|
||||
return utils.removeUndefined({
|
||||
source: utils.removeUndefined(source),
|
||||
destination: utils.removeUndefined(destination),
|
||||
memos: utils.parseMemos(tx),
|
||||
digest: tx.Digest,
|
||||
allowCancelAfter: tx.CancelAfter,
|
||||
allowExecuteAfter: tx.FinishAfter
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = parseSuspendedPaymentCreation;
|
||||
25
src/api/ledger/parse/suspended-payment-execution.js
Normal file
25
src/api/ledger/parse/suspended-payment-execution.js
Normal file
@@ -0,0 +1,25 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const assert = require('assert');
|
||||
const sjclcodec = require('sjcl-codec');
|
||||
const utils = require('./utils');
|
||||
|
||||
function convertHexToString(hexString) {
|
||||
const bits = sjclcodec.hex.toBits(hexString);
|
||||
return sjclcodec.utf8String.fromBits(bits);
|
||||
}
|
||||
|
||||
function parseSuspendedPaymentExecution(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'SuspendedPaymentFinish');
|
||||
|
||||
return utils.removeUndefined({
|
||||
memos: utils.parseMemos(tx),
|
||||
owner: tx.Owner,
|
||||
paymentSequence: tx.OfferSequence,
|
||||
method: tx.Method,
|
||||
digest: tx.Digest,
|
||||
proof: tx.Proof ? convertHexToString(tx.Proof) : undefined
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = parseSuspendedPaymentExecution;
|
||||
@@ -7,6 +7,10 @@ const parseTrustline = require('./trustline');
|
||||
const parseOrder = require('./order');
|
||||
const parseOrderCancellation = require('./cancellation');
|
||||
const parseSettings = require('./settings');
|
||||
const parseSuspendedPaymentCreation = require('./suspended-payment-creation');
|
||||
const parseSuspendedPaymentExecution = require('./suspended-payment-execution');
|
||||
const parseSuspendedPaymentCancellation =
|
||||
require('./suspended-payment-cancellation');
|
||||
|
||||
function parseTransactionType(type) {
|
||||
const mapping = {
|
||||
@@ -15,7 +19,10 @@ function parseTransactionType(type) {
|
||||
OfferCreate: 'order',
|
||||
OfferCancel: 'orderCancellation',
|
||||
AccountSet: 'settings',
|
||||
SetRegularKey: 'settings'
|
||||
SetRegularKey: 'settings',
|
||||
SuspendedPaymentCreate: 'suspendedPaymentCreation',
|
||||
SuspendedPaymentFinish: 'suspendedPaymentExecution',
|
||||
SuspendedPaymentCancel: 'suspendedPaymentCancellation'
|
||||
};
|
||||
return mapping[type] || null;
|
||||
}
|
||||
@@ -27,7 +34,10 @@ function parseTransaction(tx: Object): Object {
|
||||
'trustline': parseTrustline,
|
||||
'order': parseOrder,
|
||||
'orderCancellation': parseOrderCancellation,
|
||||
'settings': parseSettings
|
||||
'settings': parseSettings,
|
||||
'suspendedPaymentCreation': parseSuspendedPaymentCreation,
|
||||
'suspendedPaymentExecution': parseSuspendedPaymentExecution,
|
||||
'suspendedPaymentCancellation': parseSuspendedPaymentCancellation
|
||||
};
|
||||
const parser = mapping[type];
|
||||
assert(parser !== undefined, 'Unrecognized transaction type');
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
const flags = utils.core.Transaction.flags.TrustSet;
|
||||
const BigNumber = require('bignumber.js');
|
||||
|
||||
function parseFlag(flagsValue, trueValue, falseValue) {
|
||||
if (flagsValue & trueValue) {
|
||||
@@ -14,6 +15,13 @@ function parseFlag(flagsValue, trueValue, falseValue) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseQuality(quality?: number) {
|
||||
if (typeof quality === 'number') {
|
||||
return (new BigNumber(quality)).shift(-9).toNumber();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseTrustline(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'TrustSet');
|
||||
|
||||
@@ -21,8 +29,8 @@ function parseTrustline(tx: Object): Object {
|
||||
limit: tx.LimitAmount.value,
|
||||
currency: tx.LimitAmount.currency,
|
||||
counterparty: tx.LimitAmount.issuer,
|
||||
qualityIn: tx.QualityIn,
|
||||
qualityOut: tx.QualityOut,
|
||||
qualityIn: parseQuality(tx.QualityIn),
|
||||
qualityOut: parseQuality(tx.QualityOut),
|
||||
ripplingDisabled: parseFlag(
|
||||
tx.Flags, flags.SetNoRipple, flags.ClearNoRipple),
|
||||
frozen: parseFlag(tx.Flags, flags.SetFreeze, flags.ClearFreeze),
|
||||
|
||||
@@ -6,8 +6,9 @@ const toTimestamp = require('../../../core/utils').toTimestamp;
|
||||
const utils = require('../utils');
|
||||
const BigNumber = require('bignumber.js');
|
||||
|
||||
function adjustQualityForXRP(quality: string, takerGetsCurrency: string,
|
||||
takerPaysCurrency: string) {
|
||||
function adjustQualityForXRP(
|
||||
quality: string, takerGetsCurrency: string, takerPaysCurrency: string
|
||||
) {
|
||||
// quality = takerPays.value/takerGets.value
|
||||
// using drops (1e-6 XRP) for XRP values
|
||||
const numeratorShift = (takerPaysCurrency === 'XRP' ? -6 : 0);
|
||||
@@ -51,7 +52,7 @@ function parseOutcome(tx: Object): ?Object {
|
||||
}
|
||||
|
||||
const balanceChanges = transactionParser.parseBalanceChanges(tx.meta);
|
||||
const orderbookChanges = transactionParser.parseOrderBookChanges(tx.meta);
|
||||
const orderbookChanges = transactionParser.parseOrderbookChanges(tx.meta);
|
||||
removeEmptyCounterpartyInBalanceChanges(balanceChanges);
|
||||
removeEmptyCounterpartyInOrderbookChanges(orderbookChanges);
|
||||
|
||||
@@ -66,8 +67,22 @@ function parseOutcome(tx: Object): ?Object {
|
||||
};
|
||||
}
|
||||
|
||||
function parseMemos(tx: Object): ?Array<Object> {
|
||||
if (!Array.isArray(tx.Memos) || tx.Memos.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return tx.Memos.map((m) => {
|
||||
return removeUndefined({
|
||||
type: m.Memo.parsed_memo_type,
|
||||
format: m.Memo.parsed_memo_format,
|
||||
data: m.Memo.parsed_memo_data
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseOutcome,
|
||||
parseMemos,
|
||||
removeUndefined,
|
||||
adjustQualityForXRP,
|
||||
dropsToXrp: utils.common.dropsToXrp,
|
||||
|
||||
@@ -4,14 +4,18 @@ const _ = require('lodash');
|
||||
const async = require('async');
|
||||
const BigNumber = require('bignumber.js');
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
const parsePathfind = require('./parse/pathfind');
|
||||
const validate = utils.common.validate;
|
||||
const NotFoundError = utils.common.errors.NotFoundError;
|
||||
const ValidationError = utils.common.errors.ValidationError;
|
||||
const composeAsync = utils.common.composeAsync;
|
||||
const convertErrors = utils.common.convertErrors;
|
||||
const toRippledAmount = utils.common.toRippledAmount;
|
||||
|
||||
type PathFindParams = {
|
||||
src_currencies?: Array<string>, src_account: string, dst_amount: string,
|
||||
dst_account?: string
|
||||
src_currencies?: Array<string>, src_account: string,
|
||||
dst_amount: string | Object, dst_account?: string,
|
||||
src_amount?: string | Object
|
||||
}
|
||||
|
||||
function addParams(params: PathFindParams, result: {}) {
|
||||
@@ -28,10 +32,11 @@ type PathFind = {
|
||||
}
|
||||
|
||||
function requestPathFind(remote, pathfind: PathFind, callback) {
|
||||
const destinationAmount = _.assign({value: -1}, pathfind.destination.amount);
|
||||
const params: PathFindParams = {
|
||||
src_account: pathfind.source.address,
|
||||
dst_account: pathfind.destination.address,
|
||||
dst_amount: utils.common.toRippledAmount(pathfind.destination.amount)
|
||||
dst_amount: toRippledAmount(destinationAmount)
|
||||
};
|
||||
if (typeof params.dst_amount === 'object' && !params.dst_amount.issuer) {
|
||||
// Convert blank issuer to sender's address
|
||||
@@ -43,11 +48,21 @@ function requestPathFind(remote, pathfind: PathFind, callback) {
|
||||
}
|
||||
if (pathfind.source.currencies && pathfind.source.currencies.length > 0) {
|
||||
params.src_currencies = pathfind.source.currencies.map(amount =>
|
||||
_.omit(utils.common.toRippledAmount(amount), 'value'));
|
||||
_.omit(toRippledAmount(amount), 'value'));
|
||||
}
|
||||
if (pathfind.source.amount) {
|
||||
if (pathfind.destination.amount.value !== undefined) {
|
||||
throw new ValidationError('Cannot specify both source.amount'
|
||||
+ ' and destination.amount.value in getPaths');
|
||||
}
|
||||
params.src_amount = toRippledAmount(pathfind.source.amount);
|
||||
if (params.src_amount.currency && !params.src_amount.issuer) {
|
||||
params.src_amount.issuer = pathfind.source.address;
|
||||
}
|
||||
}
|
||||
|
||||
remote.requestRipplePathFind(params,
|
||||
composeAsync(_.partial(addParams, params), callback));
|
||||
remote.createPathFind(params,
|
||||
composeAsync(_.partial(addParams, params), convertErrors(callback)));
|
||||
}
|
||||
|
||||
function addDirectXrpPath(paths, xrpBalance) {
|
||||
@@ -80,10 +95,10 @@ function conditionallyAddDirectXRPPath(remote, address, paths, callback) {
|
||||
|
||||
function formatResponse(pathfind, paths) {
|
||||
if (paths.alternatives && paths.alternatives.length > 0) {
|
||||
const address = pathfind.source.address;
|
||||
return parsePathfind(address, pathfind.destination.amount, paths);
|
||||
return parsePathfind(paths);
|
||||
}
|
||||
if (!_.includes(paths.destination_currencies,
|
||||
if (paths.destination_currencies !== undefined &&
|
||||
!_.includes(paths.destination_currencies,
|
||||
pathfind.destination.amount.currency)) {
|
||||
throw new NotFoundError('No paths found. ' +
|
||||
'The destination_account does not accept ' +
|
||||
@@ -103,7 +118,7 @@ function formatResponse(pathfind, paths) {
|
||||
}
|
||||
}
|
||||
|
||||
function getPaths(pathfind, callback) {
|
||||
function getPathsAsync(pathfind, callback) {
|
||||
validate.pathfind(pathfind);
|
||||
|
||||
const address = pathfind.source.address;
|
||||
@@ -113,4 +128,8 @@ function getPaths(pathfind, callback) {
|
||||
], composeAsync(_.partial(formatResponse, pathfind), callback));
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(getPaths);
|
||||
function getPaths(pathfind: Object) {
|
||||
return utils.promisify(getPathsAsync).call(this, pathfind);
|
||||
}
|
||||
|
||||
module.exports = getPaths;
|
||||
|
||||
@@ -6,6 +6,7 @@ const validate = utils.common.validate;
|
||||
const parseFields = require('./parse/fields');
|
||||
const composeAsync = utils.common.composeAsync;
|
||||
const AccountFlags = utils.common.constants.AccountFlags;
|
||||
const convertErrors = utils.common.convertErrors;
|
||||
|
||||
function parseFlags(value) {
|
||||
const settings = {};
|
||||
@@ -24,17 +25,21 @@ function formatSettings(response) {
|
||||
return _.assign({}, parsedFlags, parsedFields);
|
||||
}
|
||||
|
||||
function getSettings(account, options, callback) {
|
||||
function getSettingsAsync(account, options, callback) {
|
||||
validate.address(account);
|
||||
validate.getSettingsOptions(options);
|
||||
|
||||
const request = {
|
||||
account: account,
|
||||
ledger: options.ledgerVersion
|
||||
ledger: options.ledgerVersion || 'validated'
|
||||
};
|
||||
|
||||
this.remote.requestAccountInfo(request,
|
||||
composeAsync(formatSettings, callback));
|
||||
composeAsync(formatSettings, convertErrors(callback)));
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(getSettings);
|
||||
function getSettings(account: string, options = {}) {
|
||||
return utils.promisify(getSettingsAsync).call(this, account, options);
|
||||
}
|
||||
|
||||
module.exports = getSettings;
|
||||
|
||||
147
src/api/ledger/transaction-types.js
Normal file
147
src/api/ledger/transaction-types.js
Normal file
@@ -0,0 +1,147 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
type Outcome = {
|
||||
result: string,
|
||||
timestamp?: string,
|
||||
fee: string,
|
||||
balanceChanges: Object,
|
||||
orderbookChanges: Object,
|
||||
ledgerVersion: number,
|
||||
indexInLedger: number
|
||||
}
|
||||
|
||||
type Adjustment = {
|
||||
address: string,
|
||||
amount: {
|
||||
currency: string,
|
||||
counterparty?: string,
|
||||
value: string
|
||||
},
|
||||
tag?: number
|
||||
}
|
||||
|
||||
type Trustline = {
|
||||
currency: string,
|
||||
counterparty: string,
|
||||
limit: string,
|
||||
qualityIn?: number,
|
||||
qualityOut?: number,
|
||||
ripplingDisabled?: boolean,
|
||||
authorized?: boolean,
|
||||
frozen?: boolean
|
||||
}
|
||||
|
||||
type Settings = {
|
||||
passwordSpent?: boolean,
|
||||
requireDestinationTag?: boolean,
|
||||
requireAuthorization?: boolean,
|
||||
disallowIncomingXRP?: boolean,
|
||||
disableMasterKey?: boolean,
|
||||
enableTransactionIDTracking?: boolean,
|
||||
noFreeze?: boolean,
|
||||
globalFreeze?: boolean,
|
||||
defaultRipple?: boolean,
|
||||
emailHash?: string,
|
||||
walletLocator?: string,
|
||||
walletSize?: number,
|
||||
messageKey?: string,
|
||||
domain?: string,
|
||||
transferRate?: number,
|
||||
signers?: string,
|
||||
regularKey?: string
|
||||
}
|
||||
|
||||
type OrderCancellation = {
|
||||
orderSequence: number
|
||||
}
|
||||
|
||||
type Memo = {
|
||||
type?: string,
|
||||
format?: string,
|
||||
data?: string
|
||||
}
|
||||
|
||||
type Amount = {
|
||||
value: string,
|
||||
currency: string,
|
||||
counterparty?: string
|
||||
}
|
||||
|
||||
type Payment = {
|
||||
source: Adjustment,
|
||||
destination: Adjustment,
|
||||
paths?: string,
|
||||
memos?: Array<Memo>,
|
||||
invoiceID?: string,
|
||||
allowPartialPayment?: boolean,
|
||||
noDirectRipple?: boolean,
|
||||
limitQuality?: boolean
|
||||
}
|
||||
|
||||
type PaymentTransaction = {
|
||||
type: string,
|
||||
specification: Payment,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
type Order = {
|
||||
direction: string,
|
||||
quantity: Amount,
|
||||
totalPrice: Amount,
|
||||
immediateOrCancel?: boolean,
|
||||
fillOrKill?: boolean,
|
||||
passive?: boolean
|
||||
}
|
||||
|
||||
type OrderTransaction = {
|
||||
type: string,
|
||||
specification: Order,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
type OrderCancellationTransaction = {
|
||||
type: string,
|
||||
specification: OrderCancellation,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
type TrustlineTransaction = {
|
||||
type: string,
|
||||
specification: Trustline,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
type SettingsTransaction = {
|
||||
type: string,
|
||||
specification: Settings,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type TransactionOptions = {
|
||||
minLedgerVersion?: number,
|
||||
maxLedgerVersion?: number
|
||||
}
|
||||
|
||||
export type GetTransactionResponse = PaymentTransaction | OrderTransaction |
|
||||
OrderCancellationTransaction | TrustlineTransaction | SettingsTransaction
|
||||
|
||||
export type GetTransactionResponseCallback =
|
||||
(err?: ?Error, data?: GetTransactionResponse) => void
|
||||
|
||||
export type CallbackType = (err?: ?Error, data?: Object) => void
|
||||
@@ -6,8 +6,18 @@ const utils = require('./utils');
|
||||
const parseTransaction = require('./parse/transaction');
|
||||
const validate = utils.common.validate;
|
||||
const errors = utils.common.errors;
|
||||
const convertErrors = utils.common.convertErrors;
|
||||
const RippleError = require('../../core/rippleerror').RippleError;
|
||||
|
||||
function attachTransactionDate(remote, tx, callback) {
|
||||
import type {Remote} from '../../core/remote';
|
||||
|
||||
import type {CallbackType, GetTransactionResponse,
|
||||
GetTransactionResponseCallback, TransactionOptions}
|
||||
from './transaction-types';
|
||||
|
||||
function attachTransactionDate(remote: Remote, tx: Object,
|
||||
callback: CallbackType
|
||||
) {
|
||||
if (tx.date) {
|
||||
callback(null, tx);
|
||||
return;
|
||||
@@ -28,40 +38,76 @@ function attachTransactionDate(remote, tx, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function isTransactionInRange(tx, options) {
|
||||
function isTransactionInRange(tx: Object, options: TransactionOptions) {
|
||||
return (!options.minLedgerVersion
|
||||
|| tx.ledger_index >= options.minLedgerVersion)
|
||||
&& (!options.maxLedgerVersion
|
||||
|| tx.ledger_index <= options.maxLedgerVersion);
|
||||
}
|
||||
|
||||
function getTransaction(identifier, options, callback) {
|
||||
function getTransactionAsync(identifier: string, options: TransactionOptions,
|
||||
callback: GetTransactionResponseCallback
|
||||
) {
|
||||
validate.identifier(identifier);
|
||||
validate.getTransactionOptions(options);
|
||||
|
||||
const remote = this.remote;
|
||||
const maxLedgerVersion = Math.min(options.maxLedgerVersion,
|
||||
remote.getLedgerSequence());
|
||||
|
||||
function callbackWrapper(error, tx) {
|
||||
function callbackWrapper(error_?: Error, tx?: Object,
|
||||
maxLedgerVersion?: number
|
||||
) {
|
||||
let error = error_;
|
||||
|
||||
if (!error && tx && tx.validated !== true) {
|
||||
return callback(new errors.NotFoundError('Transaction not found'));
|
||||
}
|
||||
|
||||
if (error instanceof RippleError && error.remote &&
|
||||
error.remote.error === 'txnNotFound') {
|
||||
error = new errors.NotFoundError('Transaction not found');
|
||||
}
|
||||
|
||||
// Missing complete ledger range
|
||||
if (error instanceof errors.NotFoundError
|
||||
&& !utils.hasCompleteLedgerRange(remote,
|
||||
options.minLedgerVersion, maxLedgerVersion)) {
|
||||
callback(new errors.MissingLedgerHistoryError('Transaction not found,'
|
||||
+ ' but the server\'s ledger history is incomplete'));
|
||||
} else if (!error && !isTransactionInRange(tx, options)) {
|
||||
&& !utils.hasCompleteLedgerRange(remote, options.minLedgerVersion,
|
||||
maxLedgerVersion)) {
|
||||
if (utils.isPendingLedgerVersion(remote, maxLedgerVersion)) {
|
||||
callback(new errors.PendingLedgerVersionError());
|
||||
} else {
|
||||
callback(new errors.MissingLedgerHistoryError());
|
||||
}
|
||||
// Transaction is found, but not in specified range
|
||||
} else if (!error && tx && !isTransactionInRange(tx, options)) {
|
||||
callback(new errors.NotFoundError('Transaction not found'));
|
||||
// Transaction is not found
|
||||
} else if (error) {
|
||||
callback(error);
|
||||
convertErrors(callback)(error);
|
||||
} else if (!tx) {
|
||||
callback(new errors.ApiError('Internal error'));
|
||||
} else {
|
||||
callback(error, parseTransaction(tx));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function maxLedgerGetter(error_?: Error, tx?: Object) {
|
||||
this.getLedgerVersion().then((version) => {
|
||||
const maxLedgerVersion = options.maxLedgerVersion || version;
|
||||
callbackWrapper(error_, tx, maxLedgerVersion);
|
||||
}, callbackWrapper);
|
||||
}
|
||||
|
||||
async.waterfall([
|
||||
_.partial(remote.requestTx.bind(remote), {hash: identifier, binary: false}),
|
||||
_.partial(remote.requestTx.bind(remote),
|
||||
{hash: identifier, binary: false}),
|
||||
_.partial(attachTransactionDate, remote)
|
||||
], callbackWrapper);
|
||||
], maxLedgerGetter.bind(this));
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(getTransaction);
|
||||
function getTransaction(identifier: string,
|
||||
options: TransactionOptions = {}
|
||||
): Promise<GetTransactionResponse> {
|
||||
return utils.promisify(getTransactionAsync).call(this, identifier, options);
|
||||
}
|
||||
|
||||
module.exports = getTransaction;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* @flow */
|
||||
/* eslint-disable max-params */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
@@ -6,6 +7,7 @@ const parseTransaction = require('./parse/transaction');
|
||||
const getTransaction = require('./transaction');
|
||||
const validate = utils.common.validate;
|
||||
const composeAsync = utils.common.composeAsync;
|
||||
const convertErrors = utils.common.convertErrors;
|
||||
|
||||
function parseAccountTxTransaction(tx) {
|
||||
// rippled uses a different response format for 'account_tx' than 'tx'
|
||||
@@ -14,6 +16,21 @@ function parseAccountTxTransaction(tx) {
|
||||
return parseTransaction(tx.tx);
|
||||
}
|
||||
|
||||
function counterpartyFilter(filters, tx) {
|
||||
if (!filters.counterparty) {
|
||||
return true;
|
||||
}
|
||||
if (tx.address === filters.counterparty || (
|
||||
tx.specification && (
|
||||
(tx.specification.destination &&
|
||||
tx.specification.destination.address === filters.counterparty) ||
|
||||
(tx.specification.counterparty === filters.counterparty)
|
||||
))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function transactionFilter(address, filters, tx) {
|
||||
if (filters.excludeFailures && tx.outcome.result !== 'tesSUCCESS') {
|
||||
return false;
|
||||
@@ -27,8 +44,7 @@ function transactionFilter(address, filters, tx) {
|
||||
if (filters.initiated === false && tx.address === address) {
|
||||
return false;
|
||||
}
|
||||
if (filters.counterparty && tx.address !== filters.counterparty
|
||||
&& tx.Destination !== filters.counterparty) {
|
||||
if (filters.counterparty && !counterpartyFilter(filters, tx)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -40,10 +56,23 @@ function orderFilter(options, tx) {
|
||||
utils.compareTransactions(tx, options.startTx) < 0);
|
||||
}
|
||||
|
||||
function formatPartialResponse(address, options, data) {
|
||||
return {
|
||||
marker: data.marker,
|
||||
results: data.transactions
|
||||
.filter((tx) => tx.validated)
|
||||
.map(parseAccountTxTransaction)
|
||||
.filter(_.partial(transactionFilter, address, options))
|
||||
.filter(_.partial(orderFilter, options))
|
||||
};
|
||||
}
|
||||
|
||||
function getAccountTx(remote, address, options, marker, limit, callback) {
|
||||
const params = {
|
||||
account: address,
|
||||
// -1 is equivalent to earliest available validated ledger
|
||||
ledger_index_min: options.minLedgerVersion || -1,
|
||||
// -1 is equivalent to most recent available validated ledger
|
||||
ledger_index_max: options.maxLedgerVersion || -1,
|
||||
forward: options.earliestFirst,
|
||||
binary: options.binary,
|
||||
@@ -51,16 +80,9 @@ function getAccountTx(remote, address, options, marker, limit, callback) {
|
||||
marker: marker
|
||||
};
|
||||
|
||||
remote.requestAccountTx(params, (error, data) => {
|
||||
return error ? callback(error) : callback(null, {
|
||||
marker: data.marker,
|
||||
results: data.transactions
|
||||
.filter((tx) => tx.validated)
|
||||
.map(parseAccountTxTransaction)
|
||||
.filter(_.partial(transactionFilter, address, options))
|
||||
.filter(_.partial(orderFilter, options))
|
||||
});
|
||||
});
|
||||
remote.requestAccountTx(params,
|
||||
composeAsync(_.partial(formatPartialResponse, address, options),
|
||||
convertErrors(callback)));
|
||||
}
|
||||
|
||||
function checkForLedgerGaps(remote, options, transactions) {
|
||||
@@ -97,27 +119,27 @@ function getTransactionsInternal(remote, address, options, callback) {
|
||||
utils.getRecursive(getter, options.limit, composeAsync(format, callback));
|
||||
}
|
||||
|
||||
function getTransactions(address, options, callback) {
|
||||
validate.address(address);
|
||||
function getTransactionsAsync(account, options, callback) {
|
||||
validate.address(account);
|
||||
validate.getTransactionsOptions(options);
|
||||
|
||||
const defaults = {maxLedgerVersion: this.remote.getLedgerSequence()};
|
||||
const defaults = {maxLedgerVersion: -1};
|
||||
if (options.start) {
|
||||
getTransaction.bind(this)(options.start, {}, (error, tx) => {
|
||||
if (error) {
|
||||
callback(error);
|
||||
return;
|
||||
}
|
||||
getTransaction.call(this, options.start).then(tx => {
|
||||
const ledgerVersion = tx.outcome.ledgerVersion;
|
||||
const bound = options.earliestFirst ?
|
||||
{minLedgerVersion: ledgerVersion} : {maxLedgerVersion: ledgerVersion};
|
||||
const newOptions = _.assign(defaults, options, {startTx: tx}, bound);
|
||||
getTransactionsInternal(this.remote, address, newOptions, callback);
|
||||
});
|
||||
getTransactionsInternal(this.remote, account, newOptions, callback);
|
||||
}).catch(callback);
|
||||
} else {
|
||||
const newOptions = _.assign(defaults, options);
|
||||
getTransactionsInternal(this.remote, address, newOptions, callback);
|
||||
getTransactionsInternal(this.remote, account, newOptions, callback);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(getTransactions);
|
||||
function getTransactions(account: string, options = {}) {
|
||||
return utils.promisify(getTransactionsAsync).call(this, account, options);
|
||||
}
|
||||
|
||||
module.exports = getTransactions;
|
||||
|
||||
@@ -1,16 +1,28 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const async = require('async');
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
const composeAsync = utils.common.composeAsync;
|
||||
const convertErrors = utils.common.convertErrors;
|
||||
const parseAccountTrustline = require('./parse/account-trustline');
|
||||
|
||||
function currencyFilter(currency, trustline) {
|
||||
return currency === null || trustline.specification.currency === currency;
|
||||
}
|
||||
|
||||
function formatResponse(options, data) {
|
||||
return {
|
||||
marker: data.marker,
|
||||
results: data.lines.map(parseAccountTrustline)
|
||||
.filter(_.partial(currencyFilter, options.currency || null))
|
||||
};
|
||||
}
|
||||
|
||||
function getAccountLines(remote, address, ledgerVersion, options, marker, limit,
|
||||
callback) {
|
||||
callback
|
||||
) {
|
||||
const requestOptions = {
|
||||
account: address,
|
||||
ledger: ledgerVersion,
|
||||
@@ -19,27 +31,27 @@ function getAccountLines(remote, address, ledgerVersion, options, marker, limit,
|
||||
peer: options.counterparty
|
||||
};
|
||||
|
||||
remote.requestAccountLines(requestOptions, (error, data) => {
|
||||
return error ? callback(error) :
|
||||
callback(null, {
|
||||
marker: data.marker,
|
||||
results: data.lines.map(parseAccountTrustline)
|
||||
.filter(_.partial(currencyFilter, options.currency || null))
|
||||
});
|
||||
});
|
||||
remote.requestAccountLines(requestOptions,
|
||||
composeAsync(_.partial(formatResponse, options),
|
||||
convertErrors(callback)));
|
||||
}
|
||||
|
||||
function getTrustlines(account: string, options: {currency: string,
|
||||
function getTrustlinesAsync(account: string, options: {currency: string,
|
||||
counterparty: string, limit: number, ledgerVersion: number},
|
||||
callback: () => void): void {
|
||||
callback: () => void
|
||||
): void {
|
||||
validate.address(account);
|
||||
validate.getTrustlinesOptions(options);
|
||||
|
||||
const ledgerVersion = options.ledgerVersion
|
||||
|| this.remote.getLedgerSequence();
|
||||
const getter = _.partial(getAccountLines, this.remote, account,
|
||||
ledgerVersion, options);
|
||||
options.ledgerVersion, options);
|
||||
utils.getRecursive(getter, options.limit, callback);
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(getTrustlines);
|
||||
function getTrustlines(account: string, options = {}) {
|
||||
return utils.promisify(async.seq(
|
||||
utils.getLedgerOptionsWithLedgerVersion,
|
||||
getTrustlinesAsync)).call(this, account, options);
|
||||
}
|
||||
|
||||
module.exports = getTrustlines;
|
||||
|
||||
@@ -1,23 +1,33 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const common = require('../common');
|
||||
const dropsToXrp = common.dropsToXrp;
|
||||
const composeAsync = common.composeAsync;
|
||||
import type {Remote} from '../../core/remote';
|
||||
|
||||
function clamp(value, min, max) {
|
||||
type Callback = (err: any, data: any) => void
|
||||
|
||||
function clamp(value: number, min: number, max: number): number {
|
||||
assert(min <= max, 'Illegal clamp bounds');
|
||||
return Math.min(Math.max(value, min), max);
|
||||
}
|
||||
|
||||
function getXRPBalance(remote, address, ledgerVersion, callback) {
|
||||
function getXRPBalance(remote: Remote, address: string, ledgerVersion?: number,
|
||||
callback: Callback
|
||||
): void {
|
||||
remote.requestAccountInfo({account: address, ledger: ledgerVersion},
|
||||
composeAsync((data) => dropsToXrp(data.account_data.Balance), callback));
|
||||
}
|
||||
|
||||
type Getter = (marker: ?string, limit: number, callback: Callback) => void
|
||||
|
||||
// If the marker is omitted from a response, you have reached the end
|
||||
// getter(marker, limit, callback), callback(error, {marker, results})
|
||||
function getRecursiveRecur(getter, marker, limit, callback) {
|
||||
function getRecursiveRecur(getter: Getter, marker?: string, limit: number,
|
||||
callback: Callback
|
||||
): void {
|
||||
getter(marker, limit, (error, data) => {
|
||||
if (error) {
|
||||
return callback(error);
|
||||
@@ -34,11 +44,13 @@ function getRecursiveRecur(getter, marker, limit, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function getRecursive(getter, limit, callback) {
|
||||
function getRecursive(getter: Getter, limit?: number, callback: Callback) {
|
||||
getRecursiveRecur(getter, undefined, limit || Infinity, callback);
|
||||
}
|
||||
|
||||
function renameCounterpartyToIssuer(amount) {
|
||||
type Amount = {counterparty?: string, issuer?: string, value: string}
|
||||
|
||||
function renameCounterpartyToIssuer(amount?: Amount): ?{issuer?: string} {
|
||||
if (amount === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -48,7 +60,9 @@ function renameCounterpartyToIssuer(amount) {
|
||||
return _.omit(withIssuer, 'counterparty');
|
||||
}
|
||||
|
||||
function renameCounterpartyToIssuerInOrder(order) {
|
||||
type Order = {taker_gets: Amount, taker_pays: Amount}
|
||||
|
||||
function renameCounterpartyToIssuerInOrder(order: Order) {
|
||||
const taker_gets = renameCounterpartyToIssuer(order.taker_gets);
|
||||
const taker_pays = renameCounterpartyToIssuer(order.taker_pays);
|
||||
const changes = {taker_gets: taker_gets, taker_pays: taker_pays};
|
||||
@@ -70,28 +84,58 @@ function signum(num) {
|
||||
* @returns {Number} [-1, 0, 1]
|
||||
*/
|
||||
|
||||
function compareTransactions(first, second) {
|
||||
if (first.ledgerVersion === second.ledgerVersion) {
|
||||
return signum(Number(first.indexInLedger) - Number(second.indexInLedger));
|
||||
type Outcome = {outcome: {ledgerVersion: number, indexInLedger: number}};
|
||||
|
||||
function compareTransactions(first: Outcome, second: Outcome): number {
|
||||
if (!first.outcome || !second.outcome) {
|
||||
return 0;
|
||||
}
|
||||
return Number(first.ledgerVersion) < Number(second.ledgerVersion) ? -1 : 1;
|
||||
if (first.outcome.ledgerVersion === second.outcome.ledgerVersion) {
|
||||
return signum(first.outcome.indexInLedger - second.outcome.indexInLedger);
|
||||
}
|
||||
return first.outcome.ledgerVersion < second.outcome.ledgerVersion ? -1 : 1;
|
||||
}
|
||||
|
||||
function hasCompleteLedgerRange(remote, minLedgerVersion, maxLedgerVersion) {
|
||||
function hasCompleteLedgerRange(remote: Remote, minLedgerVersion?: number,
|
||||
maxLedgerVersion?: number
|
||||
): boolean {
|
||||
|
||||
const firstLedgerVersion = 32570; // earlier versions have been lost
|
||||
return remote.getServer().hasLedgerRange(
|
||||
minLedgerVersion || firstLedgerVersion,
|
||||
maxLedgerVersion || remote.getLedgerSequence());
|
||||
maxLedgerVersion || remote.getLedgerSequenceSync());
|
||||
}
|
||||
|
||||
function isPendingLedgerVersion(remote: Remote, maxLedgerVersion: ?number
|
||||
): boolean {
|
||||
const currentLedger = remote.getLedgerSequenceSync();
|
||||
return currentLedger < (maxLedgerVersion || 0);
|
||||
}
|
||||
|
||||
function getLedgerOptionsWithLedgerVersion(account: string, options: Object,
|
||||
callback: (err?: ?Error, account?: string, options: Object) => void
|
||||
) {
|
||||
if (Boolean(options) && options.ledgerVersion !== undefined &&
|
||||
options.ledgerVersion !== null
|
||||
) {
|
||||
callback(null, account, options);
|
||||
} else {
|
||||
this.getLedgerVersion().then((version) => {
|
||||
callback(null, account, _.assign({}, options, {ledgerVersion: version}));
|
||||
}, callback);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getXRPBalance,
|
||||
getLedgerOptionsWithLedgerVersion,
|
||||
compareTransactions,
|
||||
renameCounterpartyToIssuer,
|
||||
renameCounterpartyToIssuerInOrder,
|
||||
getRecursive,
|
||||
hasCompleteLedgerRange,
|
||||
wrapCatch: common.wrapCatch,
|
||||
isPendingLedgerVersion,
|
||||
promisify: common.promisify,
|
||||
clamp: clamp,
|
||||
common: common
|
||||
};
|
||||
|
||||
74
src/api/offline/ledgerhash.js
Normal file
74
src/api/offline/ledgerhash.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const common = require('../common');
|
||||
|
||||
function convertLedgerHeader(header) {
|
||||
return {
|
||||
accepted: header.accepted,
|
||||
closed: header.closed,
|
||||
account_hash: header.stateHash,
|
||||
close_time: header.closeTime,
|
||||
close_time_resolution: header.closeTimeResolution,
|
||||
close_flags: header.closeFlags,
|
||||
hash: header.ledgerHash,
|
||||
ledger_hash: header.ledgerHash,
|
||||
ledger_index: header.ledgerVersion.toString(),
|
||||
seqNum: header.ledgerVersion.toString(),
|
||||
parent_hash: header.parentLedgerHash,
|
||||
parent_close_time: header.parentCloseTime,
|
||||
total_coins: header.totalDrops,
|
||||
totalCoins: header.totalDrops,
|
||||
transaction_hash: header.transactionHash
|
||||
};
|
||||
}
|
||||
|
||||
function hashLedgerHeader(ledgerHeader) {
|
||||
const header = convertLedgerHeader(ledgerHeader);
|
||||
return common.core.Ledger.calculateLedgerHash(header);
|
||||
}
|
||||
|
||||
function computeTransactionHash(ledger) {
|
||||
if (ledger.rawTransactions === undefined) {
|
||||
return ledger.transactionHash;
|
||||
}
|
||||
const transactions = JSON.parse(ledger.rawTransactions);
|
||||
const txs = _.map(transactions, tx => {
|
||||
const mergeTx = _.assign({}, _.omit(tx, 'tx'), tx.tx || {});
|
||||
const renameMeta = _.assign({}, _.omit(mergeTx, 'meta'),
|
||||
tx.meta ? {metaData: tx.meta} : {});
|
||||
return renameMeta;
|
||||
});
|
||||
const ledgerObject = common.core.Ledger.from_json({transactions: txs});
|
||||
const transactionHash = ledgerObject.calc_tx_hash().to_hex();
|
||||
if (ledger.transactionHash !== undefined
|
||||
&& ledger.transactionHash !== transactionHash) {
|
||||
throw new common.errors.ValidationError('transactionHash in header'
|
||||
+ ' does not match computed hash of transactions');
|
||||
}
|
||||
return transactionHash;
|
||||
}
|
||||
|
||||
function computeStateHash(ledger) {
|
||||
if (ledger.rawState === undefined) {
|
||||
return ledger.stateHash;
|
||||
}
|
||||
const state = JSON.parse(ledger.rawState);
|
||||
const ledgerObject = common.core.Ledger.from_json({accountState: state});
|
||||
const stateHash = ledgerObject.calc_account_hash().to_hex();
|
||||
if (ledger.stateHash !== undefined && ledger.stateHash !== stateHash) {
|
||||
throw new common.errors.ValidationError('stateHash in header'
|
||||
+ ' does not match computed hash of state');
|
||||
}
|
||||
return stateHash;
|
||||
}
|
||||
|
||||
function computeLedgerHash(ledger: Object): string {
|
||||
const hashes = {
|
||||
transactionHash: computeTransactionHash(ledger),
|
||||
stateHash: computeStateHash(ledger)
|
||||
};
|
||||
return hashLedgerHeader(_.assign({}, ledger, hashes));
|
||||
}
|
||||
|
||||
module.exports = computeLedgerHash;
|
||||
@@ -2,20 +2,43 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const common = require('../common');
|
||||
import type {Remote} from '../../core/remote';
|
||||
|
||||
// If a ledger is not received in this time, consider the connection offline
|
||||
const CONNECTION_TIMEOUT = 1000 * 30;
|
||||
|
||||
function connect(callback: (err: any, data: any) => void): void {
|
||||
this.remote.connect(callback);
|
||||
type GetServerInfoResponse = {
|
||||
buildVersion: string,
|
||||
completeLedgers: string,
|
||||
hostid: string,
|
||||
ioLatencyMs: number,
|
||||
load?: {
|
||||
jobTypes: Array<Object>,
|
||||
threads: number
|
||||
},
|
||||
lastClose: {
|
||||
convergeTimeS: number,
|
||||
proposers: number
|
||||
},
|
||||
loadFactor: number,
|
||||
peers: number,
|
||||
pubkeyNode: string,
|
||||
pubkeyValidator?: string,
|
||||
serverState: string,
|
||||
validatedLedger: {
|
||||
age: number,
|
||||
baseFeeXrp: number,
|
||||
hash: string,
|
||||
reserveBaseXrp: number,
|
||||
reserveIncXrp: number,
|
||||
seq: number
|
||||
},
|
||||
validationQuorum: number
|
||||
}
|
||||
|
||||
function disconnect(callback: (err: any, data: any) => void): void {
|
||||
this.remote.disconnect(callback);
|
||||
}
|
||||
|
||||
function isUpToDate(remote): boolean {
|
||||
function isUpToDate(remote: Remote): boolean {
|
||||
const server = remote.getServer();
|
||||
return Boolean(server) && (remote._stand_alone
|
||||
|| (Date.now() - server._lastLedgerClose) <= CONNECTION_TIMEOUT);
|
||||
@@ -25,22 +48,72 @@ function isConnected(): boolean {
|
||||
return Boolean(this.remote._ledger_current_index) && isUpToDate(this.remote);
|
||||
}
|
||||
|
||||
function getServerInfo(callback: (err: any, data: any) => void): void {
|
||||
function getServerInfoAsync(
|
||||
callback: (err: any, data?: GetServerInfoResponse) => void
|
||||
): void {
|
||||
this.remote.requestServerInfo((error, response) => {
|
||||
if (error) {
|
||||
callback(new common.errors.RippledNetworkError(error.message));
|
||||
const message = _.get(error, ['remote', 'error_message'], error.message);
|
||||
callback(new common.errors.RippledNetworkError(message));
|
||||
} else {
|
||||
callback(null, response.info);
|
||||
callback(null,
|
||||
common.convertKeysFromSnakeCaseToCamelCase(response.info));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getFee(): number {
|
||||
return common.dropsToXrp(this.remote.createTransaction()._computeFee());
|
||||
function getFee(): ?number {
|
||||
if (!this.remote.getConnectedServers().length) {
|
||||
throw new common.errors.RippledNetworkError('No servers available.');
|
||||
}
|
||||
const fee = this.remote.createTransaction()._computeFee();
|
||||
return fee === undefined ? undefined : common.dropsToXrp(fee);
|
||||
}
|
||||
|
||||
function getLedgerVersion(): number {
|
||||
return this.remote.getLedgerSequence();
|
||||
function getLedgerVersion(): Promise<number> {
|
||||
return common.promisify(this.remote.getLedgerSequence).call(this.remote);
|
||||
}
|
||||
|
||||
function connect(): Promise<void> {
|
||||
return common.promisify(callback => {
|
||||
try {
|
||||
this.remote.connect(() => callback(null));
|
||||
} catch(error) {
|
||||
callback(new common.errors.RippledNetworkError(error.message));
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
function disconnect(): Promise<void> {
|
||||
return common.promisify(callback => {
|
||||
try {
|
||||
this.remote.disconnect(() => callback(null));
|
||||
} catch(error) {
|
||||
callback(new common.errors.RippledNetworkError(error.message));
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
function getServerInfo(): Promise<GetServerInfoResponse> {
|
||||
return common.promisify(getServerInfoAsync).call(this);
|
||||
}
|
||||
|
||||
function rippleTimeToISO8601(rippleTime: string): string {
|
||||
return new Date(common.core.utils.toTimestamp(rippleTime)).toISOString();
|
||||
}
|
||||
|
||||
function formatLedgerClose(ledgerClose: Object): Object {
|
||||
return {
|
||||
feeBase: ledgerClose.fee_base,
|
||||
feeReference: ledgerClose.fee_ref,
|
||||
ledgerHash: ledgerClose.ledger_hash,
|
||||
ledgerVersion: ledgerClose.ledger_index,
|
||||
ledgerTimestamp: rippleTimeToISO8601(ledgerClose.ledger_time),
|
||||
reserveBase: ledgerClose.reserve_base,
|
||||
reserveIncrement: ledgerClose.reserve_inc,
|
||||
transactionCount: ledgerClose.txn_count,
|
||||
validatedLedgerVersions: ledgerClose.validated_ledgers
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
@@ -49,5 +122,6 @@ module.exports = {
|
||||
isConnected,
|
||||
getServerInfo,
|
||||
getFee,
|
||||
getLedgerVersion
|
||||
getLedgerVersion,
|
||||
formatLedgerClose
|
||||
};
|
||||
|
||||
@@ -30,9 +30,14 @@ function createOrderTransaction(account, order) {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
function prepareOrder(account, order, instructions, callback) {
|
||||
function prepareOrderAsync(account, order, instructions, callback) {
|
||||
const transaction = createOrderTransaction(account, order);
|
||||
utils.createTxJSON(transaction, this.remote, instructions, callback);
|
||||
utils.prepareTransaction(transaction, this.remote, instructions, callback);
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(prepareOrder);
|
||||
function prepareOrder(account: string, order: Object, instructions = {}) {
|
||||
return utils.promisify(prepareOrderAsync.bind(this))(
|
||||
account, order, instructions);
|
||||
}
|
||||
|
||||
module.exports = prepareOrder;
|
||||
|
||||
@@ -13,9 +13,18 @@ function createOrderCancellationTransaction(account, sequence) {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
function prepareOrderCancellation(account, sequence, instructions, callback) {
|
||||
function prepareOrderCancellationAsync(account, sequence, instructions,
|
||||
callback
|
||||
) {
|
||||
const transaction = createOrderCancellationTransaction(account, sequence);
|
||||
utils.createTxJSON(transaction, this.remote, instructions, callback);
|
||||
utils.prepareTransaction(transaction, this.remote, instructions, callback);
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(prepareOrderCancellation);
|
||||
function prepareOrderCancellation(account: string, sequence: number,
|
||||
instructions = {}
|
||||
) {
|
||||
return utils.promisify(prepareOrderCancellationAsync.bind(this))(
|
||||
account, sequence, instructions);
|
||||
}
|
||||
|
||||
module.exports = prepareOrderCancellation;
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const BigNumber = require('bignumber.js');
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
const toRippledAmount = utils.common.toRippledAmount;
|
||||
const Transaction = utils.common.core.Transaction;
|
||||
const ValidationError = utils.common.errors.ValidationError;
|
||||
|
||||
function isSendMaxAllowed(payment) {
|
||||
const srcAmt = payment.source.amount;
|
||||
const dstAmt = payment.destination.amount;
|
||||
|
||||
// Don't set SendMax for XRP->XRP payment
|
||||
// temREDUNDANT_SEND_MAX removed in:
|
||||
// https://github.com/ripple/rippled/commit/
|
||||
// c522ffa6db2648f1d8a987843e7feabf1a0b7de8/
|
||||
return srcAmt && !(srcAmt.currency === 'XRP' && dstAmt.currency === 'XRP');
|
||||
function isXRPToXRPPayment(payment) {
|
||||
const sourceCurrency = _.get(payment, 'source.maxAmount.currency');
|
||||
const destinationCurrency = _.get(payment, 'destination.amount.currency');
|
||||
return sourceCurrency === 'XRP' && destinationCurrency === 'XRP';
|
||||
}
|
||||
|
||||
function isIOUWithoutCounterparty(amount) {
|
||||
@@ -29,24 +24,49 @@ function applyAnyCounterpartyEncoding(payment) {
|
||||
// https://ripple.com/build/transactions/
|
||||
// #special-issuer-values-for-sendmax-and-amount
|
||||
// https://ripple.com/build/ripple-rest/#counterparties-in-payments
|
||||
if (isIOUWithoutCounterparty(payment.source.amount)) {
|
||||
payment.source.amount.counterparty = payment.source.address;
|
||||
}
|
||||
if (isIOUWithoutCounterparty(payment.destination.amount)) {
|
||||
payment.destination.amount.counterparty = payment.destination.address;
|
||||
}
|
||||
_.forEach([payment.source, payment.destination], (adjustment) => {
|
||||
_.forEach(['amount', 'minAmount', 'maxAmount'], (key) => {
|
||||
if (isIOUWithoutCounterparty(adjustment[key])) {
|
||||
adjustment[key].counterparty = adjustment.address;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function createPaymentTransaction(account, payment) {
|
||||
function createMaximalAmount(amount) {
|
||||
const maxXRPValue = '100000000000';
|
||||
const maxIOUValue = '9999999999999999e80';
|
||||
const maxValue = amount.currency === 'XRP' ? maxXRPValue : maxIOUValue;
|
||||
return _.assign(amount, {value: maxValue});
|
||||
}
|
||||
|
||||
function createPaymentTransaction(account, paymentArgument) {
|
||||
const payment = _.cloneDeep(paymentArgument);
|
||||
applyAnyCounterpartyEncoding(payment);
|
||||
validate.address(account);
|
||||
validate.payment(payment);
|
||||
|
||||
if ((payment.source.maxAmount && payment.destination.minAmount) ||
|
||||
(payment.source.amount && payment.destination.amount)) {
|
||||
throw new ValidationError('payment must specify either (source.maxAmount '
|
||||
+ 'and destination.amount) or (source.amount and destination.minAmount)');
|
||||
}
|
||||
|
||||
// when using destination.minAmount, rippled still requires that we set
|
||||
// a destination amount in addition to DeliverMin. the destination amount
|
||||
// is interpreted as the maximum amount to send. we want to be sure to
|
||||
// send the whole source amount, so we set the destination amount to the
|
||||
// maximum possible amount. otherwise it's possible that the destination
|
||||
// cap could be hit before the source cap.
|
||||
const amount = payment.destination.minAmount && !isXRPToXRPPayment(payment) ?
|
||||
createMaximalAmount(payment.destination.minAmount) :
|
||||
(payment.destination.amount || payment.destination.minAmount);
|
||||
|
||||
const transaction = new Transaction();
|
||||
transaction.payment({
|
||||
from: payment.source.address,
|
||||
to: payment.destination.address,
|
||||
amount: toRippledAmount(payment.destination.amount)
|
||||
amount: toRippledAmount(amount)
|
||||
});
|
||||
|
||||
if (payment.invoiceID) {
|
||||
@@ -58,36 +78,51 @@ function createPaymentTransaction(account, payment) {
|
||||
if (payment.destination.tag) {
|
||||
transaction.destinationTag(payment.destination.tag);
|
||||
}
|
||||
if (payment.paths) {
|
||||
transaction.paths(JSON.parse(payment.paths));
|
||||
}
|
||||
if (payment.memos) {
|
||||
_.forEach(payment.memos, memo =>
|
||||
transaction.addMemo(memo.type, memo.format, memo.data)
|
||||
);
|
||||
}
|
||||
if (payment.allowPartialPayment) {
|
||||
transaction.setFlags(['PartialPayment']);
|
||||
}
|
||||
if (payment.noDirectRipple) {
|
||||
transaction.setFlags(['NoRippleDirect']);
|
||||
}
|
||||
if (payment.limitQuality) {
|
||||
transaction.setFlags(['LimitQuality']);
|
||||
}
|
||||
if (isSendMaxAllowed(payment)) {
|
||||
const maxValue = new BigNumber(payment.source.amount.value)
|
||||
.plus(payment.source.slippage || 0).toString();
|
||||
const maxAmount = _.assign({}, payment.source.amount, {value: maxValue});
|
||||
transaction.sendMax(toRippledAmount(maxAmount));
|
||||
if (!isXRPToXRPPayment(payment)) {
|
||||
// Don't set SendMax for XRP->XRP payment
|
||||
// temREDUNDANT_SEND_MAX removed in:
|
||||
// https://github.com/ripple/rippled/commit/
|
||||
// c522ffa6db2648f1d8a987843e7feabf1a0b7de8/
|
||||
if (payment.allowPartialPayment || payment.destination.minAmount) {
|
||||
transaction.setFlags(['PartialPayment']);
|
||||
}
|
||||
|
||||
transaction.setSendMax(toRippledAmount(
|
||||
payment.source.maxAmount || payment.source.amount));
|
||||
|
||||
if (payment.destination.minAmount) {
|
||||
transaction.setDeliverMin(toRippledAmount(payment.destination.minAmount));
|
||||
}
|
||||
|
||||
if (payment.paths) {
|
||||
transaction.paths(JSON.parse(payment.paths));
|
||||
}
|
||||
} else if (payment.allowPartialPayment) {
|
||||
throw new ValidationError('XRP to XRP payments cannot be partial payments');
|
||||
}
|
||||
|
||||
return transaction;
|
||||
}
|
||||
|
||||
function preparePayment(account, payment, instructions, callback) {
|
||||
function preparePaymentAsync(account, payment, instructions, callback) {
|
||||
const transaction = createPaymentTransaction(account, payment);
|
||||
utils.createTxJSON(transaction, this.remote, instructions, callback);
|
||||
utils.prepareTransaction(transaction, this.remote, instructions, callback);
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(preparePayment);
|
||||
function preparePayment(account: string, payment: Object, instructions = {}) {
|
||||
return utils.promisify(preparePaymentAsync.bind(this))(
|
||||
account, payment, instructions);
|
||||
}
|
||||
|
||||
module.exports = preparePayment;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const BigNumber = require('bignumber.js');
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
const AccountFlagIndices = utils.common.constants.AccountFlagIndices;
|
||||
@@ -9,7 +9,7 @@ const AccountFields = utils.common.constants.AccountFields;
|
||||
const Transaction = utils.common.core.Transaction;
|
||||
|
||||
// Emptry string passed to setting will clear it
|
||||
const CLEAR_SETTING = '';
|
||||
const CLEAR_SETTING = null;
|
||||
|
||||
function setTransactionFlags(transaction, values) {
|
||||
const keys = Object.keys(values);
|
||||
@@ -64,7 +64,7 @@ function setTransactionFields(transaction, input) {
|
||||
*/
|
||||
|
||||
function convertTransferRate(transferRate) {
|
||||
return _.isNumber(transferRate) ? transferRate * 1e9 : transferRate;
|
||||
return (new BigNumber(transferRate)).shift(9).toNumber();
|
||||
}
|
||||
|
||||
function createSettingsTransaction(account, settings) {
|
||||
@@ -90,9 +90,14 @@ function createSettingsTransaction(account, settings) {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
function prepareSettings(account, settings, instructions, callback) {
|
||||
function prepareSettingsAsync(account, settings, instructions, callback) {
|
||||
const transaction = createSettingsTransaction(account, settings);
|
||||
utils.createTxJSON(transaction, this.remote, instructions, callback);
|
||||
utils.prepareTransaction(transaction, this.remote, instructions, callback);
|
||||
}
|
||||
|
||||
module.exports = utils.wrapCatch(prepareSettings);
|
||||
function prepareSettings(account: string, settings: Object, instructions = {}) {
|
||||
return utils.promisify(prepareSettingsAsync.bind(this))(
|
||||
account, settings, instructions);
|
||||
}
|
||||
|
||||
module.exports = prepareSettings;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const utils = require('./utils');
|
||||
const keypairs = require('ripple-keypairs');
|
||||
const core = utils.common.core;
|
||||
const validate = utils.common.validate;
|
||||
|
||||
@@ -15,16 +16,6 @@ const validate = utils.common.validate;
|
||||
* some arbitrary string. For example "TXN".
|
||||
*/
|
||||
const HASH_TX_ID = 0x54584E00; // 'TXN'
|
||||
const HASH_TX_SIGN = 0x53545800; // 'STX'
|
||||
const HASH_TX_SIGN_TESTNET = 0x73747800; // 'stx'
|
||||
|
||||
function getKeyPair(address, secret) {
|
||||
return core.Seed.from_json(secret).get_key(address);
|
||||
}
|
||||
|
||||
function getPublicKeyHex(keypair) {
|
||||
return keypair.to_hex_pub();
|
||||
}
|
||||
|
||||
function serialize(txJSON) {
|
||||
return core.SerializedObject.from_json(txJSON);
|
||||
@@ -34,31 +25,26 @@ function hashSerialization(serialized, prefix) {
|
||||
return serialized.hash(prefix || HASH_TX_ID).to_hex();
|
||||
}
|
||||
|
||||
function hashJSON(txJSON, prefix) {
|
||||
return hashSerialization(serialize(txJSON), prefix);
|
||||
function signingData(txJSON) {
|
||||
return core.Transaction.from_json(txJSON).signingData().buffer;
|
||||
}
|
||||
|
||||
function signingHash(txJSON, isTestNet=false) {
|
||||
return hashJSON(txJSON, isTestNet ? HASH_TX_SIGN_TESTNET : HASH_TX_SIGN);
|
||||
function computeSignature(txJSON, privateKey) {
|
||||
return keypairs.sign(signingData(txJSON), privateKey);
|
||||
}
|
||||
|
||||
function computeSignature(txJSON, keypair) {
|
||||
const signature = keypair.sign(signingHash(txJSON));
|
||||
return core.sjcl.codec.hex.fromBits(signature).toUpperCase();
|
||||
}
|
||||
function sign(txJSON: string, secret: string
|
||||
): {signedTransaction: string; id: string} {
|
||||
const tx = JSON.parse(txJSON);
|
||||
validate.txJSON(tx);
|
||||
validate.secret(secret);
|
||||
|
||||
function sign(txJSON: {Account: string; SigningPubKey: string,
|
||||
TxnSignature: string}, secret: string):
|
||||
{signedTransaction: string; id: string} {
|
||||
validate.txJSON(txJSON);
|
||||
validate.addressAndSecret({address: txJSON.Account, secret: secret});
|
||||
|
||||
const keypair = getKeyPair(txJSON.Account, secret);
|
||||
if (txJSON.SigningPubKey === undefined) {
|
||||
txJSON.SigningPubKey = getPublicKeyHex(keypair);
|
||||
const keypair = keypairs.deriveKeypair(secret);
|
||||
if (tx.SigningPubKey === undefined) {
|
||||
tx.SigningPubKey = keypair.publicKey;
|
||||
}
|
||||
txJSON.TxnSignature = computeSignature(txJSON, keypair);
|
||||
const serialized = serialize(txJSON);
|
||||
tx.TxnSignature = computeSignature(tx, keypair.privateKey);
|
||||
const serialized = serialize(tx);
|
||||
return {
|
||||
signedTransaction: serialized.to_hex(),
|
||||
id: hashSerialization(serialized, HASH_TX_ID)
|
||||
|
||||
@@ -1,15 +1,44 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
const Request = utils.common.core.Request;
|
||||
const convertErrors = utils.common.convertErrors;
|
||||
|
||||
function submit(tx_blob: string,
|
||||
callback: (err: any, data: any) => void): void {
|
||||
validate.blob(tx_blob);
|
||||
function isImmediateRejection(engineResult) {
|
||||
// note: "tel" errors mean the local server refused to process the
|
||||
// transaction *at that time*, but it could potentially buffer the
|
||||
// transaction and then process it at a later time, for example
|
||||
// if the required fee changes (this does not occur at the time of
|
||||
// this writing, but it could change in the future)
|
||||
// all other error classes can potentially result in transcation validation
|
||||
return _.startsWith(engineResult, 'tem') || _.startsWith(engineResult, 'tej');
|
||||
}
|
||||
|
||||
function convertSubmitErrors(callback) {
|
||||
return function(error, data) {
|
||||
if (!error && isImmediateRejection(data.engineResult)) {
|
||||
callback(new utils.common.errors.RippleError('Submit failed'), data);
|
||||
} else {
|
||||
callback(error, data);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function submitAsync(txBlob: string, callback: (err: any, data: any) => void
|
||||
): void {
|
||||
validate.blob(txBlob);
|
||||
const request = new Request(this.remote, 'submit');
|
||||
request.message.tx_blob = tx_blob;
|
||||
request.request(null, callback);
|
||||
request.message.tx_blob = txBlob;
|
||||
request.request(null,
|
||||
utils.common.composeAsync(
|
||||
data => utils.common.convertKeysFromSnakeCaseToCamelCase(data),
|
||||
convertSubmitErrors(convertErrors(callback))));
|
||||
}
|
||||
|
||||
function submit(txBlob: string) {
|
||||
return utils.promisify(submitAsync.bind(this))(txBlob);
|
||||
}
|
||||
|
||||
module.exports = submit;
|
||||
|
||||
40
src/api/transaction/suspended-payment-cancellation.js
Normal file
40
src/api/transaction/suspended-payment-cancellation.js
Normal file
@@ -0,0 +1,40 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
const Transaction = utils.common.core.Transaction;
|
||||
|
||||
function createSuspendedPaymentCancellationTransaction(account, payment) {
|
||||
validate.address(account);
|
||||
validate.suspendedPaymentCancellation(payment);
|
||||
|
||||
const transaction = new Transaction();
|
||||
transaction.suspendedPaymentCancel({
|
||||
account: account,
|
||||
owner: payment.owner,
|
||||
paymentSequence: payment.paymentSequence
|
||||
});
|
||||
|
||||
if (payment.memos) {
|
||||
_.forEach(payment.memos, memo =>
|
||||
transaction.addMemo(memo.type, memo.format, memo.data)
|
||||
);
|
||||
}
|
||||
return transaction;
|
||||
}
|
||||
|
||||
function prepareSuspendedPaymentCancellationAsync(account, payment,
|
||||
instructions, callback) {
|
||||
const transaction =
|
||||
createSuspendedPaymentCancellationTransaction(account, payment);
|
||||
utils.prepareTransaction(transaction, this.remote, instructions, callback);
|
||||
}
|
||||
|
||||
function prepareSuspendedPaymentCancellation(account: string, payment: Object,
|
||||
instructions = {}) {
|
||||
return utils.promisify(prepareSuspendedPaymentCancellationAsync)
|
||||
.call(this, account, payment, instructions);
|
||||
}
|
||||
|
||||
module.exports = prepareSuspendedPaymentCancellation;
|
||||
57
src/api/transaction/suspended-payment-creation.js
Normal file
57
src/api/transaction/suspended-payment-creation.js
Normal file
@@ -0,0 +1,57 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const validate = utils.common.validate;
|
||||
const toRippledAmount = utils.common.toRippledAmount;
|
||||
const Transaction = utils.common.core.Transaction;
|
||||
|
||||
function createSuspendedPaymentCreationTransaction(account, payment) {
|
||||
validate.address(account);
|
||||
validate.suspendedPaymentCreation(payment);
|
||||
|
||||
const transaction = new Transaction();
|
||||
transaction.suspendedPaymentCreate({
|
||||
account: account,
|
||||
destination: payment.destination.address,
|
||||
amount: toRippledAmount(payment.destination.amount)
|
||||
});
|
||||
|
||||
if (payment.digest) {
|
||||
transaction.setDigest(payment.digest);
|
||||
}
|
||||
if (payment.allowCancelAfter) {
|
||||
transaction.setAllowCancelAfter(payment.allowCancelAfter);
|
||||
}
|
||||
if (payment.allowExecuteAfter) {
|
||||
transaction.setAllowExecuteAfter(payment.allowExecuteAfter);
|
||||
}
|
||||
|
||||
if (payment.source.tag) {
|
||||
transaction.sourceTag(payment.source.tag);
|
||||
}
|
||||
if (payment.destination.tag) {
|
||||
transaction.destinationTag(payment.destination.tag);
|
||||
}
|
||||
if (payment.memos) {
|
||||
_.forEach(payment.memos, memo =>
|
||||
transaction.addMemo(memo.type, memo.format, memo.data)
|
||||
);
|
||||
}
|
||||
return transaction;
|
||||
}
|
||||
|
||||
function prepareSuspendedPaymentCreationAsync(account, payment, instructions,
|
||||
callback) {
|
||||
const transaction =
|
||||
createSuspendedPaymentCreationTransaction(account, payment);
|
||||
utils.prepareTransaction(transaction, this.remote, instructions, callback);
|
||||
}
|
||||
|
||||
function prepareSuspendedPaymentCreation(account: string, payment: Object,
|
||||
instructions = {}) {
|
||||
return utils.promisify(prepareSuspendedPaymentCreationAsync)
|
||||
.call(this, account, payment, instructions);
|
||||
}
|
||||
|
||||
module.exports = prepareSuspendedPaymentCreation;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user