mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-15 10:05:48 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8278dc5b5b | ||
|
|
c90d486454 | ||
|
|
35f9b7ec8d | ||
|
|
69e621af86 | ||
|
|
0e92e696d4 | ||
|
|
0b1445bfe9 | ||
|
|
db2d7ba1f5 | ||
|
|
d82703f41b | ||
|
|
8213861ab7 | ||
|
|
a842c380cf | ||
|
|
5bf6f1849a | ||
|
|
bfe4877f73 | ||
|
|
63dcddf6f4 | ||
|
|
68735ddb35 | ||
|
|
1fd9ca7ef2 | ||
|
|
2445004333 | ||
|
|
dc148bf954 | ||
|
|
f3c34bd75a | ||
|
|
5419e67dbc | ||
|
|
8d37da0952 | ||
|
|
a8075d98df | ||
|
|
fcc205b85a | ||
|
|
0f5056221f | ||
|
|
8384ace746 | ||
|
|
040cabece0 | ||
|
|
319a8d6ab2 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,5 +1,9 @@
|
||||
# .gitignore
|
||||
|
||||
# Ignore package locks other than Yarn.
|
||||
package-lock.json
|
||||
npm-shrinkwrap.json
|
||||
|
||||
# Ignore vim swap files.
|
||||
*.swp
|
||||
|
||||
|
||||
119
APPLICATIONS.md
Normal file
119
APPLICATIONS.md
Normal 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.
|
||||
184
HISTORY.md
184
HISTORY.md
@@ -1,5 +1,189 @@
|
||||
# ripple-lib Release History
|
||||
|
||||
## 1.2.1 (2019-03-23)
|
||||
|
||||
* Update `ripple-binary-codec` to 0.2.1 to support `tecKILLED`
|
||||
|
||||
The SHA-256 checksums for the browser version of this release can be found
|
||||
below.
|
||||
|
||||
```
|
||||
% shasum -a 256 *
|
||||
531c2a8f4bf6d6b5bd4afe6a40b6a68a77179a343902cfa4210d7e35b5697af0 ripple-1.2.1-debug.js
|
||||
201ee99922b16b7e32afb5317ef4bb9facc23b20c272bb5c4ed7010f5d996cab ripple-1.2.1-min.js
|
||||
c1b984581299bf00e0e3c8ac4e62eadfc9b190bd78a2458a76e59ceb56046148 ripple-1.2.1.js
|
||||
```
|
||||
|
||||
## 1.2.0 (2019-03-19)
|
||||
|
||||
This release:
|
||||
|
||||
* changes the way you handle errors for the `prepare*` methods.
|
||||
* improves the `message` field of `RippledError`s.
|
||||
* allows `Sequence` to be set in the transaction JSON provided to
|
||||
`prepareTransaction`.
|
||||
|
||||
For details, continue reading:
|
||||
|
||||
### [BREAKING CHANGE] `prepare*` methods reject the Promise on error
|
||||
|
||||
The `prepare*` methods now always reject the Promise when an error occurs, instead of throwing.
|
||||
|
||||
Previously, the methods would synchronously throw on validation errors, despite being asynchronous methods that return Promises.
|
||||
|
||||
In other words, to handle errors in the past, you would need to use a try/catch block:
|
||||
|
||||
```
|
||||
// OBSOLETE - no need for try/catch anymore
|
||||
try {
|
||||
api.preparePayment(address, payment, instructions).then(prepared => {
|
||||
res.send(prepared.txJSON);
|
||||
}).catch(error => {
|
||||
// Handle asynchronous error
|
||||
});
|
||||
} catch (error) {
|
||||
// Handle synchronous error
|
||||
}
|
||||
```
|
||||
|
||||
Now, you can rely on the Promise's `catch` handler, which is called with the error when the Promise is rejected:
|
||||
|
||||
```
|
||||
api.preparePayment(address, payment, instructions).then(prepared => {
|
||||
res.send(prepared.txJSON);
|
||||
}).catch(error => {
|
||||
// Handle error
|
||||
});
|
||||
```
|
||||
|
||||
This applies to:
|
||||
* preparePayment
|
||||
* prepareTrustline
|
||||
* prepareOrder
|
||||
* prepareOrderCancellation
|
||||
* prepareSettings
|
||||
* prepareEscrowCreation
|
||||
* prepareEscrowExecution
|
||||
* prepareCheckCreate
|
||||
* prepareCheckCash
|
||||
* prepareCheckCancel
|
||||
* preparePaymentChannelCreate
|
||||
* preparePaymentChannelClaim
|
||||
* preparePaymentChannelFund
|
||||
|
||||
### Improved `RippledError` `message`
|
||||
|
||||
Previously, `RippledErrors` (errors from rippled) used rippled's `error` field as the `message`.
|
||||
|
||||
Now, the `error_message` field is used as the `message`.
|
||||
|
||||
This helps to surface the specific cause of an error.
|
||||
|
||||
For example, before:
|
||||
```
|
||||
[RippledError(invalidParams, { error: 'invalidParams',
|
||||
error_code: 31,
|
||||
error_message: 'Missing field \'account\'.',
|
||||
id: 3,
|
||||
request: { command: 'account_info', id: 3 },
|
||||
status: 'error',
|
||||
type: 'response' })]
|
||||
```
|
||||
|
||||
After:
|
||||
```
|
||||
[RippledError(Missing field 'account'., { error: 'invalidParams',
|
||||
error_code: 31,
|
||||
error_message: 'Missing field \'account\'.',
|
||||
id: 3,
|
||||
request: { command: 'account_info', id: 3 },
|
||||
status: 'error',
|
||||
type: 'response' })]
|
||||
```
|
||||
|
||||
In this case, you can see at a glance that `account` is the missing field.
|
||||
|
||||
The `error` field is still available in `errorObject.data.error`.
|
||||
|
||||
When `error_message` is not set (as with e.g. error 'entryNotFound'), the `error` field is used as the `message`.
|
||||
|
||||
### [BUG FIX] `prepareTransaction` does not overwrite the `Sequence` field
|
||||
|
||||
The `prepareTransaction` method now allows `Sequence` to be set in the Transaction JSON object, instead of overwriting it with the account's expected sequence based on the state of the ledger.
|
||||
|
||||
Previously, you had to use the `sequence` field in the `instructions` object to manually set a transaction's sequence number.
|
||||
|
||||
### New in rippled 1.2.1
|
||||
|
||||
As this is the first release of ripple-lib following the release of rippled 1.2.1, we would like to highlight the following API improvements:
|
||||
|
||||
1. The [`delivered_amount` field](https://developers.ripple.com/partial-payments.html#the-delivered-amount-field) has been added to the `ledger` method, and to transaction subscriptions.
|
||||
|
||||
api.getLedger({includeTransactions: true, includeAllData: true, ledgerVersion: 17718771}).then(...)
|
||||
|
||||
You can also call `ledger` directly:
|
||||
|
||||
request('ledger', {...}).then(...)
|
||||
|
||||
2. [Support for Ed25519 seeds encoded using ripple-lib](https://github.com/ripple/rippled/pull/2734)
|
||||
|
||||
You have access to these improvements when you use a rippled server running version 1.2.1 or later. At the time of writing, we recommend using rippled version **1.2.2** or later.
|
||||
|
||||
The SHA-256 checksums for the browser version of this release can be found
|
||||
below.
|
||||
```
|
||||
% shasum -a 256 *
|
||||
13021fe3efbdd59faf68597b0b18204b39847b285cca82f84c737e3d19922cc2 ripple-1.2.0-debug.js
|
||||
0070225e731afd8c2c0a0976111ebf326c19a96ee1549368de9f016abdd53d2f ripple-1.2.0-min.js
|
||||
d440268397c03ad5137a3294e53a07b959ef93cd23b1990d6f82621c4776ba9f ripple-1.2.0.js
|
||||
```
|
||||
|
||||
## 1.1.2 (2018-12-12)
|
||||
|
||||
+ Update `submit` response (#978)
|
||||
+ Includes the full object returned by rippled, while keeping the existing
|
||||
fields for backward compatibility
|
||||
+ Add `getLedger` option for ledger hash (#980)
|
||||
+ Use the `ledgerHash` option to get a specific ledger by hash
|
||||
|
||||
Thanks to @alexchiriac for the contributions in this release.
|
||||
|
||||
When using `ripple-lib` with `rippled`, we recommend using `rippled` version
|
||||
1.1.2 or later.
|
||||
|
||||
The SHA-256 checksums for the browser version of this release can be found
|
||||
below.
|
||||
```
|
||||
% shasum -a 256 *
|
||||
e6cc52395d0c3e205263777ba2e528e50f4d1f84bb4b16763a3bf7f5fcc290f5 ripple-1.1.2-debug.js
|
||||
82df879bc2970e0e4fd161975a99448b4859b0cde751d8ea34e9f51d672090b9 ripple-1.1.2-min.js
|
||||
12f56330dc71bba8ac3004025cbc9698413a0c619df302dda105b31228a67319 ripple-1.1.2.js
|
||||
```
|
||||
|
||||
## 1.1.1 (2018-11-27)
|
||||
|
||||
+ Fix `getOrderbook` offer sorting (#970)
|
||||
+ **BREAKING CHANGE:** The ordering of offers returned by `getOrderbook` has
|
||||
been changed so that offers with the best quality are sorted first
|
||||
+ Add new helper methods for working with the `rippled` APIs:
|
||||
+ `formatBidsAndAsks`: Takes offers and returns a formatted order book object
|
||||
with bids and asks
|
||||
+ `renameCounterpartyToIssuer`: Takes an object and renames the `counterparty`
|
||||
field to `issuer`
|
||||
+ TypeScript: Add return type for `generateAddress` (#968)
|
||||
|
||||
When using `ripple-lib` with `rippled`, we recommend using `rippled` version 1.1.1 or
|
||||
later.
|
||||
|
||||
The SHA-256 checksums for the browser version of this release can be found
|
||||
below.
|
||||
```
|
||||
% shasum -a 256 *
|
||||
e151900e49bb5482b02bef5b0b1542ea586076363b072ae616f6d4d2f7f5b8a1 ripple-1.1.1-debug.js
|
||||
6aee3757b29de285f361e20862261090033c07a13fd09f4a3cc4c097b6e84b55 ripple-1.1.1-min.js
|
||||
bea4a889fb9ee4092324c6667490ea66469bdde869ddc1aaddf5e9d12b0cf091 ripple-1.1.1.js
|
||||
```
|
||||
|
||||
## 1.1.0 (2018-10-31)
|
||||
|
||||
+ Add support for Node.js v10 LTS (#964)
|
||||
|
||||
12
README.md
12
README.md
@@ -7,8 +7,8 @@ A JavaScript API for interacting with the XRP Ledger
|
||||
### Features
|
||||
|
||||
+ Connect to a `rippled` server from Node.js or a web browser
|
||||
+ Issue [rippled API](https://ripple.com/build/rippled-apis/) requests
|
||||
+ Listen to events on the XRP Ledger (transaction, ledger, etc.)
|
||||
+ 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
|
||||
|
||||
@@ -30,6 +30,8 @@ $ 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).
|
||||
|
||||
**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)
|
||||
@@ -56,7 +58,7 @@ $ yarn build
|
||||
|
||||
Gulp will [output](./Gulpfile.js) the resulting JS files in `./build/`.
|
||||
|
||||
For more details, see the `scripts` in `package.json`.
|
||||
For details, see the `scripts` in `package.json`.
|
||||
|
||||
## Running Tests
|
||||
|
||||
@@ -64,12 +66,12 @@ For more details, see the `scripts` in `package.json`.
|
||||
2. `cd` into the repository and install dependencies with `yarn install`
|
||||
3. `yarn test`
|
||||
|
||||
Also, run `yarn lint` to lint the code with `tslint`.
|
||||
|
||||
## Generating Documentation
|
||||
|
||||
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`.
|
||||
|
||||
`npm` may be used instead of `yarn` in the commands above.
|
||||
|
||||
## More Information
|
||||
|
||||
+ [Ripple Developer Center](https://ripple.com/build/)
|
||||
|
||||
378
docs/index.md
378
docs/index.md
@@ -38,6 +38,9 @@
|
||||
- [request](#request)
|
||||
- [hasNextPage](#hasnextpage)
|
||||
- [requestNextPage](#requestnextpage)
|
||||
- [Static Methods](#static-methods)
|
||||
- [renameCounterpartyToIssuer](#renamecounterpartytoissuer)
|
||||
- [formatBidsAndAsks](#formatbidsandasks)
|
||||
- [API Methods](#api-methods)
|
||||
- [connect](#connect)
|
||||
- [disconnect](#disconnect)
|
||||
@@ -290,7 +293,7 @@ Type | Description
|
||||
[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 unreedemed Check, removing it from the ledger without sending any money.
|
||||
[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.
|
||||
@@ -336,7 +339,7 @@ maxLedgerVersionOffset | integer | *Optional* Offset from current validated ledg
|
||||
sequence | [sequence](#account-sequence-number) | *Optional* The initiating account's sequence number for this transaction.
|
||||
signersCount | integer | *Optional* Number of signers that will be signing this transaction.
|
||||
|
||||
We recommend 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 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.
|
||||
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
|
||||
|
||||
@@ -950,6 +953,326 @@ return api.request(command, params).then(response => {
|
||||
}).catch(console.error);
|
||||
```
|
||||
|
||||
|
||||
# Static Methods
|
||||
|
||||
## 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' }
|
||||
```
|
||||
|
||||
## 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:
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
bids | array | The buy orders in the order book.
|
||||
bids[] | object | An order in the order book.
|
||||
*bids[].* specification | [order](#order) | An order specification that would create an order equivalent to the current state of this order.
|
||||
*bids[].* properties | object | Properties of the order not in the specification.
|
||||
*bids[].properties.* maker | [address](#address) | The address of the account that submitted the order.
|
||||
*bids[].properties.* sequence | [sequence](#account-sequence-number) | The account sequence number of the transaction that created this order.
|
||||
*bids[].properties.* makerExchangeRate | [value](#value) | The exchange rate from the point of view of the account that submitted the order (also known as "quality").
|
||||
*bids[].data.* \* | object |
|
||||
*bids[].* state | object | *Optional* The state of the order.
|
||||
*bids[].state.* fundedAmount | [amount](#amount) | How much of the amount the maker would have to pay that the maker currently holds.
|
||||
*bids[].state.* priceOfFundedAmount | [amount](#amount) | How much the `fundedAmount` would convert to through the exchange rate of this order.
|
||||
asks | array | The sell orders in the order book.
|
||||
asks[] | object | An order in the order book.
|
||||
*asks[].* specification | [order](#order) | An order specification that would create an order equivalent to the current state of this order.
|
||||
*asks[].* properties | object | Properties of the order not in the specification.
|
||||
*asks[].properties.* maker | [address](#address) | The address of the account that submitted the order.
|
||||
*asks[].properties.* sequence | [sequence](#account-sequence-number) | The account sequence number of the transaction that created this order.
|
||||
*asks[].properties.* makerExchangeRate | [value](#value) | The exchange rate from the point of view of the account that submitted the order (also known as "quality").
|
||||
*asks[].data.* \* | object |
|
||||
*asks[].* state | object | *Optional* The state of the order.
|
||||
*asks[].state.* fundedAmount | [amount](#amount) | How much of the amount the maker would have to pay that the maker currently holds.
|
||||
*asks[].state.* priceOfFundedAmount | [amount](#amount) | How much the `fundedAmount` would convert to through the exchange rate of this order.
|
||||
|
||||
**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 ...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
# API Methods
|
||||
|
||||
## connect
|
||||
@@ -1171,7 +1494,7 @@ sequence | [sequence](#account-sequence-number) | The account sequence number of
|
||||
type | [transactionType](#transaction-types) | The type of the transaction.
|
||||
specification | object | A specification that would produce the same outcome as this transaction. *Exception:* For payment transactions, this omits the `destination.amount` field, to prevent misunderstanding. The structure of the specification depends on the value of the `type` field (see [Transaction Types](#transaction-types) for details). *Note:* This is **not** necessarily the same as the original specification.
|
||||
outcome | object | The outcome of the transaction (what effects it had).
|
||||
*outcome.* result | string | Result code returned by rippled. See [Transaction Results](https://ripple.com/build/transactions/#full-transaction-response-list) for a complete list.
|
||||
*outcome.* result | string | Result code returned by rippled. See [Transaction Results](https://developers.ripple.com/transaction-results.html) for a complete list.
|
||||
*outcome.* fee | [value](#value) | The XRP fee that was charged for the transaction.
|
||||
*outcome.balanceChanges.* \* | array\<[balance](#amount)\> | Key is the XRP Ledger address; value is an array of signed amounts representing changes of balances for that address.
|
||||
*outcome.orderbookChanges.* \* | array | Key is the maker's XRP Ledger address; value is an array of changes
|
||||
@@ -2442,6 +2765,10 @@ return api.getOrders(address).then(orders =>
|
||||
|
||||
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
|
||||
|
||||
Name | Type | Description
|
||||
@@ -2484,9 +2811,7 @@ asks[] | object | An order in the order book.
|
||||
*asks[].state.* fundedAmount | [amount](#amount) | How much of the amount the maker would have to pay that the maker currently holds.
|
||||
*asks[].state.* priceOfFundedAmount | [amount](#amount) | How much the `fundedAmount` would convert to through the exchange rate of this order.
|
||||
|
||||
### Raw order data
|
||||
|
||||
(Requires ripple-lib 0.22.0 or higher.) The response includes a `data` property containing the raw order data. This may include `owner_funds`, `Flags`, and other fields.
|
||||
**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).
|
||||
|
||||
@@ -4062,6 +4387,7 @@ options | object | *Optional* Options affecting what ledger and how much data to
|
||||
*options.* includeAllData | boolean | *Optional* Include full transactions and/or state information if `includeTransactions` and/or `includeState` is set.
|
||||
*options.* includeState | boolean | *Optional* Return an array of hashes for all state data or an array of all state data in this ledger version, depending on whether `includeAllData` is set.
|
||||
*options.* includeTransactions | boolean | *Optional* Return an array of hashes for each transaction or an array of all transactions that were validated in this ledger version, depending on whether `includeAllData` is set.
|
||||
*options.* ledgerHash | string | *Optional* Get ledger data for this historical ledger hash.
|
||||
*options.* ledgerVersion | integer | *Optional* Get ledger data for this historical ledger version.
|
||||
*options.* ledgerVersion | string | *Optional* Get ledger data for this historical ledger version.
|
||||
|
||||
@@ -4149,7 +4475,7 @@ console.log(JSON.stringify(flags, null, 2))
|
||||
|
||||
## prepareTransaction
|
||||
|
||||
`prepareTransaction(address: string, transaction: object, instructions: object): Promise<object>`
|
||||
`prepareTransaction(transaction: object, instructions: object): Promise<object>`
|
||||
|
||||
Prepare a transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
@@ -4258,8 +4584,11 @@ const payment = {
|
||||
}
|
||||
}
|
||||
};
|
||||
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 ... */
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
@@ -5156,8 +5485,13 @@ This method returns an object with the following structure:
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
resultCode | string | The result code returned by rippled. [List of transaction responses](https://ripple.com/build/transactions/#full-transaction-response-list)
|
||||
resultMessage | string | Human-readable explanation of the status of the transaction.
|
||||
resultCode | string | Deprecated: Use `engine_result` instead.
|
||||
resultMessage | string | Deprecated: Use `engine_result_message` instead.
|
||||
engine_result | string | Code indicating the preliminary result of the transaction, for example `tesSUCCESS`. [List of transaction responses](https://developers.ripple.com/transaction-results.html)
|
||||
engine_result_code | integer | Numeric code indicating the preliminary result of the transaction, directly correlated to `engine_result`
|
||||
engine_result_message | string | Human-readable explanation of the transaction's preliminary result.
|
||||
tx_blob | string | The complete transaction in hex string format.
|
||||
tx_json | [tx-json](https://developers.ripple.com/transaction-formats.html) | The complete transaction in JSON format.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -5171,7 +5505,27 @@ return api.submit(signedTransaction)
|
||||
```json
|
||||
{
|
||||
"resultCode": "tesSUCCESS",
|
||||
"resultMessage": "The transaction was applied. Only final in a validated ledger."
|
||||
"resultMessage": "The transaction was applied. Only final in a validated ledger.",
|
||||
"engine_result": "tesSUCCESS",
|
||||
"engine_result_code": 0,
|
||||
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
|
||||
"tx_blob": "1200002280000000240000016861D4838D7EA4C6800000000000000000000000000055534400000000004B4E9C06F24296074F7BC48F92A97916C6DC5EA9684000000000002710732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7446304402200E5C2DD81FDF0BE9AB2A8D797885ED49E804DBF28E806604D878756410CA98B102203349581946B0DDA06B36B35DBC20EDA27552C1F167BCF5C6ECFF49C6A46F858081144B4E9C06F24296074F7BC48F92A97916C6DC5EA983143E9D4A2B8AA0780F682D136F7A56D6724EF53754",
|
||||
"tx_json": {
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Amount": {
|
||||
"currency": "USD",
|
||||
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"value": "1"
|
||||
},
|
||||
"Destination": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
|
||||
"Fee": "10000",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 360,
|
||||
"SigningPubKey": "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "304402200E5C2DD81FDF0BE9AB2A8D797885ED49E804DBF28E806604D878756410CA98B102203349581946B0DDA06B36B35DBC20EDA27552C1F167BCF5C6ECFF49C6A46F8580",
|
||||
"hash": "4D5D90890F8D49519E4151938601EF3D0B30B16CD6A519D9C99102C9FA77F7E0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
254
docs/src/formatBidsAndAsks.md.ejs
Normal file
254
docs/src/formatBidsAndAsks.md.ejs
Normal 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 ...
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -4,6 +4,10 @@
|
||||
|
||||
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,9 +18,7 @@ This method returns a promise that resolves with an object with the following st
|
||||
|
||||
<%- renderSchema('output/get-orderbook.json') %>
|
||||
|
||||
### Raw order data
|
||||
|
||||
(Requires ripple-lib 0.22.0 or higher.) The response includes a `data` property containing the raw order data. This may include `owner_funds`, `Flags`, and other fields.
|
||||
**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).
|
||||
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
<% 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 %>
|
||||
|
||||
@@ -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") %>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## prepareTransaction
|
||||
|
||||
`prepareTransaction(address: string, transaction: object, instructions: object): Promise<object>`
|
||||
`prepareTransaction(transaction: object, instructions: object): Promise<object>`
|
||||
|
||||
Prepare a transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
|
||||
37
docs/src/renameCounterpartyToIssuer.md.ejs
Normal file
37
docs/src/renameCounterpartyToIssuer.md.ejs
Normal 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' }
|
||||
```
|
||||
1
docs/src/staticMethods.md.ejs
Normal file
1
docs/src/staticMethods.md.ejs
Normal file
@@ -0,0 +1 @@
|
||||
# Static Methods
|
||||
@@ -15,7 +15,7 @@ Type | Description
|
||||
[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 unreedemed Check, removing it from the ledger without sending any money.
|
||||
[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.
|
||||
@@ -53,7 +53,7 @@ Transaction instructions indicate how to execute a transaction, complementary wi
|
||||
|
||||
<%- renderSchema("objects/instructions.json") %>
|
||||
|
||||
We recommend 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 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.
|
||||
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
|
||||
|
||||
|
||||
14
package.json
14
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.1",
|
||||
"license": "ISC",
|
||||
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
|
||||
"files": [
|
||||
@@ -23,8 +23,8 @@
|
||||
"jsonschema": "1.2.2",
|
||||
"lodash": "^4.17.4",
|
||||
"ripple-address-codec": "^2.0.1",
|
||||
"ripple-binary-codec": "0.2.0",
|
||||
"ripple-hashes": "^0.3.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"
|
||||
@@ -32,19 +32,16 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "^8.0.53",
|
||||
"assert-diff": "^1.0.1",
|
||||
"coveralls": "^2.13.1",
|
||||
"doctoc": "^0.15.0",
|
||||
"ejs": "^2.3.4",
|
||||
"eventemitter2": "^0.4.14",
|
||||
"gulp": "^3.8.10",
|
||||
"gulp-bump": "^0.1.13",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"http-server": "^0.8.5",
|
||||
"jayson": "^1.2.2",
|
||||
"json-loader": "^0.5.2",
|
||||
"json-schema-to-markdown-table": "^0.4.0",
|
||||
"mocha": "^2.1.0",
|
||||
"mocha-in-sauce": "^0.0.1",
|
||||
"mocha": "6.0.2",
|
||||
"mocha-junit-reporter": "^1.9.1",
|
||||
"null-loader": "^0.1.1",
|
||||
"nyc": "^11.3.0",
|
||||
@@ -66,8 +63,7 @@
|
||||
"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",
|
||||
"coveralls": "cat ./coverage/lcov.info | coveralls",
|
||||
"test": "nyc mocha --exit",
|
||||
"lint": "tslint -p ./",
|
||||
"perf": "./scripts/perf_test.sh",
|
||||
"start": "node scripts/http.js",
|
||||
|
||||
@@ -16,7 +16,7 @@ unittest() {
|
||||
# test "src"
|
||||
mocha test --reporter mocha-junit-reporter --reporter-options mochaFile=$CIRCLE_TEST_REPORTS/test-results.xml
|
||||
yarn test --coverage
|
||||
yarn run coveralls
|
||||
#yarn run coveralls
|
||||
|
||||
# test compiled version in "dist/npm"
|
||||
$(npm bin)/babel -D --optional runtime --ignore "**/node_modules/**" -d test-compiled/ test/
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
|
||||
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(),
|
||||
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: 'safari', platform: 'OS X 10.10',
|
||||
version: '8'});
|
||||
sauce.browser({browserName: 'safari', platform: 'OS X 10.9',
|
||||
version: '7'});
|
||||
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();
|
||||
14
src/api.ts
14
src/api.ts
@@ -22,7 +22,8 @@ import getBalances from './ledger/balances'
|
||||
import getBalanceSheet from './ledger/balance-sheet'
|
||||
import getPaths from './ledger/pathfind'
|
||||
import getOrders from './ledger/orders'
|
||||
import getOrderbook from './ledger/orderbook'
|
||||
import {getOrderbook,
|
||||
formatBidsAndAsks} from './ledger/orderbook'
|
||||
import {getSettings, parseAccountFlags} from './ledger/settings'
|
||||
import getAccountInfo from './ledger/accountinfo'
|
||||
import getAccountObjects from './ledger/accountobjects'
|
||||
@@ -69,8 +70,8 @@ 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} from './ledger/utils'
|
||||
import {Instructions, Prepare} from './transaction/types'
|
||||
import {clamp, renameCounterpartyToIssuer} from './ledger/utils'
|
||||
import {TransactionJSON, Instructions, Prepare} from './transaction/types'
|
||||
|
||||
export type APIOptions = {
|
||||
server?: string,
|
||||
@@ -114,6 +115,9 @@ class RippleAPI extends EventEmitter {
|
||||
schemaValidator
|
||||
}
|
||||
|
||||
static renameCounterpartyToIssuer = renameCounterpartyToIssuer
|
||||
static formatBidsAndAsks = formatBidsAndAsks
|
||||
|
||||
constructor(options: APIOptions = {}) {
|
||||
super()
|
||||
validate.apiOptions(options)
|
||||
@@ -206,7 +210,7 @@ class RippleAPI extends EventEmitter {
|
||||
*
|
||||
* You can later submit the transaction with `submit()`.
|
||||
*/
|
||||
async prepareTransaction(txJSON: object, instructions: Instructions = {}):
|
||||
async prepareTransaction(txJSON: TransactionJSON, instructions: Instructions = {}):
|
||||
Promise<Prepare> {
|
||||
return transactionUtils.prepareTransaction(txJSON, this, instructions)
|
||||
}
|
||||
@@ -295,8 +299,8 @@ class RippleAPI extends EventEmitter {
|
||||
getBalances = getBalances
|
||||
getBalanceSheet = getBalanceSheet
|
||||
getPaths = getPaths
|
||||
getOrders = getOrders
|
||||
getOrderbook = getOrderbook
|
||||
getOrders = getOrders
|
||||
getSettings = getSettings
|
||||
getAccountInfo = getAccountInfo
|
||||
getAccountObjects = getAccountObjects
|
||||
|
||||
@@ -268,7 +268,7 @@ class Connection extends EventEmitter {
|
||||
options.agent = new HttpsProxyAgent(proxyOptions)
|
||||
}
|
||||
if (this._authorization !== undefined) {
|
||||
const base64 = new Buffer(this._authorization).toString('base64')
|
||||
const base64 = Buffer.from(this._authorization).toString('base64')
|
||||
options.headers = {Authorization: `Basic ${base64}`}
|
||||
}
|
||||
const optionsOverrides = _.omitBy({
|
||||
@@ -445,7 +445,7 @@ class Connection extends EventEmitter {
|
||||
|
||||
this.once(eventName, response => {
|
||||
if (response.status === 'error') {
|
||||
_reject(new RippledError(response.error, response))
|
||||
_reject(new RippledError(response.error_message || response.error, response))
|
||||
} else if (response.status === 'success') {
|
||||
_resolve(response.result)
|
||||
} else {
|
||||
|
||||
@@ -1,16 +1,51 @@
|
||||
|
||||
import {txFlagIndices} from './txflags'
|
||||
|
||||
// Ordering from https://developers.ripple.com/accountroot.html
|
||||
const accountRootFlags = {
|
||||
PasswordSpent: 0x00010000, // password set fee is spent
|
||||
RequireDestTag: 0x00020000, // require a DestinationTag for payments
|
||||
RequireAuth: 0x00040000, // require authorization to hold IOUs
|
||||
DepositAuth: 0x01000000, // require account to auth deposits
|
||||
DisallowXRP: 0x00080000, // disallow sending XRP
|
||||
DisableMaster: 0x00100000, // force regular key
|
||||
NoFreeze: 0x00200000, // permanently disallowed freezing trustlines
|
||||
GlobalFreeze: 0x00400000, // trustlines globally frozen
|
||||
DefaultRipple: 0x00800000
|
||||
|
||||
// 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 = {
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
"options": {
|
||||
"description": "Options affecting what ledger and how much data to return.",
|
||||
"properties": {
|
||||
"ledgerHash": {
|
||||
"type": "string",
|
||||
"description": "Get ledger data for this historical ledger hash."
|
||||
},
|
||||
"ledgerVersion": {
|
||||
"$ref": "ledgerVersion",
|
||||
"description": "Get ledger data for this historical ledger version."
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "tx",
|
||||
"link": "https://ripple.com/build/transactions/",
|
||||
"title": "tx-json",
|
||||
"link": "https://developers.ripple.com/transaction-formats.html",
|
||||
"description": "An object in rippled txJSON format",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Account": {"$ref": "address"}
|
||||
"Account": {"$ref": "address"},
|
||||
"TransactionType": {"type": "string"}
|
||||
},
|
||||
"required": ["Account"]
|
||||
"required": ["Account", "TransactionType"]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"properties": {
|
||||
"result": {
|
||||
"type": "string",
|
||||
"description": "Result code returned by rippled. See [Transaction Results](https://ripple.com/build/transactions/#full-transaction-response-list) for a complete list."
|
||||
"description": "Result code returned by rippled. See [Transaction Results](https://developers.ripple.com/transaction-results.html) for a complete list."
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
|
||||
@@ -5,13 +5,33 @@
|
||||
"properties": {
|
||||
"resultCode": {
|
||||
"type": "string",
|
||||
"description": "The result code returned by rippled. [List of transaction responses](https://ripple.com/build/transactions/#full-transaction-response-list)"
|
||||
"description": "Deprecated: Use `engine_result` instead."
|
||||
},
|
||||
"resultMessage": {
|
||||
"type": "string",
|
||||
"description": "Human-readable explanation of the status of the transaction."
|
||||
"description": "Deprecated: Use `engine_result_message` instead."
|
||||
},
|
||||
"engine_result": {
|
||||
"type": "string",
|
||||
"description": "Code indicating the preliminary result of the transaction, for example `tesSUCCESS`. [List of transaction responses](https://developers.ripple.com/transaction-results.html)"
|
||||
},
|
||||
"engine_result_code": {
|
||||
"type": "integer",
|
||||
"description": "Numeric code indicating the preliminary result of the transaction, directly correlated to `engine_result`"
|
||||
},
|
||||
"engine_result_message": {
|
||||
"type": "string",
|
||||
"description": "Human-readable explanation of the transaction's preliminary result."
|
||||
},
|
||||
"tx_blob": {
|
||||
"type": "string",
|
||||
"description": "The complete transaction in hex string format."
|
||||
},
|
||||
"tx_json": {
|
||||
"$ref": "tx-json",
|
||||
"description": "The complete transaction in JSON format."
|
||||
}
|
||||
},
|
||||
"required": ["resultCode", "resultMessage"],
|
||||
"required": ["resultCode", "resultMessage", "engine_result", "engine_result_code", "engine_result_message", "tx_blob", "tx_json"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
|
||||
@@ -18,5 +18,6 @@ export interface Ledger {
|
||||
hash?: string,
|
||||
close_flags?: number,
|
||||
parent_close_time?: number,
|
||||
accountState?: any[]
|
||||
accountState?: any[],
|
||||
validated?: boolean
|
||||
}
|
||||
|
||||
@@ -125,7 +125,6 @@ function removeUndefined<T extends object>(obj: T): T {
|
||||
/**
|
||||
* @param {Number} rpepoch (seconds since 1/1/2000 GMT)
|
||||
* @return {Number} ms since unix epoch
|
||||
*
|
||||
*/
|
||||
function rippleToUnixTimestamp(rpepoch: number): number {
|
||||
return (rpepoch + 0x386D4380) * 1000
|
||||
|
||||
@@ -124,3 +124,6 @@ _.partial(schemaValidate, 'api-options')
|
||||
|
||||
export const instructions =
|
||||
_.partial(schemaValidate, 'instructions')
|
||||
|
||||
export const tx_json =
|
||||
_.partial(schemaValidate, 'tx-json')
|
||||
|
||||
@@ -3,6 +3,7 @@ import {FormattedLedger, parseLedger} from './parse/ledger'
|
||||
import {RippleAPI} from '../api'
|
||||
|
||||
export type GetLedgerOptions = {
|
||||
ledgerHash?: string,
|
||||
ledgerVersion?: number,
|
||||
includeAllData?: boolean,
|
||||
includeTransactions?: boolean,
|
||||
@@ -16,6 +17,7 @@ async function getLedger(
|
||||
validate.getLedger({options})
|
||||
// 2. Make Request
|
||||
const response = await this.request('ledger', {
|
||||
ledger_hash: options.ledgerHash,
|
||||
ledger_index: options.ledgerVersion || 'validated',
|
||||
expand: options.includeAllData,
|
||||
transactions: options.includeTransactions,
|
||||
|
||||
@@ -8,6 +8,7 @@ import {validate} from '../common'
|
||||
import {Amount, Issue} from '../common/types/objects'
|
||||
import {BookOffer} from '../common/types/commands'
|
||||
import {RippleAPI} from '../api'
|
||||
import BigNumber from 'bignumber.js'
|
||||
|
||||
export type FormattedOrderbook = {
|
||||
bids: FormattedOrderbookOrder[],
|
||||
@@ -38,7 +39,7 @@ function alignOrder(base: Amount, order: FormattedOrderbookOrder) {
|
||||
return isSameIssue(quantity, base) ? order : flipOrder(order)
|
||||
}
|
||||
|
||||
function formatBidsAndAsks(
|
||||
export function formatBidsAndAsks(
|
||||
orderbook: OrderbookInfo, offers: BookOffer[]) {
|
||||
// the "base" currency is the currency that you are buying or selling
|
||||
// the "counter" is the currency that the "base" is priced in
|
||||
@@ -50,7 +51,10 @@ function formatBidsAndAsks(
|
||||
// for asks: lowest quality => lowest totalPrice/quantity => lowest price
|
||||
// for both bids and asks, lowest quality is closest to mid-market
|
||||
// we sort the orders so that earlier orders are closer to mid-market
|
||||
const orders = _.sortBy(offers, 'quality').map(parseOrderbookOrder)
|
||||
const orders = offers.sort((a, b) => {
|
||||
return (new BigNumber(a.quality)).comparedTo(b.quality)
|
||||
}).map(parseOrderbookOrder)
|
||||
|
||||
const alignedOrders = orders.map(_.partial(alignOrder, orderbook.base))
|
||||
const bids = alignedOrders.filter(_.partial(directionFilter, 'buy'))
|
||||
const asks = alignedOrders.filter(_.partial(directionFilter, 'sell'))
|
||||
@@ -87,7 +91,7 @@ export type OrderbookInfo = {
|
||||
counter: Issue
|
||||
}
|
||||
|
||||
export default async function getOrderbook(
|
||||
export async function getOrderbook(
|
||||
this: RippleAPI,
|
||||
address: string,
|
||||
orderbook: OrderbookInfo,
|
||||
@@ -105,5 +109,6 @@ export default async function getOrderbook(
|
||||
directOfferResult => directOfferResult.offers)
|
||||
const reverseOffers = _.flatMap(reverseOfferResults,
|
||||
reverseOfferResult => reverseOfferResult.offers)
|
||||
return formatBidsAndAsks(orderbook, [...directOffers, ...reverseOffers])
|
||||
return formatBidsAndAsks(orderbook,
|
||||
[...directOffers, ...reverseOffers])
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ const AccountFields = constants.AccountFields
|
||||
|
||||
function parseField(info, value) {
|
||||
if (info.encoding === 'hex' && !info.length) { // e.g. "domain"
|
||||
return new Buffer(value, 'hex').toString('ascii')
|
||||
return Buffer.from(value, 'hex').toString('ascii')
|
||||
}
|
||||
if (info.shift) {
|
||||
return (new BigNumber(value)).shift(-info.shift).toNumber()
|
||||
|
||||
@@ -59,6 +59,11 @@ function parseState(state) {
|
||||
return {rawState: JSON.stringify(state)}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Ledger} ledger must be a *closed* ledger with valid `close_time` and `parent_close_time`
|
||||
* @returns {FormattedLedger} formatted ledger
|
||||
* @throws RangeError: Invalid time value (rippleTimeToISO8601)
|
||||
*/
|
||||
export function parseLedger(ledger: Ledger): FormattedLedger {
|
||||
const ledgerVersion = parseInt(ledger.ledger_index || ledger.seqNum, 10)
|
||||
return removeUndefined(Object.assign(
|
||||
|
||||
@@ -4,6 +4,7 @@ import {PayChannelLedgerEntry} from '../../common/types/objects'
|
||||
|
||||
export type FormattedPaymentChannel = {
|
||||
account: string,
|
||||
amount: string,
|
||||
balance: string,
|
||||
publicKey: string,
|
||||
destination: string,
|
||||
|
||||
@@ -122,7 +122,7 @@ function parseOutcome(tx: any): any|undefined {
|
||||
}
|
||||
|
||||
function hexToString(hex: string): string|undefined {
|
||||
return hex ? new Buffer(hex, 'hex').toString('utf-8') : undefined
|
||||
return hex ? Buffer.from(hex, 'hex').toString('utf-8') : undefined
|
||||
}
|
||||
|
||||
function parseMemos(tx: any): Array<Memo>|undefined {
|
||||
|
||||
@@ -46,9 +46,7 @@ function requestPathFind(connection: Connection, pathfind: PathFind
|
||||
&& !request.destination_amount.issuer) {
|
||||
// Convert blank issuer to sender's address
|
||||
// (Ripple convention for 'any issuer')
|
||||
// https://ripple.com/build/transactions/
|
||||
// #special-issuer-values-for-sendmax-and-amount
|
||||
// https://ripple.com/build/ripple-rest/#counterparties-in-payments
|
||||
// https://developers.ripple.com/payment.html#special-issuer-values-for-sendmax-and-amount
|
||||
request.destination_amount.issuer = request.destination_account
|
||||
}
|
||||
if (pathfind.source.currencies && pathfind.source.currencies.length > 0) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import parseTransaction from './parse/transaction'
|
||||
import {validate, errors} from '../common'
|
||||
import {Connection} from '../common'
|
||||
import {FormattedTransactionType} from '../transaction/types'
|
||||
import {RippledError} from '../common/errors'
|
||||
|
||||
export type TransactionOptions = {
|
||||
minLedgerVersion?: number,
|
||||
@@ -59,10 +60,16 @@ function isTransactionInRange(tx: any, options: TransactionOptions) {
|
||||
}
|
||||
|
||||
function convertError(connection: Connection, options: TransactionOptions,
|
||||
error: Error
|
||||
error: RippledError
|
||||
): Promise<Error> {
|
||||
const _error = (error.message === 'txnNotFound') ?
|
||||
new errors.NotFoundError('Transaction not found') : error
|
||||
let shouldUseNotFoundError = false
|
||||
if ((error.data && error.data.error === 'txnNotFound') || error.message === 'txnNotFound') {
|
||||
shouldUseNotFoundError = true
|
||||
}
|
||||
|
||||
// In the future, we should deprecate this error, instead passing through the one from rippled.
|
||||
const _error = shouldUseNotFoundError ? new errors.NotFoundError('Transaction not found') : error
|
||||
|
||||
if (_error instanceof errors.NotFoundError) {
|
||||
return utils.hasCompleteLedgerRange(connection, options.minLedgerVersion,
|
||||
options.maxLedgerVersion).then(hasCompleteLedgerRange => {
|
||||
|
||||
@@ -76,7 +76,7 @@ function signum(num) {
|
||||
* Order two rippled transactions based on their ledger_index.
|
||||
* If two transactions took place in the same ledger, sort
|
||||
* them based on TransactionIndex
|
||||
* See: https://ripple.com/build/transactions/
|
||||
* See: https://developers.ripple.com/transaction-metadata.html
|
||||
*/
|
||||
function compareTransactions(
|
||||
first: FormattedTransactionType, second: FormattedTransactionType
|
||||
|
||||
@@ -4,4 +4,3 @@ export {
|
||||
deriveKeypair,
|
||||
deriveAddress
|
||||
}
|
||||
|
||||
|
||||
@@ -2,17 +2,18 @@ import keypairs = require('ripple-keypairs')
|
||||
import * as common from '../common'
|
||||
const {errors, validate} = common
|
||||
|
||||
function generateAddress(options?: object): object {
|
||||
const secret = keypairs.generateSeed(options)
|
||||
const keypair = keypairs.deriveKeypair(secret)
|
||||
const address = keypairs.deriveAddress(keypair.publicKey)
|
||||
return {secret, address}
|
||||
export type GeneratedAddress = {
|
||||
secret: string,
|
||||
address: string
|
||||
}
|
||||
|
||||
function generateAddressAPI(options?: object): object {
|
||||
function generateAddressAPI(options?: any): GeneratedAddress {
|
||||
validate.generateAddress({options})
|
||||
try {
|
||||
return generateAddress(options)
|
||||
const secret = keypairs.generateSeed(options)
|
||||
const keypair = keypairs.deriveKeypair(secret)
|
||||
const address = keypairs.deriveAddress(keypair.publicKey)
|
||||
return {secret, address}
|
||||
} catch (error) {
|
||||
throw new errors.UnexpectedError(error.message)
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import * as utils from './utils'
|
||||
import {TransactionJSON, prepareTransaction} from './utils'
|
||||
import {validate} from '../common'
|
||||
import {Instructions, Prepare} from './types'
|
||||
|
||||
export type CheckCancel = {
|
||||
export type CheckCancelParameters = {
|
||||
checkID: string
|
||||
}
|
||||
|
||||
function createCheckCancelTransaction(account: string,
|
||||
cancel: CheckCancel
|
||||
): object {
|
||||
cancel: CheckCancelParameters
|
||||
): TransactionJSON {
|
||||
const txJSON = {
|
||||
Account: account,
|
||||
TransactionType: 'CheckCancel',
|
||||
@@ -19,14 +19,18 @@ function createCheckCancelTransaction(account: string,
|
||||
}
|
||||
|
||||
function prepareCheckCancel(address: string,
|
||||
checkCancel: CheckCancel,
|
||||
checkCancel: CheckCancelParameters,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareCheckCancel(
|
||||
{address, checkCancel, instructions})
|
||||
const txJSON = createCheckCancelTransaction(
|
||||
address, checkCancel)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareCheckCancel(
|
||||
{address, checkCancel, instructions})
|
||||
const txJSON = createCheckCancelTransaction(
|
||||
address, checkCancel)
|
||||
return prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareCheckCancel
|
||||
|
||||
@@ -2,18 +2,18 @@ import * as utils from './utils'
|
||||
const ValidationError = utils.common.errors.ValidationError
|
||||
const toRippledAmount = utils.common.toRippledAmount
|
||||
import {validate} from '../common'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare, TransactionJSON} from './types'
|
||||
import {Amount} from '../common/types/objects'
|
||||
|
||||
export type CheckCash = {
|
||||
export type CheckCashParameters = {
|
||||
checkID: string,
|
||||
amount?: Amount,
|
||||
deliverMin?: Amount
|
||||
}
|
||||
|
||||
function createCheckCashTransaction(account: string,
|
||||
checkCash: CheckCash
|
||||
): object {
|
||||
checkCash: CheckCashParameters
|
||||
): TransactionJSON {
|
||||
if (checkCash.amount && checkCash.deliverMin) {
|
||||
throw new ValidationError('"amount" and "deliverMin" properties on '
|
||||
+ 'CheckCash are mutually exclusive')
|
||||
@@ -37,14 +37,18 @@ function createCheckCashTransaction(account: string,
|
||||
}
|
||||
|
||||
function prepareCheckCash(address: string,
|
||||
checkCash: CheckCash,
|
||||
checkCash: CheckCashParameters,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareCheckCash(
|
||||
{address, checkCash, instructions})
|
||||
const txJSON = createCheckCashTransaction(
|
||||
address, checkCash)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareCheckCash(
|
||||
{address, checkCash, instructions})
|
||||
const txJSON = createCheckCashTransaction(
|
||||
address, checkCash)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareCheckCash
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as utils from './utils'
|
||||
const toRippledAmount = utils.common.toRippledAmount
|
||||
import {validate, iso8601ToRippleTime} from '../common'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare, TransactionJSON} from './types'
|
||||
import {Amount} from '../common/types/objects'
|
||||
|
||||
export type CheckCreate = {
|
||||
export type CheckCreateParameters = {
|
||||
destination: string,
|
||||
sendMax: Amount,
|
||||
destinationTag?: number,
|
||||
@@ -13,8 +13,8 @@ export type CheckCreate = {
|
||||
}
|
||||
|
||||
function createCheckCreateTransaction(account: string,
|
||||
check: CheckCreate
|
||||
): object {
|
||||
check: CheckCreateParameters
|
||||
): TransactionJSON {
|
||||
const txJSON: any = {
|
||||
Account: account,
|
||||
TransactionType: 'CheckCreate',
|
||||
@@ -38,14 +38,18 @@ function createCheckCreateTransaction(account: string,
|
||||
}
|
||||
|
||||
function prepareCheckCreate(address: string,
|
||||
checkCreate: CheckCreate,
|
||||
checkCreate: CheckCreateParameters,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareCheckCreate(
|
||||
{address, checkCreate, instructions})
|
||||
const txJSON = createCheckCreateTransaction(
|
||||
address, checkCreate)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareCheckCreate(
|
||||
{address, checkCreate, instructions})
|
||||
const txJSON = createCheckCreateTransaction(
|
||||
address, checkCreate)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareCheckCreate
|
||||
|
||||
@@ -7,7 +7,7 @@ import {validate} from '../common'
|
||||
import {computeBinaryTransactionHash} from 'ripple-hashes'
|
||||
|
||||
function addressToBigNumber(address) {
|
||||
const hex = (new Buffer(decodeAddress(address))).toString('hex')
|
||||
const hex = (Buffer.from(decodeAddress(address))).toString('hex')
|
||||
return new BigNumber(hex, 16)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
const validate = utils.common.validate
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare, TransactionJSON} from './types'
|
||||
import {Memo} from '../common/types/objects'
|
||||
|
||||
export type EscrowCancellation = {
|
||||
owner: string,
|
||||
escrowSequence: number,
|
||||
|
||||
// TODO: This ripple-lib memo format should be deprecated in favor of rippled's format.
|
||||
// If necessary, expose a public method for converting between the two formats.
|
||||
memos?: Array<Memo>
|
||||
}
|
||||
|
||||
function createEscrowCancellationTransaction(account: string,
|
||||
payment: EscrowCancellation
|
||||
): object {
|
||||
): TransactionJSON {
|
||||
const txJSON: any = {
|
||||
TransactionType: 'EscrowCancel',
|
||||
Account: account,
|
||||
@@ -20,7 +22,7 @@ function createEscrowCancellationTransaction(account: string,
|
||||
OfferSequence: payment.escrowSequence
|
||||
}
|
||||
if (payment.memos !== undefined) {
|
||||
txJSON.Memos = _.map(payment.memos, utils.convertMemo)
|
||||
txJSON.Memos = payment.memos.map(utils.convertMemo)
|
||||
}
|
||||
return txJSON
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
import {validate, iso8601ToRippleTime, xrpToDrops} from '../common'
|
||||
const ValidationError = utils.common.errors.ValidationError
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare, TransactionJSON} from './types'
|
||||
import {Memo} from '../common/types/objects'
|
||||
|
||||
export type EscrowCreation = {
|
||||
@@ -18,7 +17,7 @@ export type EscrowCreation = {
|
||||
|
||||
function createEscrowCreationTransaction(account: string,
|
||||
payment: EscrowCreation
|
||||
): object {
|
||||
): TransactionJSON {
|
||||
const txJSON: any = {
|
||||
TransactionType: 'EscrowCreate',
|
||||
Account: account,
|
||||
@@ -42,7 +41,7 @@ function createEscrowCreationTransaction(account: string,
|
||||
txJSON.DestinationTag = payment.destinationTag
|
||||
}
|
||||
if (payment.memos !== undefined) {
|
||||
txJSON.Memos = _.map(payment.memos, utils.convertMemo)
|
||||
txJSON.Memos = payment.memos.map(utils.convertMemo)
|
||||
}
|
||||
if (Boolean(payment.allowCancelAfter) && Boolean(payment.allowExecuteAfter) &&
|
||||
txJSON.CancelAfter <= txJSON.FinishAfter) {
|
||||
@@ -56,11 +55,15 @@ function prepareEscrowCreation(address: string,
|
||||
escrowCreation: EscrowCreation,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareEscrowCreation(
|
||||
{address, escrowCreation, instructions})
|
||||
const txJSON = createEscrowCreationTransaction(
|
||||
address, escrowCreation)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareEscrowCreation(
|
||||
{address, escrowCreation, instructions})
|
||||
const txJSON = createEscrowCreationTransaction(
|
||||
address, escrowCreation)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareEscrowCreation
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
const validate = utils.common.validate
|
||||
const ValidationError = utils.common.errors.ValidationError
|
||||
@@ -15,7 +14,7 @@ export type EscrowExecution = {
|
||||
|
||||
function createEscrowExecutionTransaction(account: string,
|
||||
payment: EscrowExecution
|
||||
): object {
|
||||
): utils.TransactionJSON {
|
||||
const txJSON: any = {
|
||||
TransactionType: 'EscrowFinish',
|
||||
Account: account,
|
||||
@@ -35,7 +34,7 @@ function createEscrowExecutionTransaction(account: string,
|
||||
txJSON.Fulfillment = payment.fulfillment
|
||||
}
|
||||
if (payment.memos !== undefined) {
|
||||
txJSON.Memos = _.map(payment.memos, utils.convertMemo)
|
||||
txJSON.Memos = payment.memos.map(utils.convertMemo)
|
||||
}
|
||||
return txJSON
|
||||
}
|
||||
@@ -44,11 +43,15 @@ function prepareEscrowExecution(address: string,
|
||||
escrowExecution: EscrowExecution,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareEscrowExecution(
|
||||
{address, escrowExecution, instructions})
|
||||
const txJSON = createEscrowExecutionTransaction(
|
||||
address, escrowExecution)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareEscrowExecution(
|
||||
{address, escrowExecution, instructions})
|
||||
const txJSON = createEscrowExecutionTransaction(
|
||||
address, escrowExecution)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareEscrowExecution
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
const offerFlags = utils.common.txFlags.OfferCreate
|
||||
import {validate, iso8601ToRippleTime} from '../common'
|
||||
@@ -39,7 +38,7 @@ function createOrderTransaction(
|
||||
txJSON.OfferSequence = order.orderToReplace
|
||||
}
|
||||
if (order.memos !== undefined) {
|
||||
txJSON.Memos = _.map(order.memos, utils.convertMemo)
|
||||
txJSON.Memos = order.memos.map(utils.convertMemo)
|
||||
}
|
||||
return txJSON as OfferCreateTransaction
|
||||
}
|
||||
@@ -47,9 +46,13 @@ function createOrderTransaction(
|
||||
function prepareOrder(address: string, order: FormattedOrderSpecification,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareOrder({address, order, instructions})
|
||||
const txJSON = createOrderTransaction(address, order)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareOrder({address, order, instructions})
|
||||
const txJSON = createOrderTransaction(address, order)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareOrder
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
const validate = utils.common.validate
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare, TransactionJSON} from './types'
|
||||
|
||||
function createOrderCancellationTransaction(account: string,
|
||||
orderCancellation: any
|
||||
): object {
|
||||
): TransactionJSON {
|
||||
const txJSON: any = {
|
||||
TransactionType: 'OfferCancel',
|
||||
Account: account,
|
||||
OfferSequence: orderCancellation.orderSequence
|
||||
}
|
||||
if (orderCancellation.memos !== undefined) {
|
||||
txJSON.Memos = _.map(orderCancellation.memos, utils.convertMemo)
|
||||
txJSON.Memos = orderCancellation.memos.map(utils.convertMemo)
|
||||
}
|
||||
return txJSON
|
||||
}
|
||||
@@ -20,9 +19,13 @@ function createOrderCancellationTransaction(account: string,
|
||||
function prepareOrderCancellation(address: string, orderCancellation: object,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareOrderCancellation({address, orderCancellation, instructions})
|
||||
const txJSON = createOrderCancellationTransaction(address, orderCancellation)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareOrderCancellation({address, orderCancellation, instructions})
|
||||
const txJSON = createOrderCancellationTransaction(address, orderCancellation)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareOrderCancellation
|
||||
|
||||
@@ -16,8 +16,8 @@ export type PaymentChannelClaim = {
|
||||
|
||||
function createPaymentChannelClaimTransaction(account: string,
|
||||
claim: PaymentChannelClaim
|
||||
): object {
|
||||
const txJSON: any = {
|
||||
): utils.TransactionJSON {
|
||||
const txJSON: utils.TransactionJSON = {
|
||||
Account: account,
|
||||
TransactionType: 'PaymentChannelClaim',
|
||||
Channel: claim.channel,
|
||||
@@ -62,11 +62,15 @@ function preparePaymentChannelClaim(address: string,
|
||||
paymentChannelClaim: PaymentChannelClaim,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.preparePaymentChannelClaim(
|
||||
{address, paymentChannelClaim, instructions})
|
||||
const txJSON = createPaymentChannelClaimTransaction(
|
||||
address, paymentChannelClaim)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.preparePaymentChannelClaim(
|
||||
{address, paymentChannelClaim, instructions})
|
||||
const txJSON = createPaymentChannelClaimTransaction(
|
||||
address, paymentChannelClaim)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default preparePaymentChannelClaim
|
||||
|
||||
@@ -14,7 +14,7 @@ export type PaymentChannelCreate = {
|
||||
|
||||
function createPaymentChannelCreateTransaction(account: string,
|
||||
paymentChannel: PaymentChannelCreate
|
||||
): object {
|
||||
): utils.TransactionJSON {
|
||||
const txJSON: any = {
|
||||
Account: account,
|
||||
TransactionType: 'PaymentChannelCreate',
|
||||
@@ -41,11 +41,15 @@ function preparePaymentChannelCreate(address: string,
|
||||
paymentChannelCreate: PaymentChannelCreate,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.preparePaymentChannelCreate(
|
||||
{address, paymentChannelCreate, instructions})
|
||||
const txJSON = createPaymentChannelCreateTransaction(
|
||||
address, paymentChannelCreate)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.preparePaymentChannelCreate(
|
||||
{address, paymentChannelCreate, instructions})
|
||||
const txJSON = createPaymentChannelCreateTransaction(
|
||||
address, paymentChannelCreate)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default preparePaymentChannelCreate
|
||||
|
||||
@@ -10,8 +10,8 @@ export type PaymentChannelFund = {
|
||||
|
||||
function createPaymentChannelFundTransaction(account: string,
|
||||
fund: PaymentChannelFund
|
||||
): object {
|
||||
const txJSON: any = {
|
||||
): utils.TransactionJSON {
|
||||
const txJSON: utils.TransactionJSON = {
|
||||
Account: account,
|
||||
TransactionType: 'PaymentChannelFund',
|
||||
Channel: fund.channel,
|
||||
@@ -29,11 +29,15 @@ function preparePaymentChannelFund(address: string,
|
||||
paymentChannelFund: PaymentChannelFund,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.preparePaymentChannelFund(
|
||||
{address, paymentChannelFund, instructions})
|
||||
const txJSON = createPaymentChannelFundTransaction(
|
||||
address, paymentChannelFund)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.preparePaymentChannelFund(
|
||||
{address, paymentChannelFund, instructions})
|
||||
const txJSON = createPaymentChannelFundTransaction(
|
||||
address, paymentChannelFund)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default preparePaymentChannelFund
|
||||
|
||||
@@ -4,7 +4,7 @@ const validate = utils.common.validate
|
||||
const toRippledAmount = utils.common.toRippledAmount
|
||||
const paymentFlags = utils.common.txFlags.Payment
|
||||
const ValidationError = utils.common.errors.ValidationError
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare, TransactionJSON} from './types'
|
||||
import {Amount, Adjustment, MaxAdjustment,
|
||||
MinAdjustment, Memo} from '../common/types/objects'
|
||||
import {xrpToDrops} from '../common'
|
||||
@@ -59,9 +59,7 @@ function isIOUWithoutCounterparty(amount: Amount): boolean {
|
||||
function applyAnyCounterpartyEncoding(payment: Payment): void {
|
||||
// Convert blank counterparty to sender or receiver's address
|
||||
// (Ripple convention for 'any counterparty')
|
||||
// https://ripple.com/build/transactions/
|
||||
// #special-issuer-values-for-sendmax-and-amount
|
||||
// https://ripple.com/build/ripple-rest/#counterparties-in-payments
|
||||
// https://developers.ripple.com/payment.html#special-issuer-values-for-sendmax-and-amount
|
||||
_.forEach([payment.source, payment.destination], adjustment => {
|
||||
_.forEach(['amount', 'minAmount', 'maxAmount'], key => {
|
||||
if (isIOUWithoutCounterparty(adjustment[key])) {
|
||||
@@ -86,7 +84,7 @@ function createMaximalAmount(amount: Amount): Amount {
|
||||
}
|
||||
|
||||
function createPaymentTransaction(address: string, paymentArgument: Payment
|
||||
): object {
|
||||
): TransactionJSON {
|
||||
const payment = _.cloneDeep(paymentArgument)
|
||||
applyAnyCounterpartyEncoding(payment)
|
||||
|
||||
@@ -172,9 +170,13 @@ function createPaymentTransaction(address: string, paymentArgument: Payment
|
||||
function preparePayment(address: string, payment: Payment,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.preparePayment({address, payment, instructions})
|
||||
const txJSON = createPaymentTransaction(address, payment)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.preparePayment({address, payment, instructions})
|
||||
const txJSON = createPaymentTransaction(address, payment)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default preparePayment
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
import * as _ from 'lodash'
|
||||
import * as assert from 'assert'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import * as utils from './utils'
|
||||
const validate = utils.common.validate
|
||||
const AccountFlagIndices = utils.common.constants.AccountFlagIndices
|
||||
const AccountFields = utils.common.constants.AccountFields
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare, SettingsTransaction} from './types'
|
||||
import {FormattedSettings, WeightedSigner} from '../common/types/objects'
|
||||
|
||||
// Emptry string passed to setting will clear it
|
||||
const CLEAR_SETTING = null
|
||||
|
||||
function setTransactionFlags(txJSON: any, values: FormattedSettings) {
|
||||
function setTransactionFlags(txJSON: utils.TransactionJSON, values: FormattedSettings) {
|
||||
const keys = Object.keys(values)
|
||||
assert(keys.length === 1, 'ERROR: can only set one setting per transaction')
|
||||
const flagName = keys[0]
|
||||
@@ -26,7 +22,8 @@ function setTransactionFlags(txJSON: any, values: FormattedSettings) {
|
||||
}
|
||||
}
|
||||
|
||||
function setTransactionFields(txJSON: object, input: FormattedSettings) {
|
||||
// Sets `null` fields to their `default`.
|
||||
function setTransactionFields(txJSON: utils.TransactionJSON, input: FormattedSettings) {
|
||||
const fieldSchema = AccountFields
|
||||
for (const fieldName in fieldSchema) {
|
||||
const field = fieldSchema[fieldName]
|
||||
@@ -37,13 +34,13 @@ function setTransactionFields(txJSON: object, input: FormattedSettings) {
|
||||
}
|
||||
|
||||
// The value required to clear an account root field varies
|
||||
if (value === CLEAR_SETTING && field.hasOwnProperty('defaults')) {
|
||||
if (value === null && field.hasOwnProperty('defaults')) {
|
||||
value = field.defaults
|
||||
}
|
||||
|
||||
if (field.encoding === 'hex' && !field.length) {
|
||||
// This is currently only used for Domain field
|
||||
value = new Buffer(value, 'ascii').toString('hex').toUpperCase()
|
||||
value = Buffer.from(value, 'ascii').toString('hex').toUpperCase()
|
||||
}
|
||||
|
||||
txJSON[fieldName] = value
|
||||
@@ -63,7 +60,7 @@ function setTransactionFields(txJSON: object, input: FormattedSettings) {
|
||||
* are returned
|
||||
*/
|
||||
|
||||
function convertTransferRate(transferRate: number | string): number | string {
|
||||
function convertTransferRate(transferRate: number): number {
|
||||
return (new BigNumber(transferRate)).shift(9).toNumber()
|
||||
}
|
||||
|
||||
@@ -78,7 +75,7 @@ function formatSignerEntry(signer: WeightedSigner): object {
|
||||
|
||||
function createSettingsTransactionWithoutMemos(
|
||||
account: string, settings: FormattedSettings
|
||||
): any {
|
||||
): SettingsTransaction {
|
||||
if (settings.regularKey !== undefined) {
|
||||
const removeRegularKey = {
|
||||
TransactionType: 'SetRegularKey',
|
||||
@@ -87,7 +84,7 @@ function createSettingsTransactionWithoutMemos(
|
||||
if (settings.regularKey === null) {
|
||||
return removeRegularKey
|
||||
}
|
||||
return _.assign({}, removeRegularKey, {RegularKey: settings.regularKey})
|
||||
return Object.assign({}, removeRegularKey, {RegularKey: settings.regularKey})
|
||||
}
|
||||
|
||||
if (settings.signers !== undefined) {
|
||||
@@ -95,17 +92,19 @@ function createSettingsTransactionWithoutMemos(
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: account,
|
||||
SignerQuorum: settings.signers.threshold,
|
||||
SignerEntries: _.map(settings.signers.weights, formatSignerEntry)
|
||||
SignerEntries: settings.signers.weights.map(formatSignerEntry)
|
||||
}
|
||||
}
|
||||
|
||||
const txJSON: any = {
|
||||
const txJSON: SettingsTransaction = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: account
|
||||
}
|
||||
|
||||
setTransactionFlags(txJSON, _.omit(settings, 'memos'))
|
||||
setTransactionFields(txJSON, settings)
|
||||
const settingsWithoutMemos = Object.assign({}, settings)
|
||||
delete settingsWithoutMemos.memos
|
||||
setTransactionFlags(txJSON, settingsWithoutMemos)
|
||||
setTransactionFields(txJSON, settings) // Sets `null` fields to their `default`.
|
||||
|
||||
if (txJSON.TransferRate !== undefined) {
|
||||
txJSON.TransferRate = convertTransferRate(txJSON.TransferRate)
|
||||
@@ -114,10 +113,10 @@ function createSettingsTransactionWithoutMemos(
|
||||
}
|
||||
|
||||
function createSettingsTransaction(account: string, settings: FormattedSettings
|
||||
): object {
|
||||
): SettingsTransaction {
|
||||
const txJSON = createSettingsTransactionWithoutMemos(account, settings)
|
||||
if (settings.memos !== undefined) {
|
||||
txJSON.Memos = _.map(settings.memos, utils.convertMemo)
|
||||
txJSON.Memos = settings.memos.map(utils.convertMemo)
|
||||
}
|
||||
return txJSON
|
||||
}
|
||||
@@ -125,9 +124,13 @@ function createSettingsTransaction(account: string, settings: FormattedSettings
|
||||
function prepareSettings(address: string, settings: FormattedSettings,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareSettings({address, settings, instructions})
|
||||
const txJSON = createSettingsTransaction(address, settings)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareSettings({address, settings, instructions})
|
||||
const txJSON = createSettingsTransaction(address, settings)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareSettings
|
||||
|
||||
@@ -20,8 +20,15 @@ function isImmediateRejection(engineResult: string): boolean {
|
||||
|
||||
function formatSubmitResponse(response): FormattedSubmitResponse {
|
||||
const data = {
|
||||
// @deprecated
|
||||
resultCode: response.engine_result,
|
||||
resultMessage: response.engine_result_message
|
||||
// @deprecated
|
||||
resultMessage: response.engine_result_message,
|
||||
engine_result: response.engine_result,
|
||||
engine_result_code: response.engine_result_code,
|
||||
engine_result_message: response.engine_result_message,
|
||||
tx_blob: response.tx_blob,
|
||||
tx_json: response.tx_json
|
||||
}
|
||||
if (isImmediateRejection(response.engine_result)) {
|
||||
throw new utils.common.errors.RippledError('Submit failed', data)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import * as _ from 'lodash'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import * as utils from './utils'
|
||||
const validate = utils.common.validate
|
||||
const trustlineFlags = utils.common.txFlags.TrustSet
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare, TransactionJSON} from './types'
|
||||
import {
|
||||
FormattedTrustlineSpecification
|
||||
} from '../common/types/objects/trustlines'
|
||||
@@ -14,7 +13,7 @@ function convertQuality(quality) {
|
||||
|
||||
function createTrustlineTransaction(account: string,
|
||||
trustline: FormattedTrustlineSpecification
|
||||
): object {
|
||||
): TransactionJSON {
|
||||
const limit = {
|
||||
currency: trustline.currency,
|
||||
issuer: trustline.counterparty,
|
||||
@@ -45,7 +44,7 @@ function createTrustlineTransaction(account: string,
|
||||
trustlineFlags.SetFreeze : trustlineFlags.ClearFreeze
|
||||
}
|
||||
if (trustline.memos !== undefined) {
|
||||
txJSON.Memos = _.map(trustline.memos, utils.convertMemo)
|
||||
txJSON.Memos = trustline.memos.map(utils.convertMemo)
|
||||
}
|
||||
return txJSON
|
||||
}
|
||||
@@ -53,9 +52,13 @@ function createTrustlineTransaction(account: string,
|
||||
function prepareTrustline(address: string,
|
||||
trustline: FormattedTrustlineSpecification, instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareTrustline({address, trustline, instructions})
|
||||
const txJSON = createTrustlineTransaction(address, trustline)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareTrustline({address, trustline, instructions})
|
||||
const txJSON = createTrustlineTransaction(address, trustline)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareTrustline
|
||||
|
||||
@@ -7,7 +7,12 @@ import {
|
||||
Memo,
|
||||
FormattedSettings
|
||||
} from '../common/types/objects'
|
||||
import {ApiMemo} from './utils'
|
||||
import {
|
||||
ApiMemo,
|
||||
TransactionJSON
|
||||
} from './utils'
|
||||
|
||||
export type TransactionJSON = TransactionJSON
|
||||
|
||||
export type Instructions = {
|
||||
sequence?: number,
|
||||
@@ -37,7 +42,7 @@ export type Submit = {
|
||||
txJson?: object
|
||||
}
|
||||
|
||||
export interface OfferCreateTransaction {
|
||||
export interface OfferCreateTransaction extends TransactionJSON {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: string,
|
||||
Fee: string,
|
||||
@@ -48,7 +53,11 @@ export interface OfferCreateTransaction {
|
||||
TakerPays: RippledAmount,
|
||||
Expiration?: number,
|
||||
OfferSequence?: number,
|
||||
Memos: {Memo: ApiMemo}[]
|
||||
Memos?: {Memo: ApiMemo}[]
|
||||
}
|
||||
|
||||
export interface SettingsTransaction extends TransactionJSON {
|
||||
TransferRate?: number
|
||||
}
|
||||
|
||||
export type KeyPair = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import BigNumber from 'bignumber.js'
|
||||
import * as common from '../common'
|
||||
import {Memo} from '../common/types/objects'
|
||||
import {Memo, RippledAmount} from '../common/types/objects'
|
||||
const txFlags = common.txFlags
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {RippleAPI} from '../api'
|
||||
@@ -12,6 +12,15 @@ export type ApiMemo = {
|
||||
MemoFormat?: string
|
||||
}
|
||||
|
||||
export type TransactionJSON = {
|
||||
Account: string,
|
||||
TransactionType: string,
|
||||
Memos?: {Memo: ApiMemo}[],
|
||||
Flags?: number,
|
||||
Fulfillment?: string,
|
||||
[Field: string]: string | number | Array<any> | RippledAmount
|
||||
}
|
||||
|
||||
function formatPrepareResponse(txJSON: any): Prepare {
|
||||
const instructions = {
|
||||
fee: common.dropsToXrp(txJSON.Fee),
|
||||
@@ -37,10 +46,11 @@ function scaleValue(value, multiplier, extra = 0) {
|
||||
return (new BigNumber(value)).times(multiplier).plus(extra).toString()
|
||||
}
|
||||
|
||||
function prepareTransaction(txJSON: any, api: RippleAPI,
|
||||
function prepareTransaction(txJSON: TransactionJSON, api: RippleAPI,
|
||||
instructions: Instructions
|
||||
): Promise<Prepare> {
|
||||
common.validate.instructions(instructions)
|
||||
common.validate.tx_json(txJSON)
|
||||
|
||||
const account = txJSON.Account
|
||||
setCanonicalFlag(txJSON)
|
||||
@@ -81,7 +91,7 @@ function prepareTransaction(txJSON: any, api: RippleAPI,
|
||||
(txJSON.TransactionType !== 'EscrowFinish' ||
|
||||
txJSON.Fulfillment === undefined) ? 0 :
|
||||
(cushion * feeRef * (32 + Math.floor(
|
||||
new Buffer(txJSON.Fulfillment, 'hex').length / 16)))
|
||||
Buffer.from(txJSON.Fulfillment, 'hex').length / 16)))
|
||||
const feeDrops = common.xrpToDrops(fee)
|
||||
const maxFeeXRP = instructions.maxFee ?
|
||||
BigNumber.min(api._maxFeeXRP, instructions.maxFee) : api._maxFeeXRP
|
||||
@@ -96,14 +106,28 @@ function prepareTransaction(txJSON: any, api: RippleAPI,
|
||||
|
||||
async function prepareSequence(): Promise<object> {
|
||||
if (instructions.sequence !== undefined) {
|
||||
txJSON.Sequence = instructions.sequence
|
||||
if (txJSON.Sequence === undefined || instructions.sequence === txJSON.Sequence) {
|
||||
txJSON.Sequence = instructions.sequence
|
||||
return Promise.resolve(txJSON)
|
||||
} else {
|
||||
// Both txJSON.Sequence and instructions.sequence are defined, and they are NOT equal
|
||||
return Promise.reject(new ValidationError('`Sequence` in txJSON must match `sequence` in Instructions'))
|
||||
}
|
||||
}
|
||||
if (txJSON.Sequence !== undefined) {
|
||||
return Promise.resolve(txJSON)
|
||||
}
|
||||
const response = await api.request('account_info', {
|
||||
account: account as string
|
||||
})
|
||||
txJSON.Sequence = response.account_data.Sequence
|
||||
return txJSON
|
||||
|
||||
try {
|
||||
// Consider requesting from the 'current' ledger (instead of 'validated').
|
||||
const response = await api.request('account_info', {
|
||||
account
|
||||
})
|
||||
txJSON.Sequence = response.account_data.Sequence
|
||||
return Promise.resolve(txJSON)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.all([
|
||||
@@ -114,7 +138,7 @@ function prepareTransaction(txJSON: any, api: RippleAPI,
|
||||
}
|
||||
|
||||
function convertStringToHex(string: string): string {
|
||||
return new Buffer(string, 'utf8').toString('hex').toUpperCase()
|
||||
return Buffer.from(string, 'utf8').toString('hex').toUpperCase()
|
||||
}
|
||||
|
||||
function convertMemo(memo: Memo): {Memo: ApiMemo} {
|
||||
|
||||
1163
test/api-test.js
1163
test/api-test.js
File diff suppressed because it is too large
Load Diff
@@ -396,7 +396,8 @@ describe('Connection', function() {
|
||||
it('propagates RippledError data', function(done) {
|
||||
this.api.request('subscribe', {streams: 'validations'}).catch(error => {
|
||||
assert.strictEqual(error.name, 'RippledError')
|
||||
assert.strictEqual(error.message, 'invalidParams')
|
||||
assert.strictEqual(error.data.error, 'invalidParams')
|
||||
assert.strictEqual(error.message, 'Invalid parameters.')
|
||||
assert.strictEqual(error.data.error_code, 31)
|
||||
assert.strictEqual(error.data.error_message, 'Invalid parameters.')
|
||||
assert.deepEqual(error.data.request, { command: 'subscribe', id: 0, streams: 'validations' })
|
||||
|
||||
12
test/fixtures/responses/get-ledger-by-hash.json
vendored
Normal file
12
test/fixtures/responses/get-ledger-by-hash.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"stateHash": "A155BFE86054BE654796EC449E7C374CD5CAA3789BA75D302E7F0F4CE470CCB3",
|
||||
"closeTime": "2018-12-07T11:10:30.000Z",
|
||||
"closeTimeResolution": 10,
|
||||
"closeFlags": 0,
|
||||
"ledgerHash": "15F20E5FA6EA9770BBFFDBD62787400960B04BE32803B20C41F117F41C13830D",
|
||||
"ledgerVersion": 14995338,
|
||||
"parentLedgerHash": "E0BC4F5FB8D9025087BE238664833DFA5658C9E7CE413B3B6F7DF4FFF1EDBF40",
|
||||
"parentCloseTime": "2018-12-07T11:10:22.000Z",
|
||||
"totalDrops": "99997114637345372",
|
||||
"transactionHash": "52C0B6604D2EF203710FEA24F4A3750A4F2BCD5C67D6EB5FB1B2DBAE9A14DCE8"
|
||||
}
|
||||
1
test/fixtures/responses/index.js
vendored
1
test/fixtures/responses/index.js
vendored
@@ -83,6 +83,7 @@ module.exports = {
|
||||
},
|
||||
getLedger: {
|
||||
header: require('./get-ledger'),
|
||||
headerByHash: require('./get-ledger-by-hash'),
|
||||
full: require('./get-ledger-full'),
|
||||
withSettingsTx: require('./get-ledger-with-settings-tx'),
|
||||
withStateAsHashes: require('./get-ledger-with-state-as-hashes'),
|
||||
|
||||
22
test/fixtures/responses/submit.json
vendored
22
test/fixtures/responses/submit.json
vendored
@@ -1,4 +1,24 @@
|
||||
{
|
||||
"resultCode": "tesSUCCESS",
|
||||
"resultMessage": "The transaction was applied. Only final in a validated ledger."
|
||||
"resultMessage": "The transaction was applied. Only final in a validated ledger.",
|
||||
"engine_result": "tesSUCCESS",
|
||||
"engine_result_code": 0,
|
||||
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
|
||||
"tx_blob": "1200002280000000240000016861D4838D7EA4C6800000000000000000000000000055534400000000004B4E9C06F24296074F7BC48F92A97916C6DC5EA9684000000000002710732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7446304402200E5C2DD81FDF0BE9AB2A8D797885ED49E804DBF28E806604D878756410CA98B102203349581946B0DDA06B36B35DBC20EDA27552C1F167BCF5C6ECFF49C6A46F858081144B4E9C06F24296074F7BC48F92A97916C6DC5EA983143E9D4A2B8AA0780F682D136F7A56D6724EF53754",
|
||||
"tx_json": {
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Amount": {
|
||||
"currency": "USD",
|
||||
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"value": "1"
|
||||
},
|
||||
"Destination": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
|
||||
"Fee": "10000",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 360,
|
||||
"SigningPubKey": "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "304402200E5C2DD81FDF0BE9AB2A8D797885ED49E804DBF28E806604D878756410CA98B102203349581946B0DDA06B36B35DBC20EDA27552C1F167BCF5C6ECFF49C6A46F8580",
|
||||
"hash": "4D5D90890F8D49519E4151938601EF3D0B30B16CD6A519D9C99102C9FA77F7E0"
|
||||
}
|
||||
}
|
||||
|
||||
916
test/fixtures/rippled/book-offers.js
vendored
916
test/fixtures/rippled/book-offers.js
vendored
@@ -2,470 +2,11 @@
|
||||
'use strict'
|
||||
const _ = require('lodash')
|
||||
|
||||
module.exports.requestBookOffersBidsResponse = function(request, options = {}) {
|
||||
_.defaults(options, {
|
||||
gets: {
|
||||
currency: 'USD',
|
||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
},
|
||||
pays: {
|
||||
currency: 'BTC',
|
||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
}
|
||||
})
|
||||
|
||||
return JSON.stringify({
|
||||
id: request.id,
|
||||
result: {
|
||||
ledger_index: 10716345,
|
||||
offers: [
|
||||
{
|
||||
Account: 'r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B15A60037FFCF',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'544932DC56D72E845AF2B738821FE07865E32EC196270678AB0D947F54E9F49F',
|
||||
PreviousTxnLgrSeq: 10679000,
|
||||
Sequence: 434,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '3205.1'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '10'
|
||||
},
|
||||
index:
|
||||
'CE457115A4ADCC8CB351B3E35A0851E48DE16605C23E305017A9B697B156DE5A',
|
||||
owner_funds: '41952.95917199965',
|
||||
quality: '0.003120027456241615'
|
||||
},
|
||||
{
|
||||
Account: 'rDYCRhpahKEhCFV25xScg67Bwf4W9sTYAm',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B1A2BC2EC5000',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'F68F9658AB3D462FEB027E6C380F054BC6D2514B43EC3C6AD46EE19C59BF1CC3',
|
||||
PreviousTxnLgrSeq: 10704238,
|
||||
Sequence: 233,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '1599.063669386278'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '4.99707396683212'
|
||||
},
|
||||
index:
|
||||
'BF14FBB305159DBCAEA91B7E848408F5B559A91B160EBCB6D244958A6A16EA6B',
|
||||
owner_funds: '3169.910902910102',
|
||||
quality: '0.003125'
|
||||
},
|
||||
{
|
||||
Account: 'raudnGKfTK23YKfnS7ixejHrqGERTYNFXk',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B2BF1C2F4D4C9',
|
||||
BookNode: '0000000000000000',
|
||||
Expiration: 472785284,
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '00000000000008F0',
|
||||
PreviousTxnID:
|
||||
'446410E1CD718AC01929DD16B558FCF6B3A7B8BF208C420E67A280C089C5C59B',
|
||||
PreviousTxnLgrSeq: 10713576,
|
||||
Sequence: 110104,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '143.1050962074379'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0.4499999999999999'
|
||||
},
|
||||
index:
|
||||
'67924B0EAA15784CC00CCD5FDD655EE2D6D2AE40341776B5F14E52341E7FC73E',
|
||||
owner_funds: '0',
|
||||
quality: '0.003144542101755081',
|
||||
taker_gets_funded: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '0'
|
||||
},
|
||||
taker_pays_funded: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0'
|
||||
}
|
||||
},
|
||||
{
|
||||
Account: 'rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B2CD7A2BFBB75',
|
||||
BookNode: '0000000000000000',
|
||||
Expiration: 472772651,
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '00000000000003CD',
|
||||
PreviousTxnID:
|
||||
'D49164AB68DDA3AEC9DFCC69A35685C4F532B5C231D3C1D25FEA7D5D0224FB84',
|
||||
PreviousTxnLgrSeq: 10711128,
|
||||
Sequence: 35625,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '254.329207354604'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0.8'
|
||||
},
|
||||
index:
|
||||
'567BF2825173E3FB28FC94E436B6EB30D9A415FC2335E6D25CDE1BE47B25D120',
|
||||
owner_funds: '0',
|
||||
quality: '0.003145529403882357',
|
||||
taker_gets_funded: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '0'
|
||||
},
|
||||
taker_pays_funded: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0'
|
||||
}
|
||||
},
|
||||
{
|
||||
Account: 'rwBYyfufTzk77zUSKEu4MvixfarC35av1J',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B3621DF140FDA',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000008',
|
||||
PreviousTxnID:
|
||||
'2E371E2B287C8A9FBB3424E4204B17AD9FA1BAA9F3B33C7D2261E3B038AFF083',
|
||||
PreviousTxnLgrSeq: 10716291,
|
||||
Sequence: 387756,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '390.4979'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '1.23231134568807'
|
||||
},
|
||||
index:
|
||||
'8CA23E55BF9F46AC7E803D3DB40FD03225EFCA66650D4CF0CBDD28A7CCDC8400',
|
||||
owner_funds: '5704.824764087842',
|
||||
quality: '0.003155743848271834'
|
||||
},
|
||||
{
|
||||
Account: 'rwjsRktX1eguUr1pHTffyHnC4uyrvX58V1',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B3A4D41FF4211',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'91763FA7089C63CC4D5D14CBA6A5A5BF7ECE949B0D34F00FD35E733AF9F05AF1',
|
||||
PreviousTxnLgrSeq: 10716292,
|
||||
Sequence: 208927,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '1'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0.003160328237957649'
|
||||
},
|
||||
index:
|
||||
'7206866E39D9843623EE79E570242753DEE3C597F3856AEFB4631DD5AD8B0557',
|
||||
owner_funds: '45.55665106096075',
|
||||
quality: '0.003160328237957649'
|
||||
},
|
||||
{
|
||||
Account: 'r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B4748E68669A7',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'3B3CF6FF1A336335E78513CF77AFD3A784ACDD7B1B4D3F1F16E22957A060BFAE',
|
||||
PreviousTxnLgrSeq: 10639969,
|
||||
Sequence: 429,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '4725'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '15'
|
||||
},
|
||||
index:
|
||||
'42894809370C7E6B23498EF8E22AD4B05F02B94F08E6983357A51EA96A95FF7F',
|
||||
quality: '0.003174603174603175'
|
||||
},
|
||||
{
|
||||
Account: 'rDbsCJr5m8gHDCNEHCZtFxcXHsD4S9jH83',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B58077ED03C1B',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 131072,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000001',
|
||||
PreviousTxnID:
|
||||
'98F3F2D02D3BB0AEAC09EECCF2F24BBE5E1AB2C71C40D7BD0A5199E12541B6E2',
|
||||
PreviousTxnLgrSeq: 10715839,
|
||||
Sequence: 110099,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '1.24252537879871'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '0.003967400879423823'
|
||||
},
|
||||
index:
|
||||
'F4404D6547149419D3607F81D7080979FBB3AFE2661F9A933E2F6C07AC1D1F6D',
|
||||
owner_funds: '73.52163803897041',
|
||||
quality: '0.003193013959408667'
|
||||
},
|
||||
{
|
||||
Account: 'rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B72A555B981A3',
|
||||
BookNode: '0000000000000000',
|
||||
Expiration: 472772652,
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '00000000000003CD',
|
||||
PreviousTxnID:
|
||||
'146C8DBB047BAAFAE5B8C8DECCCDACD9DFCD7A464E5AB273230FF975E9B83CF7',
|
||||
PreviousTxnLgrSeq: 10711128,
|
||||
Sequence: 35627,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '496.5429474010489'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '1.6'
|
||||
},
|
||||
index:
|
||||
'50CAA04E81D0009115B61C132FC9887FA9E5336E0CB8A2E7D3280ADBF6ABC043',
|
||||
quality: '0.003222279177208227',
|
||||
taker_gets_funded: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '0'
|
||||
},
|
||||
taker_pays_funded: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0'
|
||||
}
|
||||
},
|
||||
{
|
||||
Account: 'r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B730474DD96E5',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'624F9ADA85EC3BE845EAC075B47E01E4F89288EAF27823C715777B3DFFB21F24',
|
||||
PreviousTxnLgrSeq: 10639989,
|
||||
Sequence: 431,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '3103'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '10'
|
||||
},
|
||||
index:
|
||||
'8A319A496288228AD9CAD74375E32FA81805C56A9AD84798A26756A8B3F9EE23',
|
||||
quality: '0.003222687721559781'
|
||||
}
|
||||
],
|
||||
validated: false
|
||||
},
|
||||
status: 'success',
|
||||
type: 'response'
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.requestBookOffersBidsPartialFundedResponse = function(
|
||||
request,
|
||||
options = {}
|
||||
) {
|
||||
_.defaults(options, {
|
||||
gets: {
|
||||
currency: 'BTC',
|
||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
},
|
||||
pays: {
|
||||
currency: 'USD',
|
||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
}
|
||||
})
|
||||
|
||||
return JSON.stringify({
|
||||
id: request.id,
|
||||
status: 'success',
|
||||
type: 'response',
|
||||
result: {
|
||||
ledger_current_index: 10714274,
|
||||
offers: [
|
||||
{
|
||||
Account: 'rpUirQxhaFqMp7YHPLMZCWxgZQbaZkp4bM',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B75DA97A99CE7',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'52801D1249261E410632BF6C00F503B1F51B31798C1E7DBD67B976FE65BE4DA4',
|
||||
PreviousTxnLgrSeq: 10630313,
|
||||
Sequence: 132,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '310'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '1'
|
||||
},
|
||||
index:
|
||||
'861D15BECDA5DCA1327CF4D8080C181425F043AC969A992C5FAE5D12813785D0',
|
||||
owner_funds: '259.7268806690133',
|
||||
quality: '0.003225806451612903',
|
||||
taker_gets_funded: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '259.2084637415302'
|
||||
},
|
||||
taker_pays_funded: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0.8361563346500974'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.requestBookOffersAsksPartialFundedResponse = function(
|
||||
request,
|
||||
options = {}
|
||||
) {
|
||||
_.defaults(options, {
|
||||
gets: {
|
||||
currency: 'BTC',
|
||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
},
|
||||
pays: {
|
||||
currency: 'USD',
|
||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
}
|
||||
})
|
||||
|
||||
return JSON.stringify({
|
||||
id: request.id,
|
||||
status: 'success',
|
||||
type: 'response',
|
||||
result: {
|
||||
ledger_current_index: 10714274,
|
||||
offers: [
|
||||
{
|
||||
Account: 'rPyYxUGK8L4dgEvjPs3aRc1B1jEiLr3Hx5',
|
||||
BookDirectory:
|
||||
'6EAB7C172DEFA430DBFAD120FDC373B5F5AF8B191649EC98570BCB85BCA78000',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 131072,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'D22993C68C94ACE3F2FCE4A334EBEA98CC46DCA92886C12B5E5B4780B5E17D4E',
|
||||
PreviousTxnLgrSeq: 10711938,
|
||||
Sequence: 392,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '0.8095'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '268.754'
|
||||
},
|
||||
index:
|
||||
'18B136E08EF50F0DEE8521EA22D16A950CD8B6DDF5F6E07C35F7FDDBBB09718D',
|
||||
owner_funds: '0.8095132334507441',
|
||||
quality: '332',
|
||||
taker_gets_funded: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '0.8078974385735969'
|
||||
},
|
||||
taker_pays_funded: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '268.2219496064341'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.requestBookOffersAsksResponse = function(request, options = {}) {
|
||||
_.defaults(options, {
|
||||
pays: {
|
||||
currency: 'USD',
|
||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
},
|
||||
gets: {
|
||||
currency: 'BTC',
|
||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
}
|
||||
})
|
||||
module.exports.requestBookOffersBidsResponse = function(request) {
|
||||
const options = {
|
||||
gets: request.taker_gets,
|
||||
pays: request.taker_pays
|
||||
}
|
||||
|
||||
return JSON.stringify({
|
||||
id: request.id,
|
||||
@@ -782,6 +323,453 @@ module.exports.requestBookOffersAsksResponse = function(request, options = {}) {
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.requestBookOffersBidsPartialFundedResponse = function(
|
||||
request,
|
||||
options = {}
|
||||
) {
|
||||
_.defaults(options, {
|
||||
gets: {
|
||||
currency: 'BTC',
|
||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
},
|
||||
pays: {
|
||||
currency: 'USD',
|
||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
}
|
||||
})
|
||||
|
||||
return JSON.stringify({
|
||||
id: request.id,
|
||||
status: 'success',
|
||||
type: 'response',
|
||||
result: {
|
||||
ledger_current_index: 10714274,
|
||||
offers: [
|
||||
{
|
||||
Account: 'rpUirQxhaFqMp7YHPLMZCWxgZQbaZkp4bM',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B75DA97A99CE7',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'52801D1249261E410632BF6C00F503B1F51B31798C1E7DBD67B976FE65BE4DA4',
|
||||
PreviousTxnLgrSeq: 10630313,
|
||||
Sequence: 132,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '310'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '1'
|
||||
},
|
||||
index:
|
||||
'861D15BECDA5DCA1327CF4D8080C181425F043AC969A992C5FAE5D12813785D0',
|
||||
owner_funds: '259.7268806690133',
|
||||
quality: '0.003225806451612903',
|
||||
taker_gets_funded: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '259.2084637415302'
|
||||
},
|
||||
taker_pays_funded: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0.8361563346500974'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.requestBookOffersAsksPartialFundedResponse = function(
|
||||
request,
|
||||
options = {}
|
||||
) {
|
||||
_.defaults(options, {
|
||||
gets: {
|
||||
currency: 'BTC',
|
||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
},
|
||||
pays: {
|
||||
currency: 'USD',
|
||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
}
|
||||
})
|
||||
|
||||
return JSON.stringify({
|
||||
id: request.id,
|
||||
status: 'success',
|
||||
type: 'response',
|
||||
result: {
|
||||
ledger_current_index: 10714274,
|
||||
offers: [
|
||||
{
|
||||
Account: 'rPyYxUGK8L4dgEvjPs3aRc1B1jEiLr3Hx5',
|
||||
BookDirectory:
|
||||
'6EAB7C172DEFA430DBFAD120FDC373B5F5AF8B191649EC98570BCB85BCA78000',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 131072,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'D22993C68C94ACE3F2FCE4A334EBEA98CC46DCA92886C12B5E5B4780B5E17D4E',
|
||||
PreviousTxnLgrSeq: 10711938,
|
||||
Sequence: 392,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '0.8095'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '268.754'
|
||||
},
|
||||
index:
|
||||
'18B136E08EF50F0DEE8521EA22D16A950CD8B6DDF5F6E07C35F7FDDBBB09718D',
|
||||
owner_funds: '0.8095132334507441',
|
||||
quality: '332',
|
||||
taker_gets_funded: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '0.8078974385735969'
|
||||
},
|
||||
taker_pays_funded: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '268.2219496064341'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.requestBookOffersAsksResponse = function(request) {
|
||||
const options = {
|
||||
gets: request.taker_gets,
|
||||
pays: request.taker_pays
|
||||
}
|
||||
|
||||
return JSON.stringify({
|
||||
id: request.id,
|
||||
result: {
|
||||
ledger_index: 10716345,
|
||||
offers: [
|
||||
{
|
||||
Account: 'r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B15A60037FFCF',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'544932DC56D72E845AF2B738821FE07865E32EC196270678AB0D947F54E9F49F',
|
||||
PreviousTxnLgrSeq: 10679000,
|
||||
Sequence: 434,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '3205.1'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '10'
|
||||
},
|
||||
index:
|
||||
'CE457115A4ADCC8CB351B3E35A0851E48DE16605C23E305017A9B697B156DE5A',
|
||||
owner_funds: '41952.95917199965',
|
||||
quality: '0.003120027456241615'
|
||||
},
|
||||
{
|
||||
Account: 'rDYCRhpahKEhCFV25xScg67Bwf4W9sTYAm',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B1A2BC2EC5000',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'F68F9658AB3D462FEB027E6C380F054BC6D2514B43EC3C6AD46EE19C59BF1CC3',
|
||||
PreviousTxnLgrSeq: 10704238,
|
||||
Sequence: 233,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '1599.063669386278'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '4.99707396683212'
|
||||
},
|
||||
index:
|
||||
'BF14FBB305159DBCAEA91B7E848408F5B559A91B160EBCB6D244958A6A16EA6B',
|
||||
owner_funds: '3169.910902910102',
|
||||
quality: '0.003125'
|
||||
},
|
||||
{
|
||||
Account: 'raudnGKfTK23YKfnS7ixejHrqGERTYNFXk',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B2BF1C2F4D4C9',
|
||||
BookNode: '0000000000000000',
|
||||
Expiration: 472785284,
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '00000000000008F0',
|
||||
PreviousTxnID:
|
||||
'446410E1CD718AC01929DD16B558FCF6B3A7B8BF208C420E67A280C089C5C59B',
|
||||
PreviousTxnLgrSeq: 10713576,
|
||||
Sequence: 110104,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '143.1050962074379'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0.4499999999999999'
|
||||
},
|
||||
index:
|
||||
'67924B0EAA15784CC00CCD5FDD655EE2D6D2AE40341776B5F14E52341E7FC73E',
|
||||
owner_funds: '0',
|
||||
quality: '0.003144542101755081',
|
||||
taker_gets_funded: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '0'
|
||||
},
|
||||
taker_pays_funded: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0'
|
||||
}
|
||||
},
|
||||
{
|
||||
Account: 'rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B2CD7A2BFBB75',
|
||||
BookNode: '0000000000000000',
|
||||
Expiration: 472772651,
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '00000000000003CD',
|
||||
PreviousTxnID:
|
||||
'D49164AB68DDA3AEC9DFCC69A35685C4F532B5C231D3C1D25FEA7D5D0224FB84',
|
||||
PreviousTxnLgrSeq: 10711128,
|
||||
Sequence: 35625,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '254.329207354604'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0.8'
|
||||
},
|
||||
index:
|
||||
'567BF2825173E3FB28FC94E436B6EB30D9A415FC2335E6D25CDE1BE47B25D120',
|
||||
owner_funds: '0',
|
||||
quality: '0.003145529403882357',
|
||||
taker_gets_funded: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '0'
|
||||
},
|
||||
taker_pays_funded: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0'
|
||||
}
|
||||
},
|
||||
{
|
||||
Account: 'rwBYyfufTzk77zUSKEu4MvixfarC35av1J',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B3621DF140FDA',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000008',
|
||||
PreviousTxnID:
|
||||
'2E371E2B287C8A9FBB3424E4204B17AD9FA1BAA9F3B33C7D2261E3B038AFF083',
|
||||
PreviousTxnLgrSeq: 10716291,
|
||||
Sequence: 387756,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '390.4979'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '1.23231134568807'
|
||||
},
|
||||
index:
|
||||
'8CA23E55BF9F46AC7E803D3DB40FD03225EFCA66650D4CF0CBDD28A7CCDC8400',
|
||||
owner_funds: '5704.824764087842',
|
||||
quality: '0.003155743848271834'
|
||||
},
|
||||
{
|
||||
Account: 'rwjsRktX1eguUr1pHTffyHnC4uyrvX58V1',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B3A4D41FF4211',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'91763FA7089C63CC4D5D14CBA6A5A5BF7ECE949B0D34F00FD35E733AF9F05AF1',
|
||||
PreviousTxnLgrSeq: 10716292,
|
||||
Sequence: 208927,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '1'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0.003160328237957649'
|
||||
},
|
||||
index:
|
||||
'7206866E39D9843623EE79E570242753DEE3C597F3856AEFB4631DD5AD8B0557',
|
||||
owner_funds: '45.55665106096075',
|
||||
quality: '0.003160328237957649'
|
||||
},
|
||||
{
|
||||
Account: 'r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B4748E68669A7',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'3B3CF6FF1A336335E78513CF77AFD3A784ACDD7B1B4D3F1F16E22957A060BFAE',
|
||||
PreviousTxnLgrSeq: 10639969,
|
||||
Sequence: 429,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '4725'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '15'
|
||||
},
|
||||
index:
|
||||
'42894809370C7E6B23498EF8E22AD4B05F02B94F08E6983357A51EA96A95FF7F',
|
||||
quality: '0.003174603174603175'
|
||||
},
|
||||
{
|
||||
Account: 'rDbsCJr5m8gHDCNEHCZtFxcXHsD4S9jH83',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B58077ED03C1B',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 131072,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000001',
|
||||
PreviousTxnID:
|
||||
'98F3F2D02D3BB0AEAC09EECCF2F24BBE5E1AB2C71C40D7BD0A5199E12541B6E2',
|
||||
PreviousTxnLgrSeq: 10715839,
|
||||
Sequence: 110099,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '1.24252537879871'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '0.003967400879423823'
|
||||
},
|
||||
index:
|
||||
'F4404D6547149419D3607F81D7080979FBB3AFE2661F9A933E2F6C07AC1D1F6D',
|
||||
owner_funds: '73.52163803897041',
|
||||
quality: '0.003193013959408667'
|
||||
},
|
||||
{
|
||||
Account: 'rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B72A555B981A3',
|
||||
BookNode: '0000000000000000',
|
||||
Expiration: 472772652,
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '00000000000003CD',
|
||||
PreviousTxnID:
|
||||
'146C8DBB047BAAFAE5B8C8DECCCDACD9DFCD7A464E5AB273230FF975E9B83CF7',
|
||||
PreviousTxnLgrSeq: 10711128,
|
||||
Sequence: 35627,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '496.5429474010489'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '1.6'
|
||||
},
|
||||
index:
|
||||
'50CAA04E81D0009115B61C132FC9887FA9E5336E0CB8A2E7D3280ADBF6ABC043',
|
||||
quality: '0.003222279177208227',
|
||||
taker_gets_funded: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '0'
|
||||
},
|
||||
taker_pays_funded: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '0'
|
||||
}
|
||||
},
|
||||
{
|
||||
Account: 'r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ',
|
||||
BookDirectory:
|
||||
'20294C923E80A51B487EB9547B3835FD483748B170D2D0A4520B730474DD96E5',
|
||||
BookNode: '0000000000000000',
|
||||
Flags: 0,
|
||||
LedgerEntryType: 'Offer',
|
||||
OwnerNode: '0000000000000000',
|
||||
PreviousTxnID:
|
||||
'624F9ADA85EC3BE845EAC075B47E01E4F89288EAF27823C715777B3DFFB21F24',
|
||||
PreviousTxnLgrSeq: 10639989,
|
||||
Sequence: 431,
|
||||
TakerGets: {
|
||||
currency: options.gets.currency,
|
||||
issuer: options.gets.issuer,
|
||||
value: '3103'
|
||||
},
|
||||
TakerPays: {
|
||||
currency: options.pays.currency,
|
||||
issuer: options.pays.issuer,
|
||||
value: '10'
|
||||
},
|
||||
index:
|
||||
'8A319A496288228AD9CAD74375E32FA81805C56A9AD84798A26756A8B3F9EE23',
|
||||
quality: '0.003222687721559781'
|
||||
}
|
||||
],
|
||||
validated: false
|
||||
},
|
||||
status: 'success',
|
||||
type: 'response'
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.requestBookOffersXRPBaseResponse = function(request) {
|
||||
return JSON.stringify({
|
||||
id: request.id,
|
||||
|
||||
1
test/fixtures/rippled/index.js
vendored
1
test/fixtures/rippled/index.js
vendored
@@ -7,6 +7,7 @@ module.exports = {
|
||||
},
|
||||
ledger: {
|
||||
normal: require('./ledger'),
|
||||
normalByHash: require('./ledger-by-hash'),
|
||||
notFound: require('./ledger-not-found'),
|
||||
withoutCloseTime: require('./ledger-without-close-time'),
|
||||
withSettingsTx: require('./ledger-with-settings-tx'),
|
||||
|
||||
28
test/fixtures/rippled/ledger-by-hash.json
vendored
Normal file
28
test/fixtures/rippled/ledger-by-hash.json
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"id":1,
|
||||
"result": {
|
||||
"ledger": {
|
||||
"accepted": true,
|
||||
"account_hash": "A155BFE86054BE654796EC449E7C374CD5CAA3789BA75D302E7F0F4CE470CCB3",
|
||||
"close_flags": 0,
|
||||
"close_time": 597496230,
|
||||
"close_time_human": "2018-Dec-07 11:10:30.000000000",
|
||||
"close_time_resolution": 10,
|
||||
"closed": true,
|
||||
"hash": "15F20E5FA6EA9770BBFFDBD62787400960B04BE32803B20C41F117F41C13830D",
|
||||
"ledger_hash": "15F20E5FA6EA9770BBFFDBD62787400960B04BE32803B20C41F117F41C13830D",
|
||||
"ledger_index": "14995338",
|
||||
"parent_close_time": 597496222,
|
||||
"parent_hash": "E0BC4F5FB8D9025087BE238664833DFA5658C9E7CE413B3B6F7DF4FFF1EDBF40",
|
||||
"seqNum": "14995338",
|
||||
"totalCoins": "99997114637345372",
|
||||
"total_coins": "99997114637345372",
|
||||
"transaction_hash": "52C0B6604D2EF203710FEA24F4A3750A4F2BCD5C67D6EB5FB1B2DBAE9A14DCE8"
|
||||
},
|
||||
"ledger_hash": "15F20E5FA6EA9770BBFFDBD62787400960B04BE32803B20C41F117F41C13830D",
|
||||
"ledger_index": 14995338,
|
||||
"validated": true
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
13
test/fixtures/rippled/requests/1-taker_gets-XRP-taker_pays-JPY.json
vendored
Normal file
13
test/fixtures/rippled/requests/1-taker_gets-XRP-taker_pays-JPY.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"taker_gets": {
|
||||
"currency": "XRP"
|
||||
},
|
||||
"taker_pays": {
|
||||
"currency": "JPY",
|
||||
"issuer": "rB3gZey7VWHYRqJHLoHDEJXJ2pEPNieKiS"
|
||||
},
|
||||
"ledger_index": "validated",
|
||||
"limit": 400,
|
||||
"taker": "rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR",
|
||||
"command": "book_offers"
|
||||
}
|
||||
13
test/fixtures/rippled/requests/2-taker_gets-JPY-taker_pays-XRP.json
vendored
Normal file
13
test/fixtures/rippled/requests/2-taker_gets-JPY-taker_pays-XRP.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"taker_gets": {
|
||||
"currency": "JPY",
|
||||
"issuer": "rB3gZey7VWHYRqJHLoHDEJXJ2pEPNieKiS"
|
||||
},
|
||||
"taker_pays": {
|
||||
"currency": "XRP"
|
||||
},
|
||||
"ledger_index": "validated",
|
||||
"limit": 400,
|
||||
"taker": "rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR",
|
||||
"command": "book_offers"
|
||||
}
|
||||
13
test/fixtures/rippled/requests/3-taker_gets-USD-taker_pays-XRP.json
vendored
Normal file
13
test/fixtures/rippled/requests/3-taker_gets-USD-taker_pays-XRP.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"taker_gets": {
|
||||
"currency": "USD",
|
||||
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
|
||||
},
|
||||
"taker_pays": {
|
||||
"currency": "XRP"
|
||||
},
|
||||
"ledger_index": "validated",
|
||||
"limit": 400,
|
||||
"taker": "rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR",
|
||||
"command": "book_offers"
|
||||
}
|
||||
13
test/fixtures/rippled/requests/4-taker_gets-XRP-taker_pays-USD.json
vendored
Normal file
13
test/fixtures/rippled/requests/4-taker_gets-XRP-taker_pays-USD.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"taker_gets": {
|
||||
"currency": "XRP"
|
||||
},
|
||||
"taker_pays": {
|
||||
"currency": "USD",
|
||||
"issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B"
|
||||
},
|
||||
"ledger_index": "validated",
|
||||
"limit": 400,
|
||||
"taker": "rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR",
|
||||
"command": "book_offers"
|
||||
}
|
||||
3001
test/fixtures/rippled/responses/1-taker_gets-XRP-taker_pays-JPY-res.json
vendored
Normal file
3001
test/fixtures/rippled/responses/1-taker_gets-XRP-taker_pays-JPY-res.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
test/fixtures/rippled/responses/2-taker_gets-JPY-taker_pays-XRP-res.json
vendored
Normal file
6
test/fixtures/rippled/responses/2-taker_gets-JPY-taker_pays-XRP-res.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"ledger_hash": "C4F68C1CF2E0BFC09284690067ED7B1A38D4509A09DF26D66EABCE4F196CE9E9",
|
||||
"ledger_index": 42595629,
|
||||
"offers": [],
|
||||
"validated": true
|
||||
}
|
||||
6024
test/fixtures/rippled/responses/3-taker_gets-USD-taker_pays-XRP-res.json
vendored
Normal file
6024
test/fixtures/rippled/responses/3-taker_gets-USD-taker_pays-XRP-res.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8091
test/fixtures/rippled/responses/4-taker_gets-XRP-taker_pays-USD-res.json
vendored
Normal file
8091
test/fixtures/rippled/responses/4-taker_gets-XRP-taker_pays-USD-res.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
19
test/fixtures/rippled/submit.json
vendored
19
test/fixtures/rippled/submit.json
vendored
@@ -7,7 +7,22 @@
|
||||
"engine_result": "tesSUCCESS",
|
||||
"engine_result_code": 0,
|
||||
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
|
||||
"tx_blob": "12000322000000002400000017201B0086955468400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402207660BDEF67105CE1EBA9AD35DC7156BAB43FF1D47633199EE257D70B6B9AAFBF02207F5517BC8AEF2ADC1325897ECDBA8C673838048BCA62F4E98B252F19BE88796D770A726970706C652E636F6D81144FBFF73DA4ECF9B701940F27341FA8020C313443",
|
||||
"tx_json": {}
|
||||
"tx_blob": "1200002280000000240000016861D4838D7EA4C6800000000000000000000000000055534400000000004B4E9C06F24296074F7BC48F92A97916C6DC5EA9684000000000002710732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7446304402200E5C2DD81FDF0BE9AB2A8D797885ED49E804DBF28E806604D878756410CA98B102203349581946B0DDA06B36B35DBC20EDA27552C1F167BCF5C6ECFF49C6A46F858081144B4E9C06F24296074F7BC48F92A97916C6DC5EA983143E9D4A2B8AA0780F682D136F7A56D6724EF53754",
|
||||
"tx_json": {
|
||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"Amount": {
|
||||
"currency": "USD",
|
||||
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||
"value": "1"
|
||||
},
|
||||
"Destination": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
|
||||
"Fee": "10000",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 360,
|
||||
"SigningPubKey": "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "304402200E5C2DD81FDF0BE9AB2A8D797885ED49E804DBF28E806604D878756410CA98B102203349581946B0DDA06B36B35DBC20EDA27552C1F167BCF5C6ECFF49C6A46F8580",
|
||||
"hash": "4D5D90890F8D49519E4151938601EF3D0B30B16CD6A519D9C99102C9FA77F7E0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ const accountLinesResponse = require('./fixtures/rippled/account-lines');
|
||||
const accountObjectsResponse = require('./fixtures/rippled/account-objects');
|
||||
const fullLedger = require('./fixtures/rippled/ledger-full-38129.json');
|
||||
const { getFreePort } = require('./utils/net-utils');
|
||||
const fs = require('fs');
|
||||
|
||||
function isUSD(json) {
|
||||
return json === 'USD' || json === '0000000000000000000000005553440000000000';
|
||||
@@ -237,11 +238,40 @@ module.exports = function createMockRippled(port) {
|
||||
} else if (request.account === addresses.NOTFOUND) {
|
||||
conn.send(createResponse(request, fixtures.account_info.notfound));
|
||||
} else if (request.account === addresses.THIRD_ACCOUNT) {
|
||||
const response = _.assign({}, fixtures.account_info.normal);
|
||||
const response = Object.assign({}, fixtures.account_info.normal);
|
||||
response.Account = addresses.THIRD_ACCOUNT;
|
||||
conn.send(createResponse(request, response));
|
||||
} else if (request.account === undefined) {
|
||||
const response = Object.assign({}, {
|
||||
error: 'invalidParams',
|
||||
error_code: 31,
|
||||
error_message: 'Missing field \'account\'.',
|
||||
id: 2,
|
||||
request: { command: 'account_info', id: 2 },
|
||||
status: 'error',
|
||||
type: 'response'
|
||||
});
|
||||
conn.send(createResponse(request, response));
|
||||
} else {
|
||||
assert(false, 'Unrecognized account address: ' + request.account);
|
||||
const response = Object.assign({}, {
|
||||
account: request.account,
|
||||
error: 'actNotFound',
|
||||
error_code: 19,
|
||||
error_message: 'Account not found.',
|
||||
id: 2,
|
||||
ledger_current_index: 17714714,
|
||||
request:
|
||||
|
||||
// This will be inaccurate, but that's OK because this is just a mock rippled
|
||||
{ account: 'rogvkYnY8SWjxkJNgU4ZRVfLeRyt5DR9i',
|
||||
command: 'account_info',
|
||||
id: 2 },
|
||||
|
||||
status: 'error',
|
||||
type: 'response',
|
||||
validated: false
|
||||
});
|
||||
conn.send(createResponse(request, response));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -267,6 +297,8 @@ module.exports = function createMockRippled(port) {
|
||||
const response = _.assign({}, fixtures.ledger.normal,
|
||||
{ result: { ledger: fullLedger } });
|
||||
conn.send(createLedgerResponse(request, response));
|
||||
} else if (request.ledger_hash === '15F20E5FA6EA9770BBFFDBD62787400960B04BE32803B20C41F117F41C13830D') {
|
||||
conn.send(createLedgerResponse(request, fixtures.ledger.normalByHash));
|
||||
} else if (request.ledger_index === 'validated' ||
|
||||
request.ledger_index === 14661789 ||
|
||||
request.ledger_index === 14661788 /* getTransaction - order */) {
|
||||
@@ -464,6 +496,8 @@ module.exports = function createMockRippled(port) {
|
||||
}
|
||||
});
|
||||
|
||||
let requestsCache = undefined;
|
||||
|
||||
mock.on('request_book_offers', function (request, conn) {
|
||||
if (request.taker_pays.issuer === 'rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw') {
|
||||
conn.send(createResponse(request, fixtures.book_offers.xrp_usd));
|
||||
@@ -479,6 +513,30 @@ module.exports = function createMockRippled(port) {
|
||||
conn.send(
|
||||
fixtures.book_offers.fabric.requestBookOffersAsksResponse(request));
|
||||
} else {
|
||||
const rippledDir = 'test/fixtures/rippled';
|
||||
if (!requestsCache) {
|
||||
requestsCache = fs.readdirSync(rippledDir + '/requests');
|
||||
}
|
||||
for (var i = 0; i < requestsCache.length; i++) {
|
||||
const file = requestsCache[i];
|
||||
const json = fs.readFileSync(rippledDir + '/requests/' + file, 'utf8');
|
||||
const r = JSON.parse(json);
|
||||
const requestWithoutId = Object.assign({}, request);
|
||||
delete requestWithoutId.id;
|
||||
if (JSON.stringify(requestWithoutId) === JSON.stringify(r)) {
|
||||
const responseFile = rippledDir + '/responses/' + file.split('.')[0] + '-res.json';
|
||||
const res = fs.readFileSync(responseFile, 'utf8');
|
||||
const response = createResponse(request, {
|
||||
"id": 0,
|
||||
"type": "response",
|
||||
"status": "success",
|
||||
"result": JSON.parse(res)
|
||||
});
|
||||
conn.send(response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert(false, 'Unrecognized order book: ' + JSON.stringify(request));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!-- encoding must be set for mocha's special characters to render properly -->
|
||||
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
|
||||
<script src="/test/vendor/lodash.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="deb"></div>
|
||||
<div id="mocha"></div>
|
||||
<script src="/node_modules/mocha/mocha.js"></script>
|
||||
|
||||
<script src="/node_modules/mocha-in-sauce/client.js"></script>
|
||||
|
||||
<script src="/build/ripple-latest-min.js"></script>
|
||||
<script>
|
||||
mocha.ui('bdd')
|
||||
</script>
|
||||
|
||||
<script src="../test-compiled-for-web/api-test.js"></script>
|
||||
|
||||
<script src="../test-compiled-for-web/broadcast-api-test.js"></script>
|
||||
|
||||
<script src="../test-compiled-for-web/connection-test.js"></script>
|
||||
|
||||
<script src="/test-compiled-for-web/rangeset-test.js"></script>
|
||||
|
||||
<script>
|
||||
mochaSaucePlease({xunit: false});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user