Compare commits

...

306 Commits

Author SHA1 Message Date
Elliot Lee
8278dc5b5b Release 1.2.1 2019-03-23 15:50:26 -07:00
Elliot Lee
c90d486454 Update ripple-binary-codec to 0.2.1 to support tecKILLED 2019-03-23 15:12:22 -07:00
Elliot Lee
35f9b7ec8d Release 1.2.0 2019-03-19 01:28:42 -07:00
Elliot Lee
69e621af86 Remove coveralls from devDependencies 2019-03-19 01:21:36 -07:00
Elliot Lee
0e92e696d4 Remove unused http-server from devDependencies 2019-03-18 16:51:08 -07:00
Elliot Lee
0b1445bfe9 Remove sauce runner 2019-03-18 16:14:21 -07:00
Elliot Lee
db2d7ba1f5 Update mocha to 6.0.2 2019-03-18 16:09:26 -07:00
Elliot Lee
d82703f41b prepareTransaction should not overwrite Sequence (#990)
* Cleans up some code and fixes some type errors

* Clarify how null settings work

* Document updated RippledError

* Updates per review by @mDuo13
2019-03-18 15:55:42 -07:00
Elliot Lee
8213861ab7 Update HISTORY.md 2019-03-13 14:34:31 -07:00
Kincaid O'Neil
a842c380cf fix: add amount to FormattedPaymentChannel type (#989)
* fix: add amount to FormattedPaymentChannel type

* fix: ignore package-lock.json
2019-03-12 16:58:30 -07:00
Elliot Lee
5bf6f1849a Fix typos in docs 2019-03-12 15:27:19 -07:00
Elliot Lee
bfe4877f73 Merge remote-tracking branch 'origin/master' into develop 2019-03-12 15:12:58 -07:00
Elliot Lee
63dcddf6f4 [Docs] Update transaction responses link
List of transaction responses
2019-03-11 12:14:41 -07:00
Rome Reginelli
68735ddb35 Docs: Fix prepareTransaction method specification (#986) 2019-02-11 23:39:41 -08:00
Elliot Lee
1fd9ca7ef2 Use Buffer.from and clean up a few things (#985) 2019-02-07 00:29:59 -08:00
Elliot Lee
2445004333 Change prepare* methods to reject Promise on error (#984)
* Reject Promise on error, update docs, and add tests:
  * preparePayment
  * prepareTrustline
  * prepareOrder
  * prepareOrderCancellation
  * prepareSettings
  * prepareEscrowCreation
  * prepareEscrowExecution
  * prepareCheckCreate
  * prepareCheckCash
  * prepareCheckCancel
  * preparePaymentChannelCreate
  * preparePaymentChannelFund
  * preparePaymentChannelClaim

Note that we can't update mocha to ^5.2.0 because it causes testing to hang indefinitely; this needs to be investigated.
2019-01-29 15:22:18 -08:00
Elliot Lee
dc148bf954 Update HISTORY.md 2018-12-12 17:38:34 -08:00
Elliot Lee
f3c34bd75a Release 1.1.2 2018-12-12 14:55:15 -08:00
Alexandru Chiriac
5419e67dbc GetLedger by hash option (#980)
* update ledger input schema
* include ledgerHash option
2018-12-12 11:02:50 -08:00
Alexandru Chiriac
8d37da0952 Update Submit Response (#978)
* update submit output schema
* update submit response object
2018-12-04 15:35:07 -08:00
Elliot Lee
a8075d98df Add list of applications using ripple-lib (#976) 2018-11-29 16:39:48 -08:00
Elliot Lee
fcc205b85a Release 1.1.1 2018-11-27 15:17:42 -08:00
Elliot Lee
0f5056221f Fix getOrderbook (#970)
* Fix `getOrderbook` (Fix #766)
* Add `formatBidsAndAsks` as a recommended alternative to `getOrderbook`
* Add `renameCounterpartyToIssuer`
2018-11-26 15:25:15 -08:00
Elliot Lee
8384ace746 Add return type for generateAddress (#968)
For TypeScript apps
2018-11-20 15:35:34 -08:00
Elliot Lee
040cabece0 Add comments for accountRootFlags (#962) 2018-11-16 22:34:41 -08:00
Elliot Lee
319a8d6ab2 Fix book-offers test fixture by swapping bids/asks (#966) 2018-10-31 22:48:27 -07:00
Elliot Lee
50a7320886 Release 1.1.0 2018-10-31 16:36:20 -07:00
Elliot Lee
418987476e Add DepositPreauth (#958)
* Expose parseAccountFlags() and add docs
* Add example snippet
* Default to node v10 for nvm
* Maintain existing behavior for getSettings
* Increase max line length from 80 to 120 (ter-max-len)
2018-10-31 16:27:32 -07:00
Elliot Lee
89e4ff328c Apply formatting to book-offers fixture 2018-10-31 16:07:25 -07:00
Elliot Lee
04bf49cb43 Support node 10 (#964)
* Update webpack from 3.11.0 to 3.12.0 and upath from 1.0.4 to 1.1.0
* Run: yarn upgrade gulp
  * See https://github.com/gulpjs/gulp/issues/2162
* Update README
* Travis: test node 10
2018-10-30 14:15:42 -07:00
Elliot Lee
1c017df2a3 Merge pull request #955 from jcperkins12/feature/balanceChanges-TypeCorrection
Type balanceChanges should be array of changes not array with one change
2018-10-24 20:34:03 -07:00
Elliot Lee
5fed1f08e4 Document xrpToDrops, dropsToXrp, iso8601ToRippleTime, schemaValidator, and more
The following methods are available directly under the RippleAPI object,
not under schemaValidator:

isValidAddress, isValidSecret, deriveKeypair, deriveAddress
2018-10-18 01:16:50 -07:00
Elliot Lee
82c349c8c4 HISTORY: List Check transaction types
Transaction types that were added in 0.19.0
2018-10-17 16:22:48 -07:00
Elliot Lee
0f7af6a4e9 Add depositAuth to FormattedSettings type 2018-10-17 15:58:52 -07:00
Elliot Lee
8db1791ed2 README: Remove obsolete badges 2018-10-16 12:48:48 -07:00
Elliot Lee
a29ec1b8c7 Release 1.0.2 2018-10-16 12:28:24 -07:00
Elliot Lee
232a760a58 yarn: Add integrity hashes to yarn.lock
Added in yarn v1.10.0, see https://github.com/yarnpkg/yarn/pull/5042
2018-10-16 12:24:15 -07:00
Elliot Lee
f4ad04d334 Exclude SendMax from XRP to XRP payments (#957)
Fix #954
2018-10-16 12:21:29 -07:00
Cory Perkins
8dfec20871 Changed type of balanceChanges made to an account from an array of one change to an array of 1 change to and array of records with the type of a blanceChange 2018-10-10 12:21:16 -05:00
Cory Perkins
64745017e9 book_offers returns offers type OfferLedgerEntry (#951)
* rippled-api function book_offers returns offers in the format of OfferLedgerEntry not OfferCreateTransaction
* updated type of account_objects
2018-10-02 02:14:17 -07:00
Elliot Lee
37edede728 Use object instead of Object (#936) 2018-10-02 02:13:28 -07:00
Elliot Lee
f785605db8 Release 1.0.1 2018-09-27 19:01:38 -07:00
Elliot Lee
01ad30ab07 Fix typos in ledger_entries.ts 2018-09-19 14:24:02 -07:00
Cory Perkins
e08d507462 Add remaining LedgerEntry types (#943)
* Replaced the union with 'any' in the LedgerEntry type
* Added DepositPreauthLedgerEntry (new in rippled 1.1.0)
2018-09-19 14:21:52 -07:00
wudanjs
4c23bd5ad3 Include memos when parsing trustlines (#949) 2018-09-19 14:17:38 -07:00
Scott M Sunarto
b15abd5376 Update server regex to accommodate UDS (#944) 2018-09-18 11:47:46 -07:00
Elliot Lee
79971f906b Update release notes 2018-09-11 18:45:52 -07:00
Elliot Lee
9eec98778f Expose validation methods (#932)
Merge branch 'movitto-expose_validation_methods' into develop
2018-09-11 18:33:55 -07:00
Elliot Lee
dcd0e14142 Add test of deriveKeypair with ed25519 secret 2018-09-11 18:33:07 -07:00
Elliot Lee
cfcbc9aab7 Update checksums for 1.0.0 2018-09-10 14:52:14 -07:00
Mo Morsi
a80de5658a Move deriveKeypair and deriveAddress to offline module 2018-09-09 09:39:25 -04:00
Mo Morsi
34215eb309 Add docs for newly exposed API methods 2018-09-09 09:39:25 -04:00
Mo Morsi
9458005d7f Add tests for newly exposed API methods 2018-09-09 09:39:25 -04:00
Mo Morsi
5f36df0172 Expose deriveKeypair, deriveAddress, isValidAddress, and isValidSecret to the public API 2018-09-09 09:39:25 -04:00
Elliot Lee
3ff4929a49 Fix PendingLedgerVersionError message and export FormattedTransactionType (#941) 2018-09-04 18:31:24 -07:00
Elliot Lee
4bea69d647 Release 1.0.0 2018-08-30 14:30:57 -07:00
Elliot Lee
09541dae86 docs: rippled APIs use issuer 2018-08-30 14:12:45 -07:00
Elliot Lee
bcbcc53c87 No `--coverage' option anymore with nyc
See https://github.com/istanbuljs/nyc
2018-08-30 13:41:52 -07:00
Elliot Lee
76f120bec9 Merge branch 'getLedger-includeRawTransaction-2' into develop 2018-08-30 13:30:18 -07:00
Elliot Lee
f8bf28876d if statements must be braced 2018-08-30 13:29:50 -07:00
wilsonianb
b03795df09 Add hidden computeTreeHashes option 2018-08-30 13:29:50 -07:00
Elliot Lee
dbe20d6574 getLedger: include raw transaction with each transaction
computeLedgerHash: support new getLedger response by using
rawTransaction

BREAKING CHANGES:

* Remove the `rawTransactions` field and replace it with a new `rawTransaction` field in each transaction.
* Rename the `metaData` field (in each raw transaction) to `meta` (for consistency with rippled's `tx` method).
* Add `ledger_index` to each raw transaction.
2018-08-30 13:28:52 -07:00
Elliot Lee
0550fab73e Update escrowCreation error message and docs (#934)
Fix #933
2018-08-29 19:03:33 -07:00
Elliot Lee
3f2d9d198e computeLedgerHash - add requireRawTransactions option 2018-08-28 17:31:12 -07:00
Elliot Lee
b9c953fce6 Fix getPaths (#930)
* getPaths:
  * Filter paths correctly
  * Use correct value when XRP is the destination currency
2018-08-23 17:37:02 -07:00
Elliot Lee
181cfd69de Prevent 'amount' from being misinterpreted (#924)
The 'amount' field should almost never be used.
With partial payments, the field can show an amount that is
significantly less than the amount that the transaction actually
delivered. This change sets amount to 0 XRP when it may be misleading.

This change omits the `amount` when parsing payment transactions.
See `HISTORY.md` for recommended alternatives.
2018-08-23 16:17:23 -07:00
Elliot Lee
569766b8f8 Rename json schemas (#931)
Rename files for consistency with their titles:

* Rename amount-base to amountbase
* Rename tx-hash to transaction-hash
* Rename id to transactionHash
* Rename objects/settings.json to objects/settings-plus-memos.json
* Rename ledgerversion to ledger-version
2018-08-22 14:41:41 -07:00
Elliot Lee
53a232ebdc Update docs 2018-08-14 20:05:50 -07:00
Elliot Lee
4c9a2ff538 Improve Order docs. Fix #776 2018-08-14 19:27:50 -07:00
Elliot Lee
dc623cd049 Release 1.0.0-beta.5 2018-08-11 01:38:36 -07:00
Elliot Lee
7cd517268b Fix error TS2307: Cannot find module 2018-08-11 01:35:47 -07:00
Elliot Lee
2438295e70 Release 1.0.0-beta.4 2018-08-10 14:58:19 -07:00
Elliot Lee
f5e1a4a588 Revert "Expose validation methods in public api"
This reverts commit 9e9a0a7d9b.

We should move methods like deriveKeypair and deriveAddress
off of the schemaValidator object.
2018-08-10 14:54:01 -07:00
Mo Morsi
9e9a0a7d9b Expose validation methods in public api
Updated to fix tests
2018-08-06 16:09:04 -07:00
Elliot Lee
1c68283d1e ES6: omit property value since it matches the variable name 2018-07-28 00:42:37 -07:00
Elliot Lee
28796d37cb Update TypeScript to 2.9.2 2018-07-28 00:18:58 -07:00
Elliot Lee
067bc48d4e Add prepareTransaction() (#898)
* Export iso8601ToRippleTime(), txFlags, convertStringToHex()

* Fix a bug that caused fees exceeding 999 to throw an error

e.g. '1,000' would not be recognized as a valid number.
To use 6 decimal places, toFixed should be used instead of toFormat.
2018-07-26 12:24:29 -07:00
Fred K. Schott
b94698df0b Update some API methods to use api.request() internally (#896)
* use any instead of object
2018-07-26 12:23:07 -07:00
Elliot Lee
4f40b5cb6d Update README.md - How to build ripple-lib (#837) 2018-07-25 12:09:55 -07:00
Elliot Lee
14704eee6b Add more tests of getFee (#897) 2018-07-25 01:53:27 -07:00
Elliot Lee
860f6a6cd8 Release 1.0.0-beta.3 2018-07-17 22:39:00 -07:00
Elliot Lee
7a928804ec feat: add payment channel details to tx (2) (#920)
* Bump transactionparser to v0.7.1 and update output schema
* yarn docgen for required `threshold` and `weights`
2018-07-17 22:22:07 -07:00
adrianhopebailie
14444bea3f feat: add payment channel details to tx 2018-07-17 22:20:47 -07:00
Rome Reginelli
47a139fdff Fix text/plain MIMETYPE in examples with memos (#914) 2018-07-03 17:18:46 -07:00
Brandon Wilson
4e30b9b2fa Require threshold and weights in signers settings (#909)
Fixes #908
2018-07-02 16:27:03 -07:00
Elliot Lee
2112d4c0b3 Round XRP fee to 6 decimal places (#912)
* Round XRP fee to 6 decimal places

Fix #911
2018-06-28 17:59:00 -07:00
Elliot Lee
1d1132b7fa Release 1.0.0-beta.2 2018-06-08 08:11:00 -07:00
Elliot Lee
e07fa11923 Maximum fee values (#902)
* Add maxFeeXRP (default 2 XRP) as an optional RippleAPI constructor parameter
  - No calculated or specified fee can exceed this value
  - If the fee exceeds 2 XRP, throw a ValidationError
* sign() - throw ValidationError when Fee exceeds maxFeeXRP
* Document getFee parameters
* Explain new fee limits in HISTORY.md
* Deprecate `maxFee`
2018-06-07 23:29:24 -07:00
Elliot Lee
7c92adbf45 Release 1.0.0-beta.1 2018-05-24 20:13:26 -07:00
Elliot Lee
d55aa2339f Improve docs (raw order data) 2018-05-24 20:02:45 -07:00
Elliot Lee
95e39153da Bump node version to v8 2018-05-24 19:29:09 -07:00
Daniel Davis
65d8260908 Updated yarn command (#900)
`yarn install` deprecated in favor of `yarn add`
2018-05-23 23:05:09 -07:00
Elliot Lee
1aa9feda71 Allow specifying amounts in drops (#892)
* Accept "drops" in lieu of "XRP"
* Export xrpToDrops() and dropsToXrp()
* Throw our own validation errors instead of BigNumber Errors
2018-05-21 13:19:18 -07:00
Fred K. Schott
2e5b435b11 add server_info request typing (#895) 2018-05-17 16:37:17 -07:00
Elliot Lee
54f12862dc Improve errors (#893)
- `RippledError`: Include the full response from the `rippled` server.
- A new test ensures correct behavior when `streams` is not an array.
- `NotConnectedError` may be thrown with a different message than before.
2018-05-12 09:38:49 -07:00
Elliot Lee
226ef862ae Link to mailing lists 2018-05-10 16:25:05 -07:00
Elliot Lee
4a0d675726 Release 1.0.0-beta.0 2018-05-10 15:56:23 -07:00
Elliot Lee
b2b6715ac0 Add request(), hasNextPage(), and requestNextPage() (#887)
* Add support for all rippled APIs, including subscriptions.
* Add support for arbitrary stream message types.
* Note that rippled APIs take amounts in drops.
* request() will be available in ripple-lib version 1.0.0+
2018-05-10 15:43:56 -07:00
Elliot Lee
823d93b86c Add checksums for 0.22.0 2018-05-10 15:26:43 -07:00
Elliot Lee
7a42db99c9 Bump version to 0.22.0 2018-05-10 00:33:20 -07:00
Elliot Lee
f28ec27614 getOrderbook - return raw order data (#886)
Fix #799
2018-05-08 15:05:41 -07:00
Elliot Lee
a36e23ebfa Release 0.21.0 2018-04-11 21:33:44 -07:00
Elliot Lee
e978ef1888 Add getAccountObjects (#881)
Squashed commit of the following:

commit 361ead8cbbbe4fa25ecba614f8f11930ff679996
commit 5ff26d7d2defbbaaa7c50d6b3b5b74bf30be19ef
commit 97f5dfc86d4730082fd016197b0c025e499912e3
commit d48654098601f2a19484d9bbae7c65786e3c5dd4
commit 4790401123e7836f6bea8d03111bce60dcf95114
commit 57512f7fc000689bb8224f33173ba91221f27281
commit e75a7e95b11368b26c40e8e6e7b583d978475e95
2018-04-11 14:37:37 -07:00
Chris Yuen
9af3968508 Upgrade https-proxy-agent to version 2 (#883) 2018-04-10 12:59:24 -07:00
Elliot Lee
86ce7b707c Release 0.20.0 2018-04-09 12:03:05 -07:00
Elliot Lee
e0eb27ed8e Use jsonschema v1.2.2 and run yarn upgrade (#882)
- Fixes #880
2018-04-09 11:54:30 -07:00
amougel
2570e2a6d8 Add signWithKeypair (#769) 2018-04-03 15:33:24 -07:00
Rome Reginelli
c71540e77a Merge pull request #877 from mDuo13/add-tx-types
Improve Payment Channel documentation
2018-03-30 18:57:17 -07:00
mDuo13
8eba827d11 Improve Payment Channel documentation 2018-03-28 11:54:05 -07:00
Elliot Lee
90be539b09 Release 0.19.1 2018-03-22 14:12:22 -07:00
Fred K. Schott
43c08e5ea7 Clean up min/max adjustments (#873) 2018-03-22 12:31:44 -07:00
Fred K. Schott
3f22b12216 Add linting to travis (#872) 2018-03-20 14:30:37 -07:00
darkmemo
a72041a321 Fix Payment source & destination types (#870)
Payment `source` and `destination` are defined as intersection types, `Adjustment & MaxAdjustment` and  `Adjustment & MinAdjustment` respectively. But they should be union types instead. This problem was introduced during js to ts conversion.

Fixes #866
2018-03-20 11:26:41 -07:00
Elliot Lee
71a0c16fec Ledger object - accountState supersedes accounts (#868)
This appears to originate from a mistake in the docs.
The actual name of the field is `accountState`.

See:
9af994ceb4/src/ripple/app/ledger/impl/LedgerToJson.cpp (L167)

* Remove TODOs addressed by docs PR

https://github.com/ripple/ripple-dev-portal/pull/324
2018-03-19 14:52:18 -07:00
Elliot Lee
27ab98160a Fix link to checkCash (#871)
Fix source file for 4eaaa8188d
2018-03-19 14:41:18 -07:00
Ryan Young
4eaaa8188d Fix link to checkCash (#871)
#checkCash -- > #check-cash
2018-03-19 14:39:54 -07:00
Fred K. Schott
187154a2b0 Types cleanup + more API methods onto new request method (#857)
* major types cleanup, more formatted api methods onto new request method

- getPaymentChannel() now uses this.request()
- getSettings() now uses this.request()
- getLedger() now uses this.request()
- transaction types cleaned up a bit, but still some work left to do
2018-03-14 16:08:57 -07:00
Elliot Lee
c175e3f58e Point to types in package.json (#863) 2018-03-06 23:15:55 -08:00
Fred K. Schott
2ea22a099e Don't generate TS definitions for browser build (#864) 2018-03-06 23:15:11 -08:00
Elliot Lee
c3aa062edd Bump version to 0.19.0 and add release notes 2018-03-02 13:58:39 -08:00
Elliot Lee
0ad8c577c0 Export Check* transaction param types 2018-03-01 21:46:20 -08:00
Elliot Lee
facc513a52 Add support for Checks (#853)
- See https://github.com/ripple/rippled/pull/2245

* Add support for depositAuth flag

* Upgrade ripple-binary-codec to 0.1.13
2018-03-01 21:42:46 -08:00
Elliot Lee
df711ecb06 Import from 'server' to fix TS4029 2018-03-01 21:23:02 -08:00
Elliot Lee
144be08af0 Export types used by exported variables (#858)
Fixes TypeScript compile errors due to generating TS declaration files.

See #851
2018-03-01 17:48:28 -08:00
Fred K. Schott
c53db4844a Add .travis.yml (#859) 2018-03-01 17:32:31 -08:00
Elliot Lee
68b34f7532 Improve documentation of getTransactions params (#856)
* Improve documentation of getTransactions params

- Resolve #855
2018-02-26 17:39:06 -08:00
cryptcoin-junkey
3fe5d715a5 Generate/publish *.ts.d (#851)
For TypeScript
2018-02-24 23:52:45 -08:00
Elliot Lee
ca74cf1028 Apply automatic formatting 2018-02-23 16:50:40 -08:00
Elliot Lee
5b51ff6071 Support for the Deposit Authorization account root flag (#852)
* Add depositAuth flag tests
* Add support for depositAuth flag
2018-02-21 17:15:23 -08:00
Elliot Lee
3cad4f4aa3 Apply code formatting to API unit tests 2018-02-21 16:05:57 -08:00
Fred K. Schott
365de6d18a Add new request interface, implement first few request typings (#843)
* Add request interface & typings

- src/api: add basic implementation of request/requestAll()
- src/ledgers/account_info: refactor to simplify with request()
- src/ledgers/balances: refactor to simplify with request()
- src/ledgers/orderbook: refactor to simplify with requestAll()
- src/ledgers/orders: refactor to simplify with requestAll()
- src/ledgers/trustlines: refactor to simplify with requestAll()

* standardize on Formatted prefix
2018-02-20 11:44:36 -08:00
Elliot Lee
4a21360e37 Alphabetize properties for Settings object
- Generate docs to fix earlier typo (yarn run docgen)
2018-02-14 16:22:05 -08:00
Elliot Lee
43a3cfa010 HISTORY.md - remove broken link (404) 2018-02-14 16:00:51 -08:00
Elliot Lee
b89eae5cb1 Add test of getTrustlines with multiple pages of results (#850) 2018-02-14 15:57:35 -08:00
Elliot Lee
e311b74dac Add release notes for 0.18.2 2018-02-13 13:59:02 -08:00
Elliot Lee
e3748e070b Bump version to 0.18.2 2018-02-13 13:53:42 -08:00
Elliot Lee
0c318816cc Remove unnecessary files from npm
- `"bin/*"`, `"test/*"`, and `"Gulpfile.js"` can be removed
- See #844
2018-02-13 13:36:02 -08:00
Fred K. Schott
55e6801f4a Add build to prepublish in package.json (#849)
Continue to publish the build/ directory so that users can easily grab it from CDNs.
2018-02-12 09:47:25 -08:00
Elliot Lee
4f60fc301f Add "browser" property to package.json (#847)
* Use wswrapper shim for browserify
2018-02-11 08:52:19 -08:00
Elliot Lee
139159bf1a webpack config - include src instead of excluding node_modules 2018-02-07 14:14:35 -08:00
Elliot Lee
3ebbca0083 instructions.json - fix typo 2018-02-02 10:49:32 -08:00
Elliot Lee
51aaa75a05 Use BigNumber internally to compute fee 2018-01-30 15:29:28 -08:00
Elliot Lee
01a25f55f2 Initialize ledgerVersion to undefined 2018-01-30 14:58:59 -08:00
Fred K. Schott
94196ab268 post flow-to-ts cleanup 2018-01-29 12:11:32 -08:00
Elliot Lee
dc39343899 HISTORY.md - Add 0.18.1 2018-01-27 19:38:25 -08:00
Elliot Lee
272eabd1cd v0.18.1 2018-01-27 00:46:23 -08:00
Elliot Lee
7a653e6e63 Fix: isSameIssue() should check counterparty 2018-01-26 16:06:25 -08:00
Elliot Lee
994a6d5e76 Add SHA-256 checksums for 0.18.0 release 2018-01-25 15:36:02 -08:00
Elliot Lee
3db72716b4 HISTORY.md - Add release date for 0.18.0 2018-01-25 15:30:02 -08:00
Elliot Lee
6d39e072f8 Docs: getFee() returns a string 2018-01-23 16:13:27 -08:00
Elliot Lee
b7d636d157 Rerun docgen to update docs 2018-01-23 16:11:35 -08:00
Elliot Lee
e8ac4f3d40 Set PublicKey type to string 2018-01-23 16:08:40 -08:00
Elliot Lee
ae2ccd9887 Add SHA-256 checksums 2018-01-23 15:24:18 -08:00
Elliot Lee
4fff85096c Bump version to 0.18.0 and update HISTORY.md 2018-01-17 16:03:57 -08:00
Elliot Lee
b4d8684740 Update escrow creation response fixture
- Request fixture was changed by #820
- Add an ExecuteAfter (aka FinishAfter) timestamp
2018-01-17 15:50:34 -08:00
Fred K. Schott
d3fb4b6260 Add TypeScript linting (#827)
* add tslint, create tslint.json ruleset from .eslintrc

* remove leftover rules

* fix up meta files
2018-01-17 14:41:24 -08:00
Nicolás López Jullian
19eaedf50d Change yarn install to yarn add 2018-01-16 23:18:17 -08:00
Elliot Lee
c56e6a6c08 Update yarn.lock 2018-01-16 23:16:22 -08:00
Fred K. Schott
01ecfb0a07 update istanbul to nyc (their new cli) to get typescript coverage 2018-01-11 17:20:44 -08:00
Elliot Lee
e1630e1693 HISTORY - Add SHA checksums for 0.17.9 2017-12-29 01:52:24 -08:00
Elliot Lee
526d87c1fc Update HISTORY.md 2017-12-24 00:44:14 -08:00
Fred K. Schott
8204f6c648 Convert from Flow to Typescript (#816)
* convert to typescript
* add docs for custom node typing
* update webpack, gulpfile
2017-12-24 00:39:18 -08:00
Rome Reginelli
5979ff6197 Merge pull request #820 from mDuo13/fix-escrow-example
[Docs] Improve escrow creation example to have ExecuteAfter date
2017-12-20 12:15:24 -08:00
mDuo13
d22828b222 [Docs] Improve escrow creation example to have ExecuteAfter date 2017-12-18 10:23:54 -08:00
Fred K. Schott
7e5b9948a8 convert common.js modules to new standard esm module syntax (#815) 2017-12-04 11:21:56 -08:00
Fred K. Schott
7ece43e2e2 fix whitespace (lint errors) (#813) 2017-11-27 10:54:40 -08:00
Fred K. Schott
f90617eac4 fix flow type errors (#811) 2017-11-21 16:52:48 -08:00
Fred K. Schott
2469fb2307 Update package.json 2017-11-16 14:37:46 -08:00
Fred K. Schott
a051e6fd71 fix and update flow to get typechecker running again 2017-11-16 14:37:46 -08:00
Elliot Lee
cabe029861 Release 0.17.9 2017-11-14 13:45:55 -08:00
Elliot Lee
1ac4ad2076 Update HISTORY.md for 0.17.9 2017-11-14 13:41:53 -08:00
Fred K. Schott
44119ddf2d remove unneccessary double-polyfills from runtime 2017-11-12 23:40:29 -08:00
Fred K. Schott
567036f382 fix lint errors and configure eslintrc to automatically work /w tooling 2017-11-12 12:46:50 -08:00
Elliot Lee
27aa0247e7 yarn.lock: Update ripple-keypairs to 0.10.1 2017-11-10 15:22:54 -08:00
Elliot Lee
0fc10b302f Update ripple-keypairs to 0.10.1 (#805) 2017-11-10 15:21:57 -08:00
Elliot Lee
0bc51a869d Merge pull request #786 from ripple/escrow-execution-ValidationError
escrow-execution - Add reference to ValidationError
2017-11-10 14:57:38 -08:00
Elliot Lee
a3dff0dcf7 Update HISTORY.md 2017-11-08 22:51:53 -08:00
Elliot Lee
048fc7ce71 Merge branch 'bsclifton-develop' into develop 2017-11-08 22:49:58 -08:00
Elliot Lee
6265e81afb Update yarn.lock for ws 3.3.1 2017-11-08 22:49:01 -08:00
Brian Clifton
38ca96a938 Update ws dependency >= 3.3.1 per https://nodesecurity.io/advisories/550 2017-11-08 21:42:23 -07:00
wilsonianb
8ed5f764fa Add missing condition or fulfillment test 2017-11-06 13:49:38 -06:00
Elliot Lee
227ea82a29 escrow-execution - Add reference to ValidationError 2017-11-06 11:08:06 -08:00
Elliot Lee
0e2a5e36c6 Add 0.17.8 release date 2017-11-06 10:13:23 -08:00
Elliot Lee
332b656860 Merge pull request #802 from ripple/update-bignumber
Update bignumber.js, ripple-hashes, ripple-lib-transactionparser
2017-11-06 08:58:27 -08:00
Elliot Lee
0230b963c1 Update HISTORY.md 2017-11-06 08:54:49 -08:00
Waldir Pimenta
48e2ea9ff2 LICENSE: add title (#803) 2017-11-04 18:18:55 -07:00
Elliot Lee
b6f1394c61 Update HISTORY.md 2017-11-03 23:44:17 -07:00
Elliot Lee
560e43b1a6 Update scripts/ci.sh to use yarn 2017-11-03 23:43:33 -07:00
Elliot Lee
cc1ab7ae97 Update references of npm to yarn 2017-11-03 15:30:41 -07:00
Elliot Lee
4886561f7d Add yarn lockfile
Use yarn to ensure that we always get the same dependencies each time
2017-11-03 14:20:00 -07:00
Elliot Lee
658d8a182e Update bignumber.js, ripple-hashes, ripple-lib-transactionparser 2017-11-03 14:20:00 -07:00
wilsonianb
2a90f9b134 Include signers in getSettings 2017-10-10 19:10:26 -05:00
Elliot Lee
f42dafd304 Merge branch 'update-lodash' into develop 2017-09-27 15:47:51 -07:00
Elliot Lee
ec2100094a Docs: Specify Node 6.11.3
- Add .nvmrc and update HISTORY.md
2017-09-27 15:45:50 -07:00
Elliot Lee
ecd6347859 Update to lodash 4
- Update ripple-lib-transactionparser
2017-09-27 10:25:53 -07:00
Elliot Lee
ab17b19ff0 Update for CircleCI
- circle.yml - use node 6
- Fix eslint errors
- Update coveralls and add path to babel
2017-09-27 10:25:08 -07:00
Elliot Lee
a9e5ac6290 Fix typos
Thanks @seelabs
2017-09-06 23:53:20 -07:00
Elliot Lee
4974f73f26 Clean up release history
- Fix some typos
- Improve consistency of formatting
2017-09-06 00:55:26 -07:00
Rome Reginelli
e6d71471e2 Merge pull request #791 from ripple/rr-xrp-ledger-rebranding
Fix case-sensitive broken link for preparePaymentChannelClaim
2017-09-01 15:16:58 -07:00
mDuo13
50db68dff7 Fix case-sensitive broken link for preparePaymentChannelClaim 2017-09-01 15:12:58 -07:00
Rome Reginelli
c8eb5b6a70 Merge pull request #790 from ripple/rr-xrp-ledger-rebranding
Fix 'Paymment' typo
2017-09-01 15:06:11 -07:00
mDuo13
c61a15e4f3 Fix 'Paymment' typo 2017-09-01 14:50:02 -07:00
Rome Reginelli
c151ff2d66 Merge pull request #788 from ripple/rr-xrp-ledger-rebranding
Docs: fix broken links
2017-09-01 14:45:56 -07:00
mDuo13
393b2f9d78 Docs: fix broken links 2017-09-01 12:45:03 -07:00
Rome Reginelli
bf36cf03d6 Merge pull request #785 from ripple/rr-xrp-ledger-rebranding
Rebrand 'Ripple Consensus Ledger' to 'XRP Ledger'
2017-08-31 14:47:52 -07:00
mDuo13
d3332e0db9 README updates for rebranding 2017-07-31 17:17:30 -07:00
mDuo13
ed62b20645 Rebrand 'Ripple Consensus Ledger' to 'XRP Ledger' 2017-07-31 14:05:40 -07:00
Rome Reginelli
5f2c5e27f1 Merge pull request #771 from xasos/develop
Fix readme syntax
2017-07-31 11:53:20 -07:00
Abraham Tom
ff702b85e2 Merge pull request #760 from mDuo13/doc_nodever_update
Docs: Require Node 6.9.0, update boilerplate to avoid destructuring assign
2017-07-28 12:04:23 -07:00
Niraj Pant
f91eb68556 Fix readme syntax 2017-06-09 11:12:42 -07:00
mDuo13
469fefee92 Docs: Require Node 6.9.0, update boilerplate to avoid destructuring assign 2017-05-09 15:51:45 -07:00
Matthew Fettig
de47263087 0.17.7 2017-05-08 15:10:26 -07:00
Matthew Fettig
3b9679a673 Merge pull request #759 from bachase/jsonschema
Switch to jsonschema
2017-05-08 15:09:04 -07:00
Brad Chase
f175966816 Make http server dev only 2017-05-05 14:59:15 -04:00
Brad Chase
f1f5364d07 Switch to jsonschema 2017-05-03 20:34:24 -04:00
Matthew Fettig
1b8b0c76ac Merge pull request #757 from ripple/fix-condition
Fix escrow condition and fulfillment descriptions
2017-04-13 19:39:27 -07:00
Matthew Fettig
1a8096ab18 Merge pull request #756 from ripple/sign-claim
Payment channel lookup and claim signing & verification
2017-04-13 19:38:45 -07:00
wilsonianb
f177771c67 Update ripple-binary-codec version 2017-04-13 17:39:27 -07:00
wilsonianb
081fcbfa32 Fix escrow condition and fulfillment descriptions 2017-04-12 15:16:01 -07:00
wilsonianb
0a5e4e2155 Update docs for escrow and paychan activation 2017-04-07 13:04:32 -07:00
wilsonianb
19eb88a00e Add getPaymentChannel 2017-04-07 13:04:21 -07:00
wilsonianb
c8f2967de0 Sign and verify payment channel claim 2017-04-07 13:01:58 -07:00
Matthew Fettig
b5564330f6 Merge pull request #755 from ripple/develop
0.17.6
2017-03-30 21:49:59 -07:00
Matthew Fettig
43ccb83f73 0.17.6 2017-03-30 21:33:09 -07:00
Brandon Wilson
e2d92126c0 Merge pull request #745 from ripple/feat/bs-paychan
Add transactions for payment channels
2017-03-30 21:26:13 -07:00
Ben Sharafian
8c8eef45d5 Add docs for payment channels 2017-03-30 21:19:31 -07:00
Ben Sharafian
a574e1158a Add transactions for payment channels 2017-03-30 21:19:31 -07:00
Matthew Fettig
af687a6aed Merge pull request #754 from ripple/escrowcreate
Simplify EscrowCreate parameters
2017-03-30 21:18:33 -07:00
wilsonianb
016e82ab5d Simplify EscrowCreate parameters 2017-03-30 19:01:58 -07:00
Matthew Fettig
f300a412d7 Merge pull request #753 from ripple/feature/dependancy-update
update ripple-hashes and ripple-binary-codec
2017-03-30 15:21:27 -07:00
Matthew Fettig
75e2249cf3 update ripple-hashes and ripple-binary-codec 2017-03-30 15:12:09 -07:00
Matthew Fettig
1942bcb971 Merge pull request #752 from ripple/rm-escrow-iou
Disallow escrow of IOU
2017-03-30 14:53:29 -07:00
wilsonianb
9393adf66f Disallow escrow of IOU 2017-03-30 10:10:00 -07:00
Matthew Fettig
917aae9bf3 Merge pull request #751 from ripple/feature/escrow
Replace suspended payments with escrow
2017-03-29 17:38:32 -07:00
wilsonianb
da36457d5c Update condition and fulfillment for escrow
Calculate escrowFinish fulfillment fee
2017-03-29 10:27:34 -07:00
wilsonianb
15a0ededc8 Replace suspended payments with escrow 2017-03-24 12:35:22 -07:00
wilsonianb
68d7864f93 Rename suspended payment files as escrow 2017-03-24 12:32:17 -07:00
Matthew Fettig
1eddbf995f 0.17.5 2017-03-24 12:31:10 -07:00
Matthew Fettig
592385ac73 Merge pull request #750 from ripple/feature/dependancy-update
update ripple-binary-codec to version 0.1.8
2017-03-24 12:26:35 -07:00
Matthew Fettig
56d626f5b1 Merge pull request #744 from choiip/develop
Added .json in missing require()
2017-03-24 10:53:42 -07:00
Matthew Fettig
7a14300409 update ripple-binary-codec to version 0.1.8 2017-03-24 10:40:19 -07:00
alex.choi
30fa8d658e Added .json in missing require() 2017-02-15 18:51:49 +08:00
Chris Clark
c0101cb5e7 Merge pull request #740 from wilsonianb/shamapv2
Check SHAMapV2 ledger close flag
2016-12-02 12:31:46 -08:00
wilsonianb
fd640cd65e Check SHAMapV2 ledger close flag 2016-12-02 12:25:32 -08:00
Chris Clark
11528eff92 Merge pull request #741 from wilsonianb/fix-lint-errors
Fix eslint errors
2016-12-02 11:55:21 -08:00
wilsonianb
3c9175459d Fix eslint errors 2016-12-02 08:16:16 -08:00
Chris Clark
bd4e0e01e2 Merge pull request #739 from clark800/develop
Update ripple-binary-codec and ripple-hashes dependencies
2016-11-30 14:59:52 -08:00
Chris Clark
cfcf6e473c Update ripple-binary-codec and ripple-hashes dependencies 2016-11-30 14:49:40 -08:00
Chris Clark
50c6af3158 Merge pull request #734 from clark800/bump-codec
Bump version to 0.17.3 and bump ripple-binary-codec to 0.1.4
2016-09-29 11:24:04 -07:00
Chris Clark
1d4310cd3a Disable flow type checking in CircleCI 2016-09-29 11:19:46 -07:00
Chris Clark
2191596e68 Bump version to 0.17.3 and bump ripple-binary-codec to 0.1.4 2016-09-29 11:19:32 -07:00
Chris Clark
acf8f87a88 Merge pull request #727 from clark800/order-seq
Add orderToReplace option
2016-08-01 14:34:27 -07:00
Chris Clark
cfac146620 Add orderToReplace option 2016-08-01 14:27:08 -07:00
Chris Clark
f3234ad853 Merge pull request #726 from clark800/doc-typos
Fix typos in docs
2016-08-01 14:24:22 -07:00
Chris Clark
b65fee3d85 Merge pull request #725 from shekenahglory/develop
update parseDeliveredAmount for cases where delivered_amount is not p…
2016-08-01 14:21:43 -07:00
Chris Clark
82b294bc7d Update flow 2016-08-01 14:13:00 -07:00
Chris Clark
2a58573823 Fix typos in docs 2016-08-01 11:53:46 -07:00
Matthew Fettig
a96f71b7fd fix missing deliveredAmount data from getLedger requests 2016-07-19 21:29:50 -07:00
Chris Clark
077f4a4c79 Merge pull request #723 from clark800/fix-coverage
Fix code coverage tool
2016-07-08 15:04:38 -07:00
Chris Clark
9a495467fb Disable sauce tests because they usually timeout 2016-07-08 11:45:27 -07:00
Chris Clark
db2e62b219 Fix code coverage tool 2016-07-08 11:28:10 -07:00
Alan Cohen
2fafa493a2 Version 0.17.2 2016-06-24 10:59:04 -07:00
Alan Cohen
7617c3005c Merge pull request #721 from mDuo13/fix_transferrate_docs
[DOC] fix transferRate description
2016-06-22 11:13:14 -07:00
mDuo13
5cdbb71277 [DOC] fix transferRate description 2016-06-16 15:11:08 -07:00
Chris Clark
f9339c36bf Merge pull request #720 from clark800/update-binary-codec
0.17.1
2016-05-11 18:20:29 -07:00
Chris Clark
67dc57e9d0 Disable PhantomJS tests due to issue downloading from bitbucket 2016-05-11 17:49:57 -07:00
Chris Clark
757f3190d1 0.17.1 2016-05-11 17:49:54 -07:00
Chris Clark
0d94a15ee7 0.17.0 2016-05-05 18:35:13 -07:00
Chris Clark
7f1c80da1b Merge pull request #718 from clark800/pseudo
Add support for parsing SetFee and EnableAmendment pseudo-transactions
2016-05-05 16:15:32 -07:00
Chris Clark
f74e11bce0 Add support for parsing SetFee and EnableAmendment pseudo-transactions 2016-05-05 15:37:23 -07:00
Chris Clark
d4c843e8e3 Merge pull request #714 from darkdarkdragon/remove_tej
[FIX] remove check for `tej` class of errors.
2016-04-05 15:15:42 -07:00
Ivan Tivonenko
bae190b282 [FIX] remove check for tej class of errors. 2016-04-05 23:50:41 +03:00
Chris Clark
d2cbd70da8 Merge pull request #712 from darkdarkdragon/reconnect_fix_browser
[FIX] on reconnect wait for server to be synced
2016-03-30 15:50:58 -07:00
Ivan Tivonenko
5da78ce583 [FIX] handle websocket errors in browsers
emit not RippledNotInitializedError if server doesn't have any
completed ledgers on connect
2016-03-31 00:46:00 +03:00
Chris Clark
14bbe3e30b Merge pull request #680 from ripple/sublimator-patch-1
Fix typo in docs
2016-03-29 10:27:34 -07:00
Nicholas Dudfield
e52e2bbc68 Fix IOU Amount precision related typo in docs 2016-03-29 13:51:30 +07:00
Alan Cohen
b56752e45b 0.16.10 2016-03-24 14:52:36 -07:00
Chris Clark
4632f511ab Merge pull request #711 from darkdarkdragon/reconnect_fix2
[FIX] on connect return error if server doesn't have validated ledgers
2016-03-24 14:27:50 -07:00
Ivan Tivonenko
e17b6f172d [FIX] on connect return error if server doesn't have validated ledgers 2016-03-24 22:26:33 +02:00
Alan Cohen
eb04e878ba 0.16.9 2016-03-22 18:39:33 -07:00
Chris Clark
c71febd116 Merge pull request #709 from darkdarkdragon/reconnect_fix
Reconnection fix
2016-03-22 18:12:28 -07:00
Ivan Tivonenko
69c1ccbb6b [TASK] emit connected and disconnected events from api 2016-03-23 02:05:07 +02:00
Ivan Tivonenko
499b8c8d8b [FIX] fix multiple reconnections issue 2016-03-23 01:18:08 +02:00
Chris Clark
ea009f9a84 Merge pull request #708 from clark800/fix-maker-exchange-rate
Fix makerExchangeRate for getOrders when rippled provides quality
2016-03-22 14:14:23 -07:00
Chris Clark
dc784d4567 Fix makerExchangeRate for getOrders when rippled provides quality 2016-03-22 13:21:26 -07:00
Alan Cohen
9ffc8a2c0b Merge pull request #707 from ripple/fix/filter-source-amount
FIX: Filtering source_amount pathfind correctly
2016-03-21 14:48:37 -07:00
Alan Cohen
5b20fe573e FIX: Filtering source_amount pathfind correctly
Bug:

```js
api.connect().then(() => {
  const pathfind = {
    source: {
      address: USDCold,
      amount: {
        currency: 'USD',
        value: '1.00' // <<<< Rippled response has "1" not "1.00"
      }
    },
    destination: {
      address: EURCold,
      amount: {currency: 'EUR'}
    }
  };
  return api.getPaths(pathfind).then(paths => {
    console.log('PATHS: \n', JSON.stringify(paths, null, 2));
  });
}).catch(console.log);

```
2016-03-21 11:44:55 -07:00
Chris Clark
7e466bb80f Merge pull request #705 from darkdarkdragon/code_comment
[FIX] add small code comment
2016-03-15 12:14:05 -07:00
Ivan Tivonenko
1f8418b447 [FIX] add small code comment 2016-03-15 20:58:22 +02:00
Alan Cohen
ccfc57fc62 Merge pull request #704 from darkdarkdragon/fix_edge_test
[FIX] fix test hang in microsoft edge
2016-03-15 10:27:01 -07:00
Ivan Tivonenko
1d31fccd72 [FIX] fix test hang in microsoft edge 2016-03-15 05:04:47 +02:00
Alan Cohen
9ac1a89e48 0.16.8 2016-03-09 12:30:10 -08:00
Chris Clark
bfc0696324 Merge pull request #701 from h0vhannes/develop
Documentation fixes
2016-03-09 12:24:55 -08:00
Hovhannes Kuloghlyan
e33e782f9e [DOC] Fix transaction spelling in getTransaction description 2016-03-09 22:14:09 +04:00
Hovhannes Kuloghlyan
f2b591d1b2 [DOC] Fix transaction responses link in submit() description 2016-03-09 22:07:54 +04:00
Chris Clark
fe9af5153d Merge pull request #699 from darkdarkdragon/develop_connection_error
[FIX] fix connection error handling
2016-02-24 14:12:12 -08:00
Ivan Tivonenko
0dfdd0a601 [FIX] change eslint version to 2.1 2016-02-24 23:08:49 +02:00
Ivan Tivonenko
4acc42e1b6 [FIX] fix connection error handling
if connection to server can't be established, reject Promise of `connect()` method caller,
instead of throwing error event on base object.
2016-02-24 23:08:47 +02:00
Alan Cohen
7c9a179865 Merge pull request #698 from h0vhannes/develop
[FIX] Fix typo in PrepareTrustline description
2016-02-23 08:44:43 -07:00
Hovhannes Kuloghlyan
c6296a4918 [FIX] Modify PrepareTrustline doc source to pass tests 2016-02-23 16:45:32 +04:00
Hovhannes Kuloghlyan
cc399f1164 [FIX] Fix typo in PrepareTrustline description 2016-02-21 17:02:27 +03:00
Alan Cohen
e4ffb96646 Update version to 0.16.7 2016-02-12 11:38:51 -08:00
Chris Clark
8d34428dac Merge pull request #694 from lumberj/add-deliveredAmount
Add deliveredAmount to payment outcome
2016-02-12 11:25:01 -08:00
Alan Cohen
353637a0c0 Add TODO comment for fixing workaround for rippled bug 2016-02-12 10:56:35 -08:00
Alan Cohen
06f847c2d0 Fix lint errors 2016-02-10 19:45:51 -08:00
Alan Cohen
0c2f9d0e62 Add deliveredAmount to payment outcome
It is impossible to reliably compute the delivered amount from the metadata due
to fixed precision. If the partial payment flag is not set and the transaction
succeeded, the delivered amount should always be considered to be the amount
specified in the transaction.
2016-02-10 17:25:27 -08:00
480 changed files with 44497 additions and 6872 deletions

View File

@@ -1,4 +0,0 @@
{
"presets": ["es2015", "stage-1"],
"plugins": ["syntax-flow", "transform-flow-strip-types"]
}

View File

@@ -1,19 +0,0 @@
[ignore]
.*/ripple-lib/src/.*
.*/ripple-lib/dist/.*
.*/ripple-lib/test/fixtures/.*
.*/node_modules/flow-bin/.*
.*/node_modules/webpack/.*
.*/node_modules/babel-core/.*
.*/node_modules/babel-eslint/.*
.*/node_modules/babel-preset-es2015/.*
.*/node_modules/babel-preset-stage-1/.*
.*/node_modules/babel-register/.*
[include]
./node_modules/
[libs]
[options]
module.system=node

14
.gitignore vendored
View File

@@ -1,5 +1,9 @@
# .gitignore
# Ignore package locks other than Yarn.
package-lock.json
npm-shrinkwrap.json
# Ignore vim swap files.
*.swp
@@ -51,13 +55,13 @@ test/config.js
# Ignore npm-debug
npm-debug.log
# Ignore dist folder, build for bower
# Ignore dist folder, built from tsc
dist/
# Ignore flow output directory
out/
# Ignore perf test cache
scripts/cache
eslintrc
.eslintrc
# nyc (istanbul)
.nyc_output

1
.nvmrc Normal file
View File

@@ -0,0 +1 @@
v10

10
.nycrc Normal file
View File

@@ -0,0 +1,10 @@
{
"include": ["src/**/*.ts"],
"exclude": ["src/**/*.d.ts"],
"extension": [".ts"],
"require": ["ts-node/register"],
"reporter": ["text-summary", "html"],
"sourceMap": true,
"instrument": true,
"cache": true
}

11
.travis.yml Normal file
View File

@@ -0,0 +1,11 @@
language: node_js
node_js:
- 6
- 8
- 9
- 10
script:
- yarn compile
- yarn test
- yarn build
- yarn lint

119
APPLICATIONS.md Normal file
View File

@@ -0,0 +1,119 @@
# Applications using ripple-lib (RippleAPI)
A curated list of some of the projects and apps that leverage `ripple-lib` in some way.
**Have one to add?** Please edit this file and open a PR!
## Notice (disclaimer)
These sites are independent of Ripple and have not been authorized, endorsed, sponsored or otherwise approved by Ripple or its affiliates.
Warning: Use at your own risk.
## Data and visualizations
- **[Wipple - XRP Intelligence](https://wipple.devnull.network/)**
Monitor the XRP Network in real time and explore historical statistics.
- **[XRP Charts](https://xrpcharts.ripple.com/)** (xrpcharts.ripple.com)
XRP Charts provides information based on public data, including trade volume, top markets, metrics, transactions, and more.
- **[Ripple Live](https://gatehub.net/live)** (gatehub.net/live)
Visualize XRP network transactions.
- **[XRPL Dev. Dashboard](https://xrp.fans/)** (xrp.fans)
Debugging dashboard for `rippled-ws-client-pool`, transaction and query explorer, and transaction signing and submission tool.
- **[XRP Value](http://xrpvalue.com/)**
Real-time XRP price, trades, and orderbook data from the XRP Ledger.
- **[Bithomp - XRPL validators](https://bithomp.com/validators)**
List of XRPL validators, nodes, and testnet validators.
## Send and request payments
- **[XRP Tip Bot](https://www.xrptipbot.com/)**
A bot that enables users on reddit, Twitter and Discord to send XRP to each other through reddit comments and Twitter tweets.
- **[XRP Text](https://xrptext.com/)**
Send XRP using SMS text messages.
- **[XRParrot](https://xrparrot.com/)** (uses `ripple-address-codec`)
Easy EUR (SEPA) to XRP transfer (currency conversion).
- **[XRP Payment](https://xrpayments.co/)** (xrpayments.co)
Tool for generating a XRP payment request URI in a QR code, with currency converter.
## Wallets and wallet tools
- **[Toast Wallet](https://toastwallet.com/)**
A free, open source XRP Wallet for iOS, Android, Windows, Mac and Linux.
- **[Toastify Ledger](https://github.com/WietseWind/toastify-ledger)** (uses `ripple-keypairs`)
Add a Regular Key to a mnemonic XRP Wallet (e.g. Ledger Nano S) to use the account with a Family Seed (secret).
- **[Bithomp-submit](https://github.com/Bithomp/bithomp-submit)** (GitHub)
A tool to submit an offline-signed XRPL transaction.
- **[Kyte](https://kyteapp.co/)** (kyteapp.co) ([Source](https://github.com/WietseWind/Zerp-Wallet)) (Deprecated)
Web-based XRP wallet.
- **[XRP Vanity Address Generator](https://github.com/WietseWind/xrp-vanity-generator)** (Node.js)
A vanity address is a wallet address containing a few characters you like at the beginning or the end of the wallet address.
- **[XRP Account Mnemonic Recovery](https://github.com/WietseWind/xrp-mnemonic-recovery)** (uses `ripple-keypairs`)
Recover a 24 word mnemonic if one word is wrong or one word is missing.
## Development tools
- **[XRP Test Net Faucet](https://developers.ripple.com/xrp-test-net-faucet.html)**
Get some test funds for development on the test network. The faucet was built using `ripple-lib`.
## Code samples and libraries
- **[ilp-plugin-xrp-paychan](https://github.com/interledgerjs/ilp-plugin-xrp-paychan)**
Send ILP payments using XRP and payment channels (PayChan).
- **[RunKit: WietseWind](https://runkit.com/wietsewind/)**
XRP Ledger code samples for Node.js.
- **[GitHub Gist: WietseWind](https://gist.github.com/WietseWind)**
XRP Ledger code samples for Node.js and the web (mostly).
- **[rippled-ws-client-sign](https://github.com/WietseWind/rippled-ws-client-sign)**
Sign transactions, with support for MultiSign.
- **[ILP-enabled power switch](https://xrpcommunity.blog/raspberry-pi-interledger-xp-powerswitch-howto/)** ([video](https://www.youtube.com/watch?v=c-eS0HQUuJg)) (uses [`moneyd-uplink-xrp`](https://github.com/interledgerjs/moneyd-uplink-xrp))
For about $30 in parts (Raspberry Pi, 3.3V Relay board and a few wires) you can build your own power switch that will switch on if a streaming ILP payment comes in. When the payment stream stops, the power turns off.
## Related apps that do not appear to use ripple-lib
- **[XRP Stats](https://ledger.exposed/)** (ledger.exposed)
Rich list, live ledger stats and XRP distribution. Visualize escrows and flow of funds.
- **[XRP Vanity](https://xrpvanity.com/)** (xrpvanity.com)
Custom XRP addresses for sale, delivered by SetRegularKey.

View File

@@ -1,21 +1,22 @@
/* eslint-disable no-var, no-param-reassign */
/* these eslint rules are disabled because gulp does not support babel yet */
'use strict';
var _ = require('lodash');
var gulp = require('gulp');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var webpack = require('webpack');
var bump = require('gulp-bump');
var argv = require('yargs').argv;
var assert = require('assert');
var fs = require('fs');
const _ = require('lodash');
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const gulp = require('gulp');
const rename = require('gulp-rename');
const webpack = require('webpack');
const bump = require('gulp-bump');
const argv = require('yargs').argv;
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
var pkg = require('./package.json');
var uglifyOptions = {
mangle: {
except: ['_', 'RippleError', 'RippledError', 'UnexpectedError',
reserved: ['_', 'RippleError', 'RippledError', 'UnexpectedError',
'LedgerVersionError', 'ConnectionError', 'NotConnectedError',
'DisconnectedError', 'TimeoutError', 'ResponseFormatError',
'ValidationError', 'NotFoundError', 'MissingLedgerHistoryError',
@@ -24,17 +25,17 @@ var uglifyOptions = {
}
};
function webpackConfig(extension, overrides) {
function getWebpackConfig(extension, overrides) {
overrides = overrides || {};
var defaults = {
let defaults = {
cache: true,
externals: [{
'lodash': '_'
}],
entry: './src/index.js',
entry: './src/index.ts',
output: {
library: 'ripple',
path: './build/',
path: path.join(__dirname, 'build/'),
filename: ['ripple-', extension].join(pkg.version)
},
plugins: [
@@ -44,18 +45,25 @@ function webpackConfig(extension, overrides) {
'./setup-api-web')
],
module: {
loaders: [{
rules: [{
test: /jayson/,
loader: 'null'
use: 'null',
}, {
test: /\.js$/,
exclude: [/node_modules/],
loader: 'babel-loader'
test: /\.ts$/,
use: [{
loader: 'ts-loader',
options: {
compilerOptions: {declaration: false}
},
}],
}, {
test: /\.json/,
loader: 'json-loader'
use: 'json-loader',
}]
}
},
resolve: {
extensions: [ '.ts', '.js' ]
},
};
return _.assign({}, defaults, overrides);
}
@@ -78,7 +86,7 @@ function webpackConfigForWebTest(testFileName, path) {
filename: match[1] + '-test.js'
}
};
return webpackConfig('.js', configOverrides);
return getWebpackConfig('.js', configOverrides);
}
gulp.task('build-tests', function(callback) {
@@ -112,30 +120,29 @@ function createBuildLink(callback) {
}
gulp.task('build', function(callback) {
webpack(webpackConfig('.js'), createBuildLink(callback));
webpack(getWebpackConfig('.js'), createBuildLink(callback));
});
gulp.task('build-min', ['build'], function() {
return gulp.src(['./build/ripple-', '.js'].join(pkg.version))
.pipe(uglify(uglifyOptions))
.pipe(rename(['ripple-', '-min.js'].join(pkg.version)))
.pipe(gulp.dest('./build/'))
.on('end', function() {
gulp.task('build-min', function(callback) {
const webpackConfig = getWebpackConfig('-min.js');
webpackConfig.plugins.push(new UglifyJsPlugin({uglifyOptions}));
webpack(webpackConfig, function() {
createLink('./build/ripple-' + pkg.version + '-min.js',
'./build/ripple-latest-min.js');
callback();
});
});
gulp.task('build-debug', function(callback) {
var configOverrides = {debug: true, devtool: 'eval'};
webpack(webpackConfig('-debug.js', configOverrides), callback);
const webpackConfig = getWebpackConfig('-debug.js', {devtool: 'eval'});
webpackConfig.plugins.unshift(new webpack.LoaderOptionsPlugin({debug: true}));
webpack(webpackConfig, callback);
});
/**
* Generate a WebPack external for a given unavailable module which replaces
* that module's constructor with an error-thrower
*/
function buildUseError(cons) {
return ('var {<CONS>:function(){throw new Error('
+ '"Class is unavailable in this build: <CONS>")}}')
@@ -145,7 +152,7 @@ function buildUseError(cons) {
gulp.task('build-core', function(callback) {
var configOverrides = {
cache: false,
entry: './src/remote.js',
entry: './src/remote.ts',
externals: [{
'./transaction': buildUseError('Transaction'),
'./orderbook': buildUseError('OrderBook'),
@@ -153,10 +160,10 @@ gulp.task('build-core', function(callback) {
'./serializedobject': buildUseError('SerializedObject')
}],
plugins: [
new webpack.optimize.UglifyJsPlugin()
new UglifyJsPlugin()
]
};
webpack(webpackConfig('-core.js', configOverrides), callback);
webpack(getWebpackConfig('-core.js', configOverrides), callback);
});
gulp.task('bower-build', ['build'], function() {

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,5 @@
ISC License
Copyright (c) 2012-2015 Ripple Labs Inc.
Permission to use, copy, modify, and distribute this software for any

View File

@@ -1,37 +1,77 @@
#ripple-lib
# ripple-lib
A JavaScript API for interacting with Ripple in Node.js
[![Circle CI](https://circleci.com/gh/ripple/ripple-lib/tree/develop.svg?style=svg)](https://circleci.com/gh/ripple/ripple-lib/tree/develop) [![Coverage Status](https://coveralls.io/repos/ripple/ripple-lib/badge.png?branch=develop)](https://coveralls.io/r/ripple/ripple-lib?branch=develop)
A JavaScript API for interacting with the XRP Ledger
[![NPM](https://nodei.co/npm/ripple-lib.png)](https://www.npmjs.org/package/ripple-lib)
###Features
### Features
+ Connect to a rippled server in Node.js
+ Issue [rippled API](https://ripple.com/build/rippled-apis/) requests
+ Listen to events on the Ripple network (transaction, ledger, etc.)
+ Sign and submit transactions to the Ripple network
+ Connect to a `rippled` server from Node.js or a web browser
+ Helpers for creating requests and parsing responses for the [rippled API](https://developers.ripple.com/rippled-api.html)
+ Listen to events on the XRP Ledger (transactions, ledger, validations, etc.)
+ Sign and submit transactions to the XRP Ledger
+ Type definitions for TypeScript
##Getting Started
## Getting Started
Install `ripple-lib` using npm:
See also: [RippleAPI Beginners Guide](https://ripple.com/build/rippleapi-beginners-guide/)
### Requirements
+ **[Node v10](https://nodejs.org/)** is recommended. Other versions may work but are not frequently tested.
+ **[Yarn](https://yarnpkg.com/)** is recommended. `npm` may work but we use `yarn.lock`.
### Install
In an existing project (with `package.json`), install `ripple-lib`:
```
$ npm install ripple-lib
$ yarn add ripple-lib
```
Then see the [documentation](https://github.com/ripple/ripple-lib/blob/develop/docs/index.md) and [code samples](https://github.com/ripple/ripple-lib/tree/develop/docs/samples)
Then see the [documentation](https://github.com/ripple/ripple-lib/blob/develop/docs/index.md) and [code samples](https://github.com/ripple/ripple-lib/tree/develop/docs/samples).
##Running tests
**What is ripple-lib used for?** Here's a [list of applications](APPLICATIONS.md) that use `ripple-lib`. Open a PR to add your app or project to the list!
### Mailing Lists
We have a low-traffic mailing list for announcements of new ripple-lib releases. (About 1 email per week)
+ [Subscribe to ripple-lib-announce](https://groups.google.com/forum/#!forum/ripple-lib-announce)
If you're using the XRP Ledger in production, you should run a [rippled server](https://github.com/ripple/rippled) and subscribe to the ripple-server mailing list as well.
+ [Subscribe to ripple-server](https://groups.google.com/forum/#!forum/ripple-server)
## Development
To build the library for Node.js:
```
$ yarn compile
```
The TypeScript compiler will [output](./tsconfig.json#L7) the resulting JS files in `./dist/npm/`.
To build the library for the browser:
```
$ yarn build
```
Gulp will [output](./Gulpfile.js) the resulting JS files in `./build/`.
For details, see the `scripts` in `package.json`.
## Running Tests
1. Clone the repository
2. `cd` into the repository and install dependencies with `npm install`
3. `npm test` or `npm test --coverage` (`istanbul` will create coverage reports in coverage/lcov-report/`)
2. `cd` into the repository and install dependencies with `yarn install`
3. `yarn test`
##Generating Documentation
Also, run `yarn lint` to lint the code with `tslint`.
The continuous integration tests require that the documentation stays up-to-date. If you make changes the the JSON schemas, fixtures, or documentation sources, you must update the documentation by running `npm run docgen`.
## Generating Documentation
##More Information
The continuous integration tests require that the documentation stays up-to-date. If you make changes to the JSON schemas, fixtures, or documentation sources, you must update the documentation by running `yarn run docgen`.
+ [Ripple Dev Portal](https://ripple.com/build/)
## More Information
+ [Ripple Developer Center](https://ripple.com/build/)

View File

@@ -1,6 +1,6 @@
machine:
node:
version: 0.12.0
version: 6.11.3
hosts:
testripple.circleci.com: 127.0.0.1
dependencies:

9
custom_typings/node.d.ts vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* This is an extension of Node's `process` object to include the browser
* property, which is added by webpack.
*/
interface AmbiguousProcess extends NodeJS.Process {
browser?: true
}
declare var process: AmbiguousProcess;

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +1,31 @@
# Basic Types
## Ripple Address
## Address
```json
"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59"
```
Every Ripple account has an *address*, which is a base58-encoding of a hash of the account's public key. Ripple addresses always start with the lowercase letter `r`.
Every XRP Ledger account has an *address*, which is a base58-encoding of a hash of the account's public key. XRP Ledger addresses always start with the lowercase letter `r`.
## Account Sequence Number
Every Ripple account has a *sequence number* that is used to keep transactions in order. Every transaction must have a sequence number. A transaction can only be executed if it has the next sequence number in order, of the account sending it. This prevents one transaction from executing twice and transactions executing out of order. The sequence number starts at `1` and increments for each transaction that the account makes.
Every XRP Ledger account has a *sequence number* that is used to keep transactions in order. Every transaction must have a sequence number. A transaction can only be executed if it has the next sequence number in order, of the account sending it. This prevents one transaction from executing twice and transactions executing out of order. The sequence number starts at `1` and increments for each transaction that the account makes.
## Currency
Currencies are represented as either 3-character currency codes or 40-character uppercase hexadecimal strings. We recommend using uppercase [ISO 4217 Currency Codes](http://www.xe.com/iso4217.php) only. The string "XRP" is disallowed on trustlines because it is reserved for the Ripple native currency. The following characters are permitted: all uppercase and lowercase letters, digits, as well as the symbols `?`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `<`, `>`, `(`, `)`, `{`, `}`, `[`, `]`, and `|`.
Currencies are represented as either 3-character currency codes or 40-character uppercase hexadecimal strings. We recommend using uppercase [ISO 4217 Currency Codes](http://www.xe.com/iso4217.php) only. The string "XRP" is disallowed on trustlines because it is reserved for the XRP Ledger's native currency. The following characters are permitted: all uppercase and lowercase letters, digits, as well as the symbols `?`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `<`, `>`, `(`, `)`, `{`, `}`, `[`, `]`, and `|`.
## Value
A *value* is a quantity of a currency represented as a decimal string. Be careful: JavaScript's native number format does not have sufficient precision to represent all values. XRP has different precision from other currencies.
**XRP** has 6 significant digits past the decimal point. In other words, XRP cannot be divided into positive values smaller than `0.000001` (1e-6). XRP has a maximum value of `100000000000` (1e11).
**Non-XRP values** have 15 decimal digits of precision, with a maximum value of `9999999999999999e80`. The smallest positive non-XRP value is `1e-81`.
**XRP** has 6 significant digits past the decimal point. In other words, XRP cannot be divided into positive values smaller than `0.000001` (1e-6). This smallest unit is called a "drop". XRP has a maximum value of `100000000000` (1e11). Some RippleAPI methods accept XRP in order to maintain compatibility with older versions of the API. For consistency with the `rippled` APIs, we recommend formally specifying XRP values in *drops* in all API requests, and converting them to XRP for display. This is similar to Bitcoin's *satoshis* and Ethereum's *wei*. 1 XRP = 1,000,000 drops.
**Non-XRP values** have 16 decimal digits of precision, with a maximum value of `9999999999999999e80`. The smallest positive non-XRP value is `1e-81`.
## Amount
Example amount:
Example 100.00 USD amount:
```json
{
@@ -36,15 +35,16 @@ Example amount:
}
```
Example XRP amount:
Example 3.0 XRP amount, in drops:
```json
{
"currency": "XRP",
"value": "2000"
"currency": "drops",
"value": "3000000"
}
```
(Requires `ripple-lib` version 1.0.0 or higher.)
An *amount* is data structure representing a currency, a quantity of that currency, and the counterparty on the trustline that holds the value. For XRP, there is no counterparty.
An *amount* is an object specifying a currency, a quantity of that currency, and the counterparty (issuer) on the trustline that holds the value. For XRP, there is no counterparty.
A *lax amount* allows the counterparty to be omitted for all currencies. If the counterparty is not specified in an amount within a transaction specification, then any counterparty may be used for that amount.
@@ -52,4 +52,4 @@ A *lax lax amount* allows either or both the counterparty and value to be omitte
A *balance* is an amount than can have a negative value.
<%- renderSchema('objects/amount-base.json') %>
<%- renderSchema('objects/amountbase.json') %>

View File

@@ -3,7 +3,7 @@
Use the following [boilerplate code](https://en.wikipedia.org/wiki/Boilerplate_code) to wrap your custom code using RippleAPI.
```javascript
const {RippleAPI} = require('ripple-lib');
const RippleAPI = require('ripple-lib').RippleAPI;
const api = new RippleAPI({
server: 'wss://s1.ripple.com' // Public rippled server hosted by Ripple, Inc.
@@ -11,6 +11,14 @@ const api = new RippleAPI({
api.on('error', (errorCode, errorMessage) => {
console.log(errorCode + ': ' + errorMessage);
});
api.on('connected', () => {
console.log('connected');
});
api.on('disconnected', (code) => {
// code - [close code](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent) sent by the server
// will be 1000 if this was normal closure
console.log('disconnected, code:', code);
});
api.connect().then(() => {
/* insert code here */
}).then(() => {
@@ -18,9 +26,9 @@ api.connect().then(() => {
}).catch(console.error);
```
RippleAPI is designed to work in [NodeJS](https://nodejs.org) (version `0.12.0` or greater) using [Babel](https://babeljs.io/) for [ECMAScript 6](https://babeljs.io/docs/learn-es2015/) support.
RippleAPI is designed to work in [Node.js](https://nodejs.org) version **6.11.3**. RippleAPI may work on older Node.js versions if you use [Babel](https://babeljs.io/) for [ECMAScript 6](https://babeljs.io/docs/learn-es2015/) support.
The code samples in this documentation are written in ES6, but `RippleAPI` will work with ES5 also. Regardless of whether you use ES5 or ES6, the methods that return promises will return [ES6-style promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
The code samples in this documentation are written with ECMAScript 6 (ES6) features, but `RippleAPI` also works with ECMAScript 5 (ES5). Regardless of whether you use ES5 or ES6, the methods that return Promises return [ES6-style promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
<aside class="notice">
All the code snippets in this documentation assume that you have surrounded them with this boilerplate.
@@ -45,16 +53,10 @@ If you omit the `server` parameter, RippleAPI operates [offline](#offline-functi
### Installation ###
1. Install [NodeJS](https://nodejs.org) and the Node Package Manager (npm). Most Linux distros have a package for NodeJS, but make sure you have version `0.12.0` or higher.
2. Use npm to install [Babel](https://babeljs.io/) globally:
`npm install -g babel-cli`
3. Use npm to install RippleAPI:
`npm install ripple-lib`
1. Install [Node.js](https://nodejs.org) and [Yarn](https://yarnpkg.com/en/docs/install). Most Linux distros have a package for Node.js; check that it's the version you want.
2. Use yarn to install RippleAPI:
`yarn add ripple-lib`
After you have installed ripple-lib, you can create scripts using the [boilerplate](#boilerplate) and run them using babel-node:
`babel-node script.js`
<aside class="notice">
Instead of using babel-node in production, we recommend using Babel to transpile to ECMAScript 5 first.
</aside>
After you have installed ripple-lib, you can create scripts using the [boilerplate](#boilerplate) and run them using the Node.js executable, typically named `node`:
`node script.js`

View File

@@ -1,6 +1,6 @@
## computeLedgerHash
`computeLedgerHash(ledger: Object): string`
`computeLedgerHash(ledger: object): string`
Compute the hash of a ledger.

View File

@@ -0,0 +1,19 @@
## deriveAddress
`deriveAddress(publicKey: string): string`
Derive an XRP Ledger address from a public key.
### Parameters
This method takes one parameter, the public key from which to derive the address.
### Return Value
This method returns a string corresponding to the address derived from the public key.
### Example
```javascript
var address = api.deriveAddress(public_key);
```

View File

@@ -0,0 +1,21 @@
## deriveKeypair
`deriveKeypair(seed: string): {privateKey: string, publicKey: string}`
Derive a public and private key from a seed.
### Parameters
This method takes one parameter, the seed from which to derive the public and private key.
### Return Value
This method returns an object containing the public and private components of the keypair corresponding to the seed.
### Example
```javascript
var keypair = api.deriveKeypair(seed)
var public_key = keypair.publicKey;
var private_key = keypair.privateKey;
```

View File

@@ -47,3 +47,35 @@ api.on('error', (errorCode, errorMessage, data) => {
```
tooBusy: The server is too busy to help you now.
```
## connected
This event is emitted after connection successfully opened.
### Example
```javascript
api.on('connected', () => {
console.log('Connection is open now.');
});
```
## disconnected
This event is emitted when connection is closed.
### Return Value
The only parameter is a number containing the [close code](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent) send by the server.
### Example
```javascript
api.on('disconnected', (code) => {
if (code !== 1000) {
console.log('Connection is closed due to error.');
} else {
console.log('Connection is closed normally.');
}
});
```

View File

@@ -0,0 +1,254 @@
## formatBidsAndAsks
`formatBidsAndAsks(orderbookInfo: {base: Issue, counter: Issue}, offers: BookOffer[]): orderbook`
Returns formatted bids and asks, which make up an orderbook.
This is a static method on the `RippleAPI` class.
### Parameters
This method takes two parameters.
1. An `OrderbookInfo` object: `{ base: Issue, counter: Issue }`.
2. An array of `BookOffer` objects.
### Return Value
This method returns an object with two properties: `bids` and `asks`, each of which is an array of bids (buy orders) or asks (sell orders), respectively. (Note: the structures of `bids` and `asks` are identical.)
Object structure:
<%- renderSchema('output/get-orderbook.json') %>
**Raw order data:** The response includes a `data` property containing the raw order data. This may include `owner_funds`, `Flags`, and other fields.
For details, see the rippled method [book_offers](https://ripple.com/build/rippled-apis/#book-offers).
### Example
```javascript
const orderbookInfo = {
"base": {
"currency": "USD",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
},
"counter": {
"currency": "BTC",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
};
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
return Promise.all(
[
this.api.request('book_offers', {
taker_gets: RippleAPI.renameCounterpartyToIssuer(orderbookInfo.base),
taker_pays: RippleAPI.renameCounterpartyToIssuer(orderbookInfo.counter),
ledger_index: 'validated',
limit: 20,
taker: address
}),
this.api.request('book_offers', {
taker_gets: RippleAPI.renameCounterpartyToIssuer(orderbookInfo.counter),
taker_pays: RippleAPI.renameCounterpartyToIssuer(orderbookInfo.base),
ledger_index: 'validated',
limit: 20,
taker: address
})
]
).then((directOfferResults, reverseOfferResults) => {
const directOffers = (directOfferResults ? directOfferResults : []).reduce((acc, res) => acc.concat(res.offers), [])
const reverseOffers = (reverseOfferResults ? reverseOfferResults : []).reduce((acc, res) => acc.concat(res.offers), [])
const orderbook = RippleAPI.formatBidsAndAsks(orderbookInfo, [...directOffers, ...reverseOffers]);
console.log(JSON.stringify(orderbook, null, 2));
});
```
```
{
"bids": [
{
"specification": {
"direction": "buy",
"quantity": {
"currency": "USD",
"value": "0.71800168",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
},
"totalPrice": {
"currency": "BTC",
"value": "0.00016708342",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
},
"properties": {
"maker": "rUKoQ1Zhn6c8EfPsaVa2Yx5NqaKN1JQSvq",
"sequence": 262660,
"makerExchangeRate": "4297.264683713081"
},
"data": {
"Account": "rUKoQ1Zhn6c8EfPsaVa2Yx5NqaKN1JQSvq",
"BookDirectory": "6EAB7C172DEFA430DBFAD120FDC373B5F5AF8B191649EC98580F4456E6FA8239",
"BookNode": "0000000000000000",
"Flags": 0,
"LedgerEntryType": "Offer",
"OwnerNode": "000000000000001D",
"PreviousTxnID": "16D75506C6317723FC03543130B5E0AAB13E8AD22514C1DB098BE05771C90447",
"PreviousTxnLgrSeq": 43127860,
"Sequence": 262660,
"TakerGets": {
"currency": "BTC",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"value": "0.00016708342"
},
"TakerPays": {
"currency": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"value": "0.71800168"
},
"index": "DE877FB94EF892A4BCC58DB8CDE063D97AB5133201905DE6C8650B5DEA19E11B",
"owner_funds": "0.03358376764081196",
"quality": "4297.264683713081"
}
},
{
"specification": {
"direction": "buy",
"quantity": {
"currency": "USD",
"value": "1.6770875",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
},
"totalPrice": {
"currency": "BTC",
"value": "0.00038681218",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
},
"properties": {
"maker": "rpmL45YbZWKgp8AH8EjBSknWo5c8dNuuBM",
"sequence": 231459,
"makerExchangeRate": "4335.663628792661"
},
"data": {
"Account": "rpmL45YbZWKgp8AH8EjBSknWo5c8dNuuBM",
"BookDirectory": "6EAB7C172DEFA430DBFAD120FDC373B5F5AF8B191649EC98580F67435A75B355",
"BookNode": "0000000000000000",
"Flags": 0,
"LedgerEntryType": "Offer",
"OwnerNode": "0000000000000001",
"PreviousTxnID": "F049EAFDDDA7B99970F77533743D95C9E12A16FE6C56215A0B09C32C4D23163F",
"PreviousTxnLgrSeq": 43127094,
"Sequence": 231459,
"TakerGets": {
"currency": "BTC",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"value": "0.00038681218"
},
"TakerPays": {
"currency": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"value": "1.6770875"
},
"index": "3B314A51BD57601CA1509834DF9462037BF4B05AFCC1E1EFD334DB4E2D7B2AA6",
"owner_funds": "0.03906802968738533",
"quality": "4335.663628792661"
}
},
// ... trimmed for brevity ...
],
"asks": [
{
"specification": {
"direction": "sell",
"quantity": {
"currency": "USD",
"value": "0.71085738",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
},
"totalPrice": {
"currency": "BTC",
"value": "0.00016876265",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
},
"properties": {
"maker": "rUKoQ1Zhn6c8EfPsaVa2Yx5NqaKN1JQSvq",
"sequence": 262664,
"makerExchangeRate": "0.0002374071856720401"
},
"data": {
"Account": "rUKoQ1Zhn6c8EfPsaVa2Yx5NqaKN1JQSvq",
"BookDirectory": "20294C923E80A51B487EB9547B3835FD483748B170D2D0A451086F34ADB0EA11",
"BookNode": "0000000000000000",
"Flags": 0,
"LedgerEntryType": "Offer",
"OwnerNode": "000000000000001D",
"PreviousTxnID": "54CE0B2783AF973718FAFA35E864A3C172BE488EBBB6F2852611C6DAC8893BDF",
"PreviousTxnLgrSeq": 43127875,
"Sequence": 262664,
"TakerGets": {
"currency": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"value": "0.71085738"
},
"TakerPays": {
"currency": "BTC",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"value": "0.00016876265"
},
"index": "2D4ED103D6B3FEFA21BC385C53B63359F5678E5AA5429DDE6E1D8FE8B41CD6A8",
"owner_funds": "142.8821425048244",
"quality": "0.0002374071856720401"
}
},
{
"specification": {
"direction": "sell",
"quantity": {
"currency": "USD",
"value": "1.6438778",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
},
"totalPrice": {
"currency": "BTC",
"value": "0.00039462656",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
},
"properties": {
"maker": "rpmL45YbZWKgp8AH8EjBSknWo5c8dNuuBM",
"sequence": 231483,
"makerExchangeRate": "0.0002400583303698121"
},
"data": {
"Account": "rpmL45YbZWKgp8AH8EjBSknWo5c8dNuuBM",
"BookDirectory": "20294C923E80A51B487EB9547B3835FD483748B170D2D0A4510887515B1216C9",
"BookNode": "0000000000000000",
"Flags": 0,
"LedgerEntryType": "Offer",
"OwnerNode": "0000000000000001",
"PreviousTxnID": "6FA370F52C45F6149482156FF7B4226713AECE991FB7D053F74172CB0B8F24E9",
"PreviousTxnLgrSeq": 43127158,
"Sequence": 231483,
"TakerGets": {
"currency": "USD",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"value": "1.6438778"
},
"TakerPays": {
"currency": "BTC",
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"value": "0.00039462656"
},
"index": "735F9661AD006BA0776859BE371D445555FC0815604603AC056469C16AC84AE3",
"owner_funds": "166.0316626329364",
"quality": "0.0002400583303698121"
}
},
// ... trimmed for brevity ...
]
}
```

View File

@@ -2,7 +2,7 @@
`generateAddress(): {address: string, secret: string}`
Generate a new Ripple address and corresponding secret.
Generate a new XRP Ledger address and corresponding secret.
### Parameters

View File

@@ -1,6 +1,6 @@
## getAccountInfo
`getAccountInfo(address: string, options: Object): Promise<Object>`
`getAccountInfo(address: string, options: object): Promise<object>`
Returns information for the specified account. Note: For account data that is modifiable by the user, see [getSettings](#getsettings).

View File

@@ -0,0 +1,33 @@
## getAccountObjects
`getAccountObjects(address: string, options: object): Promise<AccountObjectsResponse>`
Returns objects owned by an account. For an account's trust lines and balances, see `getTrustlines` and `getBalances`.
### Parameters
<%- renderSchema('input/get-account-objects.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<%- renderSchema('output/get-account-objects.json') %>
The types of objects that may be returned include:
* Offer objects for orders that are currently live, unfunded, or expired but not yet removed.
* RippleState objects for trust lines where this account's side is not in the default state.
* A SignerList object if the account has multi-signing enabled.
* Escrow objects for held payments that have not yet been executed or canceled.
* PayChannel objects for open payment channels.
* Check objects for pending checks.
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
return api.getAccountObjects(address: address).then(objects =>
{/* ... */});
```
<%- renderFixture('responses/get-account-objects.json') %>

View File

@@ -1,6 +1,6 @@
## getBalanceSheet
`getBalanceSheet(address: string, options: Object): Promise<Object>`
`getBalanceSheet(address: string, options: object): Promise<object>`
Returns aggregate balances by currency plus a breakdown of assets and obligations for a specified account.
@@ -10,7 +10,7 @@ Returns aggregate balances by currency plus a breakdown of assets and obligation
### Return Value
This method returns a promise that resolves with an array of objects with the following structure:
This method returns a promise that resolves with an object with the following structure:
<%- renderSchema('output/get-balance-sheet.json') %>

View File

@@ -1,6 +1,6 @@
## getBalances
`getBalances(address: string, options: Object): Promise<Array<Object>>`
`getBalances(address: string, options: object): Promise<Array<object>>`
Returns balances for a specified account.

View File

@@ -1,16 +1,18 @@
## getFee
`getFee(): Promise<number>`
`getFee(): Promise<string>`
Returns the estimated transaction fee for the rippled server the RippleAPI instance is connected to.
This will use the [feeCushion parameter](#parameters) provided to the RippleAPI constructor, or the default value of `1.2`.
### Parameters
This method has no parameters.
<%- renderSchema('input/get-fee.json') %>
### Return Value
This method returns a promise that resolves with a string encoded floating point value representing the estimated fee to submit a transaction, expressed in XRP.
This method returns a promise that resolves with a string-encoded floating point value representing the estimated fee to submit a transaction, expressed in XRP.
### Example
@@ -19,5 +21,5 @@ return api.getFee().then(fee => {/* ... */});
```
```json
"0.012"
"0.000012"
```

View File

@@ -1,6 +1,6 @@
## getLedger
`getLedger(options: Object): Promise<Object>`
`getLedger(options: object): Promise<object>`
Returns header information for the specified ledger (or the most recent validated ledger if no ledger is specified). Optionally, all the transactions that were validated in the ledger or the account state information can be returned with the ledger header.

View File

@@ -1,9 +1,13 @@
## getOrderbook
`getOrderbook(address: string, orderbook: Object, options: Object): Promise<Object>`
`getOrderbook(address: string, orderbook: object, options: object): Promise<object>`
Returns open orders for the specified account. Open orders are orders that have not yet been fully executed and are still in the order book.
**Breaking change:** In ripple-lib 1.1.0 and earlier, orders returned by this method were not sorted correctly. Orders are now sorted correctly, from best to worst.
**See also:** An alternative way to get orderbooks is with `request` and [`formatBidsAndAsks`](#formatbidsandasks).
### Parameters
<%- renderSchema('input/get-orderbook.json') %>
@@ -14,6 +18,10 @@ This method returns a promise that resolves with an object with the following st
<%- renderSchema('output/get-orderbook.json') %>
**Raw order data:** The response includes a `data` property containing the raw order data. This may include `owner_funds`, `Flags`, and other fields.
For details, see the rippled method [book_offers](https://ripple.com/build/rippled-apis/#book-offers).
### Example
```javascript

View File

@@ -1,6 +1,6 @@
## getOrders
`getOrders(address: string, options: Object): Promise<Array<Object>>`
`getOrders(address: string, options: object): Promise<Array<object>>`
Returns open orders for the specified account. Open orders are orders that have not yet been fully executed and are still in the order book.

View File

@@ -1,6 +1,6 @@
## getPaths
`getPaths(pathfind: Object): Promise<Array<Object>>`
`getPaths(pathfind: object): Promise<Array<object>>`
Finds paths to send a payment. Paths are options for how to route a payment.

View File

@@ -0,0 +1,26 @@
## getPaymentChannel
`getPaymentChannel(id: string): Promise<object>`
Returns specified payment channel.
### Parameters
<%- renderSchema('input/get-payment-channel.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<%- renderSchema('output/get-payment-channel.json') %>
### Example
```javascript
const channelId =
'E30E709CF009A1F26E0E5C48F7AA1BFB79393764F15FB108BDC6E06D3CBD8415';
return api.getPaymentChannel(channelId).then(channel =>
{/* ... */});
```
<%- renderFixture('responses/get-payment-channel.json') %>

View File

@@ -1,6 +1,6 @@
## getSettings
`getSettings(address: string, options: Object): Promise<Object>`
`getSettings(address: string, options: object): Promise<object>`
Returns settings for the specified account. Note: For account data that is not modifiable by the user, see [getAccountInfo](#getaccountinfo).

View File

@@ -1,6 +1,6 @@
## getTransaction
`getTransaction(id: string, options: Object): Promise<Object>`
`getTransaction(id: string, options: object): Promise<object>`
Retrieves a transaction by its [Transaction ID](#transaction-id).

View File

@@ -1,6 +1,6 @@
## getTransactions
`getTransactions(address: string, options: Object): Promise<Array<Object>>`
`getTransactions(address: string, options: object): Promise<Array<object>>`
Retrieves historical transactions of an account.

View File

@@ -1,6 +1,6 @@
## getTrustlines
`getTrustlines(address: string, options: Object): Promise<Array<Object>>`
`getTrustlines(address: string, options: object): Promise<Array<object>>`
Returns trustlines for a specified account.

View File

@@ -0,0 +1,27 @@
## hasNextPage
`hasNextPage(currentResponse): boolean`
Returns `true` when there are more pages available.
When there are more results than contained in the response, the response includes a `marker` field. You can use this convenience method, or check for `marker` yourself.
See [Markers and Pagination](https://ripple.com/build/rippled-apis/#markers-and-pagination).
### Return Value
This method returns `true` if `currentResponse` includes a `marker`.
### Example
```javascript
return api.request('ledger_data', {
ledger_index: 'validated'
}).then(response => {
/* Do something useful with response */
if (api.hasNextPage(response)) {
/* There are more pages available */
}
}).catch(console.error);
```

View File

@@ -4,6 +4,15 @@
<% include basictypes.md.ejs %>
<% include transactions.md.ejs %>
<% include specifications.md.ejs %>
<% include rippledAPIs.md.ejs %>
<% include request.md.ejs %>
<% include hasNextPage.md.ejs %>
<% include requestNextPage.md.ejs %>
<% include staticMethods.md.ejs %>
<% include renameCounterpartyToIssuer.md.ejs %>
<% include formatBidsAndAsks.md.ejs %>
<% include methods.md.ejs %>
<% include connect.md.ejs %>
<% include disconnect.md.ejs %>
@@ -21,18 +30,38 @@
<% include getOrderbook.md.ejs %>
<% include getSettings.md.ejs %>
<% include getAccountInfo.md.ejs %>
<% include getAccountObjects.md.ejs %>
<% include getPaymentChannel.md.ejs %>
<% include getLedger.md.ejs %>
<% include parseAccountFlags.md.ejs %>
<% include prepareTransaction.md.ejs %>
<% include preparePayment.md.ejs %>
<% include prepareTrustline.md.ejs %>
<% include prepareOrder.md.ejs %>
<% include prepareOrderCancellation.md.ejs %>
<% include prepareSettings.md.ejs %>
<% include prepareSuspendedPaymentCreation.md.ejs %>
<% include prepareSuspendedPaymentCancellation.md.ejs %>
<% include prepareSuspendedPaymentExecution.md.ejs %>
<% include prepareEscrowCreation.md.ejs %>
<% include prepareEscrowCancellation.md.ejs %>
<% include prepareEscrowExecution.md.ejs %>
<% include preparePaymentChannelCreate.md.ejs %>
<% include preparePaymentChannelClaim.md.ejs %>
<% include preparePaymentChannelFund.md.ejs %>
<% include prepareCheckCreate.md.ejs %>
<% include prepareCheckCancel.md.ejs %>
<% include prepareCheckCash.md.ejs %>
<% include sign.md.ejs %>
<% include combine.md.ejs %>
<% include submit.md.ejs %>
<% include generateAddress.md.ejs %>
<% include isValidAddress.md.ejs %>
<% include isValidSecret.md.ejs %>
<% include deriveKeypair.md.ejs %>
<% include deriveAddress.md.ejs %>
<% include signPaymentChannelClaim.md.ejs %>
<% include verifyPaymentChannelClaim.md.ejs %>
<% include computeLedgerHash.md.ejs %>
<% include xrpToDropsAndDropsToXrp.md.ejs %>
<% include iso8601ToRippleTime.md.ejs %>
<% include txFlags.md.ejs %>
<% include schemaValidator.md.ejs %>
<% include events.md.ejs %>

View File

@@ -1,12 +1,10 @@
# Introduction
RippleAPI is the official client library to the Ripple Consensus Ledger. Currently, RippleAPI is only available in JavaScript.
RippleAPI (ripple-lib) is the official client library to the XRP Ledger. Currently, RippleAPI is only available in JavaScript.
Using RippleAPI, you can:
* [Query transactions from the network](#gettransaction)
* [Query transactions from the XRP Ledger history](#gettransaction)
* [Sign](#sign) transactions securely without connecting to any server
* [Submit](#submit) transactions to the Ripple Consensus Ledger, including [Payments](#payment), [Orders](#order), [Settings changes](#settings), and [other types](#transaction-types)
* [Generate a new Ripple Address](#generateaddress)
* [Submit](#submit) transactions to the XRP Ledger, including [Payments](#payment), [Orders](#order), [Settings changes](#settings), and [other types](#transaction-types)
* [Generate a new XRP Ledger Address](#generateaddress)
* ... and [much more](#api-methods).
RippleAPI only provides access to *validated*, *immutable* transaction data.

View File

@@ -0,0 +1,19 @@
## isValidAddress
`isValidAddress(address: string): boolean`
Checks if the specified string contains a valid address.
### Parameters
This method takes one parameter, the address to validate.
### Return Value
This method returns `true` if the address is valid and `false` if it is not.
### Example
```javascript
return api.isValidAddress("address")
```

View File

@@ -0,0 +1,19 @@
## isValidSecret
`isValidSecret(secret: string): boolean`
Checks if the specified string contains a valid secret.
### Parameters
This method takes one parameter, the secret which to validate.
### Return Value
This method returns `true` if the secret is valid and `false` if it is not.
### Example
```javascript
return api.isValidSecret("secret")
```

View File

@@ -0,0 +1,27 @@
## iso8601ToRippleTime
`iso8601ToRippleTime(iso8601: string): number`
This method parses a string representation of a date, and returns the number of seconds since the "Ripple Epoch" of January 1, 2000 (00:00 UTC).
The Ripple Epoch is 946684800 seconds after the Unix Epoch.
This method is useful for creating timestamps to use with the rippled APIs. The rippled APIs represent time as an unsigned integer of the number of seconds since the Ripple Epoch.
### Parameters
`iso8601`: A string representing a date and time. This string is parsed using JavaScript's `Date.parse()` method.
### Return Value
The number of seconds since the Ripple Epoch.
### Example
```javascript
api.iso8601ToRippleTime('2017-02-17T15:04:57Z');
```
```json
540659097
```

View File

@@ -5,23 +5,22 @@ RippleAPI can also function without internet connectivity. This can be useful in
To instantiate RippleAPI in offline mode, use the following boilerplate code:
```javascript
const {RippleAPI} = require('ripple-lib');
const RippleAPI = require('ripple-lib').RippleAPI;
const api = new RippleAPI();
/* insert code here */
```
Methods that depend on the state of the Ripple Consensus Ledger are unavailable in offline mode. To prepare transactions offline, you **must** specify the `fee`, `sequence`, and `maxLedgerVersion` parameters in the [transaction instructions](#transaction-instructions). The following methods should work offline:
Methods that depend on the state of the XRP Ledger are unavailable in offline mode. To prepare transactions offline, you **must** specify the `fee`, `sequence`, and `maxLedgerVersion` parameters in the [transaction instructions](#transaction-instructions). You can use the following methods while offline:
* [preparePayment](#preparepayment)
* [prepareTrustline](#preparetrustline)
* [prepareOrder](#prepareorder)
* [prepareOrderCancellation](#prepareordercancellation)
* [prepareSettings](#preparesettings)
* [prepareSuspendedPaymentCreation](#preparesuspendedpaymentcreation)
* [prepareSuspendedPaymentCancellation](#preparesuspendedpaymentcancellation)
* [prepareSuspendedPaymentExecution](#preparesuspendedpaymentexecution)
* [prepareEscrowCreation](#prepareescrowcreation)
* [prepareEscrowCancellation](#prepareescrowcancellation)
* [prepareEscrowExecution](#prepareescrowexecution)
* [sign](#sign)
* [generateAddress](#generateaddress)
* [computeLedgerHash](#computeledgerhash)

View File

@@ -0,0 +1,35 @@
## parseAccountFlags
`parseAccountFlags(Flags: number): object`
Parse an `AccountRoot` object's [`Flags`](https://developers.ripple.com/accountroot.html#accountroot-flags).
### Parameters
This method takes one parameter, the AccountRoot `Flags` number to parse. Note that flags have different mappings on other types of objects or in transactions such as AccountSet.
### Return Value
This method returns an object with containing a key for each AccountRoot flag known to this version of RippleAPI. Each flag has a boolean value of `true` or `false`.
### Example
```javascript
const account_info = await api.request('account_info', {account: 'rKsdkGhyZH6b2Zzd5hNnEqSv2wpznn4n6N'})
const flags = api.parseAccountFlags(account_info.account_data.Flags)
console.log(JSON.stringify(flags, null, 2))
```
```json
{
"passwordSpent": false,
"requireDestinationTag": false,
"requireAuthorization": false,
"depositAuth": true,
"disallowIncomingXRP": false,
"disableMasterKey": false,
"noFreeze": false,
"globalFreeze": false,
"defaultRipple": false
}
```

View File

@@ -0,0 +1,30 @@
## prepareCheckCancel
`prepareCheckCancel(address: string, checkCancel: object, instructions: object): Promise<object>`
Prepare a Check cancellation transaction. This cancels an unredeemed Check, removing it from the ledger without sending any money. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
### Parameters
<%- renderSchema('input/prepare-check-cancel.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema('output/prepare.json') %>
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const checkCancel = <%- importFile('test/fixtures/requests/prepare-check-cancel.json') %>;
return api.prepareCheckCancel(address, checkCancel).then(prepared =>
{/* ... */});
```
<%- renderFixture('responses/prepare-check-cancel.json') %>

View File

@@ -0,0 +1,30 @@
## prepareCheckCash
`prepareCheckCash(address: string, checkCash: object, instructions: object): Promise<object>`
Prepare a Check cashing transaction. This redeems a Check to receive up to the amount authorized by the corresponding CheckCreate transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
### Parameters
<%- renderSchema('input/prepare-check-cash.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema('output/prepare.json') %>
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const checkCash = <%- importFile('test/fixtures/requests/prepare-check-cash-amount.json') %>;
return api.prepareCheckCash(address, checkCash).then(prepared =>
{/* ... */});
```
<%- renderFixture('responses/prepare-check-cash-amount.json') %>

View File

@@ -0,0 +1,30 @@
## prepareCheckCreate
`prepareCheckCreate(address: string, checkCreate: object, instructions: object): Promise<object>`
Prepare a Check creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
### Parameters
<%- renderSchema('input/prepare-check-create.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema('output/prepare.json') %>
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const checkCreate = <%- importFile('test/fixtures/requests/prepare-check-create.json') %>;
return api.prepareCheckCreate(address, checkCreate).then(prepared =>
{/* ... */});
```
<%- renderFixture('responses/prepare-check-create.json') %>

View File

@@ -0,0 +1,30 @@
## prepareEscrowCancellation
`prepareEscrowCancellation(address: string, escrowCancellation: object, instructions: object): Promise<object>`
Prepare an escrow cancellation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
### Parameters
<%- renderSchema('input/prepare-escrow-cancellation.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema('output/prepare.json') %>
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const escrowCancellation = <%- importFile('test/fixtures/requests/prepare-escrow-cancellation.json') %>;
return api.prepareEscrowCancellation(address, escrowCancellation).then(prepared =>
{/* ... */});
```
<%- renderFixture('responses/prepare-escrow-cancellation.json') %>

View File

@@ -0,0 +1,36 @@
## prepareEscrowCreation
`prepareEscrowCreation(address: string, escrowCreation: object, instructions: object): Promise<object>`
Prepare an escrow creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
### Parameters
<%- renderSchema('input/prepare-escrow-creation.json') %>
This is a convenience method for generating the EscrowCreate JSON used by rippled, so the same restrictions apply.
Field mapping: `allowCancelAfter` is equivalent to rippled's `CancelAfter`; `allowExecuteAfter` is equivalent to `FinishAfter`. At the `allowCancelAfter` time, the escrow is considered expired. This means that the funds can only be returned to the sender. At the `allowExecuteAfter` time, the escrow is permitted to be released to the recipient (if the `condition` is fulfilled).
Note that `allowCancelAfter` must be chronologically later than `allowExecuteAfter`.
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema('output/prepare.json') %>
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const escrowCreation = <%- importFile('test/fixtures/requests/prepare-escrow-creation.json') %>;
return api.prepareEscrowCreation(address, escrowCreation).then(prepared =>
{/* ... */});
```
<%- renderFixture('responses/prepare-escrow-creation.json') %>

View File

@@ -0,0 +1,30 @@
## prepareEscrowExecution
`prepareEscrowExecution(address: string, escrowExecution: object, instructions: object): Promise<object>`
Prepare an escrow execution transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
### Parameters
<%- renderSchema('input/prepare-escrow-execution.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema('output/prepare.json') %>
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const escrowExecution = <%- importFile('test/fixtures/requests/prepare-escrow-execution.json') %>;
return api.prepareEscrowExecution(address, escrowExecution).then(prepared =>
{/* ... */});
```
<%- renderFixture('responses/prepare-escrow-execution.json') %>

View File

@@ -1,6 +1,6 @@
## prepareOrder
`prepareOrder(address: string, order: Object, instructions: Object): Promise<Object>`
`prepareOrder(address: string, order: object, instructions: object): Promise<object>`
Prepare an order transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
@@ -22,6 +22,8 @@ All "prepare*" methods have the same return type.
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
// Buy 10.10 USD (of the specified issuer) for 2.0 XRP (2000000 drops), fill or kill.
const order = <%- importFile('test/fixtures/requests/prepare-order.json') %>;
return api.prepareOrder(address, order)
.then(prepared => {/* ... */});

View File

@@ -1,6 +1,6 @@
## prepareOrderCancellation
`prepareOrderCancellation(address: string, orderCancellation: Object, instructions: Object): Promise<Object>`
`prepareOrderCancellation(address: string, orderCancellation: object, instructions: object): Promise<object>`
Prepare an order cancellation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
@@ -23,7 +23,7 @@ All "prepare*" methods have the same return type.
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const orderCancellation = {orderSequence: 123};
return api.prepareOrderCancellation(address, sequence)
return api.prepareOrderCancellation(address, orderCancellation)
.then(prepared => {/* ... */});
```

View File

@@ -1,6 +1,6 @@
## preparePayment
`preparePayment(address: string, payment: Object, instructions: Object): Promise<Object>`
`preparePayment(address: string, payment: object, instructions: object): Promise<object>`
Prepare a payment transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
@@ -23,8 +23,11 @@ All "prepare*" methods have the same return type.
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const payment = <%- importFile('test/fixtures/requests/prepare-payment.json') %>;
return api.preparePayment(address, payment).then(prepared =>
{/* ... */});
return api.preparePayment(address, payment).then(prepared => {
/* ... */
}).catch(error => {
/* ... as with all prepare* methods, use a Promise catch block to handle errors ... */
})
```
<%- renderFixture("responses/prepare-payment.json") %>

View File

@@ -0,0 +1,30 @@
## preparePaymentChannelClaim
`preparePaymentChannelClaim(address: string, paymentChannelClaim: object, instructions: object): Promise<object>`
Prepare a payment channel claim transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
### Parameters
<%- renderSchema('input/prepare-payment-channel-claim.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema('output/prepare.json') %>
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const paymentChannelClaim = <%- importFile('test/fixtures/requests/prepare-payment-channel-claim.json') %>;
return api.preparePaymentChannelClaim(address, paymentChannelClaim).then(prepared =>
{/* ... */});
```
<%- renderFixture('responses/prepare-payment-channel-claim.json') %>

View File

@@ -0,0 +1,30 @@
## preparePaymentChannelCreate
`preparePaymentChannelCreate(address: string, paymentChannelCreate: object, instructions: object): Promise<object>`
Prepare a payment channel creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
### Parameters
<%- renderSchema('input/prepare-payment-channel-create.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema('output/prepare.json') %>
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const paymentChannelCreate = <%- importFile('test/fixtures/requests/prepare-payment-channel-create.json') %>;
return api.preparePaymentChannelCreate(address, paymentChannelCreate).then(prepared =>
{/* ... */});
```
<%- renderFixture('responses/prepare-payment-channel-create.json') %>

View File

@@ -0,0 +1,30 @@
## preparePaymentChannelFund
`preparePaymentChannelFund(address: string, paymentChannelFund: object, instructions: object): Promise<object>`
Prepare a payment channel fund transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
### Parameters
<%- renderSchema('input/prepare-payment-channel-fund.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema('output/prepare.json') %>
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const paymentChannelFund = <%- importFile('test/fixtures/requests/prepare-payment-channel-fund.json') %>;
return api.preparePaymentChannelFund(address, paymentChannelFund).then(prepared =>
{/* ... */});
```
<%- renderFixture('responses/prepare-payment-channel-fund.json') %>

View File

@@ -1,6 +1,6 @@
## prepareSettings
`prepareSettings(address: string, settings: Object, instructions: Object): Promise<Object>`
`prepareSettings(address: string, settings: object, instructions: object): Promise<object>`
Prepare a settings transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).

View File

@@ -1,32 +0,0 @@
## prepareSuspendedPaymentCancellation
`prepareSuspendedPaymentCancellation(address: string, suspendedPaymentCancellation: Object, instructions: Object): Promise<Object>`
Prepare a suspended payment cancellation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
**Caution:** Suspended Payments are currently available on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) only.
### Parameters
<%- renderSchema('input/prepare-suspended-payment-cancellation.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema('output/prepare.json') %>
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const suspendedPaymentCancellation = <%- importFile('test/fixtures/requests/prepare-suspended-payment-cancellation.json') %>;
return api.prepareSuspendedPaymentCancellation(address, suspendedPaymentCancellation).then(prepared =>
{/* ... */});
```
<%- renderFixture('responses/prepare-suspended-payment-cancellation.json') %>

View File

@@ -1,32 +0,0 @@
## prepareSuspendedPaymentCreation
`prepareSuspendedPaymentCreation(address: string, suspendedPaymentCreation: Object, instructions: Object): Promise<Object>`
Prepare a suspended payment creation transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
**Caution:** Suspended Payments are currently available on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) only.
### Parameters
<%- renderSchema('input/prepare-suspended-payment-creation.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema('output/prepare.json') %>
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const suspendedPaymentCreation = <%- importFile('test/fixtures/requests/prepare-suspended-payment-creation.json') %>;
return api.prepareSuspendedPaymentCreation(address, suspendedPaymentCreation).then(prepared =>
{/* ... */});
```
<%- renderFixture('responses/prepare-suspended-payment-creation.json') %>

View File

@@ -1,32 +0,0 @@
## prepareSuspendedPaymentExecution
`prepareSuspendedPaymentExecution(address: string, suspendedPaymentExecution: Object, instructions: Object): Promise<Object>`
Prepare a suspended payment execution transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
**Caution:** Suspended Payments are currently available on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) only.
### Parameters
<%- renderSchema('input/prepare-suspended-payment-execution.json') %>
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema('output/prepare.json') %>
### Example
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const suspendedPaymentExecution = <%- importFile('test/fixtures/requests/prepare-suspended-payment-execution.json') %>;
return api.prepareSuspendedPaymentExecution(address, suspendedPaymentExecution).then(prepared =>
{/* ... */});
```
<%- renderFixture('responses/prepare-suspended-payment-execution.json') %>

View File

@@ -0,0 +1,50 @@
## prepareTransaction
`prepareTransaction(transaction: object, instructions: object): Promise<object>`
Prepare a transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
This method works with any of [the transaction types supported by rippled](https://developers.ripple.com/transaction-types.html).
Notably, this is the preferred method for preparing a `DepositPreauth` transaction (added in rippled 1.1.0).
### Parameters
Name | Type | Description
---- | ---- | -----------
transaction | [transaction](https://developers.ripple.com/transaction-formats.html) | The specification (JSON) of the transaction to prepare. Set `Account` to the address of the account that is creating the transaction. You may omit auto-fillable fields like `Fee`, `Flags`, and `Sequence` to have them set automatically.
instructions | [instructions](#transaction-instructions) | *Optional* Instructions for executing the transaction.
### Return Value
This method returns a promise that resolves with an object with the following structure:
<aside class="notice">
All "prepare*" methods have the same return type.
</aside>
<%- renderSchema("output/prepare.json") %>
### Example
```javascript
async function preparedPreauth() {
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
return api.prepareTransaction({
TransactionType: 'DepositPreauth',
Account: address,
Authorize: 'rMyVso4p83khNyHdV1m1PggV9QNadCj8wM'
});
}
```
```javascript
{
txJSON: '{"TransactionType":"DepositPreauth","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Authorize":"rMyVso4p83khNyHdV1m1PggV9QNadCj8wM","Flags":2147483648,"LastLedgerSequence":13561714,"Fee":"12","Sequence":1}',
instructions: {
fee: '0.000012',
sequence: 1,
maxLedgerVersion: 13561714
}
}
```

View File

@@ -1,6 +1,6 @@
## prepareTrustline
`prepareTrustline(address: string, trustline: Object, instructions: Object): Promise<Object>`
`prepareTrustline(address: string, trustline: object, instructions: object): Promise<object>`
Prepare a trustline transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
@@ -23,7 +23,7 @@ All "prepare*" methods have the same return type.
```javascript
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
const trustline = <%- importFile('test/fixtures/requests/prepare-trustline.json') %>;
return api.preparePayment(address, trustline).then(prepared =>
return api.prepareTrustline(address, trustline).then(prepared =>
{/* ... */});
```

View File

@@ -0,0 +1,37 @@
## renameCounterpartyToIssuer
`renameCounterpartyToIssuer(issue: {currency: string, counterparty: address}): {currency: string, issuer: address}`
Returns an object with the `counterparty` field renamed to `issuer`. This is useful because RippleAPI generally uses the name `counterparty` while the rippled API generally uses the name `issuer`.
This is a static method on the `RippleAPI` class.
### Parameters
This method takes one parameter, an object with a `counterparty` field.
### Return Value
This method returns a new object similar to the source object, but with `issuer` instead of `counterparty`.
### Example
```javascript
const orderbookInfo = {
"base": {
"currency": "USD",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
},
"counter": {
"currency": "BTC",
"counterparty": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
}
};
console.log(RippleAPI.renameCounterpartyToIssuer(orderbookInfo.base))
console.log(RippleAPI.renameCounterpartyToIssuer(orderbookInfo.counter))
```
```
{ currency: 'USD', issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' }
{ currency: 'BTC', issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' }
```

27
docs/src/request.md.ejs Normal file
View File

@@ -0,0 +1,27 @@
## request
`request(command: string, options: object): Promise<object>`
Returns the response from invoking the specified command, with the specified options, on the connected rippled server.
Refer to [rippled APIs](https://ripple.com/build/rippled-apis/) for commands and options. All XRP amounts must be specified in drops. One drop is equal to 0.000001 XRP. See [Specifying Currency Amounts](https://ripple.com/build/rippled-apis/#specifying-currency-amounts).
Most commands return data for the `current` (in-progress, open) ledger by default. Do not rely on this. Always specify a ledger version in your request. In the example below, the 'validated' ledger is requested, which is the most recent ledger that has been validated by the whole network. See [Specifying Ledgers](https://ripple.com/build/rippled-apis/#specifying-ledgers).
### Return Value
This method returns a promise that resolves with the response from rippled.
### Example
```javascript
// Replace 'ledger' with your desired rippled command
return api.request('ledger', {
ledger_index: 'validated'
}).then(response => {
/* Do something useful with response */
console.log(JSON.stringify(response, null, 2))
}).catch(console.error);
```
<%- renderFixture('responses/ledger.json') %>

View File

@@ -0,0 +1,29 @@
## requestNextPage
`requestNextPage(command: string, params: object = {}, currentResponse: object): Promise<object>`
Requests the next page of data.
You can use this convenience method, or include `currentResponse.marker` in `params` yourself, when using `request`.
See [Markers and Pagination](https://ripple.com/build/rippled-apis/#markers-and-pagination).
### Return Value
This method returns a promise that resolves with the next page of data from rippled.
If the response does not have a next page, the promise will reject with `new errors.NotFoundError('response does not have a next page')`.
### Example
```javascript
const command = 'ledger_data'
const params = {
ledger_index: 'validated'
}
return api.request(command, params).then(response => {
return api.requestNextPage(command, params, response)
}).then(response_page_2 => {
/* Do something useful with second page of response */
}).catch(console.error);
```

View File

@@ -0,0 +1,69 @@
# rippled APIs
ripple-lib relies on [rippled APIs](https://ripple.com/build/rippled-apis/) for all online functionality. With ripple-lib version 1.0.0 and higher, you can easily access rippled APIs through ripple-lib. Use the `request()`, `hasNextPage()`, and `requestNextPage()` methods:
* Use `request()` to issue any `rippled` command, including `account_currencies`, `subscribe`, and `unsubscribe`. [Full list of API Methods](https://ripple.com/build/rippled-apis/#api-methods).
* Use `hasNextPage()` to determine whether a response has more pages. This is true when the response includes a [`marker` field](https://ripple.com/build/rippled-apis/#markers-and-pagination).
* Use `requestNextPage()` to request the next page of data.
When using rippled APIs:
* [Specify XRP amounts in drops](https://developers.ripple.com/basic-data-types.html#specifying-currency-amounts).
* [Specify timestamps as the number of seconds since the "Ripple Epoch"](https://developers.ripple.com/basic-data-types.html#specifying-time).
* Instead of `counterparty`, use `issuer`.
## Listening to streams
The `rippled` server can push updates to your client when various events happen. Refer to [Subscriptions in the `rippled` API docs](https://developers.ripple.com/subscription-methods.html) for details.
Note that the `streams` parameter for generic streams takes an array. For example, to subscribe to the `validations` stream, use `{ streams: [ 'validations' ] }`.
The string names of some generic streams to subscribe to are in the table below. (Refer to `rippled` for an up-to-date list of streams.)
Type | Description
---- | -----------
`server` | Sends a message whenever the status of the `rippled` server (for example, network connectivity) changes.
`ledger` | Sends a message whenever the consensus process declares a new validated ledger.
`transactions` | Sends a message whenever a transaction is included in a closed ledger.
`transactions_proposed` | Sends a message whenever a transaction is included in a closed ledger, as well as some transactions that have not yet been included in a validated ledger and may never be. Not all proposed transactions appear before validation. Even some transactions that don't succeed are included in validated ledgers because they take the anti-spam transaction fee.
`validations` | Sends a message whenever the server receives a validation message, also called a validation vote, regardless of whether the server trusts the validator.
`manifests` | Sends a message whenever the server receives a manifest.
`peer_status` | (Admin-only) Information about connected peer `rippled` servers, especially with regards to the consensus process.
When you subscribe to a stream, you must also listen to the relevant message type(s). Some of the available message types are in the table below. (Refer to `rippled` for an up-to-date list of message types.)
Type | Description
---- | -----------
`ledgerClosed` | Sent by the `ledger` stream when the consensus process declares a new fully validated ledger. The message identifies the ledger and provides some information about its contents.
`validationReceived` | Sent by the `validations` stream when the server receives a validation message, also called a validation vote, regardless of whether the server trusts the validator.
`manifestReceived` | Sent by the `manifests` stream when the server receives a manifest.
`transaction` | Sent by many subscriptions including `transactions`, `transactions_proposed`, `accounts`, `accounts_proposed`, and `book` (Order Book). See [Transaction Streams](https://ripple.com/build/rippled-apis/#transaction-streams) for details.
`peerStatusChange` | (Admin-only) Reports a large amount of information on the activities of other `rippled` servers to which the server is connected.
To register your listener function, use `connection.on(type, handler)`.
Here is an example of listening for transactions on given account(s):
```
const account = 'rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn' // Replace with the account you want notifications for
api.connect().then(() => { // Omit this if you are already connected
// 'transaction' can be replaced with the relevant `type` from the table above
api.connection.on('transaction', (event) => {
// Do something useful with `event`
console.log(JSON.stringify(event, null, 2))
})
api.request('subscribe', {
accounts: [ account ]
}).then(response => {
if (response.status === 'success') {
console.log('Successfully subscribed')
}
}).catch(error => {
// Handle `error`
})
})
```
The subscription ends when you unsubscribe or the WebSocket connection is closed.
For full details, see [rippled Subscriptions](https://ripple.com/build/rippled-apis/#subscriptions).

View File

@@ -0,0 +1,35 @@
## schemaValidator
Unlike the rest of the ripple-lib API, schemaValidator is a static object on RippleAPI. It provides utility methods that do not use a server.
## schemaValidate
`RippleAPI.schemaValidator.schemaValidate(schemaName: string, object: any): void`
This method checks an object for conformance to a specified schema. It does not return anything, but will throw a `ValidationError` if the object does not conform to the schema.
### Example
```javascript
RippleAPI.schemaValidator.schemaValidate('sign', {
signedTransaction: '12000322800000002400000017201B0086955368400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D874473045022100BDE09A1F6670403F341C21A77CF35BA47E45CDE974096E1AA5FC39811D8269E702203D60291B9A27F1DCABA9CF5DED307B4F23223E0B6F156991DB601DFB9C41CE1C770A726970706C652E636F6D81145E7B112523F68D2F5E879DB4EAC51C6698A69304',
id: '02ACE87F1996E3A23690A5BB7F1774BF71CCBA68F79805831B42ABAD5913D6F4'
})
```
```json
undefined
```
If the object is valid (conforms to the schema), nothing is returned. Otherwise, `schemaValidate` throws an error:
```javascript
RippleAPI.schemaValidator.schemaValidate('sign', {
signedTransaction: '12000322800000002400000017201B0086955368400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D874473045022100BDE09A1F6670403F341C21A77CF35BA47E45CDE974096E1AA5FC39811D8269E702203D60291B9A27F1DCABA9CF5DED307B4F23223E0B6F156991DB601DFB9C41CE1C770A726970706C652E636F6D81145E7B112523F68D2F5E879DB4EAC51C6698A69304',
id: '123'
})
```
```
[ValidationError(instance.id does not match pattern "^[A-F0-9]{64}$")]
```

View File

@@ -1,9 +1,16 @@
## sign
`sign(txJSON: string, secret: string, options: Object): {signedTransaction: string, id: string}`
```
sign(txJSON: string, secret: string, options: object): {signedTransaction: string, id: string}
sign(txJSON: string, keypair: object, options: object): {signedTransaction: string, id: string}
```
Sign a prepared transaction. The signed transaction must subsequently be [submitted](#submit).
This method can sign any of [the transaction types supported by ripple-binary-codec](https://github.com/ripple/ripple-binary-codec/blob/cfcde79c19c359e9a0466d7bc3dc9a3aef47bb99/src/enums/definitions.json#L1637). When a new transaction type is added to the XRP Ledger, it will be unrecognized until `ripple-binary-codec` is updated. If you try to sign an unrecognized transaction type, this method throws an error similar to the following:
`Error: [TRANSACTION_TYPE] is not a valid name or ordinal for TransactionType`
### Parameters
<%- renderSchema("input/sign.json") %>
@@ -19,7 +26,8 @@ This method returns an object with the following structure:
```javascript
const txJSON = '{"Flags":2147483648,"TransactionType":"AccountSet","Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59","Domain":"726970706C652E636F6D","LastLedgerSequence":8820051,"Fee":"12","Sequence":23}';
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV';
return api.sign(txJSON, secret);
const keypair = { privateKey: '00ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A', publicKey: '02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8' };
return api.sign(txJSON, secret); // or: api.sign(txJSON, keypair);
```
<%- renderFixture("responses/sign.json") %>

View File

@@ -0,0 +1,28 @@
## signPaymentChannelClaim
`signPaymentChannelClaim(channel: string, amount: string, privateKey: string): string`
Sign a payment channel claim. The signature can be submitted in a subsequent [PaymentChannelClaim](#preparepaymentchannelclaim) transaction.
### Parameters
<%- renderSchema("input/sign-payment-channel-claim.json") %>
### Return Value
This method returns a signature string:
<%- renderSchema("output/sign-payment-channel-claim.json") %>
### Example
```javascript
const channel =
'3E18C05AD40319B809520F1A136370C4075321B285217323396D6FD9EE1E9037';
const amount = '.00001';
const privateKey =
'ACCD3309DB14D1A4FC9B1DAE608031F4408C85C73EE05E035B7DC8B25840107A';
return api.signPaymentChannelClaim(channel, amount, privateKey);
```
<%- renderFixture("responses/sign-payment-channel-claim.json") %>

View File

@@ -28,6 +28,8 @@ See [Transaction Types](#transaction-types) for a description.
<%- renderSchema('specifications/order.json') %>
The following invalid flag combination causes a `ValidationError`: `immediateOrCancel` and `fillOrKill`. These fields are mutually exclusive, and cannot both be set at the same time.
### Example
<%- renderFixture('requests/prepare-order.json') %>
@@ -52,32 +54,92 @@ See [Transaction Types](#transaction-types) for a description.
<%- renderFixture('requests/prepare-settings.json') %>
## Suspended Payment Creation
## Escrow Creation
See [Transaction Types](#transaction-types) for a description.
<%- renderSchema('specifications/suspended-payment-creation.json') %>
<%- renderSchema('specifications/escrow-creation.json') %>
### Example
<%- renderFixture('requests/prepare-suspended-payment-creation.json') %>
<%- renderFixture('requests/prepare-escrow-creation.json') %>
## Suspended Payment Cancellation
## Escrow Cancellation
See [Transaction Types](#transaction-types) for a description.
<%- renderSchema('specifications/suspended-payment-cancellation.json') %>
<%- renderSchema('specifications/escrow-cancellation.json') %>
### Example
<%- renderFixture('requests/prepare-suspended-payment-cancellation.json') %>
<%- renderFixture('requests/prepare-escrow-cancellation.json') %>
## Suspended Payment Execution
## Escrow Execution
See [Transaction Types](#transaction-types) for a description.
<%- renderSchema('specifications/suspended-payment-execution.json') %>
<%- renderSchema('specifications/escrow-execution.json') %>
### Example
<%- renderFixture('requests/prepare-suspended-payment-execution.json') %>
<%- renderFixture('requests/prepare-escrow-execution.json') %>
## Check Create
See [Transaction Types](#transaction-types) for a description.
<%- renderSchema('specifications/check-create.json') %>
### Example
<%- renderFixture('requests/prepare-check-create.json') %>
## Check Cancel
See [Transaction Types](#transaction-types) for a description.
<%- renderSchema('specifications/check-cancel.json') %>
### Example
<%- renderFixture('requests/prepare-check-cancel.json') %>
## Check Cash
See [Transaction Types](#transaction-types) for a description.
<%- renderSchema('specifications/check-cash.json') %>
### Example
<%- renderFixture('requests/prepare-check-cash-amount.json') %>
## Payment Channel Create
See [Transaction Types](#transaction-types) for a description.
<%- renderSchema('specifications/payment-channel-create.json') %>
### Example
<%- renderFixture('requests/prepare-payment-channel-create.json') %>
## Payment Channel Fund
See [Transaction Types](#transaction-types) for a description.
<%- renderSchema('specifications/payment-channel-fund.json') %>
### Example
<%- renderFixture('requests/prepare-payment-channel-fund.json') %>
## Payment Channel Claim
See [Transaction Types](#transaction-types) for a description.
<%- renderSchema('specifications/payment-channel-claim.json') %>
### Example
<%- renderFixture('requests/prepare-payment-channel-claim.json') %>

View File

@@ -0,0 +1 @@
# Static Methods

View File

@@ -1,6 +1,6 @@
## submit
`submit(signedTransaction: string): Promise<Object>`
`submit(signedTransaction: string): Promise<object>`
Submits a signed transaction. The transaction is not guaranteed to succeed; it must be verified with [getTransaction](#gettransaction).

View File

@@ -7,15 +7,19 @@ A transaction type is specified by the strings in the first column in the table
Type | Description
---- | -----------
[payment](#payment) | A `payment` transaction represents a transfer of value from one account to another. Depending on the [path](https://ripple.com/build/paths/) taken, additional exchanges of value may occur atomically to facilitate the payment.
[order](#order) | An `order` transaction creates a limit order. It defines an intent to exchange currencies, and creates an order in the Ripple Consensus Ledger's order book if not completely fulfilled when placed. Orders can be partially fulfilled.
[orderCancellation](#order-cancellation) | An `orderCancellation` transaction cancels an order in the Ripple Consensus Ledger's order book.
[order](#order) | An `order` transaction creates a limit order. It defines an intent to exchange currencies, and creates an order in the XRP Ledger's order book if not completely fulfilled when placed. Orders can be partially fulfilled.
[orderCancellation](#order-cancellation) | An `orderCancellation` transaction cancels an order in the XRP Ledger's order book.
[trustline](#trustline) | A `trustline` transactions creates or modifies a trust line between two accounts.
[settings](#settings) | A `settings` transaction modifies the settings of an account in the Ripple Consensus Ledger.
[suspendedPaymentCreation](#suspended-payment-creation) | A `suspendedPaymentCreation` transaction creates a suspended payment on the ledger, which locks XRP until a cryptographic condition is met or it expires. It is like an escrow service where the Ripple network acts as the escrow agent.
[suspendedPaymentCancellation](#suspended-payment-cancellation) | A `suspendedPaymentCancellation` transaction unlocks the funds in a suspended payment and sends them back to the creator of the suspended payment, but it will only work after the suspended payment expires.
[suspendedPaymentExecution](#suspended-payment-execution) | A `suspendedPaymentExecution` transaction unlocks the funds in a suspended payment and sends them to the destination of the suspended payment, but it will only work if the cryptographic condition is provided.
The three "suspended payment" transaction types are not supported by the production Ripple peer-to-peer network at this time. They are available for testing purposes if you [configure RippleAPI](#boilerplate) to connect to the [Ripple Test Net](https://ripple.com/build/ripple-test-net/) instead.
[settings](#settings) | A `settings` transaction modifies the settings of an account in the XRP Ledger.
[escrowCreation](#escrow-creation) | An `escrowCreation` transaction creates an escrow on the ledger, which locks XRP until a cryptographic condition is met or it expires. It is like an escrow service where the XRP Ledger acts as the escrow agent.
[escrowCancellation](#escrow-cancellation) | An `escrowCancellation` transaction unlocks the funds in an escrow and sends them back to the creator of the escrow, but it will only work after the escrow expires.
[escrowExecution](#escrow-execution) | An `escrowExecution` transaction unlocks the funds in an escrow and sends them to the destination of the escrow, but it will only work if the cryptographic condition is provided.
[checkCreate](#check-create) | A `checkCreate` transaction creates a check on the ledger, which is a deferred payment that can be cashed by its intended destination.
[checkCancel](#check-cancel) | A `checkCancel` transaction cancels an unredeemed Check, removing it from the ledger without sending any money.
[checkCash](#check-cash) | A `checkCash` transaction redeems a Check to receive up to the amount authorized by the corresponding `checkCreate` transaction. Only the `destination` address of a Check can cash it.
[paymentChannelCreate](#payment-channel-create) | A `paymentChannelCreate` transaction opens a payment channel between two addresses with XRP set aside for asynchronous payments.
[paymentChannelFund](#payment-channel-fund) | A `paymentChannelFund` transaction adds XRP to a payment channel and optionally sets a new expiration for the channel.
[paymentChannelClaim](#payment-channel-claim) | A `paymentChannelClaim` transaction withdraws XRP from a channel and optionally requests to close it.
## Transaction Flow
@@ -27,16 +31,19 @@ Executing a transaction with `RippleAPI` requires the following four steps:
* [prepareOrder](#prepareorder)
* [prepareOrderCancellation](#prepareordercancellation)
* [prepareSettings](#preparesettings)
* [prepareSuspendedPaymentCreation](#preparesuspendedpaymentcreation)
* [prepareSuspendedPaymentCancellation](#preparesuspendedpaymentcancellation)
* [prepareSuspendedPaymentExecution](#preparesuspendedpaymentexecution)
* [prepareEscrowCreation](#prepareescrowcreation)
* [prepareEscrowCancellation](#prepareescrowcancellation)
* [prepareEscrowExecution](#prepareescrowexecution)
* [prepareCheckCreate](#preparecheckcreate)
* [prepareCheckCancel](#preparecheckcancel)
* [prepareCheckCash](#preparecheckcash)
2. [Sign](#sign) - Cryptographically sign the transaction locally and save the [transaction ID](#transaction-id). Signing is how the owner of an account authorizes a transaction to take place. For multisignature transactions, the `signedTransaction` fields returned by `sign` must be collected and passed to the [combine](#combine) method.
3. [Submit](#submit) - Submit the transaction to the connected server.
4. Verify - Verify that the transaction got validated by querying with [getTransaction](#gettransaction). This is necessary because transactions may fail even if they were successfully submitted.
## Transaction Fees
Every transaction must destroy a small amount of XRP as a cost to send the transaction. This is also called a *transaction fee*. The transaction cost is designed to increase along with the load on the Ripple network, making it very expensive to deliberately or inadvertently overload the network.
Every transaction must destroy a small amount of XRP as a cost to send the transaction. This is also called a *transaction fee*. The transaction cost is designed to increase along with the load on the XRP Ledger, making it very expensive to deliberately or inadvertently overload the peer-to-peer network that powers the XRP Ledger.
You can choose the size of the fee you want to pay or let a default be used. You can get an estimate of the fee required to be included in the next ledger closing with the [getFee](#getfee) method.
@@ -46,7 +53,7 @@ Transaction instructions indicate how to execute a transaction, complementary wi
<%- renderSchema("objects/instructions.json") %>
We recommended that you specify a `maxLedgerVersion` so that you can quickly determine that a failed transaction will never succeeed in the future. It is impossible for a transaction to succeed after the network ledger version exceeds the transaction's `maxLedgerVersion`. If you omit `maxLedgerVersion`, the "prepare*" method automatically supplies a `maxLedgerVersion` equal to the current ledger plus 3, which it includes in the return value from the "prepare*" method.
We recommend that you specify a `maxLedgerVersion` so that you can quickly determine that a failed transaction will never succeed in the future. It is impossible for a transaction to succeed after the XRP Ledger's consensus-validated ledger version exceeds the transaction's `maxLedgerVersion`. If you omit `maxLedgerVersion`, the "prepare\*" method automatically supplies a `maxLedgerVersion` equal to the current ledger plus 3, which it includes in the return value from the "prepare\*" method.
## Transaction ID

81
docs/src/txFlags.md.ejs Normal file
View File

@@ -0,0 +1,81 @@
## txFlags
`txFlags.TRANSACTION_TYPE.FLAG`
This object provides constants for use when creating or interpreting transaction flags. Most transactions have a set of bit-flags that represent various options that affect how a transaction should behave. These options are represented as binary values that can be combined with bitwise-or operations to encode multiple flags at once.
Most flags only have meaning for a specific transaction type. The same bitwise value may be reused for flags on different transaction types, so it is important to pay attention to the transaction type when setting and reading flags.
Bits that are not defined as flags MUST be 0.
### Global Flag
Applies globally to all transactions.
`txFlags.Universal.FullyCanonicalSig`: Require a fully-canonical signature. When preparing transactions, ripple-lib enables this flag for you.
### Payment Flags
`txFlags.Payment.NoRippleDirect`: Do not use the default path; only use specified paths. This is intended to force the transaction to take arbitrage opportunities. Most clients do not need this.
`txFlags.Payment.PartialPayment`: If the specified destination amount cannot be sent without spending more than the source maxAmount, reduce the received amount instead of failing outright. See [Partial Payments](https://developers.ripple.com/partial-payments.html) for more details.
`txFlags.Payment.LimitQuality`: Only take paths where all the conversions have an input:output ratio that is equal or better than the ratio of `destination.amount`:`source.maxAmount`. See [Limit Quality](https://developers.ripple.com/payment.html#limit-quality) for details.
### OfferCreate Flags
`txFlags.OfferCreate.Passive`: If enabled, the offer does not consume offers that exactly match it, and instead becomes an Offer object in the ledger. It still consumes offers that cross it.
`txFlags.OfferCreate.ImmediateOrCancel`: Treat the offer as an Immediate or Cancel order. If enabled, the offer never becomes a ledger object: it only tries to match existing offers in the ledger.
`txFlags.OfferCreate.FillOrKill`: Treat the offer as a Fill or Kill order.
`txFlags.OfferCreate.Sell`: Treat the offer as a Sell order. With `order.direction = 'sell'`, exchange the entire `order.quantity`, even if it means obtaining more than the `order.totalPrice` amount in exchange. If using `prepareOrder`, ripple-lib sets this flag for you.
### TrustSet Flags
`txFlags.TrustSet.SetAuth`: Authorize the other party to hold issuances from this account. (No effect unless using the AccountSet.RequireAuth flag.) Cannot be unset.
`txFlags.TrustSet.NoRipple`: Obsolete.
`txFlags.TrustSet.SetNoRipple`: Blocks [rippling](https://developers.ripple.com/rippling.html) between two trustlines of the same currency, if this flag is set on both.
`txFlags.TrustSet.ClearNoRipple`: Clears the No-[Rippling](https://developers.ripple.com/rippling.html) flag.
`txFlags.TrustSet.SetFreeze`: Freeze the trustline. A non-XRP currency can be frozen by the exchange or gateway that issued it. XRP cannot be frozen.
`txFlags.TrustSet.ClearFreeze`: Unfreeze the trustline.
### AccountSet Flags
You can use the `prepareSettings` method to change your account flags. This method uses AccountSet flags internally.
In the rippled API, Account Flags can be enabled and disabled with the SetFlag and ClearFlag parameters. See [AccountSet Flags](https://developers.ripple.com/accountset.html#accountset-flags).
The AccountSet transaction type has some transaction flags, but their use is discouraged.
* `txFlags.AccountSet.RequireDestTag`
* `txFlags.AccountSet.OptionalDestTag`
* `txFlags.AccountSet.RequireAuth`
* `txFlags.AccountSet.OptionalAuth`
* `txFlags.AccountSet.DisallowXRP`
* `txFlags.AccountSet.AllowXRP`
### PaymentChannelClaim Flags
`txFlags.PaymentChannelClaim.Renew`: Clear the channel's Expiration time. (Expiration is different from the channel's immutable CancelAfter time.) Only the source address of the payment channel can use this flag.
`txFlags.PaymentChannelClaim.Close`: Request to close the channel. Only the channel source and destination addresses can use this flag. This flag closes the channel immediately if it has no more XRP allocated to it after processing the current claim, or if the destination address uses it. If the source address uses this flag when the channel still holds XRP, this schedules the channel to close after SettleDelay seconds have passed. (Specifically, this sets the Expiration of the channel to the close time of the previous ledger plus the channel's SettleDelay time, unless the channel already has an earlier Expiration time.) If the destination address uses this flag when the channel still holds XRP, any XRP that remains after processing the claim is returned to the source address.
### Other Transaction Types
The remaining transaction types do not have any flags at this time.
* OfferCancel
* SetRegularKey
* SignerListSet
* EscrowCreate
* EscrowFinish
* EscrowCancel
* PaymentChannelCreate
* PaymentChannelFund

View File

@@ -0,0 +1,31 @@
## verifyPaymentChannelClaim
`verifyPaymentChannelClaim(channel: string, amount: string, signature: string, publicKey: string): boolean`
Verify a payment channel claim signature.
### Parameters
<%- renderSchema("input/verify-payment-channel-claim.json") %>
### Return Value
This method returns `true` if the claim signature is valid.
<%- renderSchema("output/verify-payment-channel-claim.json") %>
### Example
```javascript
const channel =
'3E18C05AD40319B809520F1A136370C4075321B285217323396D6FD9EE1E9037';
const amount = '.00001';
const signature = <%- importFile("test/fixtures/responses/sign-payment-channel-claim.json") %>;
const publicKey =
'02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8';
return api.verifyPaymentChannelClaim(channel, amount, signature, publicKey);
```
```json
true
```

View File

@@ -0,0 +1,47 @@
## xrpToDrops
`xrpToDrops(xrp: string | BigNumber): string`
Converts an XRP amount to drops. 1 XRP = 1,000,000 drops, so 1 drop = 0.000001 XRP. This method is useful when converting amounts for use with the rippled API, which requires XRP amounts to be specified in drops.
### Parameters
`xrp`: A string or BigNumber representing an amount of XRP. If `xrp` is a string, it may start with `-`, must contain at least one number, and may contain up to one `.`. This method throws a `ValidationError` for invalid input.
### Return Value
A string representing an equivalent amount of drops.
### Example
```javascript
return api.xrpToDrops('1');
```
```json
'1000000'
```
## dropsToXrp
`dropsToXrp(drops: string | BigNumber): string`
Converts an amount of drops to XRP. 1 drop = 0.000001 XRP, so 1 XRP = 1,000,000 drops. This method is useful when converting amounts from the rippled API, which describes XRP amounts in drops.
### Parameters
`drops`: A string or BigNumber representing an amount of drops. If `drops` is a string, it may start with `-` and must contain at least one number. This method throws a `ValidationError` for invalid input.
### Return Value
A string representing an equivalent amount of XRP.
### Example
```javascript
return api.dropsToXrp('1');
```
```json
'0.000001'
```

352
npm-shrinkwrap.json generated
View File

@@ -1,352 +0,0 @@
{
"name": "ripple-lib",
"version": "0.16.6",
"dependencies": {
"ajv": {
"version": "1.4.10",
"from": "https://registry.npmjs.org/ajv/-/ajv-1.4.10.tgz",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-1.4.10.tgz",
"dependencies": {
"json-stable-stringify": {
"version": "1.0.0",
"from": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.0.tgz",
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.0.tgz",
"dependencies": {
"jsonify": {
"version": "0.0.0",
"from": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz"
}
}
}
}
},
"ajv-i18n": {
"version": "0.1.1",
"from": "https://registry.npmjs.org/ajv-i18n/-/ajv-i18n-0.1.1.tgz",
"resolved": "https://registry.npmjs.org/ajv-i18n/-/ajv-i18n-0.1.1.tgz"
},
"babel-polyfill": {
"version": "6.3.14",
"from": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.3.14.tgz",
"resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.3.14.tgz",
"dependencies": {
"core-js": {
"version": "1.2.6",
"from": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz"
},
"babel-regenerator-runtime": {
"version": "6.3.13",
"from": "https://registry.npmjs.org/babel-regenerator-runtime/-/babel-regenerator-runtime-6.3.13.tgz",
"resolved": "https://registry.npmjs.org/babel-regenerator-runtime/-/babel-regenerator-runtime-6.3.13.tgz"
},
"babel-runtime": {
"version": "5.8.34",
"from": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.34.tgz",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.34.tgz"
}
}
},
"babel-runtime": {
"version": "6.3.19",
"from": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.3.19.tgz",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.3.19.tgz",
"dependencies": {
"core-js": {
"version": "1.2.6",
"from": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz"
}
}
},
"bignumber.js": {
"version": "2.1.2",
"from": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.1.2.tgz",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.1.2.tgz"
},
"https-proxy-agent": {
"version": "1.0.0",
"from": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
"dependencies": {
"agent-base": {
"version": "2.0.1",
"from": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz",
"dependencies": {
"semver": {
"version": "5.0.3",
"from": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz"
}
}
},
"debug": {
"version": "2.2.0",
"from": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
"dependencies": {
"ms": {
"version": "0.7.1",
"from": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
}
}
},
"extend": {
"version": "3.0.0",
"from": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz"
}
}
},
"jayson": {
"version": "1.2.2",
"from": "https://registry.npmjs.org/jayson/-/jayson-1.2.2.tgz",
"resolved": "https://registry.npmjs.org/jayson/-/jayson-1.2.2.tgz",
"dependencies": {
"JSONStream": {
"version": "1.0.3",
"from": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.0.3.tgz",
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.0.3.tgz",
"dependencies": {
"jsonparse": {
"version": "1.0.0",
"from": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.0.0.tgz",
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.0.0.tgz"
},
"through": {
"version": "2.3.8",
"from": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
}
}
},
"commander": {
"version": "1.3.2",
"from": "https://registry.npmjs.org/commander/-/commander-1.3.2.tgz",
"resolved": "https://registry.npmjs.org/commander/-/commander-1.3.2.tgz",
"dependencies": {
"keypress": {
"version": "0.1.0",
"from": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz",
"resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz"
}
}
},
"eyes": {
"version": "0.1.8",
"from": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
"resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz"
},
"lodash": {
"version": "3.6.0",
"from": "https://registry.npmjs.org/lodash/-/lodash-3.6.0.tgz",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.6.0.tgz"
}
}
},
"lodash": {
"version": "3.10.1",
"from": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz"
},
"ripple-address-codec": {
"version": "2.0.1",
"from": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-2.0.1.tgz",
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-2.0.1.tgz",
"dependencies": {
"hash.js": {
"version": "1.0.3",
"from": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz",
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz",
"dependencies": {
"inherits": {
"version": "2.0.1",
"from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
}
}
},
"x-address-codec": {
"version": "0.7.2",
"from": "https://registry.npmjs.org/x-address-codec/-/x-address-codec-0.7.2.tgz",
"resolved": "https://registry.npmjs.org/x-address-codec/-/x-address-codec-0.7.2.tgz",
"dependencies": {
"base-x": {
"version": "1.0.1",
"from": "https://registry.npmjs.org/base-x/-/base-x-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/base-x/-/base-x-1.0.1.tgz"
}
}
}
}
},
"ripple-binary-codec": {
"version": "0.1.2",
"from": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.1.2.tgz",
"resolved": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.1.2.tgz",
"dependencies": {
"babel-runtime": {
"version": "5.8.34",
"from": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.34.tgz",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.34.tgz",
"dependencies": {
"core-js": {
"version": "1.2.6",
"from": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz"
}
}
},
"bn.js": {
"version": "3.3.0",
"from": "https://registry.npmjs.org/bn.js/-/bn.js-3.3.0.tgz",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-3.3.0.tgz"
},
"create-hash": {
"version": "1.1.2",
"from": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz",
"dependencies": {
"cipher-base": {
"version": "1.0.2",
"from": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.2.tgz",
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.2.tgz"
},
"ripemd160": {
"version": "1.0.1",
"from": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz"
},
"sha.js": {
"version": "2.4.4",
"from": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.4.tgz",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.4.tgz"
}
}
},
"decimal.js": {
"version": "4.0.3",
"from": "https://registry.npmjs.org/decimal.js/-/decimal.js-4.0.3.tgz",
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-4.0.3.tgz"
},
"inherits": {
"version": "2.0.1",
"from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
}
}
},
"ripple-hashes": {
"version": "0.1.0",
"from": "https://registry.npmjs.org/ripple-hashes/-/ripple-hashes-0.1.0.tgz",
"resolved": "https://registry.npmjs.org/ripple-hashes/-/ripple-hashes-0.1.0.tgz",
"dependencies": {
"create-hash": {
"version": "1.1.2",
"from": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz",
"dependencies": {
"cipher-base": {
"version": "1.0.2",
"from": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.2.tgz",
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.2.tgz"
},
"inherits": {
"version": "2.0.1",
"from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
},
"ripemd160": {
"version": "1.0.1",
"from": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz"
},
"sha.js": {
"version": "2.4.4",
"from": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.4.tgz",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.4.tgz"
}
}
}
}
},
"ripple-keypairs": {
"version": "0.10.0",
"from": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-0.10.0.tgz",
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-0.10.0.tgz",
"dependencies": {
"babel-runtime": {
"version": "5.8.34",
"from": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.34.tgz",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.34.tgz",
"dependencies": {
"core-js": {
"version": "1.2.6",
"from": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz"
}
}
},
"bn.js": {
"version": "3.3.0",
"from": "https://registry.npmjs.org/bn.js/-/bn.js-3.3.0.tgz",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-3.3.0.tgz"
},
"brorand": {
"version": "1.0.5",
"from": "https://registry.npmjs.org/brorand/-/brorand-1.0.5.tgz",
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.0.5.tgz"
},
"elliptic": {
"version": "5.2.1",
"from": "https://registry.npmjs.org/elliptic/-/elliptic-5.2.1.tgz",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-5.2.1.tgz",
"dependencies": {
"inherits": {
"version": "2.0.1",
"from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
}
}
},
"hash.js": {
"version": "1.0.3",
"from": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz",
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz",
"dependencies": {
"inherits": {
"version": "2.0.1",
"from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
}
}
}
}
},
"ripple-lib-transactionparser": {
"version": "0.6.0",
"from": "https://registry.npmjs.org/ripple-lib-transactionparser/-/ripple-lib-transactionparser-0.6.0.tgz",
"resolved": "https://registry.npmjs.org/ripple-lib-transactionparser/-/ripple-lib-transactionparser-0.6.0.tgz"
},
"ws": {
"version": "1.0.1",
"from": "https://registry.npmjs.org/ws/-/ws-1.0.1.tgz",
"resolved": "https://registry.npmjs.org/ws/-/ws-1.0.1.tgz",
"dependencies": {
"options": {
"version": "0.0.6",
"from": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz"
},
"ultron": {
"version": "1.0.2",
"from": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz"
}
}
}
}
}

View File

@@ -1,83 +1,73 @@
{
"name": "ripple-lib",
"version": "0.16.6",
"version": "1.2.1",
"license": "ISC",
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
"files": [
"dist/npm/*",
"bin/*",
"build/*",
"test/*",
"Gulpfile.js"
"build/*"
],
"main": "dist/npm/",
"types": "dist/npm/index.d.ts",
"browser": {
"ws": "./dist/npm/common/wswrapper.js"
},
"directories": {
"test": "test"
},
"dependencies": {
"ajv": "^1.4.8",
"babel-polyfill": "^6.3.14",
"babel-runtime": "^6.3.19",
"bignumber.js": "^2.0.3",
"https-proxy-agent": "^1.0.0",
"jayson": "^1.2.2",
"lodash": "^3.1.0",
"@types/lodash": "^4.14.85",
"@types/ws": "^3.2.0",
"bignumber.js": "^4.1.0",
"https-proxy-agent": "2.2.1",
"jsonschema": "1.2.2",
"lodash": "^4.17.4",
"ripple-address-codec": "^2.0.1",
"ripple-binary-codec": "^0.1.2",
"ripple-hashes": "^0.1.0",
"ripple-keypairs": "^0.10.0",
"ripple-lib-transactionparser": "^0.6.0",
"ws": "^1.0.1"
"ripple-binary-codec": "0.2.1",
"ripple-hashes": "0.3.2",
"ripple-keypairs": "^0.10.1",
"ripple-lib-transactionparser": "0.7.1",
"ws": "^3.3.1"
},
"devDependencies": {
"@types/node": "^8.0.53",
"assert-diff": "^1.0.1",
"babel-cli": "^6.4.0",
"babel-core": "^6.4.0",
"babel-eslint": "^4.1.6",
"babel-loader": "^6.2.1",
"babel-plugin-syntax-flow": "^6.3.13",
"babel-plugin-transform-flow-strip-types": "^6.4.0",
"babel-preset-es2015": "^6.3.13",
"babel-preset-stage-1": "^6.3.13",
"babel-register": "^6.3.13",
"coveralls": "^2.10.0",
"doctoc": "^0.15.0",
"ejs": "^2.3.4",
"eslint": "^1.3.0",
"eventemitter2": "^0.4.14",
"flow-bin": "^0.14",
"gulp": "^3.8.10",
"gulp-bump": "^0.1.13",
"gulp-rename": "^1.2.0",
"gulp-uglify": "^1.1.0",
"http-server": "^0.8.5",
"isparta": "^4.0.0",
"jayson": "^1.2.2",
"json-loader": "^0.5.2",
"json-schema-to-markdown-table": "^0.4.0",
"mocha": "^2.1.0",
"mocha": "6.0.2",
"mocha-junit-reporter": "^1.9.1",
"mocha-phantomjs": "^4.0.1",
"mocha-in-sauce": "^0.0.1",
"null-loader": "^0.1.1",
"webpack": "^1.5.3",
"yargs": "^1.3.1"
"nyc": "^11.3.0",
"source-map-support": "^0.5.0",
"ts-loader": "^3.2.0",
"ts-node": "^3.3.0",
"tslint": "^5.8.0",
"tslint-eslint-rules": "^4.1.1",
"typescript": "2.9.2",
"uglifyjs-webpack-plugin": "^1.1.4",
"webpack": "3.12.0",
"yargs": "^8.0.2"
},
"scripts": {
"build": "gulp",
"doctoc": "doctoc docs/index.md --title '# RippleAPI Reference' --github --maxlevel 2",
"docgen": "node --harmony scripts/build_docs.js",
"clean": "rm -rf dist/npm && rm -rf build/flow",
"typecheck": "babel --optional runtime --blacklist flow -d build/flow/ src/ && flow check",
"compile": "babel -D --optional runtime -d dist/npm/ src/",
"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": "babel-node node_modules/isparta/lib/cli cover ./node_modules/mocha/bin/_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 'parser: babel-eslint' >> eslintrc; fi; eslint -c eslintrc src/",
"clean": "rm -rf dist/npm",
"compile": "mkdir -p dist/npm/common && cp -r src/common/schemas dist/npm/common/ && tsc",
"watch": "tsc -w",
"prepublish": "npm run clean && npm run compile && npm run build",
"test": "nyc mocha --exit",
"lint": "tslint -p ./",
"perf": "./scripts/perf_test.sh",
"start": "babel-node scripts/http.js",
"sauce": "babel-node scripts/sauce-runner.js"
"start": "node scripts/http.js",
"sauce": "node scripts/sauce-runner.js"
},
"repository": {
"type": "git",
@@ -85,6 +75,6 @@
},
"readmeFilename": "README.md",
"engines": {
"node": ">=0.12.0"
"node": ">=6.12.3"
}
}

View File

@@ -7,49 +7,39 @@ function checkEOL {
./scripts/checkeol.sh
}
typecheck() {
npm install -g flow-bin
flow --version
npm run typecheck
}
lint() {
echo "eslint $(node_modules/.bin/eslint --version)"
npm list babel-eslint
REPO_URL="https://raw.githubusercontent.com/ripple/javascript-style-guide"
curl "$REPO_URL/es6/eslintrc" > ./eslintrc
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$")
echo "tslint $(node_modules/.bin/tslint --version)"
yarn lint
}
unittest() {
# test "src"
mocha test --reporter mocha-junit-reporter --reporter-options mochaFile=$CIRCLE_TEST_REPORTS/test-results.xml
npm test --coverage
npm run coveralls
yarn test --coverage
#yarn run coveralls
# test compiled version in "dist/npm"
babel -D --optional runtime --ignore "**/node_modules/**" -d test-compiled/ test/
$(npm bin)/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 test-compiled/node_modules/ripple-api
mocha --opts test-compiled/mocha.opts test-compiled
# compile tests for browser testing
gulp build-min build-tests
node --harmony test-compiled/mocked-server.js > /dev/null &
#compile tests for browser testing
#gulp build-min build-tests
#node --harmony test-compiled/mocked-server.js > /dev/null &
echo "Running tests in PhantomJS"
mocha-phantomjs test/localrunner.html
echo "Running tests using minified version in PhantomJS"
mocha-phantomjs test/localrunnermin.html
#echo "Running tests in PhantomJS"
#mocha-phantomjs test/localrunner.html
#echo "Running tests using minified version in PhantomJS"
#mocha-phantomjs test/localrunnermin.html
echo "Running tests in SauceLabs"
http-server &
npm run sauce
#echo "Running tests in SauceLabs"
#http-server &
#yarn run sauce
pkill -f mocked-server.js
pkill -f http-server
#pkill -f mocked-server.js
#pkill -f http-server
rm -rf test-compiled
}
@@ -58,14 +48,14 @@ integrationtest() {
mocha test/integration/http-integration-test.js
# run integration tests in PhantomJS
gulp build-tests build-min
echo "Running integragtion tests in PhantomJS"
mocha-phantomjs test/localintegrationrunner.html
#gulp build-tests build-min
#echo "Running integragtion tests in PhantomJS"
#mocha-phantomjs test/localintegrationrunner.html
}
doctest() {
mv docs/index.md docs/index.md.save
npm run docgen
yarn run docgen
mv docs/index.md docs/index.md.test
mv docs/index.md.save docs/index.md
cmp docs/index.md docs/index.md.test
@@ -76,7 +66,6 @@ oneNode() {
checkEOL
doctest
lint
typecheck
unittest
integrationtest
}
@@ -84,7 +73,7 @@ oneNode() {
twoNodes() {
case "$NODE_INDEX" in
0) doctest; lint; integrationtest;;
1) checkEOL; typecheck; unittest;;
1) checkEOL; unittest;;
*) echo "ERROR: invalid usage"; exit 2;;
esac
}
@@ -92,7 +81,7 @@ twoNodes() {
threeNodes() {
case "$NODE_INDEX" in
0) doctest; lint; integrationtest;;
1) checkEOL; typecheck;;
1) checkEOL;;
2) unittest;;
*) echo "ERROR: invalid usage"; exit 2;;
esac

View File

@@ -1,6 +1,6 @@
'use strict';
const createHTTPServer = require('../src/index').createHTTPServer;
'use strict';
const createHTTPServer = require('../dist/npm/http').createHTTPServer;
const port = 5990;
const serverUrl = 'wss://s1.ripple.com';

View File

@@ -7,12 +7,12 @@ function exit_on_error {
rm -rf build
npm install
yarn install
gulp
npm test
yarn test
exit_on_error
echo ""
echo "publish to npm"
npm publish
yarn publish
exit_on_error

View File

@@ -7,12 +7,12 @@ function exit_on_error {
rm -rf build
npm install
yarn install
gulp
npm test
yarn test
exit_on_error
echo ""
echo "publish rc to npm"
npm publish --tag beta
yarn publish --tag beta
exit_on_error

View File

@@ -1,98 +0,0 @@
'use strict';
const _ = require('lodash');
const MochaSauce = require('mocha-in-sauce');
const testUrl = 'http://testripple.circleci.com:8080/test/saucerunner.html';
function main() {
// uncomment for more debug info
// process.env.DEBUG = '*';
// configure
const config = {
name: 'RippleAPI',
host: 'localhost',
port: 4445,
maxDuration: 180000,
// the current build name (optional)
build: Date.now(),
seleniumVersion: '2.50.1',
url: testUrl,
runSauceConnect: true
};
if (process.env.CIRCLE_BUILD_NUM) {
config.build = process.env.CIRCLE_BUILD_NUM;
config.tags = [process.env.CIRCLE_BRANCH, process.env.CIRCLE_SHA1];
config.tunnelIdentifier = process.env.CIRCLE_BUILD_NUM;
}
const sauce = new MochaSauce(config);
sauce.concurrency(5);
// setup what browsers to test with
sauce.browser({browserName: 'firefox', platform: 'Linux',
version: '43'});
sauce.browser({browserName: 'firefox', platform: 'Windows 8.1',
version: '43'});
sauce.browser({browserName: 'firefox', platform: 'OS X 10.11',
version: '43'});
sauce.browser({browserName: 'safari', platform: 'OS X 10.11',
version: '9'});
sauce.browser({browserName: 'chrome', platform: 'OS X 10.11',
version: '47'});
sauce.browser({browserName: 'chrome', platform: 'Linux',
version: '47'});
sauce.browser({browserName: 'chrome', platform: 'Windows 8.1',
version: '47'});
sauce.browser({browserName: 'internet explorer', platform: 'Windows 10',
version: '11'});
sauce.browser({browserName: 'MicrosoftEdge', platform: 'Windows 10',
version: '20'});
sauce.on('init', function(browser) {
console.log(' init : %s %s', browser.browserName, browser.platform);
});
sauce.on('start', function(browser) {
console.log(' start : %s %s', browser.browserName, browser.platform);
});
sauce.on('end', function(browser, res) {
console.log(' end : %s %s : %d failures', browser.browserName,
browser.platform, res && res.failures);
});
sauce.on('connected', sauceConnectProcess => {
sauceConnectProcess.on('exit', function(code, /* signal */) {
if (code > 0) {
console.log('something wrong - exiting');
process.exit();
} else {
console.log('normal tunnel exit');
}
});
});
sauce.start(function(err, res) {
let failure = false;
if (err) {
console.log('Error starting Sauce');
console.error(err);
process.exitCode = 2;
} else {
console.log('-------------- done --------------');
failure = _.some(res, 'failures');
console.log('Tests are failed:', failure);
if (failure) {
process.exitCode = 1;
}
}
});
}
main();

View File

@@ -0,0 +1,11 @@
const RippleAPI = require('../dist/npm').RippleAPI
const api = new RippleAPI({server: 'wss://s.altnet.rippletest.net:51233'})
parseAccountFlags()
async function parseAccountFlags() {
await api.connect()
const account_info = await api.request('account_info', {account: 'rKsdkGhyZH6b2Zzd5hNnEqSv2wpznn4n6N'})
const flags = api.parseAccountFlags(account_info.account_data.Flags)
console.log(JSON.stringify(flags, null, 2))
}

View File

@@ -1,147 +0,0 @@
/* @flow */
'use strict';
/* eslint-disable max-len */
// Enable core-js polyfills. This allows use of ES6/7 extensions listed here:
// https://github.com/zloirock/core-js/blob/fb0890f32dabe8d4d88a4350d1b268446127132e/shim.js#L1-L103
/* eslint-enable max-len */
// In node.js env, polyfill might be already loaded (from any npm package),
// that's why we do this check.
if (!global._babelPolyfill) {
require('babel-polyfill');
}
const _ = require('lodash');
const EventEmitter = require('events').EventEmitter;
const common = require('./common');
const server = require('./server/server');
const connect = server.connect;
const disconnect = server.disconnect;
const getServerInfo = server.getServerInfo;
const getFee = server.getFee;
const isConnected = server.isConnected;
const getLedgerVersion = server.getLedgerVersion;
const getTransaction = require('./ledger/transaction');
const getTransactions = require('./ledger/transactions');
const getTrustlines = require('./ledger/trustlines');
const getBalances = require('./ledger/balances');
const getBalanceSheet = require('./ledger/balance-sheet');
const getPaths = require('./ledger/pathfind');
const getOrders = require('./ledger/orders');
const getOrderbook = require('./ledger/orderbook');
const getSettings = require('./ledger/settings');
const getAccountInfo = require('./ledger/accountinfo');
const preparePayment = require('./transaction/payment');
const prepareTrustline = require('./transaction/trustline');
const prepareOrder = require('./transaction/order');
const prepareOrderCancellation = require('./transaction/ordercancellation');
const prepareSuspendedPaymentCreation =
require('./transaction/suspended-payment-creation');
const prepareSuspendedPaymentExecution =
require('./transaction/suspended-payment-execution');
const prepareSuspendedPaymentCancellation =
require('./transaction/suspended-payment-cancellation');
const prepareSettings = require('./transaction/settings');
const sign = require('./transaction/sign');
const combine = require('./transaction/combine');
const submit = require('./transaction/submit');
const errors = require('./common').errors;
const generateAddress =
require('./offline/generate-address').generateAddressAPI;
const computeLedgerHash = require('./offline/ledgerhash');
const getLedger = require('./ledger/ledger');
type APIOptions = {
server?: string,
feeCushion?: number,
trace?: boolean,
proxy?: string,
timeout?: number
}
// prevent access to non-validated ledger versions
class RestrictedConnection extends common.Connection {
request(request, timeout) {
const ledger_index = request.ledger_index;
if (ledger_index !== undefined && ledger_index !== 'validated') {
if (!_.isNumber(ledger_index) || ledger_index > this._ledgerVersion) {
return Promise.reject(new errors.LedgerVersionError(
`ledgerVersion ${ledger_index} is greater than server\'s ` +
`most recent validated ledger: ${this._ledgerVersion}`));
}
}
return super.request(request, timeout);
}
}
class RippleAPI extends EventEmitter {
constructor(options: APIOptions = {}) {
common.validate.apiOptions(options);
super();
this._feeCushion = options.feeCushion || 1.2;
const serverURL = options.server;
if (serverURL !== undefined) {
this.connection = new RestrictedConnection(serverURL, options);
this.connection.on('ledgerClosed', message => {
this.emit('ledger', server.formatLedgerClose(message));
});
this.connection.on('error', (errorCode, errorMessage, data) => {
this.emit('error', errorCode, errorMessage, data);
});
} else {
// use null object pattern to provide better error message if user
// tries to call a method that requires a connection
this.connection = new RestrictedConnection(null, options);
}
}
}
_.assign(RippleAPI.prototype, {
connect,
disconnect,
isConnected,
getServerInfo,
getFee,
getLedgerVersion,
getTransaction,
getTransactions,
getTrustlines,
getBalances,
getBalanceSheet,
getPaths,
getOrders,
getOrderbook,
getSettings,
getAccountInfo,
getLedger,
preparePayment,
prepareTrustline,
prepareOrder,
prepareOrderCancellation,
prepareSuspendedPaymentCreation,
prepareSuspendedPaymentExecution,
prepareSuspendedPaymentCancellation,
prepareSettings,
sign,
combine,
submit,
generateAddress,
computeLedgerHash,
errors
});
// these are exposed only for use by unit tests; they are not part of the API
RippleAPI._PRIVATE = {
validate: common.validate,
RangeSet: require('./common/rangeset').RangeSet,
ledgerUtils: require('./ledger/utils'),
schemaValidator: require('./common/schema-validator')
};
module.exports = {
RippleAPI
};

348
src/api.ts Normal file
View File

@@ -0,0 +1,348 @@
import {EventEmitter} from 'events'
import {
Connection,
errors,
validate,
xrpToDrops,
dropsToXrp,
iso8601ToRippleTime,
txFlags
} from './common'
import {
connect,
disconnect,
isConnected,
getLedgerVersion,
formatLedgerClose
} from './server/server'
import getTransaction from './ledger/transaction'
import getTransactions from './ledger/transactions'
import getTrustlines from './ledger/trustlines'
import getBalances from './ledger/balances'
import getBalanceSheet from './ledger/balance-sheet'
import getPaths from './ledger/pathfind'
import getOrders from './ledger/orders'
import {getOrderbook,
formatBidsAndAsks} from './ledger/orderbook'
import {getSettings, parseAccountFlags} from './ledger/settings'
import getAccountInfo from './ledger/accountinfo'
import getAccountObjects from './ledger/accountobjects'
import getPaymentChannel from './ledger/payment-channel'
import preparePayment from './transaction/payment'
import prepareTrustline from './transaction/trustline'
import prepareOrder from './transaction/order'
import prepareOrderCancellation from './transaction/ordercancellation'
import prepareEscrowCreation from './transaction/escrow-creation'
import prepareEscrowExecution from './transaction/escrow-execution'
import prepareEscrowCancellation from './transaction/escrow-cancellation'
import preparePaymentChannelCreate from './transaction/payment-channel-create'
import preparePaymentChannelFund from './transaction/payment-channel-fund'
import preparePaymentChannelClaim from './transaction/payment-channel-claim'
import prepareCheckCreate from './transaction/check-create'
import prepareCheckCancel from './transaction/check-cancel'
import prepareCheckCash from './transaction/check-cash'
import prepareSettings from './transaction/settings'
import sign from './transaction/sign'
import combine from './transaction/combine'
import submit from './transaction/submit'
import {generateAddressAPI} from './offline/generate-address'
import {deriveKeypair, deriveAddress} from './offline/derive'
import computeLedgerHash from './offline/ledgerhash'
import signPaymentChannelClaim from './offline/sign-payment-channel-claim'
import verifyPaymentChannelClaim from './offline/verify-payment-channel-claim'
import getLedger from './ledger/ledger'
import {
AccountObjectsRequest, AccountObjectsResponse,
AccountOffersRequest, AccountOffersResponse,
AccountInfoRequest, AccountInfoResponse,
AccountLinesRequest, AccountLinesResponse,
BookOffersRequest, BookOffersResponse,
GatewayBalancesRequest, GatewayBalancesResponse,
LedgerRequest, LedgerResponse,
LedgerEntryRequest, LedgerEntryResponse,
ServerInfoRequest, ServerInfoResponse
} from './common/types/commands'
import RangeSet from './common/rangeset'
import * as ledgerUtils from './ledger/utils'
import * as transactionUtils from './transaction/utils'
import * as schemaValidator from './common/schema-validator'
import {getServerInfo, getFee} from './common/serverinfo'
import {clamp, renameCounterpartyToIssuer} from './ledger/utils'
import {TransactionJSON, Instructions, Prepare} from './transaction/types'
export type APIOptions = {
server?: string,
feeCushion?: number,
maxFeeXRP?: string,
trace?: boolean,
proxy?: string,
timeout?: number
}
/**
* Get the response key / property name that contains the listed data for a
* command. This varies from command to command, but we need to know it to
* properly count across many requests.
*/
function getCollectKeyFromCommand(command: string): string|undefined {
switch (command) {
case 'account_offers':
case 'book_offers':
return 'offers'
case 'account_lines':
return 'lines'
default:
return undefined
}
}
class RippleAPI extends EventEmitter {
_feeCushion: number
_maxFeeXRP: string
// New in > 0.21.0
// non-validated ledger versions are allowed, and passed to rippled as-is.
connection: Connection
// these are exposed only for use by unit tests; they are not part of the API.
static _PRIVATE = {
validate,
RangeSet,
ledgerUtils,
schemaValidator
}
static renameCounterpartyToIssuer = renameCounterpartyToIssuer
static formatBidsAndAsks = formatBidsAndAsks
constructor(options: APIOptions = {}) {
super()
validate.apiOptions(options)
this._feeCushion = options.feeCushion || 1.2
this._maxFeeXRP = options.maxFeeXRP || '2'
const serverURL = options.server
if (serverURL !== undefined) {
this.connection = new Connection(serverURL, options)
this.connection.on('ledgerClosed', message => {
this.emit('ledger', formatLedgerClose(message))
})
this.connection.on('error', (errorCode, errorMessage, data) => {
this.emit('error', errorCode, errorMessage, data)
})
this.connection.on('connected', () => {
this.emit('connected')
})
this.connection.on('disconnected', code => {
this.emit('disconnected', code)
})
} else {
// use null object pattern to provide better error message if user
// tries to call a method that requires a connection
this.connection = new Connection(null, options)
}
}
/**
* Makes a request to the API with the given command and
* additional request body parameters.
*/
async request(command: 'account_info', params: AccountInfoRequest):
Promise<AccountInfoResponse>
async request(command: 'account_lines', params: AccountLinesRequest):
Promise<AccountLinesResponse>
async request(command: 'account_objects', params: AccountObjectsRequest):
Promise<AccountObjectsResponse>
async request(command: 'account_offers', params: AccountOffersRequest):
Promise<AccountOffersResponse>
async request(command: 'book_offers', params: BookOffersRequest):
Promise<BookOffersResponse>
async request(command: 'gateway_balances', params: GatewayBalancesRequest):
Promise<GatewayBalancesResponse>
async request(command: 'ledger', params: LedgerRequest):
Promise<LedgerResponse>
async request(command: 'ledger_entry', params: LedgerEntryRequest):
Promise<LedgerEntryResponse>
async request(command: 'server_info', params?: ServerInfoRequest):
Promise<ServerInfoResponse>
async request(command: string, params: any):
Promise<any>
async request(command: string, params: any = {}): Promise<any> {
return this.connection.request({
...params,
command
})
}
/**
* Returns true if there are more pages of data.
*
* When there are more results than contained in the response, the response
* includes a `marker` field.
*
* See https://ripple.com/build/rippled-apis/#markers-and-pagination
*/
hasNextPage<T extends {marker?: string}>(currentResponse: T): boolean {
return !!currentResponse.marker
}
async requestNextPage<T extends {marker?: string}>(
command: string,
params: object = {},
currentResponse: T
): Promise<object> {
if (!currentResponse.marker) {
return Promise.reject(
new errors.NotFoundError('response does not have a next page')
)
}
const nextPageParams = Object.assign({}, params, {
marker: currentResponse.marker
})
return this.request(command, nextPageParams)
}
/**
* Prepare a transaction.
*
* You can later submit the transaction with `submit()`.
*/
async prepareTransaction(txJSON: TransactionJSON, instructions: Instructions = {}):
Promise<Prepare> {
return transactionUtils.prepareTransaction(txJSON, this, instructions)
}
/**
* Convert a string to hex.
*
* This can be used to generate `MemoData`, `MemoType`, and `MemoFormat`.
*
* @param string string to convert to hex
*/
convertStringToHex(string: string): string {
return transactionUtils.convertStringToHex(string)
}
/**
* Makes multiple paged requests to the API to return a given number of
* resources. _requestAll() will make multiple requests until the `limit`
* number of resources is reached (if no `limit` is provided, a single request
* will be made).
*
* If the command is unknown, an additional `collect` property is required to
* know which response key contains the array of resources.
*
* NOTE: This command is used by existing methods and is not recommended for
* general use. Instead, use rippled's built-in pagination and make multiple
* requests as needed.
*/
async _requestAll(command: 'account_offers', params: AccountOffersRequest):
Promise<AccountOffersResponse[]>
async _requestAll(command: 'book_offers', params: BookOffersRequest):
Promise<BookOffersResponse[]>
async _requestAll(command: 'account_lines', params: AccountLinesRequest):
Promise<AccountLinesResponse[]>
async _requestAll(
command: string,
params: any = {},
options: {collect?: string} = {}): Promise<any[]> {
// The data under collection is keyed based on the command. Fail if command
// not recognized and collection key not provided.
const collectKey = options.collect || getCollectKeyFromCommand(command)
if (!collectKey) {
throw new errors.ValidationError(`no collect key for command ${command}`)
}
// If limit is not provided, fetches all data over multiple requests.
// NOTE: This may return much more than needed. Set limit when possible.
const countTo: number =
(params.limit !== undefined) ? params.limit : Infinity
let count: number = 0
let marker: string = params.marker
let lastBatchLength: number
const results = []
do {
const countRemaining = clamp(countTo - count, 10, 400)
const repeatProps = {
...params,
limit: countRemaining,
marker
}
const singleResult = await this.request(command, repeatProps)
const collectedData = singleResult[collectKey]
marker = singleResult['marker']
results.push(singleResult)
// Make sure we handle when no data (not even an empty array) is returned.
const isExpectedFormat = Array.isArray(collectedData)
if (isExpectedFormat) {
count += collectedData.length
lastBatchLength = collectedData.length
} else {
lastBatchLength = 0
}
} while(!!marker && count < countTo && lastBatchLength !== 0)
return results
}
connect = connect
disconnect = disconnect
isConnected = isConnected
getServerInfo = getServerInfo
getFee = getFee
getLedgerVersion = getLedgerVersion
getTransaction = getTransaction
getTransactions = getTransactions
getTrustlines = getTrustlines
getBalances = getBalances
getBalanceSheet = getBalanceSheet
getPaths = getPaths
getOrderbook = getOrderbook
getOrders = getOrders
getSettings = getSettings
getAccountInfo = getAccountInfo
getAccountObjects = getAccountObjects
getPaymentChannel = getPaymentChannel
getLedger = getLedger
parseAccountFlags = parseAccountFlags
preparePayment = preparePayment
prepareTrustline = prepareTrustline
prepareOrder = prepareOrder
prepareOrderCancellation = prepareOrderCancellation
prepareEscrowCreation = prepareEscrowCreation
prepareEscrowExecution = prepareEscrowExecution
prepareEscrowCancellation = prepareEscrowCancellation
preparePaymentChannelCreate = preparePaymentChannelCreate
preparePaymentChannelFund = preparePaymentChannelFund
preparePaymentChannelClaim = preparePaymentChannelClaim
prepareCheckCreate = prepareCheckCreate
prepareCheckCash = prepareCheckCash
prepareCheckCancel = prepareCheckCancel
prepareSettings = prepareSettings
sign = sign
combine = combine
submit = submit
generateAddress = generateAddressAPI
deriveKeypair = deriveKeypair
deriveAddress = deriveAddress
computeLedgerHash = computeLedgerHash
signPaymentChannelClaim = signPaymentChannelClaim
verifyPaymentChannelClaim = verifyPaymentChannelClaim
errors = errors
xrpToDrops = xrpToDrops
dropsToXrp = dropsToXrp
iso8601ToRippleTime = iso8601ToRippleTime
txFlags = txFlags
isValidAddress = schemaValidator.isValidAddress
isValidSecret = schemaValidator.isValidSecret
}
export {
RippleAPI
}

View File

@@ -1,70 +0,0 @@
'use strict';
const _ = require('lodash');
const RippleAPI = require('./api').RippleAPI;
class RippleAPIBroadcast extends RippleAPI {
constructor(servers, options) {
super(options);
this.ledgerVersion = 0;
const apis = servers.map(server => new RippleAPI(
_.assign({}, options, {server})
));
// exposed for testing
this._apis = apis;
this.getMethodNames().forEach(name => {
this[name] = function() { // eslint-disable-line no-loop-func
return Promise.race(apis.map(api => api[name].apply(api, arguments)));
};
});
// connection methods must be overridden to apply to all api instances
this.connect = function() {
return Promise.all(apis.map(api => api.connect()));
};
this.disconnect = function() {
return Promise.all(apis.map(api => api.disconnect()));
};
this.isConnected = function() {
return _.every(apis.map(api => api.isConnected()));
};
// synchronous methods are all passed directly to the first api instance
const defaultAPI = apis[0];
const syncMethods = ['sign', 'generateAddress', 'computeLedgerHash'];
syncMethods.forEach(name => {
this[name] = defaultAPI[name].bind(defaultAPI);
});
apis.forEach(api => {
api.on('ledger', this.onLedgerEvent.bind(this));
api.on('error', (errorCode, errorMessage, data) =>
this.emit('error', errorCode, errorMessage, data));
});
}
onLedgerEvent(ledger) {
if (ledger.ledgerVersion > this.ledgerVersion) {
this.ledgerVersion = ledger.ledgerVersion;
this.emit('ledger', ledger);
}
}
getMethodNames() {
const methodNames = [];
for (const name in RippleAPI.prototype) {
if (RippleAPI.prototype.hasOwnProperty(name)) {
if (typeof RippleAPI.prototype[name] === 'function') {
methodNames.push(name);
}
}
}
return methodNames;
}
}
module.exports = {
RippleAPIBroadcast
};

73
src/broadcast.ts Normal file
View File

@@ -0,0 +1,73 @@
import * as _ from 'lodash'
import {RippleAPI} from './api'
class RippleAPIBroadcast extends RippleAPI {
ledgerVersion: number | undefined = undefined
private _apis: RippleAPI[]
constructor(servers, options) {
super(options)
const apis: RippleAPI[] = servers.map(server => new RippleAPI(
_.assign({}, options, {server})
))
// exposed for testing
this._apis = apis
this.getMethodNames().forEach(name => {
this[name] = function() { // eslint-disable-line no-loop-func
return Promise.race(apis.map(api => api[name](...arguments)))
}
})
// connection methods must be overridden to apply to all api instances
this.connect = async function() {
await Promise.all(apis.map(api => api.connect()))
}
this.disconnect = async function() {
await Promise.all(apis.map(api => api.disconnect()))
}
this.isConnected = function() {
return apis.map(api => api.isConnected()).every(Boolean)
}
// synchronous methods are all passed directly to the first api instance
const defaultAPI = apis[0]
const syncMethods = ['sign', 'generateAddress', 'computeLedgerHash']
syncMethods.forEach(name => {
this[name] = defaultAPI[name].bind(defaultAPI)
})
apis.forEach(api => {
api.on('ledger', this.onLedgerEvent.bind(this))
api.on('error', (errorCode, errorMessage, data) =>
this.emit('error', errorCode, errorMessage, data))
})
}
onLedgerEvent(ledger) {
if (ledger.ledgerVersion > this.ledgerVersion ||
this.ledgerVersion === undefined) {
this.ledgerVersion = ledger.ledgerVersion
this.emit('ledger', ledger)
}
}
getMethodNames() {
const methodNames: string[] = []
const rippleAPI = this._apis[0]
for (const name of Object.getOwnPropertyNames(rippleAPI)) {
if (typeof rippleAPI[name] === 'function') {
methodNames.push(name)
}
}
return methodNames
}
}
export {
RippleAPIBroadcast
}

View File

@@ -1,21 +0,0 @@
'use strict';
function setPrototypeOf(object, prototype) {
// Object.setPrototypeOf not supported on Internet Explorer 9
/* eslint-disable */
Object.setPrototypeOf ? Object.setPrototypeOf(object, prototype) :
object.__proto__ = prototype;
/* eslint-enable */
}
function getConstructorName(object) {
// hack for internet explorer
return process.browser ?
object.constructor.toString().match(/^function\s+([^(]*)/)[1] :
object.constructor.name;
}
module.exports = {
getConstructorName,
setPrototypeOf
};

View File

@@ -0,0 +1,20 @@
function setPrototypeOf(object, prototype) {
// Object.setPrototypeOf not supported on Internet Explorer 9
Object.setPrototypeOf ? Object.setPrototypeOf(object, prototype) :
// @ts-ignore: Specifically a fallback for IE9
object.__proto__ = prototype
}
function getConstructorName(object: object): string {
// hack for internet explorer
if (!object.constructor.name) {
return object.constructor.toString().match(/^function\s+([^(]*)/)![1]
}
return object.constructor.name
}
export {
getConstructorName,
setPrototypeOf
}

View File

@@ -1,318 +0,0 @@
'use strict';
const _ = require('lodash');
const {EventEmitter} = require('events');
const WebSocket = require('ws');
const parseURL = require('url').parse;
const RangeSet = require('./rangeset').RangeSet;
const {RippledError, DisconnectedError, NotConnectedError,
TimeoutError, ResponseFormatError, ConnectionError} = require('./errors');
function isStreamMessageType(type) {
return type === 'ledgerClosed' ||
type === 'transaction' ||
type === 'path_find';
}
class Connection extends EventEmitter {
constructor(url, options = {}) {
super();
this.setMaxListeners(Infinity);
this._url = url;
this._trace = options.trace;
if (this._trace) {
// for easier unit testing
this._console = console;
}
this._proxyURL = options.proxy;
this._proxyAuthorization = options.proxyAuthorization;
this._authorization = options.authorization;
this._trustedCertificates = options.trustedCertificates;
this._key = options.key;
this._passphrase = options.passphrase;
this._certificate = options.certificate;
this._timeout = options.timeout || (20 * 1000);
this._isReady = false;
this._ws = null;
this._ledgerVersion = null;
this._availableLedgerVersions = new RangeSet();
this._nextRequestID = 1;
}
_updateLedgerVersions(data) {
this._ledgerVersion = Number(data.ledger_index);
if (data.validated_ledgers) {
this._availableLedgerVersions.reset();
this._availableLedgerVersions.parseAndAddRanges(
data.validated_ledgers);
} else {
this._availableLedgerVersions.addValue(this._ledgerVersion);
}
}
// return value is array of arguments to Connection.emit
_parseMessage(message) {
const data = JSON.parse(message);
if (data.type === 'response') {
if (!(Number.isInteger(data.id) && data.id >= 0)) {
throw new ResponseFormatError('valid id not found in response');
}
return [data.id.toString(), data];
} else if (isStreamMessageType(data.type)) {
if (data.type === 'ledgerClosed') {
this._updateLedgerVersions(data);
}
return [data.type, data];
} else if (data.type === undefined && data.error) {
return ['error', data.error, data.error_message, data]; // e.g. slowDown
}
throw new ResponseFormatError('unrecognized message type: ' + data.type);
}
_onMessage(message) {
let parameters;
if (this._trace) {
this._console.log(message);
}
try {
parameters = this._parseMessage(message);
} catch (error) {
this.emit('error', 'badMessage', error.message, message);
return;
}
// we don't want this inside the try/catch or exceptions in listener
// will be caught
this.emit(...parameters);
}
get _state() {
return this._ws ? this._ws.readyState : WebSocket.CLOSED;
}
get _shouldBeConnected() {
return this._ws !== null;
}
isConnected() {
return this._state === WebSocket.OPEN && this._isReady;
}
_onUnexpectedClose(resolve = function() {}, reject = function() {}) {
this._ws = null;
this._isReady = false;
this.connect().then(resolve, reject);
}
_onOpen() {
this._ws.removeListener('close', this._onUnexpectedCloseBound);
this._onUnexpectedCloseBound = this._onUnexpectedClose.bind(this);
this._ws.once('close', this._onUnexpectedCloseBound);
const request = {
command: 'subscribe',
streams: ['ledger']
};
return this.request(request).then(data => {
this._updateLedgerVersions(data);
this._isReady = true;
this.emit('connected');
});
}
_createWebSocket() {
const options = {};
if (this._proxyURL !== undefined) {
const parsedURL = parseURL(this._url);
const parsedProxyURL = parseURL(this._proxyURL);
const proxyOverrides = _.omit({
secureEndpoint: (parsedURL.protocol === 'wss:'),
secureProxy: (parsedProxyURL.protocol === 'https:'),
auth: this._proxyAuthorization,
ca: this._trustedCertificates,
key: this._key,
passphrase: this._passphrase,
cert: this._certificate
}, _.isUndefined);
const proxyOptions = _.assign({}, parsedProxyURL, proxyOverrides);
let HttpsProxyAgent;
try {
HttpsProxyAgent = require('https-proxy-agent');
} catch (error) {
throw new Error('"proxy" option is not supported in the browser');
}
options.agent = new HttpsProxyAgent(proxyOptions);
}
if (this._authorization !== undefined) {
const base64 = new Buffer(this._authorization).toString('base64');
options.headers = {Authorization: `Basic ${base64}`};
}
const optionsOverrides = _.omit({
ca: this._trustedCertificates,
key: this._key,
passphrase: this._passphrase,
cert: this._certificate
}, _.isUndefined);
const websocketOptions = _.assign({}, options, optionsOverrides);
const websocket = new WebSocket(this._url, null, websocketOptions);
// we will have a listener for each outstanding request,
// so we have to raise the limit (the default is 10)
if (typeof websocket.setMaxListeners === 'function') {
websocket.setMaxListeners(Infinity);
}
return websocket;
}
connect() {
return new Promise((resolve, reject) => {
if (!this._url) {
reject(new ConnectionError(
'Cannot connect because no server was specified'));
}
if (this._state === WebSocket.OPEN) {
resolve();
} else if (this._state === WebSocket.CONNECTING) {
this._ws.once('open', resolve);
} else {
this._ws = this._createWebSocket();
// when an error causes the connection to close, the close event
// should still be emitted; the "ws" documentation says: "The close
// event is also emitted when then underlying net.Socket closes the
// connection (end or close)."
this._ws.on('error', error =>
this.emit('error', 'websocket', error.message, error));
this._ws.on('message', this._onMessage.bind(this));
// in browser close event can came before open event, so we must
// resolve connect's promise after reconnect in that case.
// after open event we will rebound _onUnexpectedCloseBound
// without resolve and reject functions
this._onUnexpectedCloseBound = this._onUnexpectedClose.bind(this,
resolve, reject);
this._ws.once('close', this._onUnexpectedCloseBound);
this._ws.once('open', () => this._onOpen().then(resolve, reject));
}
});
}
disconnect() {
return new Promise(resolve => {
if (this._state === WebSocket.CLOSED) {
resolve();
} else if (this._state === WebSocket.CLOSING) {
this._ws.once('close', resolve);
} else {
this._ws.removeListener('close', this._onUnexpectedCloseBound);
this._ws.once('close', () => {
this._ws = null;
this._isReady = false;
resolve();
});
this._ws.close();
}
});
}
reconnect() {
return this.disconnect().then(() => this.connect());
}
_whenReady(promise) {
return new Promise((resolve, reject) => {
if (!this._shouldBeConnected) {
reject(new NotConnectedError());
} else if (this._state === WebSocket.OPEN && this._isReady) {
promise.then(resolve, reject);
} else {
this.once('connected', () => promise.then(resolve, reject));
}
});
}
getLedgerVersion() {
return this._whenReady(Promise.resolve(this._ledgerVersion));
}
hasLedgerVersions(lowLedgerVersion, highLedgerVersion) {
return this._whenReady(Promise.resolve(
this._availableLedgerVersions.containsRange(
lowLedgerVersion, highLedgerVersion || this._ledgerVersion)));
}
hasLedgerVersion(ledgerVersion) {
return this.hasLedgerVersions(ledgerVersion, ledgerVersion);
}
_send(message) {
if (this._trace) {
this._console.log(message);
}
return new Promise((resolve, reject) => {
this._ws.send(message, undefined, (error, result) => {
if (error) {
reject(new DisconnectedError(error.message));
} else {
resolve(result);
}
});
});
}
request(request, timeout) {
return new Promise((resolve, reject) => {
if (!this._shouldBeConnected) {
reject(new NotConnectedError());
}
let timer = null;
const self = this;
const id = this._nextRequestID;
this._nextRequestID += 1;
const eventName = id.toString();
function onDisconnect() {
clearTimeout(timer);
self.removeAllListeners(eventName);
reject(new DisconnectedError());
}
function cleanup() {
clearTimeout(timer);
self.removeAllListeners(eventName);
if (self._ws !== null) {
self._ws.removeListener('close', onDisconnect);
}
}
function _resolve(response) {
cleanup();
resolve(response);
}
function _reject(error) {
cleanup();
reject(error);
}
this.once(eventName, response => {
if (response.status === 'error') {
_reject(new RippledError(response.error));
} else if (response.status === 'success') {
_resolve(response.result);
} else {
_reject(new ResponseFormatError(
'unrecognized status: ' + response.status));
}
});
this._ws.once('close', onDisconnect);
// JSON.stringify automatically removes keys with value of 'undefined'
const message = JSON.stringify(Object.assign({}, request, {id}));
this._whenReady(this._send(message)).then(() => {
const delay = timeout || this._timeout;
timer = setTimeout(() => _reject(new TimeoutError()), delay);
}).catch(_reject);
});
}
}
module.exports = Connection;

470
src/common/connection.ts Normal file
View File

@@ -0,0 +1,470 @@
import * as _ from 'lodash'
import {EventEmitter} from 'events'
import {parse as parseUrl} from 'url'
import * as WebSocket from 'ws'
import RangeSet from './rangeset'
import {RippledError, DisconnectedError, NotConnectedError,
TimeoutError, ResponseFormatError, ConnectionError,
RippledNotInitializedError} from './errors'
export interface ConnectionOptions {
trace?: boolean,
proxy?: string
proxyAuthorization?: string
authorization?: string
trustedCertificates?: string[]
key?: string
passphrase?: string
certificate?: string
timeout?: number
}
class Connection extends EventEmitter {
private _url: string
private _trace: boolean
private _console?: Console
private _proxyURL?: string
private _proxyAuthorization?: string
private _authorization?: string
private _trustedCertificates?: string[]
private _key?: string
private _passphrase?: string
private _certificate?: string
private _timeout: number
private _isReady: boolean = false
private _ws: null|WebSocket = null
protected _ledgerVersion: null|number = null
private _availableLedgerVersions = new RangeSet()
private _nextRequestID: number = 1
private _retry: number = 0
private _retryTimer: null|NodeJS.Timer = null
private _onOpenErrorBound: null| null|((...args: any[]) => void) = null
private _onUnexpectedCloseBound: null|((...args: any[]) => void) = null
private _fee_base: null|number = null
private _fee_ref: null|number = null
constructor(url, options: ConnectionOptions = {}) {
super()
this.setMaxListeners(Infinity)
this._url = url
this._trace = options.trace || false
if (this._trace) {
// for easier unit testing
this._console = console
}
this._proxyURL = options.proxy
this._proxyAuthorization = options.proxyAuthorization
this._authorization = options.authorization
this._trustedCertificates = options.trustedCertificates
this._key = options.key
this._passphrase = options.passphrase
this._certificate = options.certificate
this._timeout = options.timeout || (20 * 1000)
}
_updateLedgerVersions(data) {
this._ledgerVersion = Number(data.ledger_index)
if (data.validated_ledgers) {
this._availableLedgerVersions.reset()
this._availableLedgerVersions.parseAndAddRanges(
data.validated_ledgers)
} else {
this._availableLedgerVersions.addValue(this._ledgerVersion)
}
}
_updateFees(data) {
this._fee_base = Number(data.fee_base)
this._fee_ref = Number(data.fee_ref)
}
// return value is array of arguments to Connection.emit
_parseMessage(message): [string, Object] | ['error', string, string, Object] {
const data = JSON.parse(message)
if (data.type === 'response') {
if (!(Number.isInteger(data.id) && data.id >= 0)) {
throw new ResponseFormatError('valid id not found in response', data)
}
return [data.id.toString(), data]
} else if (data.type === undefined && data.error) {
return ['error', data.error, data.error_message, data] // e.g. slowDown
}
// Possible `data.type` values include 'ledgerClosed',
// 'transaction', 'path_find', and many others.
if (data.type === 'ledgerClosed') {
this._updateLedgerVersions(data)
this._updateFees(data)
}
return [data.type, data]
}
_onMessage(message) {
if (this._trace) {
this._console!.log(message)
}
let parameters
try {
parameters = this._parseMessage(message)
} catch (error) {
this.emit('error', 'badMessage', error.message, message)
return
}
// we don't want this inside the try/catch or exceptions in listener
// will be caught
this.emit.apply(this, parameters)
}
get _state() {
return this._ws ? this._ws.readyState : WebSocket.CLOSED
}
get _shouldBeConnected() {
return this._ws !== null
}
isConnected() {
return this._state === WebSocket.OPEN && this._isReady
}
_onUnexpectedClose(beforeOpen, resolve, reject, code) {
if (this._onOpenErrorBound) {
this._ws!.removeListener('error', this._onOpenErrorBound)
this._onOpenErrorBound = null
}
// just in case
this._ws!.removeAllListeners('open')
this._ws = null
this._isReady = false
if (beforeOpen) {
// connection was closed before it was properly opened, so we must return
// error to connect's caller
this.connect().then(resolve, reject)
} else {
// if first parameter ws lib sends close code,
// but sometimes it forgots about it, so default to 1006 - CLOSE_ABNORMAL
this.emit('disconnected', code || 1006)
this._retryConnect()
}
}
_calculateTimeout(retriesCount) {
return (retriesCount < 40)
// First, for 2 seconds: 20 times per second
? (1000 / 20)
: (retriesCount < 40 + 60)
// Then, for 1 minute: once per second
? (1000)
: (retriesCount < 40 + 60 + 60)
// Then, for 10 minutes: once every 10 seconds
? (10 * 1000)
// Then: once every 30 seconds
: (30 * 1000)
}
_retryConnect() {
this._retry += 1
const retryTimeout = this._calculateTimeout(this._retry)
this._retryTimer = setTimeout(() => {
this.emit('reconnecting', this._retry)
this.connect().catch(this._retryConnect.bind(this))
}, retryTimeout)
}
_clearReconnectTimer() {
if (this._retryTimer !== null) {
clearTimeout(this._retryTimer)
this._retryTimer = null
}
}
_onOpen() {
if (!this._ws) {
return Promise.reject(new DisconnectedError())
}
if (this._onOpenErrorBound) {
this._ws.removeListener('error', this._onOpenErrorBound)
this._onOpenErrorBound = null
}
const request = {
command: 'subscribe',
streams: ['ledger']
}
return this.request(request).then((data: any) => {
if (_.isEmpty(data) || !data.ledger_index) {
// rippled instance doesn't have validated ledgers
return this._disconnect(false).then(() => {
throw new RippledNotInitializedError('Rippled not initialized')
})
}
this._updateLedgerVersions(data)
this._updateFees(data)
this._rebindOnUnxpectedClose()
this._retry = 0
this._ws.on('error', error => {
// TODO: "type" does not exist on official error type, safe to remove?
if (process.browser && error && (<any>error).type === 'error') {
// we are in browser, ignore error - `close` event will be fired
// after error
return
}
this.emit('error', 'websocket', error.message, error)
})
this._isReady = true
this.emit('connected')
return undefined
})
}
_rebindOnUnxpectedClose() {
if (this._onUnexpectedCloseBound) {
this._ws.removeListener('close', this._onUnexpectedCloseBound)
}
this._onUnexpectedCloseBound =
this._onUnexpectedClose.bind(this, false, null, null)
this._ws.once('close', this._onUnexpectedCloseBound)
}
_unbindOnUnxpectedClose() {
if (this._onUnexpectedCloseBound) {
this._ws.removeListener('close', this._onUnexpectedCloseBound)
}
this._onUnexpectedCloseBound = null
}
_onOpenError(reject, error) {
this._onOpenErrorBound = null
this._unbindOnUnxpectedClose()
reject(new NotConnectedError(error.message, error))
}
_createWebSocket(): WebSocket {
const options: WebSocket.ClientOptions = {}
if (this._proxyURL !== undefined) {
const parsedURL = parseUrl(this._url)
const parsedProxyURL = parseUrl(this._proxyURL)
const proxyOverrides = _.omitBy({
secureEndpoint: (parsedURL.protocol === 'wss:'),
secureProxy: (parsedProxyURL.protocol === 'https:'),
auth: this._proxyAuthorization,
ca: this._trustedCertificates,
key: this._key,
passphrase: this._passphrase,
cert: this._certificate
}, _.isUndefined)
const proxyOptions = _.assign({}, parsedProxyURL, proxyOverrides)
let HttpsProxyAgent
try {
HttpsProxyAgent = require('https-proxy-agent')
} catch (error) {
throw new Error('"proxy" option is not supported in the browser')
}
options.agent = new HttpsProxyAgent(proxyOptions)
}
if (this._authorization !== undefined) {
const base64 = Buffer.from(this._authorization).toString('base64')
options.headers = {Authorization: `Basic ${base64}`}
}
const optionsOverrides = _.omitBy({
ca: this._trustedCertificates,
key: this._key,
passphrase: this._passphrase,
cert: this._certificate
}, _.isUndefined)
const websocketOptions = _.assign({}, options, optionsOverrides)
const websocket = new WebSocket(this._url, null, websocketOptions)
// we will have a listener for each outstanding request,
// so we have to raise the limit (the default is 10)
if (typeof websocket.setMaxListeners === 'function') {
websocket.setMaxListeners(Infinity)
}
return websocket
}
connect() {
this._clearReconnectTimer()
return new Promise((resolve, reject) => {
if (!this._url) {
reject(new ConnectionError(
'Cannot connect because no server was specified'))
}
if (this._state === WebSocket.OPEN) {
resolve()
} else if (this._state === WebSocket.CONNECTING) {
this._ws.once('open', resolve)
} else {
this._ws = this._createWebSocket()
// when an error causes the connection to close, the close event
// should still be emitted; the "ws" documentation says: "The close
// event is also emitted when then underlying net.Socket closes the
// connection (end or close)."
// In case if there is connection error (say, server is not responding)
// we must return this error to connection's caller. After successful
// opening, we will forward all errors to main api object.
this._onOpenErrorBound = this._onOpenError.bind(this, reject)
this._ws.once('error', this._onOpenErrorBound)
this._ws.on('message', this._onMessage.bind(this))
// in browser close event can came before open event, so we must
// resolve connect's promise after reconnect in that case.
// after open event we will rebound _onUnexpectedCloseBound
// without resolve and reject functions
this._onUnexpectedCloseBound = this._onUnexpectedClose.bind(this, true,
resolve, reject)
this._ws.once('close', this._onUnexpectedCloseBound)
this._ws.once('open', () => this._onOpen().then(resolve, reject))
}
})
}
disconnect() {
return this._disconnect(true)
}
_disconnect(calledByUser) {
if (calledByUser) {
this._clearReconnectTimer()
this._retry = 0
}
return new Promise(resolve => {
if (this._state === WebSocket.CLOSED) {
resolve()
} else if (this._state === WebSocket.CLOSING) {
this._ws.once('close', resolve)
} else {
if (this._onUnexpectedCloseBound) {
this._ws.removeListener('close', this._onUnexpectedCloseBound)
this._onUnexpectedCloseBound = null
}
this._ws.once('close', code => {
this._ws = null
this._isReady = false
if (calledByUser) {
this.emit('disconnected', code || 1000) // 1000 - CLOSE_NORMAL
}
resolve()
})
this._ws.close()
}
})
}
reconnect() {
return this.disconnect().then(() => this.connect())
}
_whenReady<T>(promise: Promise<T>): Promise<T> {
return new Promise((resolve, reject) => {
if (!this._shouldBeConnected) {
reject(new NotConnectedError())
} else if (this._state === WebSocket.OPEN && this._isReady) {
promise.then(resolve, reject)
} else {
this.once('connected', () => promise.then(resolve, reject))
}
})
}
getLedgerVersion(): Promise<number> {
return this._whenReady(Promise.resolve(this._ledgerVersion!))
}
hasLedgerVersions(lowLedgerVersion, highLedgerVersion): Promise<boolean> {
return this._whenReady(Promise.resolve(
this._availableLedgerVersions.containsRange(
lowLedgerVersion, highLedgerVersion || this._ledgerVersion)))
}
hasLedgerVersion(ledgerVersion): Promise<boolean> {
return this.hasLedgerVersions(ledgerVersion, ledgerVersion)
}
getFeeBase(): Promise<number> {
return this._whenReady(Promise.resolve(Number(this._fee_base)))
}
getFeeRef(): Promise<number> {
return this._whenReady(Promise.resolve(Number(this._fee_ref)))
}
_send(message: string): Promise<void> {
if (this._trace) {
this._console.log(message)
}
return new Promise((resolve, reject) => {
this._ws.send(message, undefined, error => {
if (error) {
reject(new DisconnectedError(error.message, error))
} else {
resolve()
}
})
})
}
request(request, timeout?: number): Promise<any> {
return new Promise((resolve, reject) => {
if (!this._shouldBeConnected) {
reject(new NotConnectedError())
}
let timer = null
const self = this
const id = this._nextRequestID
this._nextRequestID += 1
const eventName = id.toString()
function onDisconnect() {
clearTimeout(timer)
self.removeAllListeners(eventName)
reject(new DisconnectedError('websocket was closed'))
}
function cleanup() {
clearTimeout(timer)
self.removeAllListeners(eventName)
if (self._ws !== null) {
self._ws.removeListener('close', onDisconnect)
}
}
function _resolve(response) {
cleanup()
resolve(response)
}
function _reject(error) {
cleanup()
reject(error)
}
this.once(eventName, response => {
if (response.status === 'error') {
_reject(new RippledError(response.error_message || response.error, response))
} else if (response.status === 'success') {
_resolve(response.result)
} else {
_reject(new ResponseFormatError(
'unrecognized status: ' + response.status, response))
}
})
this._ws.once('close', onDisconnect)
// JSON.stringify automatically removes keys with value of 'undefined'
const message = JSON.stringify(Object.assign({}, request, {id}))
this._whenReady(this._send(message)).then(() => {
const delay = timeout || this._timeout
timer = setTimeout(() => _reject(new TimeoutError()), delay)
}).catch(_reject)
})
}
}
export default Connection

View File

@@ -1,49 +0,0 @@
'use strict';
const flagIndices = require('./txflags').txFlagIndices.AccountSet;
const accountRootFlags = {
PasswordSpent: 0x00010000, // password set fee is spent
RequireDestTag: 0x00020000, // require a DestinationTag for payments
RequireAuth: 0x00040000, // require a authorization to hold IOUs
DisallowXRP: 0x00080000, // disallow sending XRP
DisableMaster: 0x00100000, // force regular key
NoFreeze: 0x00200000, // permanently disallowed freezing trustlines
GlobalFreeze: 0x00400000, // trustlines globally frozen
DefaultRipple: 0x00800000
};
const AccountFlags = {
passwordSpent: accountRootFlags.PasswordSpent,
requireDestinationTag: accountRootFlags.RequireDestTag,
requireAuthorization: accountRootFlags.RequireAuth,
disallowIncomingXRP: accountRootFlags.DisallowXRP,
disableMasterKey: accountRootFlags.DisableMaster,
noFreeze: accountRootFlags.NoFreeze,
globalFreeze: accountRootFlags.GlobalFreeze,
defaultRipple: accountRootFlags.DefaultRipple
};
const AccountFlagIndices = {
requireDestinationTag: flagIndices.asfRequireDest,
requireAuthorization: flagIndices.asfRequireAuth,
disallowIncomingXRP: flagIndices.asfDisallowXRP,
disableMasterKey: flagIndices.asfDisableMaster,
enableTransactionIDTracking: flagIndices.asfAccountTxnID,
noFreeze: flagIndices.asfNoFreeze,
globalFreeze: flagIndices.asfGlobalFreeze,
defaultRipple: flagIndices.asfDefaultRipple
};
const AccountFields = {
EmailHash: {name: 'emailHash', encoding: 'hex',
length: 32, defaults: '0'},
MessageKey: {name: 'messageKey'},
Domain: {name: 'domain', encoding: 'hex'},
TransferRate: {name: 'transferRate', defaults: 0, shift: 9}
};
module.exports = {
AccountFields,
AccountFlagIndices,
AccountFlags
};

87
src/common/constants.ts Normal file
View File

@@ -0,0 +1,87 @@
import {txFlagIndices} from './txflags'
// Ordering from https://developers.ripple.com/accountroot.html
const accountRootFlags = {
// lsfDefaultRipple:
// Enable rippling on trust lines by default.
// Required for issuing addresses; discouraged for others.
DefaultRipple: 0x00800000,
// lsfDepositAuth:
// Require account to auth deposits.
// This account can only receive funds from transactions it sends,
// or preauthorized accounts.
DepositAuth: 0x01000000,
// lsfDisableMaster:
// Force regular key.
// Disallows use of the master key.
DisableMaster: 0x00100000,
// lsfDisallowXRP:
// Disallow sending XRP.
// Not enforced by rippled; client applications should check.
DisallowXRP: 0x00080000,
// lsfGlobalFreeze:
// Trustlines globally frozen.
GlobalFreeze: 0x00400000,
// lsfNoFreeze:
// Permanently disallowed freezing trustlines.
// Once enabled, cannot be disabled.
NoFreeze: 0x00200000,
// lsfPasswordSpent:
// Password set fee is spent.
// The account has used its free SetRegularKey transaction.
PasswordSpent: 0x00010000,
// lsfRequireAuth:
// Require authorization to hold IOUs (issuances).
RequireAuth: 0x00040000,
// lsfRequireDestTag:
// Require a DestinationTag for incoming payments.
RequireDestTag: 0x00020000
}
const AccountFlags = {
passwordSpent: accountRootFlags.PasswordSpent,
requireDestinationTag: accountRootFlags.RequireDestTag,
requireAuthorization: accountRootFlags.RequireAuth,
depositAuth: accountRootFlags.DepositAuth,
disallowIncomingXRP: accountRootFlags.DisallowXRP,
disableMasterKey: accountRootFlags.DisableMaster,
noFreeze: accountRootFlags.NoFreeze,
globalFreeze: accountRootFlags.GlobalFreeze,
defaultRipple: accountRootFlags.DefaultRipple
}
const AccountFlagIndices = {
requireDestinationTag: txFlagIndices.AccountSet.asfRequireDest,
requireAuthorization: txFlagIndices.AccountSet.asfRequireAuth,
depositAuth: txFlagIndices.AccountSet.asfDepositAuth,
disallowIncomingXRP: txFlagIndices.AccountSet.asfDisallowXRP,
disableMasterKey: txFlagIndices.AccountSet.asfDisableMaster,
enableTransactionIDTracking: txFlagIndices.AccountSet.asfAccountTxnID,
noFreeze: txFlagIndices.AccountSet.asfNoFreeze,
globalFreeze: txFlagIndices.AccountSet.asfGlobalFreeze,
defaultRipple: txFlagIndices.AccountSet.asfDefaultRipple
}
const AccountFields = {
EmailHash: {name: 'emailHash', encoding: 'hex',
length: 32, defaults: '0'},
MessageKey: {name: 'messageKey'},
Domain: {name: 'domain', encoding: 'hex'},
TransferRate: {name: 'transferRate', defaults: 0, shift: 9}
}
export {
AccountFields,
AccountFlagIndices,
AccountFlags
}

View File

@@ -1,43 +1,38 @@
'use strict';
const util = require('util');
const browserHacks = require('./browser-hacks');
// this is needed because extending builtins doesn't work in babel 6.x
function extendableBuiltin(cls) {
function ExtendableBuiltin() {
cls.apply(this, arguments);
}
ExtendableBuiltin.prototype = Object.create(cls.prototype);
browserHacks.setPrototypeOf(ExtendableBuiltin, cls);
return ExtendableBuiltin;
}
import {inspect} from 'util'
import * as browserHacks from './browser-hacks'
class RippleError extends extendableBuiltin(Error) {
constructor(message, data) {
super(message);
class RippleError extends Error {
this.name = browserHacks.getConstructorName(this);
this.message = message;
this.data = data;
name: string
message: string
data?: any
constructor(message = '', data?: any) {
super(message)
this.name = browserHacks.getConstructorName(this)
this.message = message
this.data = data
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor.name);
Error.captureStackTrace(this, this.constructor)
}
}
toString() {
let result = '[' + this.name + '(' + this.message;
let result = '[' + this.name + '(' + this.message
if (this.data) {
result += ', ' + util.inspect(this.data);
result += ', ' + inspect(this.data)
}
result += ')]';
return result;
result += ')]'
return result
}
/* console.log in node uses util.inspect on object, and util.inspect allows
us to cutomize its output:
us to customize its output:
https://nodejs.org/api/util.html#util_custom_inspect_function_on_objects */
inspect() {
return this.toString();
return this.toString()
}
}
@@ -53,6 +48,8 @@ class NotConnectedError extends ConnectionError {}
class DisconnectedError extends ConnectionError {}
class RippledNotInitializedError extends ConnectionError {}
class TimeoutError extends ConnectionError {}
class ResponseFormatError extends ConnectionError {}
@@ -60,31 +57,32 @@ class ResponseFormatError extends ConnectionError {}
class ValidationError extends RippleError {}
class NotFoundError extends RippleError {
constructor(message) {
super(message || 'Not found');
constructor(message = 'Not found') {
super(message)
}
}
class MissingLedgerHistoryError extends RippleError {
constructor(message) {
super(message || 'Server is missing ledger history in the specified range');
constructor(message?: string) {
super(message || 'Server is missing ledger history in the specified range')
}
}
class PendingLedgerVersionError extends RippleError {
constructor(message) {
super(message || 'maxLedgerVersion is greater than server\'s'
+ ' most recent validated ledger');
constructor(message?: string) {
super(message || 'maxLedgerVersion is greater than server\'s most recent' +
' validated ledger')
}
}
module.exports = {
export {
RippleError,
UnexpectedError,
ConnectionError,
RippledError,
NotConnectedError,
DisconnectedError,
RippledNotInitializedError,
TimeoutError,
ResponseFormatError,
ValidationError,
@@ -92,4 +90,4 @@ module.exports = {
PendingLedgerVersionError,
MissingLedgerHistoryError,
LedgerVersionError
};
}

View File

@@ -1,22 +0,0 @@
'use strict';
const utils = require('./utils');
module.exports = {
Connection: require('./connection'),
constants: require('./constants'),
errors: require('./errors'),
validate: require('./validate'),
txFlags: require('./txflags').txFlags,
serverInfo: require('./serverinfo'),
dropsToXrp: utils.dropsToXrp,
xrpToDrops: utils.xrpToDrops,
toRippledAmount: utils.toRippledAmount,
generateAddress: utils.generateAddress,
generateAddressAPI: utils.generateAddressAPI,
removeUndefined: utils.removeUndefined,
convertKeysFromSnakeCaseToCamelCase:
utils.convertKeysFromSnakeCaseToCamelCase,
iso8601ToRippleTime: utils.iso8601ToRippleTime,
rippleTimeToISO8601: utils.rippleTimeToISO8601,
isValidSecret: utils.isValidSecret
};

23
src/common/index.ts Normal file
View File

@@ -0,0 +1,23 @@
import * as constants from './constants'
import * as errors from './errors'
import * as validate from './validate'
import * as serverInfo from './serverinfo'
export {
constants,
errors,
validate,
serverInfo
}
export {
dropsToXrp,
xrpToDrops,
toRippledAmount,
removeUndefined,
convertKeysFromSnakeCaseToCamelCase,
iso8601ToRippleTime,
rippleTimeToISO8601
} from './utils'
export {default as Connection} from './connection'
export {txFlags} from './txflags'

View File

@@ -1,61 +0,0 @@
/* @flow */
'use strict';
const _ = require('lodash');
const assert = require('assert');
const ranges = Symbol();
function mergeIntervals(intervals: Array<[number, number]>) {
const stack = [[-Infinity, -Infinity]];
_.forEach(_.sortBy(intervals, x => x[0]), interval => {
const lastInterval = stack.pop();
if (interval[0] <= lastInterval[1] + 1) {
stack.push([lastInterval[0], Math.max(interval[1], lastInterval[1])]);
} else {
stack.push(lastInterval);
stack.push(interval);
}
});
return stack.slice(1);
}
class RangeSet {
constructor() {
this.reset();
}
reset() {
this[ranges] = [];
}
serialize() {
return this[ranges].map(range =>
range[0].toString() + '-' + range[1].toString()).join(',');
}
addRange(start: number, end: number) {
assert(start <= end, 'invalid range');
this[ranges] = mergeIntervals(this[ranges].concat([[start, end]]));
}
addValue(value: number) {
this.addRange(value, value);
}
parseAndAddRanges(rangesString: string) {
const rangeStrings = rangesString.split(',');
_.forEach(rangeStrings, rangeString => {
const range = rangeString.split('-').map(Number);
this.addRange(range[0], range.length === 1 ? range[0] : range[1]);
});
}
containsRange(start: number, end: number) {
return _.some(this[ranges], range => range[0] <= start && range[1] >= end);
}
containsValue(value: number) {
return this.containsRange(value, value);
}
}
module.exports.RangeSet = RangeSet;

63
src/common/rangeset.ts Normal file
View File

@@ -0,0 +1,63 @@
import * as _ from 'lodash'
import * as assert from 'assert'
type Interval = [number, number]
function mergeIntervals(intervals: Interval[]): Interval[] {
const stack: Interval[] = [[-Infinity, -Infinity]]
_.sortBy(intervals, x => x[0]).forEach(interval => {
const lastInterval: Interval = stack.pop()!
if (interval[0] <= lastInterval[1] + 1) {
stack.push([lastInterval[0], Math.max(interval[1], lastInterval[1])])
} else {
stack.push(lastInterval)
stack.push(interval)
}
})
return stack.slice(1)
}
class RangeSet {
ranges: Array<[number, number]>
constructor() {
this.reset()
}
reset() {
this.ranges = []
}
serialize() {
return this.ranges.map(range =>
range[0].toString() + '-' + range[1].toString()).join(',')
}
addRange(start: number, end: number) {
assert(start <= end, 'invalid range')
this.ranges = mergeIntervals(this.ranges.concat([[start, end]]))
}
addValue(value: number) {
this.addRange(value, value)
}
parseAndAddRanges(rangesString: string) {
const rangeStrings = rangesString.split(',')
_.forEach(rangeStrings, rangeString => {
const range = rangeString.split('-').map(Number)
this.addRange(range[0], range.length === 1 ? range[0] : range[1])
})
}
containsRange(start: number, end: number) {
return _.some(this.ranges, range => range[0] <= start && range[1] >= end)
}
containsValue(value: number) {
return this.containsRange(value, value)
}
}
export default RangeSet

Some files were not shown because too many files have changed in this diff Show More