mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-04 21:15:47 +00:00
Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7bfe4a6cd8 | ||
|
|
aa467681e4 | ||
|
|
6b8cd6151d | ||
|
|
0d6aaee12a | ||
|
|
dc03c6e0ac | ||
|
|
0f4d957d14 | ||
|
|
71a13224a1 | ||
|
|
8097ed60ba | ||
|
|
408bb74214 | ||
|
|
9433b43873 | ||
|
|
896bf48c79 | ||
|
|
3dd21a7e11 | ||
|
|
ed79a04018 | ||
|
|
ebfe20defb | ||
|
|
28b148348d | ||
|
|
fe099f2c8b | ||
|
|
107c8c9f0f | ||
|
|
39e818b3e5 | ||
|
|
588ffa3d5c | ||
|
|
691e4dd114 | ||
|
|
55bc42725f | ||
|
|
cce55b9361 | ||
|
|
c23c6e4fc9 | ||
|
|
afdd60efe8 | ||
|
|
8f6ea573ff | ||
|
|
3271b544ef | ||
|
|
6e83130754 | ||
|
|
f6ebe32519 | ||
|
|
3caed3c761 | ||
|
|
ce1c55427a | ||
|
|
9cd72595f0 | ||
|
|
ad1d3e135f | ||
|
|
76866ab901 | ||
|
|
20b647dfbf | ||
|
|
99d08065e4 | ||
|
|
261fba3d21 | ||
|
|
e1d9de7b1f | ||
|
|
391b2f3622 | ||
|
|
86ff315ef2 | ||
|
|
8d8a850864 | ||
|
|
7bf2da6014 | ||
|
|
7eae3ce709 | ||
|
|
5f5e48e414 | ||
|
|
4f6a37f7b1 | ||
|
|
82613e7e8b | ||
|
|
588aa382a1 | ||
|
|
809d981987 | ||
|
|
cfc21fde8c | ||
|
|
5c06ef547b | ||
|
|
0990ad4a6f |
59
Gulpfile.js
59
Gulpfile.js
@@ -8,6 +8,7 @@ var rename = require('gulp-rename');
|
||||
var webpack = require('webpack');
|
||||
var bump = require('gulp-bump');
|
||||
var argv = require('yargs').argv;
|
||||
var assert = require('assert');
|
||||
|
||||
var pkg = require('./package.json');
|
||||
|
||||
@@ -21,10 +22,19 @@ function webpackConfig(extension, overrides) {
|
||||
path: './build/',
|
||||
filename: ['ripple-', extension].join(pkg.version)
|
||||
},
|
||||
plugins: [
|
||||
new webpack.NormalModuleReplacementPlugin(/^ws$/, './wswrapper'),
|
||||
new webpack.NormalModuleReplacementPlugin(/^\.\/wallet$/, './wallet-web'),
|
||||
new webpack.NormalModuleReplacementPlugin(/^.*setup-api$/,
|
||||
'./setup-api-web')
|
||||
],
|
||||
module: {
|
||||
loaders: [{
|
||||
test: /jayson/,
|
||||
loader: 'null'
|
||||
}, {
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
exclude: [/node_modules/],
|
||||
loader: 'babel-loader?optional=runtime'
|
||||
}, {
|
||||
test: /\.json/,
|
||||
@@ -35,6 +45,53 @@ function webpackConfig(extension, overrides) {
|
||||
return _.assign({}, defaults, overrides);
|
||||
}
|
||||
|
||||
function webpackConfigForWebTest(testFileName, path) {
|
||||
var match = testFileName.match(/\/?([^\/]*)-test.js$/);
|
||||
if (!match) {
|
||||
assert(false, 'wrong filename:' + testFileName);
|
||||
}
|
||||
var configOverrides = {
|
||||
externals: [{
|
||||
'ripple-api': 'ripple',
|
||||
'net': 'null'
|
||||
}],
|
||||
entry: testFileName,
|
||||
output: {
|
||||
library: match[1].replace(/-/g, '_'),
|
||||
path: './test-compiled-for-web/' + (path ? path : ''),
|
||||
filename: match[1] + '-test.js'
|
||||
}
|
||||
};
|
||||
return webpackConfig('.js', configOverrides);
|
||||
}
|
||||
|
||||
gulp.task('build-for-web-tests', function(callback) {
|
||||
var configOverrides = {
|
||||
output: {
|
||||
library: 'ripple',
|
||||
path: './test-compiled-for-web/',
|
||||
filename: 'ripple-for-web-tests.js'
|
||||
}
|
||||
};
|
||||
var config = webpackConfig('-debug.js', configOverrides);
|
||||
webpack(config, callback);
|
||||
});
|
||||
|
||||
gulp.task('build-tests', function(callback) {
|
||||
var times = 0;
|
||||
function done() {
|
||||
if (++times >= 5) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
webpack(webpackConfigForWebTest('./test/rangeset-test.js'), done);
|
||||
webpack(webpackConfigForWebTest('./test/connection-test.js'), done);
|
||||
webpack(webpackConfigForWebTest('./test/api-test.js'), done);
|
||||
webpack(webpackConfigForWebTest('./test/broadcast-api-test.js'), done);
|
||||
webpack(webpackConfigForWebTest('./test/integration/integration-test.js',
|
||||
'integration/'), done);
|
||||
});
|
||||
|
||||
gulp.task('build', function(callback) {
|
||||
webpack(webpackConfig('.js'), callback);
|
||||
});
|
||||
|
||||
35
HISTORY.md
35
HISTORY.md
@@ -1,3 +1,38 @@
|
||||
##0.16.5
|
||||
**Changes**
|
||||
+ [Filter insufficient source funds paths from pathfind results](https://github.com/ripple/ripple-lib/pull/688)
|
||||
|
||||
##0.16.4
|
||||
**Changes**
|
||||
+ [Update ws to 1.0.1](https://github.com/ripple/ripple-lib/pull/682)
|
||||
|
||||
##0.16.2
|
||||
**Changes**
|
||||
+ [Bump ripple-binary-codec dependency version to 0.1.1 to fix issue with computeLedgerHash for transactions with DeliverMin]
|
||||
|
||||
##0.16.1
|
||||
**Changes**
|
||||
+ [FIX: Use assert not assert-diff](https://github.com/ripple/ripple-lib/commit/f6ebe325193e7208c5ee8d8e84a7504714f0009e)
|
||||
|
||||
##0.16.0
|
||||
**Breaking Changes**
|
||||
+ [Fix types of XRP values in getServerInfo response](https://github.com/ripple/ripple-lib/commit/99d08065e4bda3dda6ae1f183adbd11abc70a9b7)
|
||||
+ [Change error event format and fix crash due to error event on webscocket](https://github.com/ripple/ripple-lib/commit/9cd72595f0efc062d77b9d625695d6030c524cc6)
|
||||
|
||||
**Changes**
|
||||
+ [Fix generateAddress docs and add error event listener to boilerplate](https://github.com/ripple/ripple-lib/commit/809d981987a2890fac3a73a40a05c598b9040334)
|
||||
+ [Allow setting maxLedgerVersion to null to specify no maximum](https://github.com/ripple/ripple-lib/commit/82613e7e8b360d1ae1552eab4559ab4763c06d7e)
|
||||
+ [Add support for client certificates](https://github.com/ripple/ripple-lib/commit/5f5e48e4140345d166b8c1a3ee0847b0d9e2d893)
|
||||
+ [getFee returns a string not float](https://github.com/ripple/ripple-lib/commit/7bf2da6014c87e164542e69356efeaabb575a157)
|
||||
+ [Fix parsing of quality for getTrustlines](https://github.com/ripple/ripple-lib/commit/86ff315ef2a39dfdc2ce97e0e1c4aa73f04e363b)
|
||||
+ [Fix DeliverMin value when specifying minAmount](Fix DeliverMin value when specifying minAmount)
|
||||
+ [http server example](https://github.com/ripple/ripple-lib/commit/76866ab901ea46a2dd73181605e0f7f4220043d4)
|
||||
|
||||
|
||||
##0.15.2
|
||||
**Changes**
|
||||
+ [Fix support for proxy credentials in proxy URL and fix error when there are more than 10 outstanding requests](https://github.com/ripple/ripple-lib/commit/0990ad4a6f1d59ca9d2cb859b4e2d71693f3fc4b)
|
||||
|
||||
##0.15.1
|
||||
**Changes**
|
||||
+ [Fix babel-polyfill require](https://github.com/ripple/ripple-lib/commit/062148674c3b1293ab82c28e25615ddd530339fa)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#ripple-lib
|
||||
|
||||
A JavaScript API for interacting with Ripple in Node.js and the browser
|
||||
A JavaScript API for interacting with Ripple in Node.js
|
||||
|
||||
[](https://circleci.com/gh/ripple/ripple-lib/tree/develop) [](https://coveralls.io/r/ripple/ripple-lib?branch=develop)
|
||||
|
||||
@@ -8,7 +8,7 @@ A JavaScript API for interacting with Ripple in Node.js and the browser
|
||||
|
||||
###Features
|
||||
|
||||
+ Connect to a rippled server in JavaScript (Node.js or browser)
|
||||
+ Connect to a rippled server in Node.js
|
||||
+ Issue [rippled API](https://ripple.com/build/rippled-apis/) requests
|
||||
+ Listen to events on the Ripple network (transaction, ledger, etc.)
|
||||
+ Sign and submit transactions to the Ripple network
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
machine:
|
||||
node:
|
||||
version: 0.12.0
|
||||
dependencies:
|
||||
pre:
|
||||
- wget https://s3-us-west-2.amazonaws.com/ripple-debs/rippled_0.30.1-b11-1.deb
|
||||
- sudo dpkg -i rippled_0.30.1-b11-1.deb
|
||||
test:
|
||||
pre:
|
||||
- rippled -a --start --conf "$HOME/$CIRCLE_PROJECT_REPONAME/test/integration/rippled.cfg":
|
||||
background: true
|
||||
override:
|
||||
- scripts/ci.sh "$CIRCLE_NODE_INDEX" "$CIRCLE_NODE_TOTAL":
|
||||
parallel: true
|
||||
post:
|
||||
- killall /usr/bin/rippled
|
||||
|
||||
155
docs/index.md
155
docs/index.md
@@ -54,6 +54,7 @@
|
||||
- [prepareSuspendedPaymentCancellation](#preparesuspendedpaymentcancellation)
|
||||
- [prepareSuspendedPaymentExecution](#preparesuspendedpaymentexecution)
|
||||
- [sign](#sign)
|
||||
- [combine](#combine)
|
||||
- [submit](#submit)
|
||||
- [generateAddress](#generateaddress)
|
||||
- [computeLedgerHash](#computeledgerhash)
|
||||
@@ -86,6 +87,9 @@ const {RippleAPI} = require('ripple-lib');
|
||||
const api = new RippleAPI({
|
||||
server: 'wss://s1.ripple.com' // Public rippled server hosted by Ripple, Inc.
|
||||
});
|
||||
api.on('error', (errorCode, errorMessage) => {
|
||||
console.log(errorCode + ': ' + errorMessage);
|
||||
});
|
||||
api.connect().then(() => {
|
||||
/* insert code here */
|
||||
}).then(() => {
|
||||
@@ -105,6 +109,10 @@ All the code snippets in this documentation assume that you have surrounded them
|
||||
If you omit the "catch" section, errors may not be visible.
|
||||
</aside>
|
||||
|
||||
<aside class="notice">
|
||||
The "error" event is emitted whenever an error occurs that cannot be associated with a specific request. If the listener is not registered, an exception will be thrown whenever the event is emitted.
|
||||
</aside>
|
||||
|
||||
### Parameters
|
||||
|
||||
The RippleAPI constructor optionally takes one argument, an object with the following options:
|
||||
@@ -112,7 +120,10 @@ The RippleAPI constructor optionally takes one argument, an object with the foll
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
authorization | string | *Optional* Username and password for HTTP basic authentication to the rippled server in the format **username:password**.
|
||||
certificate | string | *Optional* A string containing the certificate key of the client in PEM format. (Can be an array of certificates).
|
||||
feeCushion | number | *Optional* Factor to multiply estimated fee by to provide a cushion in case the required fee rises during submission of a transaction. Defaults to `1.2`.
|
||||
key | string | *Optional* A string containing the private key of the client in PEM format. (Can be an array of keys).
|
||||
passphrase | string | *Optional* The passphrase for the private key of the client.
|
||||
proxy | uri string | *Optional* URI for HTTP/HTTPS proxy to use to connect to the rippled server.
|
||||
proxyAuthorization | string | *Optional* Username and password for HTTP basic authentication to the proxy in the format **username:password**.
|
||||
server | uri string | *Optional* URI for rippled websocket port to connect to. Must start with `wss://` or `ws://`.
|
||||
@@ -259,7 +270,7 @@ Executing a transaction with `RippleAPI` requires the following four steps:
|
||||
* [prepareSuspendedPaymentCreation](#preparesuspendedpaymentcreation)
|
||||
* [prepareSuspendedPaymentCancellation](#preparesuspendedpaymentcancellation)
|
||||
* [prepareSuspendedPaymentExecution](#preparesuspendedpaymentexecution)
|
||||
2. [Sign](#sign) - Cryptographically sign the transaction locally and save the [transaction ID](#transaction-id). Signing is how the owner of an account authorizes a transaction to take place.
|
||||
2. [Sign](#sign) - Cryptographically sign the transaction locally and save the [transaction ID](#transaction-id). Signing is how the owner of an account authorizes a transaction to take place. For multisignature transactions, the `signedTransaction` fields returned by `sign` must be collected and passed to the [combine](#combine) method.
|
||||
3. [Submit](#submit) - Submit the transaction to the connected server.
|
||||
4. Verify - Verify that the transaction got validated by querying with [getTransaction](#gettransaction). This is necessary because transactions may fail even if they were successfully submitted.
|
||||
|
||||
@@ -277,9 +288,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
fee | [value](#value) | *Optional* An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information.
|
||||
maxFee | [value](#value) | *Optional* The maximum fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information.
|
||||
maxLedgerVersion | integer | *Optional* The highest ledger version that the transaction can be included in.
|
||||
maxLedgerVersionOffset | integer | *Optional* Offset from current legder version to highest ledger version that the transaction can be included in.
|
||||
maxLedgerVersion | integer,null | *Optional* The highest ledger version that the transaction can be included in. If this option and `maxLedgerVersionOffset` are both omitted, the `maxLedgerVersion` option will default to 3 greater than the current validated ledger version (equivalent to `maxLedgerVersionOffset=3`). Use `null` to not set a maximum ledger version.
|
||||
maxLedgerVersionOffset | integer | *Optional* Offset from current validated legder version to highest ledger version that the transaction can be included in.
|
||||
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 recommended that you specify a `maxLedgerVersion` so that you can quickly determine that a failed transaction will never succeeed in the future. It is impossible for a transaction to succeed after the network ledger version exceeds the transaction's `maxLedgerVersion`. If you omit `maxLedgerVersion`, the "prepare*" method automatically supplies a `maxLedgerVersion` equal to the current ledger plus 3, which it includes in the return value from the "prepare*" method.
|
||||
|
||||
@@ -470,6 +482,12 @@ passwordSpent | boolean | *Optional* Indicates that the account has used its fre
|
||||
regularKey | [address](#ripple-address),null | *Optional* The public key of a new keypair, to use as the regular key to this account, as a base-58-encoded string in the same format as an account address. Use `null` to remove the regular key.
|
||||
requireAuthorization | boolean | *Optional* If set, this account must individually approve other users in order for those users to hold this account’s issuances.
|
||||
requireDestinationTag | boolean | *Optional* Requires incoming payments to specify a destination tag.
|
||||
signers | object | *Optional* Settings that determine what sets of accounts can be used to sign a transaction on behalf of this account using multisigning.
|
||||
*signers.* threshold | integer | *Optional* A target number for the signer weights. A multi-signature from this list is valid only if the sum weights of the signatures provided is equal or greater than this value. To delete the signers setting, use the value `0`.
|
||||
*signers.* weights | array | *Optional* Weights of signatures for each signer.
|
||||
*signers.* weights[] | object | An association of an address and a weight.
|
||||
*signers.weights[].* address | [address](#ripple-address) | A Ripple account address
|
||||
*signers.weights[].* weight | integer | The weight that the signature of this account counts as towards the threshold.
|
||||
transferRate | number,null | *Optional* The fee to charge when users transfer this account’s issuances, represented as billionths of a unit. Use `null` to set no fee.
|
||||
|
||||
### Example
|
||||
@@ -673,10 +691,10 @@ pubkeyNode | string | Public key used to verify this node for internal communica
|
||||
serverState | string | A string indicating to what extent the server is participating in the network. See [Possible Server States](https://ripple.com/build/rippled-apis/#possible-server-states) for more details.
|
||||
validatedLedger | object | Information about the fully-validated ledger with the highest sequence number (the most recent).
|
||||
*validatedLedger.* age | integer | The time since the ledger was closed, in seconds.
|
||||
*validatedLedger.* baseFeeXRP | number | Base fee, in XRP. This may be represented in scientific notation such as 1e-05 for 0.00005.
|
||||
*validatedLedger.* baseFeeXRP | [value](#value) | Base fee, in XRP. This may be represented in scientific notation such as 1e-05 for 0.00005.
|
||||
*validatedLedger.* hash | string | Unique hash for the ledger, as an uppercase hexadecimal string.
|
||||
*validatedLedger.* reserveBaseXRP | integer | Minimum amount of XRP necessary for every account to keep in reserve.
|
||||
*validatedLedger.* reserveIncrementXRP | integer | Amount of XRP added to the account reserve for each object an account is responsible for in the ledger.
|
||||
*validatedLedger.* reserveBaseXRP | [value](#value) | Minimum amount of XRP necessary for every account to keep in reserve.
|
||||
*validatedLedger.* reserveIncrementXRP | [value](#value) | Amount of XRP added to the account reserve for each object an account is responsible for in the ledger.
|
||||
*validatedLedger.* ledgerVersion | integer | Identifying sequence number of this ledger version.
|
||||
validationQuorum | number | Minimum number of trusted validations required in order to validate a ledger version. Some circumstances may cause the server to require more validations.
|
||||
load | object | *Optional* *(Admin only)* Detailed information about the current load state of the server.
|
||||
@@ -707,10 +725,10 @@ return api.getServerInfo().then(info => {/* ... */});
|
||||
"serverState": "full",
|
||||
"validatedLedger": {
|
||||
"age": 5,
|
||||
"baseFeeXRP": 0.00001,
|
||||
"baseFeeXRP": "0.00001",
|
||||
"hash": "4482DEE5362332F54A4036ED57EE1767C9F33CF7CE5A6670355C16CECE381D46",
|
||||
"reserveBaseXRP": 20,
|
||||
"reserveIncrementXRP": 5,
|
||||
"reserveBaseXRP": "20",
|
||||
"reserveIncrementXRP": "5",
|
||||
"ledgerVersion": 6595042
|
||||
},
|
||||
"validationQuorum": 3
|
||||
@@ -730,7 +748,7 @@ This method has no parameters.
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with a floating point value representing the estimated fee to submit a transaction, expressed in XRP.
|
||||
This method returns a promise that resolves with a string encoded floating point value representing the estimated fee to submit a transaction, expressed in XRP.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -739,7 +757,7 @@ return api.getFee().then(fee => {/* ... */});
|
||||
```
|
||||
|
||||
```json
|
||||
0.012
|
||||
"0.012"
|
||||
```
|
||||
|
||||
## getLedgerVersion
|
||||
@@ -1589,18 +1607,18 @@ paths | string | The paths of trustlines and orders to use in executing the paym
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const pathfind = {
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59"
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"amount": {
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM",
|
||||
"value": "100"
|
||||
}
|
||||
}
|
||||
const pathfind = {
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59"
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"amount": {
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM",
|
||||
"value": "100"
|
||||
}
|
||||
}
|
||||
};
|
||||
return api.getPaths(pathfind)
|
||||
.then(paths => {/* ... */});
|
||||
@@ -2634,6 +2652,12 @@ passwordSpent | boolean | *Optional* Indicates that the account has used its fre
|
||||
regularKey | [address](#ripple-address),null | *Optional* The public key of a new keypair, to use as the regular key to this account, as a base-58-encoded string in the same format as an account address. Use `null` to remove the regular key.
|
||||
requireAuthorization | boolean | *Optional* If set, this account must individually approve other users in order for those users to hold this account’s issuances.
|
||||
requireDestinationTag | boolean | *Optional* Requires incoming payments to specify a destination tag.
|
||||
signers | object | *Optional* Settings that determine what sets of accounts can be used to sign a transaction on behalf of this account using multisigning.
|
||||
*signers.* threshold | integer | *Optional* A target number for the signer weights. A multi-signature from this list is valid only if the sum weights of the signatures provided is equal or greater than this value. To delete the signers setting, use the value `0`.
|
||||
*signers.* weights | array | *Optional* Weights of signatures for each signer.
|
||||
*signers.* weights[] | object | An association of an address and a weight.
|
||||
*signers.weights[].* address | [address](#ripple-address) | A Ripple account address
|
||||
*signers.weights[].* weight | integer | The weight that the signature of this account counts as towards the threshold.
|
||||
transferRate | number,null | *Optional* The fee to charge when users transfer this account’s issuances, represented as billionths of a unit. Use `null` to set no fee.
|
||||
|
||||
### Example
|
||||
@@ -2793,7 +2817,7 @@ txJSON | string | The prepared transaction in rippled JSON format.
|
||||
instructions | object | The instructions for how to execute the transaction after adding automatic defaults.
|
||||
*instructions.* fee | [value](#value) | An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer | *Optional* The highest ledger version that the transaction can be included in.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -2862,7 +2886,7 @@ txJSON | string | The prepared transaction in rippled JSON format.
|
||||
instructions | object | The instructions for how to execute the transaction after adding automatic defaults.
|
||||
*instructions.* fee | [value](#value) | An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer | *Optional* The highest ledger version that the transaction can be included in.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -2929,7 +2953,7 @@ txJSON | string | The prepared transaction in rippled JSON format.
|
||||
instructions | object | The instructions for how to execute the transaction after adding automatic defaults.
|
||||
*instructions.* fee | [value](#value) | An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer | *Optional* The highest ledger version that the transaction can be included in.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -2994,7 +3018,7 @@ txJSON | string | The prepared transaction in rippled JSON format.
|
||||
instructions | object | The instructions for how to execute the transaction after adding automatic defaults.
|
||||
*instructions.* fee | [value](#value) | An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer | *Optional* The highest ledger version that the transaction can be included in.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -3046,7 +3070,7 @@ txJSON | string | The prepared transaction in rippled JSON format.
|
||||
instructions | object | The instructions for how to execute the transaction after adding automatic defaults.
|
||||
*instructions.* fee | [value](#value) | An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer | *Optional* The highest ledger version that the transaction can be included in.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -3111,7 +3135,7 @@ txJSON | string | The prepared transaction in rippled JSON format.
|
||||
instructions | object | The instructions for how to execute the transaction after adding automatic defaults.
|
||||
*instructions.* fee | [value](#value) | An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer | *Optional* The highest ledger version that the transaction can be included in.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -3183,7 +3207,7 @@ txJSON | string | The prepared transaction in rippled JSON format.
|
||||
instructions | object | The instructions for how to execute the transaction after adding automatic defaults.
|
||||
*instructions.* fee | [value](#value) | An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer | *Optional* The highest ledger version that the transaction can be included in.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -3240,7 +3264,7 @@ txJSON | string | The prepared transaction in rippled JSON format.
|
||||
instructions | object | The instructions for how to execute the transaction after adding automatic defaults.
|
||||
*instructions.* fee | [value](#value) | An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer | *Optional* The highest ledger version that the transaction can be included in.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -3272,7 +3296,7 @@ return api.prepareSuspendedPaymentExecution(address, suspendedPaymentExecution).
|
||||
|
||||
## sign
|
||||
|
||||
`sign(txJSON: string, secret: string): {signedTransaction: string, id: string}`
|
||||
`sign(txJSON: string, secret: string, options: Object): {signedTransaction: string, id: string}`
|
||||
|
||||
Sign a prepared transaction. The signed transaction must subsequently be [submitted](#submit).
|
||||
|
||||
@@ -3282,6 +3306,8 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
txJSON | string | Transaction represented as a JSON string in rippled format.
|
||||
secret | secret string | The secret of the account that is initiating the transaction.
|
||||
options | object | *Optional* Options that control the type of signature that will be generated.
|
||||
*options.* signAs | [address](#ripple-address) | *Optional* The account that the signature should count for in multisigning.
|
||||
|
||||
### Return Value
|
||||
|
||||
@@ -3309,6 +3335,44 @@ return api.sign(txJSON, secret);
|
||||
```
|
||||
|
||||
|
||||
## combine
|
||||
|
||||
`combine(signedTransactions: Array<string>): {signedTransaction: string, id: string}`
|
||||
|
||||
Combines signed transactions from multiple accounts for a multisignature transaction. The signed transaction must subsequently be [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
signedTransactions | array\<string\> | An array of signed transactions (from the output of [sign](#sign)) to combine.
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns an object with the following structure:
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
signedTransaction | string | The signed transaction represented as an uppercase hexadecimal string.
|
||||
id | [id](#transaction-id) | The [Transaction ID](#transaction-id) of the signed transaction.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const signedTransactions = [ "12000322800000002400000004201B000000116840000000000F42407300770B6578616D706C652E636F6D811407C532442A675C881BA1235354D4AB9D023243A6F3E0107321026C784C1987F83BACBF02CD3E484AFC84ADE5CA6B36ED4DCA06D5BA233B9D382774473045022100E484F54FF909469FA2033E22EFF3DF8EDFE62217062680BB2F3EDF2F185074FE0220350DB29001C710F0450DAF466C5D819DC6D6A3340602DE9B6CB7DA8E17C90F798114FE9337B0574213FA5BCC0A319DBB4A7AC0CCA894E1F1",
|
||||
"12000322800000002400000004201B000000116840000000000F42407300770B6578616D706C652E636F6D811407C532442A675C881BA1235354D4AB9D023243A6F3E01073210287AAAB8FBE8C4C4A47F6F1228C6E5123A7ED844BFE88A9B22C2F7CC34279EEAA74473045022100B09DDF23144595B5A9523B20E605E138DC6549F5CA7B5984D7C32B0E3469DF6B022018845CA6C203D4B6288C87DDA439134C83E7ADF8358BD41A8A9141A9B631419F8114517D9B9609229E0CDFE2428B586738C5B2E84D45E1F1" ];
|
||||
return api.combine(signedTransactions);
|
||||
```
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"signedTransaction": "12000322800000002400000004201B000000116840000000000F42407300770B6578616D706C652E636F6D811407C532442A675C881BA1235354D4AB9D023243A6F3E01073210287AAAB8FBE8C4C4A47F6F1228C6E5123A7ED844BFE88A9B22C2F7CC34279EEAA74473045022100B09DDF23144595B5A9523B20E605E138DC6549F5CA7B5984D7C32B0E3469DF6B022018845CA6C203D4B6288C87DDA439134C83E7ADF8358BD41A8A9141A9B631419F8114517D9B9609229E0CDFE2428B586738C5B2E84D45E1E0107321026C784C1987F83BACBF02CD3E484AFC84ADE5CA6B36ED4DCA06D5BA233B9D382774473045022100E484F54FF909469FA2033E22EFF3DF8EDFE62217062680BB2F3EDF2F185074FE0220350DB29001C710F0450DAF466C5D819DC6D6A3340602DE9B6CB7DA8E17C90F798114FE9337B0574213FA5BCC0A319DBB4A7AC0CCA894E1F1",
|
||||
"id": "8A3BFD2214B4C8271ED62648FCE9ADE4EE82EF01827CF7D1F7ED497549A368CC"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## submit
|
||||
|
||||
`submit(signedTransaction: string): Promise<Object>`
|
||||
@@ -3355,7 +3419,11 @@ Generate a new Ripple address and corresponding secret.
|
||||
|
||||
### Parameters
|
||||
|
||||
This method has no parameters.
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
options | object | *Optional* Options to control how the address and secret are generated.
|
||||
*options.* algorithm | string | *Optional* The digital signature algorithm to generate an address for. Can be `ecdsa-secp256k1` (default) or `ed25519`.
|
||||
*options.* entropy | array\<integer\> | *Optional* The entropy to use to generate the seed.
|
||||
|
||||
### Return Value
|
||||
|
||||
@@ -3369,8 +3437,7 @@ secret | secret string | The secret corresponding to the `address`.
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
return api.generateAddress()
|
||||
.then(result => {/* ... */});
|
||||
return api.generateAddress();
|
||||
```
|
||||
|
||||
|
||||
@@ -3451,7 +3518,7 @@ Name | Type | Description
|
||||
baseFeeXRP | [value](#value) | Base fee, in XRP.
|
||||
ledgerHash | string | Unique hash of the ledger that was closed, as hex.
|
||||
ledgerTimestamp | date-time string | The time at which this ledger closed.
|
||||
reserveBaseXRP | [value](#value) | The minimum reserve, in drops of XRP, that is required for an account.
|
||||
reserveBaseXRP | [value](#value) | The minimum reserve, in XRP, that is required for an account.
|
||||
reserveIncrementXRP | [value](#value) | The increase in account reserve that is added for each item the account owns, such as offers or trust lines.
|
||||
transactionCount | integer | Number of new transactions included in this ledger.
|
||||
ledgerVersion | integer | Ledger version of the ledger that closed.
|
||||
@@ -3482,16 +3549,26 @@ api.on('ledger', ledger => {
|
||||
|
||||
## error
|
||||
|
||||
This event is emitted when there is an error on the connection to the server.
|
||||
This event is emitted when there is an error on the connection to the server that cannot be associated to a specific request.
|
||||
|
||||
### Return Value
|
||||
|
||||
The first parameter is a string indicating the error type, which may be `badMessage` (meaning that rippled returned a malformed message), or one of the [rippled Universal Errors](https://ripple.com/build/rippled-apis/#universal-errors). The second parameter is a message explaining the error, or the message that caused the error in the case of `badMessage`.
|
||||
The first parameter is a string indicating the error type:
|
||||
* `badMessage` - rippled returned a malformed message
|
||||
* `websocket` - the websocket library emitted an error
|
||||
* one of the error codes found in the [rippled Universal Errors](https://ripple.com/build/rippled-apis/#universal-errors).
|
||||
|
||||
The second parameter is a message explaining the error.
|
||||
|
||||
The third parameter is:
|
||||
* the message that caused the error for `badMessage`
|
||||
* the error object emitted for `websocket`
|
||||
* the parsed response for rippled errors
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
api.on('error', (errorCode, errorMessage) => {
|
||||
api.on('error', (errorCode, errorMessage, data) => {
|
||||
console.log(errorCode + ': ' + errorMessage);
|
||||
});
|
||||
```
|
||||
|
||||
38
docs/samples/cancelall.js
Normal file
38
docs/samples/cancelall.js
Normal file
@@ -0,0 +1,38 @@
|
||||
'use strict';
|
||||
const RippleAPI = require('../../dist/npm').RippleAPI; // require('ripple-lib')
|
||||
|
||||
const address = 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K';
|
||||
const secret = '';
|
||||
|
||||
const api = new RippleAPI({server: 'wss://s1.ripple.com:443'});
|
||||
const instructions = {maxLedgerVersionOffset: 5};
|
||||
|
||||
function fail(message) {
|
||||
console.error(message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function cancelOrder(orderSequence) {
|
||||
console.log('Cancelling order: ' + orderSequence.toString());
|
||||
return api.prepareOrderCancellation(address, {orderSequence}, instructions)
|
||||
.then(prepared => {
|
||||
const signing = api.sign(prepared.txJSON, secret);
|
||||
return api.submit(signing.signedTransaction);
|
||||
});
|
||||
}
|
||||
|
||||
function cancelAllOrders(orderSequences) {
|
||||
if (orderSequences.length === 0) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const orderSequence = orderSequences.pop();
|
||||
return cancelOrder(orderSequence).then(() => cancelAllOrders(orderSequences));
|
||||
}
|
||||
|
||||
api.connect().then(() => {
|
||||
console.log('Connected...');
|
||||
return api.getOrders(address).then(orders => {
|
||||
const orderSequences = orders.map(order => order.properties.sequence);
|
||||
return cancelAllOrders(orderSequences);
|
||||
}).then(() => process.exit(0));
|
||||
}).catch(fail);
|
||||
@@ -8,6 +8,9 @@ const {RippleAPI} = require('ripple-lib');
|
||||
const api = new RippleAPI({
|
||||
server: 'wss://s1.ripple.com' // Public rippled server hosted by Ripple, Inc.
|
||||
});
|
||||
api.on('error', (errorCode, errorMessage) => {
|
||||
console.log(errorCode + ': ' + errorMessage);
|
||||
});
|
||||
api.connect().then(() => {
|
||||
/* insert code here */
|
||||
}).then(() => {
|
||||
@@ -27,6 +30,10 @@ All the code snippets in this documentation assume that you have surrounded them
|
||||
If you omit the "catch" section, errors may not be visible.
|
||||
</aside>
|
||||
|
||||
<aside class="notice">
|
||||
The "error" event is emitted whenever an error occurs that cannot be associated with a specific request. If the listener is not registered, an exception will be thrown whenever the event is emitted.
|
||||
</aside>
|
||||
|
||||
### Parameters
|
||||
|
||||
The RippleAPI constructor optionally takes one argument, an object with the following options:
|
||||
|
||||
24
docs/src/combine.md.ejs
Normal file
24
docs/src/combine.md.ejs
Normal file
@@ -0,0 +1,24 @@
|
||||
## combine
|
||||
|
||||
`combine(signedTransactions: Array<string>): {signedTransaction: string, id: string}`
|
||||
|
||||
Combines signed transactions from multiple accounts for a multisignature transaction. The signed transaction must subsequently be [submitted](#submit).
|
||||
|
||||
### Parameters
|
||||
|
||||
<%- renderSchema("input/combine.json") %>
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns an object with the following structure:
|
||||
|
||||
<%- renderSchema("output/sign.json") %>
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
const signedTransactions = <%- importFile('test/fixtures/requests/combine.json') %>;
|
||||
return api.combine(signedTransactions);
|
||||
```
|
||||
|
||||
<%- renderFixture("responses/combine.json") %>
|
||||
@@ -20,16 +20,26 @@ api.on('ledger', ledger => {
|
||||
|
||||
## error
|
||||
|
||||
This event is emitted when there is an error on the connection to the server.
|
||||
This event is emitted when there is an error on the connection to the server that cannot be associated to a specific request.
|
||||
|
||||
### Return Value
|
||||
|
||||
The first parameter is a string indicating the error type, which may be `badMessage` (meaning that rippled returned a malformed message), or one of the [rippled Universal Errors](https://ripple.com/build/rippled-apis/#universal-errors). The second parameter is a message explaining the error, or the message that caused the error in the case of `badMessage`.
|
||||
The first parameter is a string indicating the error type:
|
||||
* `badMessage` - rippled returned a malformed message
|
||||
* `websocket` - the websocket library emitted an error
|
||||
* one of the error codes found in the [rippled Universal Errors](https://ripple.com/build/rippled-apis/#universal-errors).
|
||||
|
||||
The second parameter is a message explaining the error.
|
||||
|
||||
The third parameter is:
|
||||
* the message that caused the error for `badMessage`
|
||||
* the error object emitted for `websocket`
|
||||
* the parsed response for rippled errors
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
api.on('error', (errorCode, errorMessage) => {
|
||||
api.on('error', (errorCode, errorMessage, data) => {
|
||||
console.log(errorCode + ': ' + errorMessage);
|
||||
});
|
||||
```
|
||||
|
||||
@@ -6,7 +6,7 @@ Generate a new Ripple address and corresponding secret.
|
||||
|
||||
### Parameters
|
||||
|
||||
This method has no parameters.
|
||||
<%- renderSchema('input/generate-address.json') %>
|
||||
|
||||
### Return Value
|
||||
|
||||
@@ -17,8 +17,7 @@ This method returns an object with the following structure:
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
return api.generateAddress()
|
||||
.then(result => {/* ... */});
|
||||
return api.generateAddress();
|
||||
```
|
||||
|
||||
<%- renderFixture('responses/generate-address.json') %>
|
||||
|
||||
@@ -10,7 +10,7 @@ This method has no parameters.
|
||||
|
||||
### Return Value
|
||||
|
||||
This method returns a promise that resolves with a floating point value representing the estimated fee to submit a transaction, expressed in XRP.
|
||||
This method returns a promise that resolves with a string encoded floating point value representing the estimated fee to submit a transaction, expressed in XRP.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -19,5 +19,5 @@ return api.getFee().then(fee => {/* ... */});
|
||||
```
|
||||
|
||||
```json
|
||||
0.012
|
||||
"0.012"
|
||||
```
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<% include prepareSuspendedPaymentCancellation.md.ejs %>
|
||||
<% include prepareSuspendedPaymentExecution.md.ejs %>
|
||||
<% include sign.md.ejs %>
|
||||
<% include combine.md.ejs %>
|
||||
<% include submit.md.ejs %>
|
||||
<% include generateAddress.md.ejs %>
|
||||
<% include computeLedgerHash.md.ejs %>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## sign
|
||||
|
||||
`sign(txJSON: string, secret: string): {signedTransaction: string, id: string}`
|
||||
`sign(txJSON: string, secret: string, options: Object): {signedTransaction: string, id: string}`
|
||||
|
||||
Sign a prepared transaction. The signed transaction must subsequently be [submitted](#submit).
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ Executing a transaction with `RippleAPI` requires the following four steps:
|
||||
* [prepareSuspendedPaymentCreation](#preparesuspendedpaymentcreation)
|
||||
* [prepareSuspendedPaymentCancellation](#preparesuspendedpaymentcancellation)
|
||||
* [prepareSuspendedPaymentExecution](#preparesuspendedpaymentexecution)
|
||||
2. [Sign](#sign) - Cryptographically sign the transaction locally and save the [transaction ID](#transaction-id). Signing is how the owner of an account authorizes a transaction to take place.
|
||||
2. [Sign](#sign) - Cryptographically sign the transaction locally and save the [transaction ID](#transaction-id). Signing is how the owner of an account authorizes a transaction to take place. For multisignature transactions, the `signedTransaction` fields returned by `sign` must be collected and passed to the [combine](#combine) method.
|
||||
3. [Submit](#submit) - Submit the transaction to the connected server.
|
||||
4. Verify - Verify that the transaction got validated by querying with [getTransaction](#gettransaction). This is necessary because transactions may fail even if they were successfully submitted.
|
||||
|
||||
|
||||
207
npm-shrinkwrap.json
generated
207
npm-shrinkwrap.json
generated
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "0.15.1",
|
||||
"version": "0.16.5",
|
||||
"dependencies": {
|
||||
"ajv": {
|
||||
"version": "1.4.8",
|
||||
"from": "https://registry.npmjs.org/ajv/-/ajv-1.4.8.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-1.4.8.tgz",
|
||||
"version": "1.4.10",
|
||||
"from": "https://registry.npmjs.org/ajv/-/ajv-1.4.10.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-1.4.10.tgz",
|
||||
"dependencies": {
|
||||
"json-stable-stringify": {
|
||||
"version": "1.0.0",
|
||||
@@ -21,106 +21,157 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ajv-i18n": {
|
||||
"version": "0.1.1",
|
||||
"from": "https://registry.npmjs.org/ajv-i18n/-/ajv-i18n-0.1.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ajv-i18n/-/ajv-i18n-0.1.1.tgz"
|
||||
},
|
||||
"babel-polyfill": {
|
||||
"version": "6.2.0",
|
||||
"from": "babel-polyfill@*",
|
||||
"resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.2.0.tgz",
|
||||
"version": "6.3.14",
|
||||
"from": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.3.14.tgz",
|
||||
"resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.3.14.tgz",
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "1.2.6",
|
||||
"from": "core-js@>=1.0.1 <2.0.0",
|
||||
"from": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz"
|
||||
},
|
||||
"babel-regenerator-runtime": {
|
||||
"version": "6.2.0",
|
||||
"from": "babel-regenerator-runtime@>=6.2.0 <7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-regenerator-runtime/-/babel-regenerator-runtime-6.2.0.tgz"
|
||||
"version": "6.3.13",
|
||||
"from": "https://registry.npmjs.org/babel-regenerator-runtime/-/babel-regenerator-runtime-6.3.13.tgz",
|
||||
"resolved": "https://registry.npmjs.org/babel-regenerator-runtime/-/babel-regenerator-runtime-6.3.13.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"babel-runtime": {
|
||||
"version": "5.8.29",
|
||||
"from": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.29.tgz",
|
||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.29.tgz",
|
||||
"version": "5.8.34",
|
||||
"from": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.34.tgz",
|
||||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.34.tgz",
|
||||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "1.2.3",
|
||||
"from": "https://registry.npmjs.org/core-js/-/core-js-1.2.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.3.tgz"
|
||||
"version": "1.2.6",
|
||||
"from": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.6.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bignumber.js": {
|
||||
"version": "2.1.0",
|
||||
"from": "bignumber.js@>=2.0.3 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.1.0.tgz"
|
||||
"version": "2.1.2",
|
||||
"from": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.1.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.1.2.tgz"
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "1.0.0",
|
||||
"from": "https-proxy-agent@>=1.0.0 <2.0.0",
|
||||
"from": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
|
||||
"dependencies": {
|
||||
"agent-base": {
|
||||
"version": "2.0.1",
|
||||
"from": "agent-base@>=2.0.0 <3.0.0",
|
||||
"from": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz",
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.0.3",
|
||||
"from": "semver@>=5.0.1 <5.1.0",
|
||||
"from": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.2.0",
|
||||
"from": "debug@>=2.0.0 <3.0.0",
|
||||
"from": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "0.7.1",
|
||||
"from": "ms@0.7.1",
|
||||
"from": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.0",
|
||||
"from": "extend@>=3.0.0 <4.0.0",
|
||||
"from": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"jayson": {
|
||||
"version": "1.2.2",
|
||||
"from": "https://registry.npmjs.org/jayson/-/jayson-1.2.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/jayson/-/jayson-1.2.2.tgz",
|
||||
"dependencies": {
|
||||
"JSONStream": {
|
||||
"version": "1.0.3",
|
||||
"from": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.0.3.tgz",
|
||||
"dependencies": {
|
||||
"jsonparse": {
|
||||
"version": "1.0.0",
|
||||
"from": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.0.0.tgz"
|
||||
},
|
||||
"through": {
|
||||
"version": "2.3.8",
|
||||
"from": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "1.3.2",
|
||||
"from": "https://registry.npmjs.org/commander/-/commander-1.3.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-1.3.2.tgz",
|
||||
"dependencies": {
|
||||
"keypress": {
|
||||
"version": "0.1.0",
|
||||
"from": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyes": {
|
||||
"version": "0.1.8",
|
||||
"from": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
|
||||
"resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz"
|
||||
},
|
||||
"lodash": {
|
||||
"version": "3.6.0",
|
||||
"from": "https://registry.npmjs.org/lodash/-/lodash-3.6.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.6.0.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "3.10.1",
|
||||
"from": "lodash@>=3.1.0 <4.0.0",
|
||||
"from": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz"
|
||||
},
|
||||
"ripple-address-codec": {
|
||||
"version": "2.0.1",
|
||||
"from": "ripple-address-codec@>=2.0.1 <3.0.0",
|
||||
"from": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-2.0.1.tgz",
|
||||
"dependencies": {
|
||||
"hash.js": {
|
||||
"version": "1.0.3",
|
||||
"from": "hash.js@>=1.0.3 <2.0.0",
|
||||
"from": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz",
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@>=2.0.1 <3.0.0",
|
||||
"from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-address-codec": {
|
||||
"version": "0.7.2",
|
||||
"from": "x-address-codec@>=0.7.0 <0.8.0",
|
||||
"from": "https://registry.npmjs.org/x-address-codec/-/x-address-codec-0.7.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/x-address-codec/-/x-address-codec-0.7.2.tgz",
|
||||
"dependencies": {
|
||||
"base-x": {
|
||||
"version": "1.0.1",
|
||||
"from": "base-x@>=1.0.1 <2.0.0",
|
||||
"from": "https://registry.npmjs.org/base-x/-/base-x-1.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/base-x/-/base-x-1.0.1.tgz"
|
||||
}
|
||||
}
|
||||
@@ -128,77 +179,77 @@
|
||||
}
|
||||
},
|
||||
"ripple-binary-codec": {
|
||||
"version": "0.1.0",
|
||||
"from": "ripple-binary-codec@0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.1.0.tgz",
|
||||
"version": "0.1.1",
|
||||
"from": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.1.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.1.1.tgz",
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "3.3.0",
|
||||
"from": "bn.js@>=3.2.0 <4.0.0",
|
||||
"from": "https://registry.npmjs.org/bn.js/-/bn.js-3.3.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-3.3.0.tgz"
|
||||
},
|
||||
"create-hash": {
|
||||
"version": "1.1.2",
|
||||
"from": "create-hash@>=1.1.2 <2.0.0",
|
||||
"from": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz",
|
||||
"dependencies": {
|
||||
"cipher-base": {
|
||||
"version": "1.0.2",
|
||||
"from": "cipher-base@>=1.0.1 <2.0.0",
|
||||
"from": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.2.tgz"
|
||||
},
|
||||
"ripemd160": {
|
||||
"version": "1.0.1",
|
||||
"from": "ripemd160@>=1.0.0 <2.0.0",
|
||||
"from": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz"
|
||||
},
|
||||
"sha.js": {
|
||||
"version": "2.4.4",
|
||||
"from": "sha.js@>=2.3.6 <3.0.0",
|
||||
"from": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.4.tgz",
|
||||
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.4.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"decimal.js": {
|
||||
"version": "4.0.3",
|
||||
"from": "decimal.js@>=4.0.2 <5.0.0",
|
||||
"from": "https://registry.npmjs.org/decimal.js/-/decimal.js-4.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-4.0.3.tgz"
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@>=2.0.1 <3.0.0",
|
||||
"from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ripple-hashes": {
|
||||
"version": "0.1.0",
|
||||
"from": "ripple-hashes@0.1.0",
|
||||
"from": "https://registry.npmjs.org/ripple-hashes/-/ripple-hashes-0.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ripple-hashes/-/ripple-hashes-0.1.0.tgz",
|
||||
"dependencies": {
|
||||
"create-hash": {
|
||||
"version": "1.1.2",
|
||||
"from": "create-hash@>=1.1.2 <2.0.0",
|
||||
"from": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz",
|
||||
"dependencies": {
|
||||
"cipher-base": {
|
||||
"version": "1.0.2",
|
||||
"from": "cipher-base@>=1.0.1 <2.0.0",
|
||||
"from": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.2.tgz"
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@>=2.0.1 <3.0.0",
|
||||
"from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
},
|
||||
"ripemd160": {
|
||||
"version": "1.0.1",
|
||||
"from": "ripemd160@>=1.0.0 <2.0.0",
|
||||
"from": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz"
|
||||
},
|
||||
"sha.js": {
|
||||
"version": "2.4.4",
|
||||
"from": "sha.js@>=2.3.6 <3.0.0",
|
||||
"from": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.4.tgz",
|
||||
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.4.tgz"
|
||||
}
|
||||
}
|
||||
@@ -207,39 +258,39 @@
|
||||
},
|
||||
"ripple-keypairs": {
|
||||
"version": "0.10.0",
|
||||
"from": "ripple-keypairs@>=0.10.0 <0.11.0",
|
||||
"from": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-0.10.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-0.10.0.tgz",
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "3.3.0",
|
||||
"from": "bn.js@>=3.1.1 <4.0.0",
|
||||
"from": "https://registry.npmjs.org/bn.js/-/bn.js-3.3.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-3.3.0.tgz"
|
||||
},
|
||||
"brorand": {
|
||||
"version": "1.0.5",
|
||||
"from": "brorand@>=1.0.5 <2.0.0",
|
||||
"from": "https://registry.npmjs.org/brorand/-/brorand-1.0.5.tgz",
|
||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.0.5.tgz"
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "5.2.1",
|
||||
"from": "elliptic@>=5.1.0 <6.0.0",
|
||||
"from": "https://registry.npmjs.org/elliptic/-/elliptic-5.2.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-5.2.1.tgz",
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@>=2.0.1 <3.0.0",
|
||||
"from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hash.js": {
|
||||
"version": "1.0.3",
|
||||
"from": "hash.js@>=1.0.3 <2.0.0",
|
||||
"from": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz",
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"from": "inherits@>=2.0.1 <3.0.0",
|
||||
"from": "inherits@>=2.0.1 <2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
@@ -248,57 +299,23 @@
|
||||
},
|
||||
"ripple-lib-transactionparser": {
|
||||
"version": "0.6.0",
|
||||
"from": "ripple-lib-transactionparser@>=0.6.0 <0.7.0",
|
||||
"from": "https://registry.npmjs.org/ripple-lib-transactionparser/-/ripple-lib-transactionparser-0.6.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ripple-lib-transactionparser/-/ripple-lib-transactionparser-0.6.0.tgz"
|
||||
},
|
||||
"ws": {
|
||||
"version": "0.7.2",
|
||||
"from": "ws@>=0.7.1 <0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-0.7.2.tgz",
|
||||
"version": "1.0.1",
|
||||
"from": "https://registry.npmjs.org/ws/-/ws-1.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-1.0.1.tgz",
|
||||
"dependencies": {
|
||||
"options": {
|
||||
"version": "0.0.6",
|
||||
"from": "options@>=0.0.5",
|
||||
"from": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz"
|
||||
},
|
||||
"ultron": {
|
||||
"version": "1.0.2",
|
||||
"from": "ultron@>=1.0.0 <1.1.0",
|
||||
"from": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz"
|
||||
},
|
||||
"bufferutil": {
|
||||
"version": "1.1.0",
|
||||
"from": "bufferutil@>=1.1.0 <1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-1.1.0.tgz",
|
||||
"dependencies": {
|
||||
"bindings": {
|
||||
"version": "1.2.1",
|
||||
"from": "bindings@>=1.2.0 <1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
|
||||
},
|
||||
"nan": {
|
||||
"version": "1.8.4",
|
||||
"from": "nan@>=1.8.0 <1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-1.8.4.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"version": "1.1.0",
|
||||
"from": "utf-8-validate@>=1.1.0 <1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-1.1.0.tgz",
|
||||
"dependencies": {
|
||||
"bindings": {
|
||||
"version": "1.2.1",
|
||||
"from": "bindings@>=1.2.0 <1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
|
||||
},
|
||||
"nan": {
|
||||
"version": "1.8.4",
|
||||
"from": "nan@>=1.8.0 <1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-1.8.4.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
package.json
13
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "0.15.1",
|
||||
"version": "0.16.5",
|
||||
"license": "ISC",
|
||||
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
|
||||
"files": [
|
||||
@@ -20,13 +20,14 @@
|
||||
"babel-runtime": "^5.5.4",
|
||||
"bignumber.js": "^2.0.3",
|
||||
"https-proxy-agent": "^1.0.0",
|
||||
"jayson": "^1.2.2",
|
||||
"lodash": "^3.1.0",
|
||||
"ripple-address-codec": "^2.0.1",
|
||||
"ripple-binary-codec": "^0.1.0",
|
||||
"ripple-binary-codec": "^0.1.1",
|
||||
"ripple-hashes": "^0.1.0",
|
||||
"ripple-keypairs": "^0.10.0",
|
||||
"ripple-lib-transactionparser": "^0.6.0",
|
||||
"ws": "^0.7.1"
|
||||
"ws": "^1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"assert-diff": "^1.0.1",
|
||||
@@ -49,6 +50,9 @@
|
||||
"json-loader": "^0.5.2",
|
||||
"json-schema-to-markdown-table": "^0.4.0",
|
||||
"mocha": "^2.1.0",
|
||||
"mocha-junit-reporter": "^1.9.1",
|
||||
"mocha-phantomjs": "^4.0.1",
|
||||
"null-loader": "^0.1.1",
|
||||
"webpack": "^1.5.3",
|
||||
"yargs": "^1.3.1"
|
||||
},
|
||||
@@ -65,7 +69,8 @@
|
||||
"test": "istanbul test _mocha",
|
||||
"coveralls": "cat ./coverage/lcov.info | coveralls",
|
||||
"lint": "if ! [ -f eslintrc ]; then curl -o eslintrc 'https://raw.githubusercontent.com/ripple/javascript-style-guide/es6/eslintrc'; echo 'parser: babel-eslint' >> eslintrc; fi; eslint -c eslintrc src/",
|
||||
"perf": "./scripts/perf_test.sh"
|
||||
"perf": "./scripts/perf_test.sh",
|
||||
"start": "babel-node scripts/http.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
18
scripts/checkeol.sh
Executable file
18
scripts/checkeol.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
function checkEOL {
|
||||
local changedFiles=$(git --no-pager diff --name-only -M100% --diff-filter=AM --relative $(git merge-base FETCH_HEAD origin/HEAD) FETCH_HEAD)
|
||||
local result=0
|
||||
for name in $changedFiles; do
|
||||
grep -c -U -q $'\r' $name
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "windows eol found in $name" >&2
|
||||
result=1
|
||||
fi
|
||||
done
|
||||
if [ $result -eq 1 ]; then
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
checkEOL
|
||||
@@ -3,6 +3,10 @@
|
||||
NODE_INDEX="$1"
|
||||
TOTAL_NODES="$2"
|
||||
|
||||
function checkEOL {
|
||||
./scripts/checkeol.sh
|
||||
}
|
||||
|
||||
typecheck() {
|
||||
npm install -g flow-bin
|
||||
flow --version
|
||||
@@ -20,6 +24,7 @@ lint() {
|
||||
|
||||
unittest() {
|
||||
# test "src"
|
||||
mocha test --reporter mocha-junit-reporter --reporter-options mochaFile=$CIRCLE_TEST_REPORTS/test-results.xml
|
||||
npm test --coverage
|
||||
npm run coveralls
|
||||
|
||||
@@ -29,11 +34,26 @@ unittest() {
|
||||
mkdir -p test-compiled/node_modules
|
||||
ln -nfs ../../dist/npm test-compiled/node_modules/ripple-api
|
||||
mocha --opts test-compiled/mocha.opts test-compiled
|
||||
|
||||
# compile tests for browser testing
|
||||
gulp build-tests build-for-web-tests
|
||||
node --harmony test-compiled/mocked-server.js > /dev/null &
|
||||
|
||||
echo "Running tests in PhantomJS"
|
||||
mocha-phantomjs test/localrunner.html
|
||||
|
||||
pkill -f mocked-server.js
|
||||
rm -rf test-compiled
|
||||
}
|
||||
|
||||
integrationtest() {
|
||||
mocha test/integration/integration-test.js
|
||||
mocha test/integration/http-integration-test.js
|
||||
|
||||
# run integration tests in PhantomJS
|
||||
gulp build-tests build-for-web-tests
|
||||
echo "Running integragtion tests in PhantomJS"
|
||||
mocha-phantomjs test/localintegrationrunner.html
|
||||
}
|
||||
|
||||
doctest() {
|
||||
@@ -46,6 +66,7 @@ doctest() {
|
||||
}
|
||||
|
||||
oneNode() {
|
||||
checkEOL
|
||||
doctest
|
||||
lint
|
||||
typecheck
|
||||
@@ -56,7 +77,7 @@ oneNode() {
|
||||
twoNodes() {
|
||||
case "$NODE_INDEX" in
|
||||
0) doctest; lint; integrationtest;;
|
||||
1) typecheck; unittest;;
|
||||
1) checkEOL; typecheck; unittest;;
|
||||
*) echo "ERROR: invalid usage"; exit 2;;
|
||||
esac
|
||||
}
|
||||
@@ -64,7 +85,7 @@ twoNodes() {
|
||||
threeNodes() {
|
||||
case "$NODE_INDEX" in
|
||||
0) doctest; lint; integrationtest;;
|
||||
1) typecheck;;
|
||||
1) checkEOL; typecheck;;
|
||||
2) unittest;;
|
||||
*) echo "ERROR: invalid usage"; exit 2;;
|
||||
esac
|
||||
|
||||
16
scripts/http.js
Normal file
16
scripts/http.js
Normal file
@@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
const createHTTPServer = require('../src/index').createHTTPServer;
|
||||
const port = 5990;
|
||||
const serverUrl = 'wss://s1.ripple.com';
|
||||
|
||||
|
||||
function main() {
|
||||
const server = createHTTPServer({server: serverUrl}, port);
|
||||
server.start().then(() => {
|
||||
console.log('Server started on port ' + String(port));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
main();
|
||||
@@ -16,28 +16,3 @@ echo ""
|
||||
echo "publish to npm"
|
||||
npm publish
|
||||
exit_on_error
|
||||
|
||||
rm -rf dist/bower
|
||||
echo ""
|
||||
echo "publish to bower"
|
||||
|
||||
git clone git@github.com:ripple/bower-ripple.git dist/bower
|
||||
gulp bower
|
||||
exit_on_error
|
||||
|
||||
cd dist/bower
|
||||
version=$(cat bower.json | grep -Eo '([0-9]\.?)+(-rc([0-9])+)?')
|
||||
echo "version: $version"
|
||||
git add ripple.js ripple-debug.js ripple-min.js bower.json
|
||||
exit_on_error
|
||||
|
||||
git commit -m "[TASK] add v$version"
|
||||
exit_on_error
|
||||
|
||||
git tag "v$version"
|
||||
exit_on_error
|
||||
|
||||
git push origin master
|
||||
git push --tags origin master
|
||||
|
||||
cd ../..
|
||||
|
||||
@@ -16,28 +16,3 @@ echo ""
|
||||
echo "publish rc to npm"
|
||||
npm publish --tag beta
|
||||
exit_on_error
|
||||
|
||||
rm -rf dist/bower
|
||||
echo ""
|
||||
echo "publish to bower"
|
||||
|
||||
git clone git@github.com:ripple/bower-ripple.git dist/bower
|
||||
gulp bower
|
||||
exit_on_error
|
||||
|
||||
cd dist/bower
|
||||
version=$(cat bower.json | grep -Eo '([0-9]\.?)+(-rc([0-9])+)?')
|
||||
echo "version: $version"
|
||||
git add ripple.js ripple-debug.js ripple-min.js bower.json
|
||||
exit_on_error
|
||||
|
||||
git commit -m "[TASK] add v$version"
|
||||
exit_on_error
|
||||
|
||||
git tag "v$version"
|
||||
exit_on_error
|
||||
|
||||
git push origin master
|
||||
git push --tags origin master
|
||||
|
||||
cd ../..
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
rm -rf dist/bower
|
||||
git clone git@github.com:ripple/bower-ripple.git dist/bower
|
||||
gulp bower
|
||||
cd dist/bower
|
||||
version=$(cat bower.json | grep -Eo '([0-9]\.?)+(-rc[0-9])?')
|
||||
echo "version: $version"
|
||||
git add ripple.js ripple-debug.js ripple-min.js bower.json
|
||||
git commit -m "[TASK] add v$version"
|
||||
git tag "v$version"
|
||||
git push origin master
|
||||
git push --tags origin master
|
||||
cd ..
|
||||
@@ -44,9 +44,11 @@ const prepareSuspendedPaymentCancellation =
|
||||
require('./transaction/suspended-payment-cancellation');
|
||||
const prepareSettings = require('./transaction/settings');
|
||||
const sign = require('./transaction/sign');
|
||||
const combine = require('./transaction/combine');
|
||||
const submit = require('./transaction/submit');
|
||||
const errors = require('./common').errors;
|
||||
const generateAddress = common.generateAddressAPI;
|
||||
const generateAddress =
|
||||
require('./offline/generate-address').generateAddressAPI;
|
||||
const computeLedgerHash = require('./offline/ledgerhash');
|
||||
const getLedger = require('./ledger/ledger');
|
||||
|
||||
@@ -84,8 +86,8 @@ class RippleAPI extends EventEmitter {
|
||||
this.connection.on('ledgerClosed', message => {
|
||||
this.emit('ledger', server.formatLedgerClose(message));
|
||||
});
|
||||
this.connection.on('error', (type, info) => {
|
||||
this.emit('error', type, info);
|
||||
this.connection.on('error', (errorCode, errorMessage, data) => {
|
||||
this.emit('error', errorCode, errorMessage, data);
|
||||
});
|
||||
} else {
|
||||
// use null object pattern to provide better error message if user
|
||||
@@ -124,6 +126,7 @@ _.assign(RippleAPI.prototype, {
|
||||
prepareSuspendedPaymentCancellation,
|
||||
prepareSettings,
|
||||
sign,
|
||||
combine,
|
||||
submit,
|
||||
|
||||
generateAddress,
|
||||
|
||||
@@ -11,6 +11,9 @@ class RippleAPIBroadcast extends RippleAPI {
|
||||
_.assign({}, options, {server})
|
||||
));
|
||||
|
||||
// exposed for testing
|
||||
this._apis = apis;
|
||||
|
||||
this.getMethodNames().forEach(name => {
|
||||
this[name] = function() { // eslint-disable-line no-loop-func
|
||||
return Promise.race(apis.map(api => api[name].apply(api, arguments)));
|
||||
@@ -37,7 +40,8 @@ class RippleAPIBroadcast extends RippleAPI {
|
||||
|
||||
apis.forEach(api => {
|
||||
api.on('ledger', this.onLedgerEvent.bind(this));
|
||||
api.on('error', (type, info) => this.emit('error', type, info));
|
||||
api.on('error', (errorCode, errorMessage, data) =>
|
||||
this.emit('error', errorCode, errorMessage, data));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const {EventEmitter} = require('events');
|
||||
const WebSocket = require('ws');
|
||||
const parseURL = require('url').parse;
|
||||
@@ -15,6 +16,7 @@ function isStreamMessageType(type) {
|
||||
class Connection extends EventEmitter {
|
||||
constructor(url, options = {}) {
|
||||
super();
|
||||
this.setMaxListeners(Infinity);
|
||||
this._url = url;
|
||||
this._trace = options.trace;
|
||||
if (this._trace) {
|
||||
@@ -25,6 +27,9 @@ class Connection extends EventEmitter {
|
||||
this._proxyAuthorization = options.proxyAuthorization;
|
||||
this._authorization = options.authorization;
|
||||
this._trustedCertificates = options.trustedCertificates;
|
||||
this._key = options.key;
|
||||
this._passphrase = options.passphrase;
|
||||
this._certificate = options.certificate;
|
||||
this._timeout = options.timeout || (20 * 1000);
|
||||
this._isReady = false;
|
||||
this._ws = null;
|
||||
@@ -33,6 +38,17 @@ class Connection extends EventEmitter {
|
||||
this._nextRequestID = 1;
|
||||
}
|
||||
|
||||
_updateLedgerVersions(data) {
|
||||
this._ledgerVersion = Number(data.ledger_index);
|
||||
if (data.validated_ledgers) {
|
||||
this._availableLedgerVersions.reset();
|
||||
this._availableLedgerVersions.parseAndAddRanges(
|
||||
data.validated_ledgers);
|
||||
} else {
|
||||
this._availableLedgerVersions.addValue(this._ledgerVersion);
|
||||
}
|
||||
}
|
||||
|
||||
// return value is array of arguments to Connection.emit
|
||||
_parseMessage(message) {
|
||||
const data = JSON.parse(message);
|
||||
@@ -43,14 +59,11 @@ class Connection extends EventEmitter {
|
||||
return [data.id.toString(), data];
|
||||
} else if (isStreamMessageType(data.type)) {
|
||||
if (data.type === 'ledgerClosed') {
|
||||
this._ledgerVersion = Number(data.ledger_index);
|
||||
this._availableLedgerVersions.reset();
|
||||
this._availableLedgerVersions.parseAndAddRanges(
|
||||
data.validated_ledgers);
|
||||
this._updateLedgerVersions(data);
|
||||
}
|
||||
return [data.type, data];
|
||||
} else if (data.type === undefined && data.error) {
|
||||
return ['error', data.error, data.error_message]; // e.g. slowDown
|
||||
return ['error', data.error, data.error_message, data]; // e.g. slowDown
|
||||
}
|
||||
throw new ResponseFormatError('unrecognized message type: ' + data.type);
|
||||
}
|
||||
@@ -63,7 +76,7 @@ class Connection extends EventEmitter {
|
||||
try {
|
||||
parameters = this._parseMessage(message);
|
||||
} catch (error) {
|
||||
this.emit('error', 'badMessage', message);
|
||||
this.emit('error', 'badMessage', error.message, message);
|
||||
return;
|
||||
}
|
||||
// we don't want this inside the try/catch or exceptions in listener
|
||||
@@ -94,27 +107,28 @@ class Connection extends EventEmitter {
|
||||
command: 'subscribe',
|
||||
streams: ['ledger']
|
||||
};
|
||||
return this.request(request).then(response => {
|
||||
this._ledgerVersion = Number(response.ledger_index);
|
||||
this._availableLedgerVersions.parseAndAddRanges(
|
||||
response.validated_ledgers);
|
||||
return this.request(request).then(data => {
|
||||
this._updateLedgerVersions(data);
|
||||
this._isReady = true;
|
||||
this.emit('connected');
|
||||
});
|
||||
}
|
||||
|
||||
_createWebSocket(url, proxyURL, proxyAuthorization, authorization,
|
||||
trustedCertificates) {
|
||||
_createWebSocket() {
|
||||
const options = {};
|
||||
if (proxyURL !== undefined) {
|
||||
const parsedURL = parseURL(url);
|
||||
const proxyOptions = parseURL(proxyURL);
|
||||
proxyOptions.secureEndpoint = (parsedURL.protocol === 'wss:');
|
||||
proxyOptions.secureProxy = (proxyOptions.protocol === 'https:');
|
||||
proxyOptions.auth = proxyAuthorization;
|
||||
if (trustedCertificates) {
|
||||
proxyOptions.ca = trustedCertificates;
|
||||
}
|
||||
if (this._proxyURL !== undefined) {
|
||||
const parsedURL = parseURL(this._url);
|
||||
const parsedProxyURL = parseURL(this._proxyURL);
|
||||
const proxyOverrides = _.omit({
|
||||
secureEndpoint: (parsedURL.protocol === 'wss:'),
|
||||
secureProxy: (parsedProxyURL.protocol === 'https:'),
|
||||
auth: this._proxyAuthorization,
|
||||
ca: this._trustedCertificates,
|
||||
key: this._key,
|
||||
passphrase: this._passphrase,
|
||||
cert: this._certificate
|
||||
}, _.isUndefined);
|
||||
const proxyOptions = _.assign({}, parsedProxyURL, proxyOverrides);
|
||||
let HttpsProxyAgent;
|
||||
try {
|
||||
HttpsProxyAgent = require('https-proxy-agent');
|
||||
@@ -123,11 +137,24 @@ class Connection extends EventEmitter {
|
||||
}
|
||||
options.agent = new HttpsProxyAgent(proxyOptions);
|
||||
}
|
||||
if (authorization !== undefined) {
|
||||
const base64 = new Buffer(authorization).toString('base64');
|
||||
if (this._authorization !== undefined) {
|
||||
const base64 = new Buffer(this._authorization).toString('base64');
|
||||
options.headers = {Authorization: `Basic ${base64}`};
|
||||
}
|
||||
return new WebSocket(url, options);
|
||||
const optionsOverrides = _.omit({
|
||||
ca: this._trustedCertificates,
|
||||
key: this._key,
|
||||
passphrase: this._passphrase,
|
||||
cert: this._certificate
|
||||
}, _.isUndefined);
|
||||
const websocketOptions = _.assign({}, options, optionsOverrides);
|
||||
const websocket = new WebSocket(this._url, null, websocketOptions);
|
||||
// we will have a listener for each outstanding request,
|
||||
// so we have to raise the limit (the default is 10)
|
||||
if (typeof websocket.setMaxListeners === 'function') {
|
||||
websocket.setMaxListeners(Infinity);
|
||||
}
|
||||
return websocket;
|
||||
}
|
||||
|
||||
connect() {
|
||||
@@ -141,9 +168,13 @@ class Connection extends EventEmitter {
|
||||
} else if (this._state === WebSocket.CONNECTING) {
|
||||
this._ws.once('open', resolve);
|
||||
} else {
|
||||
this._ws = this._createWebSocket(this._url, this._proxyURL,
|
||||
this._proxyAuthorization, this._authorization,
|
||||
this._trustedCertificates);
|
||||
this._ws = this._createWebSocket();
|
||||
// when an error causes the connection to close, the close event
|
||||
// should still be emitted; the "ws" documentation says: "The close
|
||||
// event is also emitted when then underlying net.Socket closes the
|
||||
// connection (end or close)."
|
||||
this._ws.on('error', error =>
|
||||
this.emit('error', 'websocket', error.messsage, error));
|
||||
this._ws.on('message', this._onMessage.bind(this));
|
||||
this._onUnexpectedCloseBound = this._onUnexpectedClose.bind(this);
|
||||
this._ws.once('close', this._onUnexpectedCloseBound);
|
||||
|
||||
@@ -7,7 +7,9 @@ class RippleError extends Error {
|
||||
this.name = this.constructor.name;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
Error.captureStackTrace(this, this.constructor.name);
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor.name);
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -92,8 +92,10 @@ function loadSchemas() {
|
||||
require('./schemas/input/prepare-suspended-payment-cancellation.json'),
|
||||
require('./schemas/input/prepare-suspended-payment-execution.json'),
|
||||
require('./schemas/input/compute-ledger-hash'),
|
||||
require('./schemas/input/sign'),
|
||||
require('./schemas/input/submit')
|
||||
require('./schemas/input/sign.json'),
|
||||
require('./schemas/input/submit.json'),
|
||||
require('./schemas/input/generate-address.json'),
|
||||
require('./schemas/input/combine.json')
|
||||
];
|
||||
const titles = _.map(schemas, schema => schema.title);
|
||||
const duplicates = _.keys(_.pick(_.countBy(titles), count => count > 1));
|
||||
|
||||
@@ -42,6 +42,18 @@
|
||||
"type": "string",
|
||||
"description": "A PEM-formatted SSL certificate to trust when connecting to a proxy."
|
||||
}
|
||||
},
|
||||
"key": {
|
||||
"type": "string",
|
||||
"description": "A string containing the private key of the client in PEM format. (Can be an array of keys)."
|
||||
},
|
||||
"passphrase": {
|
||||
"type": "string",
|
||||
"description": "The passphrase for the private key of the client."
|
||||
},
|
||||
"certificate": {
|
||||
"type": "string",
|
||||
"description": "A string containing the certificate key of the client in PEM format. (Can be an array of certificates)."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
||||
19
src/common/schemas/input/combine.json
Normal file
19
src/common/schemas/input/combine.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "combineParameters",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"signedTransactions": {
|
||||
"type": "array",
|
||||
"description": "An array of signed transactions (from the output of [sign](#sign)) to combine.",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-F0-9]+$",
|
||||
"description": "A single-signed transaction represented as an uppercase hexadecimal string (from the output of [sign](#sign))"
|
||||
},
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["signedTransactions"]
|
||||
}
|
||||
29
src/common/schemas/input/generate-address.json
Normal file
29
src/common/schemas/input/generate-address.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "generateAddressParameters",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"options": {
|
||||
"type": "object",
|
||||
"description": "Options to control how the address and secret are generated.",
|
||||
"properties": {
|
||||
"entropy": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 255
|
||||
},
|
||||
"description": "The entropy to use to generate the seed."
|
||||
},
|
||||
"algorithm": {
|
||||
"type": "string",
|
||||
"enum": ["ecdsa-secp256k1", "ed25519"],
|
||||
"description": "The digital signature algorithm to generate an address for. Can be `ecdsa-secp256k1` (default) or `ed25519`."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -11,6 +11,17 @@
|
||||
"type": "string",
|
||||
"format": "secret",
|
||||
"description": "The secret of the account that is initiating the transaction."
|
||||
},
|
||||
"options": {
|
||||
"type": "object",
|
||||
"description": "Options that control the type of signature that will be generated.",
|
||||
"properties": {
|
||||
"signAs": {
|
||||
"$ref": "address",
|
||||
"description": "The account that the signature should count for in multisigning."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
||||
@@ -18,13 +18,21 @@
|
||||
"$ref": "value"
|
||||
},
|
||||
"maxLedgerVersion": {
|
||||
"description": "The highest ledger version that the transaction can be included in.",
|
||||
"$ref": "ledgerVersion"
|
||||
"description": "The highest ledger version that the transaction can be included in. If this option and `maxLedgerVersionOffset` are both omitted, the `maxLedgerVersion` option will default to 3 greater than the current validated ledger version (equivalent to `maxLedgerVersionOffset=3`). Use `null` to not set a maximum ledger version.",
|
||||
"oneOf": [
|
||||
{"$ref": "ledgerVersion"},
|
||||
{"type": "null"}
|
||||
]
|
||||
},
|
||||
"maxLedgerVersionOffset": {
|
||||
"description": "Offset from current legder version to highest ledger version that the transaction can be included in.",
|
||||
"description": "Offset from current validated legder version to highest ledger version that the transaction can be included in.",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"signersCount": {
|
||||
"description": "Number of signers that will be signing this transaction.",
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
||||
@@ -68,6 +68,35 @@
|
||||
],
|
||||
"description": "The public key of a new keypair, to use as the regular key to this account, as a base-58-encoded string in the same format as an account address. Use `null` to remove the regular key."
|
||||
},
|
||||
"signers": {
|
||||
"type": "object",
|
||||
"description": "Settings that determine what sets of accounts can be used to sign a transaction on behalf of this account using multisigning.",
|
||||
"properties": {
|
||||
"threshold": {
|
||||
"$ref": "uint32",
|
||||
"description": "A target number for the signer weights. A multi-signature from this list is valid only if the sum weights of the signatures provided is equal or greater than this value. To delete the signers setting, use the value `0`."
|
||||
},
|
||||
"weights": {
|
||||
"type": "array",
|
||||
"description": "Weights of signatures for each signer.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "An association of an address and a weight.",
|
||||
"properties": {
|
||||
"address": {"$ref": "address"},
|
||||
"weight": {
|
||||
"$ref": "uint32",
|
||||
"description": "The weight that the signature of this account counts as towards the threshold."
|
||||
}
|
||||
},
|
||||
"required": ["address", "weight"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"minItems": 1,
|
||||
"maxItems": 8
|
||||
}
|
||||
}
|
||||
},
|
||||
"memos": {"$ref": "memos"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
"description": "The time since the ledger was closed, in seconds."
|
||||
},
|
||||
"baseFeeXRP": {
|
||||
"type": "number",
|
||||
"$ref": "value",
|
||||
"description": "Base fee, in XRP. This may be represented in scientific notation such as 1e-05 for 0.00005."
|
||||
},
|
||||
"hash": {
|
||||
@@ -91,13 +91,11 @@
|
||||
"description": "Unique hash for the ledger, as an uppercase hexadecimal string."
|
||||
},
|
||||
"reserveBaseXRP": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"$ref": "value",
|
||||
"description": "Minimum amount of XRP necessary for every account to keep in reserve."
|
||||
},
|
||||
"reserveIncrementXRP": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"$ref": "value",
|
||||
"description": "Amount of XRP added to the account reserve for each object an account is responsible for in the ledger."
|
||||
},
|
||||
"ledgerVersion": {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
},
|
||||
"reserveBaseXRP": {
|
||||
"$ref": "value",
|
||||
"description": "The minimum reserve, in drops of XRP, that is required for an account."
|
||||
"description": "The minimum reserve, in XRP, that is required for an account."
|
||||
},
|
||||
"reserveIncrementXRP": {
|
||||
"$ref": "value",
|
||||
|
||||
@@ -21,12 +21,15 @@
|
||||
"description": "The initiating account's sequence number for this transaction."
|
||||
},
|
||||
"maxLedgerVersion": {
|
||||
"$ref": "ledgerVersion",
|
||||
"description": "The highest ledger version that the transaction can be included in."
|
||||
"oneOf": [
|
||||
{"$ref": "ledgerVersion"},
|
||||
{"type": "null"}
|
||||
],
|
||||
"description": "The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["fee", "sequence"]
|
||||
"required": ["fee", "sequence", "maxLedgerVersion"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {Connection} from './connection';
|
||||
export type GetServerInfoResponse = {
|
||||
buildVersion: string,
|
||||
completeLedgers: string,
|
||||
hostid: string,
|
||||
hostID: string,
|
||||
ioLatencyMs: number,
|
||||
load?: {
|
||||
jobTypes: Array<Object>,
|
||||
@@ -23,11 +23,11 @@ export type GetServerInfoResponse = {
|
||||
serverState: string,
|
||||
validatedLedger: {
|
||||
age: number,
|
||||
baseFeeXrp: number,
|
||||
baseFeeXRP: string,
|
||||
hash: string,
|
||||
reserveBaseXrp: number,
|
||||
reserveIncXrp: number,
|
||||
seq: number
|
||||
reserveBaseXRP: string,
|
||||
reserveIncrementXRP: string,
|
||||
ledgerVersion: number
|
||||
},
|
||||
validationQuorum: number
|
||||
}
|
||||
@@ -49,6 +49,12 @@ function getServerInfo(connection: Connection): Promise<GetServerInfoResponse> {
|
||||
reserveIncXrp: 'reserveIncrementXRP',
|
||||
seq: 'ledgerVersion'
|
||||
});
|
||||
info.validatedLedger.baseFeeXRP =
|
||||
info.validatedLedger.baseFeeXRP.toString();
|
||||
info.validatedLedger.reserveBaseXRP =
|
||||
info.validatedLedger.reserveBaseXRP.toString();
|
||||
info.validatedLedger.reserveIncrementXRP =
|
||||
info.validatedLedger.reserveIncrementXRP.toString();
|
||||
return info;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
export type RippledAmountIOU = {
|
||||
currency: string,
|
||||
value: string,
|
||||
issuer?: string
|
||||
}
|
||||
|
||||
export type RippledAmount = string | RippledAmountIOU
|
||||
|
||||
|
||||
export type Amount = {
|
||||
value: string,
|
||||
currency: string,
|
||||
counterparty?: string
|
||||
}
|
||||
|
||||
|
||||
// Amount where counterparty and value are optional
|
||||
export type LaxLaxAmount = {
|
||||
currency: string,
|
||||
value?: string,
|
||||
counterparty?: string
|
||||
}
|
||||
|
||||
// A currency-counterparty pair, or just currency if it's XRP
|
||||
export type Issue = {
|
||||
currency: string,
|
||||
counterparty?: string
|
||||
}
|
||||
|
||||
export type Adjustment = {
|
||||
address: string,
|
||||
amount: Amount,
|
||||
tag?: number
|
||||
}
|
||||
|
||||
export type MaxAdjustment = {
|
||||
address: string,
|
||||
maxAmount: Amount,
|
||||
tag?: number
|
||||
}
|
||||
|
||||
export type MinAdjustment = {
|
||||
address: string,
|
||||
minAmount: Amount,
|
||||
tag?: number
|
||||
}
|
||||
|
||||
export type Memo = {
|
||||
type?: string,
|
||||
format?: string,
|
||||
data?: string
|
||||
}
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
export type RippledAmountIOU = {
|
||||
currency: string,
|
||||
value: string,
|
||||
issuer?: string
|
||||
}
|
||||
|
||||
export type RippledAmount = string | RippledAmountIOU
|
||||
|
||||
|
||||
export type Amount = {
|
||||
value: string,
|
||||
currency: string,
|
||||
counterparty?: string
|
||||
}
|
||||
|
||||
|
||||
// Amount where counterparty and value are optional
|
||||
export type LaxLaxAmount = {
|
||||
currency: string,
|
||||
value?: string,
|
||||
counterparty?: string
|
||||
}
|
||||
|
||||
// A currency-counterparty pair, or just currency if it's XRP
|
||||
export type Issue = {
|
||||
currency: string,
|
||||
counterparty?: string
|
||||
}
|
||||
|
||||
export type Adjustment = {
|
||||
address: string,
|
||||
amount: Amount,
|
||||
tag?: number
|
||||
}
|
||||
|
||||
export type MaxAdjustment = {
|
||||
address: string,
|
||||
maxAmount: Amount,
|
||||
tag?: number
|
||||
}
|
||||
|
||||
export type MinAdjustment = {
|
||||
address: string,
|
||||
minAmount: Amount,
|
||||
tag?: number
|
||||
}
|
||||
|
||||
export type Memo = {
|
||||
type?: string,
|
||||
format?: string,
|
||||
data?: string
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const BigNumber = require('bignumber.js');
|
||||
const errors = require('./errors');
|
||||
const keypairs = require('ripple-keypairs');
|
||||
const {deriveKeypair} = require('ripple-keypairs');
|
||||
|
||||
import type {Amount, RippledAmount} from './types.js';
|
||||
@@ -37,27 +35,13 @@ function toRippledAmount(amount: Amount): RippledAmount {
|
||||
};
|
||||
}
|
||||
|
||||
function generateAddress(options?: Object): Object {
|
||||
const secret = keypairs.generateSeed(options);
|
||||
const keypair = keypairs.deriveKeypair(secret);
|
||||
const address = keypairs.deriveAddress(keypair.publicKey);
|
||||
return {secret, address};
|
||||
}
|
||||
|
||||
function generateAddressAPI(options?: Object): Object {
|
||||
try {
|
||||
return generateAddress(options);
|
||||
} catch (error) {
|
||||
throw new errors.UnexpectedError(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
const FINDSNAKE = /([a-zA-Z]_[a-zA-Z])/g;
|
||||
function convertKeysFromSnakeCaseToCamelCase(obj: any): any {
|
||||
if (typeof obj === 'object') {
|
||||
let newKey;
|
||||
return _.reduce(obj, (result, value, key) => {
|
||||
newKey = key;
|
||||
// taking this out of function leads to error in PhantomJS
|
||||
const FINDSNAKE = /([a-zA-Z]_[a-zA-Z])/g;
|
||||
if (FINDSNAKE.test(key)) {
|
||||
newKey = key.replace(FINDSNAKE, r => r[0] + r[2].toUpperCase());
|
||||
}
|
||||
@@ -101,8 +85,6 @@ module.exports = {
|
||||
dropsToXrp,
|
||||
xrpToDrops,
|
||||
toRippledAmount,
|
||||
generateAddress,
|
||||
generateAddressAPI,
|
||||
convertKeysFromSnakeCaseToCamelCase,
|
||||
removeUndefined,
|
||||
rippleTimeToISO8601,
|
||||
|
||||
@@ -47,8 +47,10 @@ module.exports = {
|
||||
prepareSuspendedPaymentExecution: _.partial(schemaValidate,
|
||||
'prepareSuspendedPaymentExecutionParameters'),
|
||||
sign: _.partial(schemaValidate, 'signParameters'),
|
||||
combine: _.partial(schemaValidate, 'combineParameters'),
|
||||
submit: _.partial(schemaValidate, 'submitParameters'),
|
||||
computeLedgerHash: _.partial(schemaValidate, 'computeLedgerHashParameters'),
|
||||
generateAddress: _.partial(schemaValidate, 'generateAddressParameters'),
|
||||
apiOptions: _.partial(schemaValidate, 'api-options'),
|
||||
instructions: _.partial(schemaValidate, 'instructions')
|
||||
};
|
||||
|
||||
62
src/common/wswrapper.js
Normal file
62
src/common/wswrapper.js
Normal file
@@ -0,0 +1,62 @@
|
||||
'use strict';
|
||||
|
||||
const {EventEmitter} = require('events');
|
||||
|
||||
function unsused() {}
|
||||
|
||||
/**
|
||||
* Provides `EventEmitter` interface for native browser `WebSocket`,
|
||||
* same, as `ws` package provides.
|
||||
*/
|
||||
class WSWrapper extends EventEmitter {
|
||||
constructor(url, protocols = null, websocketOptions = {}) {
|
||||
super();
|
||||
unsused(protocols);
|
||||
unsused(websocketOptions);
|
||||
this.setMaxListeners(Infinity);
|
||||
|
||||
this._ws = new WebSocket(url);
|
||||
|
||||
this._ws.onclose = () => {
|
||||
this.emit('close');
|
||||
};
|
||||
|
||||
this._ws.onopen = () => {
|
||||
this.emit('open');
|
||||
};
|
||||
|
||||
this._ws.onerror = (error) => {
|
||||
if (this.listenerCount('error') > 0) {
|
||||
this.emit('error', error);
|
||||
}
|
||||
};
|
||||
|
||||
this._ws.onmessage = (message) => {
|
||||
this.emit('message', message.data);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
close() {
|
||||
if (this.readyState === 1) {
|
||||
this._ws.close();
|
||||
}
|
||||
}
|
||||
|
||||
send(message) {
|
||||
this._ws.send(message);
|
||||
}
|
||||
|
||||
get readyState() {
|
||||
return this._ws.readyState;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WSWrapper.CONNECTING = 0;
|
||||
WSWrapper.OPEN = 1;
|
||||
WSWrapper.CLOSING = 2;
|
||||
WSWrapper.CLOSED = 3;
|
||||
|
||||
module.exports = WSWrapper;
|
||||
|
||||
85
src/http.js
Normal file
85
src/http.js
Normal file
@@ -0,0 +1,85 @@
|
||||
/* eslint-disable new-cap */
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const _ = require('lodash');
|
||||
const jayson = require('jayson');
|
||||
|
||||
const RippleAPI = require('./api').RippleAPI;
|
||||
|
||||
|
||||
function createHTTPServer(options, httpPort) {
|
||||
const rippleAPI = new RippleAPI(options);
|
||||
|
||||
const methodNames = _.filter(_.keys(RippleAPI.prototype), k => {
|
||||
return typeof RippleAPI.prototype[k] === 'function'
|
||||
&& k !== 'connect'
|
||||
&& k !== 'disconnect'
|
||||
&& k !== 'constructor'
|
||||
&& k !== 'RippleAPI';
|
||||
});
|
||||
|
||||
function applyPromiseWithCallback(fnName, callback, args_) {
|
||||
try {
|
||||
let args = args_;
|
||||
if (!_.isArray(args_)) {
|
||||
const fnParameters = jayson.Utils.getParameterNames(rippleAPI[fnName]);
|
||||
args = fnParameters.map(name => args_[name]);
|
||||
const defaultArgs = _.omit(args_, fnParameters);
|
||||
assert(_.size(defaultArgs) <= 1,
|
||||
'Function must have no more than one default argument');
|
||||
if (_.size(defaultArgs) > 0) {
|
||||
args.push(defaultArgs[_.keys(defaultArgs)[0]]);
|
||||
}
|
||||
}
|
||||
Promise.resolve(rippleAPI[fnName].apply(rippleAPI, args))
|
||||
.then(res => callback(null, res))
|
||||
.catch(err => {
|
||||
callback({code: 99, message: err.message, data: {name: err.name}});
|
||||
});
|
||||
} catch (err) {
|
||||
callback({code: 99, message: err.message, data: {name: err.name}});
|
||||
}
|
||||
}
|
||||
|
||||
const methods = {};
|
||||
_.forEach(methodNames, fn => {
|
||||
methods[fn] = jayson.Method((args, cb) => {
|
||||
applyPromiseWithCallback(fn, cb, args);
|
||||
}, {collect: true});
|
||||
});
|
||||
|
||||
const server = jayson.server(methods);
|
||||
let httpServer = null;
|
||||
|
||||
return {
|
||||
server: server,
|
||||
start: function() {
|
||||
if (httpServer !== null) {
|
||||
return Promise.reject('Already started');
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
rippleAPI.connect().then(() => {
|
||||
httpServer = server.http();
|
||||
httpServer.listen(httpPort, resolve);
|
||||
});
|
||||
});
|
||||
},
|
||||
stop: function() {
|
||||
if (httpServer === null) {
|
||||
return Promise.reject('Not started');
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
rippleAPI.disconnect();
|
||||
httpServer.close(() => {
|
||||
httpServer = null;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createHTTPServer
|
||||
};
|
||||
@@ -2,5 +2,8 @@
|
||||
|
||||
module.exports = {
|
||||
RippleAPI: require('./api').RippleAPI,
|
||||
RippleAPIBroadcast: require('./broadcast').RippleAPIBroadcast
|
||||
// Broadcast api is experimental
|
||||
RippleAPIBroadcast: require('./broadcast').RippleAPIBroadcast,
|
||||
// HTTP server is experimental
|
||||
createHTTPServer: require('./http').createHTTPServer
|
||||
};
|
||||
|
||||
@@ -24,8 +24,8 @@ function parseAccountTrustline(trustline: Trustline): AccountTrustline {
|
||||
limit: trustline.limit,
|
||||
currency: trustline.currency,
|
||||
counterparty: trustline.account,
|
||||
qualityIn: trustline.quality_in || undefined,
|
||||
qualityOut: trustline.quality_out || undefined,
|
||||
qualityIn: utils.parseQuality(trustline.quality_in) || undefined,
|
||||
qualityOut: utils.parseQuality(trustline.quality_out) || undefined,
|
||||
ripplingDisabled: trustline.no_ripple || undefined,
|
||||
frozen: trustline.freeze || undefined,
|
||||
authorized: trustline.authorized || undefined
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const BigNumber = require('bignumber.js');
|
||||
const AccountFields = require('./utils').constants.AccountFields;
|
||||
|
||||
@@ -22,6 +23,26 @@ function parseFields(data: Object): Object {
|
||||
settings[info.name] = parseField(info, fieldValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.RegularKey) {
|
||||
settings.regularKey = data.RegularKey;
|
||||
}
|
||||
|
||||
// TODO: this isn't implemented in rippled yet, may have to change this later
|
||||
if (data.SignerQuorum || data.SignerEntries) {
|
||||
settings.signers = {};
|
||||
if (data.SignerQuorum) {
|
||||
settings.signers.threshold = data.SignerQuorum;
|
||||
}
|
||||
if (data.SignerEntries) {
|
||||
settings.signers.weights = _.map(data.SignerEntries, entry => {
|
||||
return {
|
||||
address: entry.SignerEntry.Account,
|
||||
weight: entry.SignerEntry.SignerWeight
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,10 +52,10 @@ function parseFlags(tx: Object) {
|
||||
|
||||
function parseSettings(tx: Object) {
|
||||
const txType = tx.TransactionType;
|
||||
assert(txType === 'AccountSet' || txType === 'SetRegularKey');
|
||||
assert(txType === 'AccountSet' || txType === 'SetRegularKey' ||
|
||||
txType === 'SignerListSet');
|
||||
|
||||
const regularKey = tx.RegularKey ? {regularKey: tx.RegularKey} : {};
|
||||
return _.assign(regularKey, parseFlags(tx), parseFields(tx));
|
||||
return _.assign({}, parseFlags(tx), parseFields(tx));
|
||||
}
|
||||
|
||||
module.exports = parseSettings;
|
||||
|
||||
@@ -22,7 +22,8 @@ function parseTransactionType(type) {
|
||||
SetRegularKey: 'settings',
|
||||
SuspendedPaymentCreate: 'suspendedPaymentCreation',
|
||||
SuspendedPaymentFinish: 'suspendedPaymentExecution',
|
||||
SuspendedPaymentCancel: 'suspendedPaymentCancellation'
|
||||
SuspendedPaymentCancel: 'suspendedPaymentCancellation',
|
||||
SignerListSet: 'settings'
|
||||
};
|
||||
return mapping[type] || null;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
const flags = utils.txFlags.TrustSet;
|
||||
const BigNumber = require('bignumber.js');
|
||||
|
||||
function parseFlag(flagsValue, trueValue, falseValue) {
|
||||
if (flagsValue & trueValue) {
|
||||
@@ -15,13 +14,6 @@ function parseFlag(flagsValue, trueValue, falseValue) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseQuality(quality?: number) {
|
||||
if (typeof quality === 'number') {
|
||||
return (new BigNumber(quality)).shift(-9).toNumber();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseTrustline(tx: Object): Object {
|
||||
assert(tx.TransactionType === 'TrustSet');
|
||||
|
||||
@@ -29,8 +21,8 @@ function parseTrustline(tx: Object): Object {
|
||||
limit: tx.LimitAmount.value,
|
||||
currency: tx.LimitAmount.currency,
|
||||
counterparty: tx.LimitAmount.issuer,
|
||||
qualityIn: parseQuality(tx.QualityIn),
|
||||
qualityOut: parseQuality(tx.QualityOut),
|
||||
qualityIn: utils.parseQuality(tx.QualityIn),
|
||||
qualityOut: utils.parseQuality(tx.QualityOut),
|
||||
ripplingDisabled: parseFlag(
|
||||
tx.Flags, flags.SetNoRipple, flags.ClearNoRipple),
|
||||
frozen: parseFlag(tx.Flags, flags.SetFreeze, flags.ClearFreeze),
|
||||
|
||||
@@ -17,6 +17,13 @@ function adjustQualityForXRP(
|
||||
(new BigNumber(quality)).shift(shift).toString();
|
||||
}
|
||||
|
||||
function parseQuality(quality: ?number) {
|
||||
if (typeof quality === 'number') {
|
||||
return (new BigNumber(quality)).shift(-9).toNumber();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseTimestamp(rippleTime: number): string | void {
|
||||
return rippleTime ? utils.common.rippleTimeToISO8601(rippleTime) : undefined;
|
||||
}
|
||||
@@ -80,6 +87,7 @@ function parseMemos(tx: Object): ?Array<Object> {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseQuality,
|
||||
parseOutcome,
|
||||
parseMemos,
|
||||
hexToString,
|
||||
|
||||
@@ -85,6 +85,20 @@ function conditionallyAddDirectXRPPath(connection: Connection, address: string,
|
||||
xrpBalance => addDirectXrpPath(paths, xrpBalance));
|
||||
}
|
||||
|
||||
function filterSourceFundsLowPaths(pathfind: PathFind,
|
||||
paths: RippledPathsResponse
|
||||
): RippledPathsResponse {
|
||||
if (pathfind.source.amount &&
|
||||
pathfind.destination.amount.value === undefined && paths.alternatives) {
|
||||
paths.alternatives = _.filter(paths.alternatives, alt => {
|
||||
return alt.source_amount &&
|
||||
pathfind.source.amount &&
|
||||
alt.source_amount.value === pathfind.source.amount.value;
|
||||
});
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
function formatResponse(pathfind: PathFind, paths: RippledPathsResponse) {
|
||||
if (paths.alternatives && paths.alternatives.length > 0) {
|
||||
return parsePathfind(paths);
|
||||
@@ -116,7 +130,9 @@ function getPaths(pathfind: PathFind): Promise<GetPaths> {
|
||||
const address = pathfind.source.address;
|
||||
return requestPathFind(this.connection, pathfind).then(paths =>
|
||||
conditionallyAddDirectXRPPath(this.connection, address, paths)
|
||||
).then(paths => formatResponse(pathfind, paths));
|
||||
)
|
||||
.then(paths => filterSourceFundsLowPaths(pathfind, paths))
|
||||
.then(paths => formatResponse(pathfind, paths));
|
||||
}
|
||||
|
||||
module.exports = getPaths;
|
||||
|
||||
@@ -1,135 +1,135 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
import type {Amount, Memo} from '../common/types.js';
|
||||
|
||||
type Outcome = {
|
||||
result: string,
|
||||
ledgerVersion: number,
|
||||
indexInLedger: number,
|
||||
fee: string,
|
||||
balanceChanges: {
|
||||
[key: string]: [{
|
||||
currency: string,
|
||||
counterparty?: string,
|
||||
value: string
|
||||
}]
|
||||
},
|
||||
orderbookChanges: Object,
|
||||
timestamp?: string
|
||||
}
|
||||
|
||||
type Adjustment = {
|
||||
address: string,
|
||||
amount: {
|
||||
currency: string,
|
||||
counterparty?: string,
|
||||
value: string
|
||||
},
|
||||
tag?: number
|
||||
}
|
||||
|
||||
type Trustline = {
|
||||
currency: string,
|
||||
counterparty: string,
|
||||
limit: string,
|
||||
qualityIn?: number,
|
||||
qualityOut?: number,
|
||||
ripplingDisabled?: boolean,
|
||||
authorized?: boolean,
|
||||
frozen?: boolean
|
||||
}
|
||||
|
||||
type Settings = {
|
||||
passwordSpent?: boolean,
|
||||
requireDestinationTag?: boolean,
|
||||
requireAuthorization?: boolean,
|
||||
disallowIncomingXRP?: boolean,
|
||||
disableMasterKey?: boolean,
|
||||
enableTransactionIDTracking?: boolean,
|
||||
noFreeze?: boolean,
|
||||
globalFreeze?: boolean,
|
||||
defaultRipple?: boolean,
|
||||
emailHash?: string,
|
||||
messageKey?: string,
|
||||
domain?: string,
|
||||
transferRate?: number,
|
||||
regularKey?: string
|
||||
}
|
||||
|
||||
type OrderCancellation = {
|
||||
orderSequence: number
|
||||
}
|
||||
|
||||
type Payment = {
|
||||
source: Adjustment,
|
||||
destination: Adjustment,
|
||||
paths?: string,
|
||||
memos?: Array<Memo>,
|
||||
invoiceID?: string,
|
||||
allowPartialPayment?: boolean,
|
||||
noDirectRipple?: boolean,
|
||||
limitQuality?: boolean
|
||||
}
|
||||
|
||||
type PaymentTransaction = {
|
||||
type: string,
|
||||
specification: Payment,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type Order = {
|
||||
direction: string,
|
||||
quantity: Amount,
|
||||
totalPrice: Amount,
|
||||
immediateOrCancel?: boolean,
|
||||
fillOrKill?: boolean,
|
||||
passive?: boolean
|
||||
}
|
||||
|
||||
type OrderTransaction = {
|
||||
type: string,
|
||||
specification: Order,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
type OrderCancellationTransaction = {
|
||||
type: string,
|
||||
specification: OrderCancellation,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
type TrustlineTransaction = {
|
||||
type: string,
|
||||
specification: Trustline,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
type SettingsTransaction = {
|
||||
type: string,
|
||||
specification: Settings,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type TransactionOptions = {
|
||||
minLedgerVersion?: number,
|
||||
maxLedgerVersion?: number
|
||||
}
|
||||
|
||||
export type TransactionType = PaymentTransaction | OrderTransaction |
|
||||
OrderCancellationTransaction | TrustlineTransaction | SettingsTransaction
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
import type {Amount, Memo} from '../common/types.js';
|
||||
|
||||
type Outcome = {
|
||||
result: string,
|
||||
ledgerVersion: number,
|
||||
indexInLedger: number,
|
||||
fee: string,
|
||||
balanceChanges: {
|
||||
[key: string]: [{
|
||||
currency: string,
|
||||
counterparty?: string,
|
||||
value: string
|
||||
}]
|
||||
},
|
||||
orderbookChanges: Object,
|
||||
timestamp?: string
|
||||
}
|
||||
|
||||
type Adjustment = {
|
||||
address: string,
|
||||
amount: {
|
||||
currency: string,
|
||||
counterparty?: string,
|
||||
value: string
|
||||
},
|
||||
tag?: number
|
||||
}
|
||||
|
||||
type Trustline = {
|
||||
currency: string,
|
||||
counterparty: string,
|
||||
limit: string,
|
||||
qualityIn?: number,
|
||||
qualityOut?: number,
|
||||
ripplingDisabled?: boolean,
|
||||
authorized?: boolean,
|
||||
frozen?: boolean
|
||||
}
|
||||
|
||||
type Settings = {
|
||||
passwordSpent?: boolean,
|
||||
requireDestinationTag?: boolean,
|
||||
requireAuthorization?: boolean,
|
||||
disallowIncomingXRP?: boolean,
|
||||
disableMasterKey?: boolean,
|
||||
enableTransactionIDTracking?: boolean,
|
||||
noFreeze?: boolean,
|
||||
globalFreeze?: boolean,
|
||||
defaultRipple?: boolean,
|
||||
emailHash?: string,
|
||||
messageKey?: string,
|
||||
domain?: string,
|
||||
transferRate?: number,
|
||||
regularKey?: string
|
||||
}
|
||||
|
||||
type OrderCancellation = {
|
||||
orderSequence: number
|
||||
}
|
||||
|
||||
type Payment = {
|
||||
source: Adjustment,
|
||||
destination: Adjustment,
|
||||
paths?: string,
|
||||
memos?: Array<Memo>,
|
||||
invoiceID?: string,
|
||||
allowPartialPayment?: boolean,
|
||||
noDirectRipple?: boolean,
|
||||
limitQuality?: boolean
|
||||
}
|
||||
|
||||
type PaymentTransaction = {
|
||||
type: string,
|
||||
specification: Payment,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type Order = {
|
||||
direction: string,
|
||||
quantity: Amount,
|
||||
totalPrice: Amount,
|
||||
immediateOrCancel?: boolean,
|
||||
fillOrKill?: boolean,
|
||||
passive?: boolean
|
||||
}
|
||||
|
||||
type OrderTransaction = {
|
||||
type: string,
|
||||
specification: Order,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
type OrderCancellationTransaction = {
|
||||
type: string,
|
||||
specification: OrderCancellation,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
type TrustlineTransaction = {
|
||||
type: string,
|
||||
specification: Trustline,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
type SettingsTransaction = {
|
||||
type: string,
|
||||
specification: Settings,
|
||||
outcome: Outcome,
|
||||
id: string,
|
||||
address: string,
|
||||
sequence: number
|
||||
}
|
||||
|
||||
export type TransactionOptions = {
|
||||
minLedgerVersion?: number,
|
||||
maxLedgerVersion?: number
|
||||
}
|
||||
|
||||
export type TransactionType = PaymentTransaction | OrderTransaction |
|
||||
OrderCancellationTransaction | TrustlineTransaction | SettingsTransaction
|
||||
|
||||
@@ -170,11 +170,11 @@ function getTransactions(address: string, options: TransactionsOptions = {}
|
||||
const ledgerVersion = tx.outcome.ledgerVersion;
|
||||
const bound = options.earliestFirst ?
|
||||
{minLedgerVersion: ledgerVersion} : {maxLedgerVersion: ledgerVersion};
|
||||
const newOptions = _.assign(defaults, options, {startTx: tx}, bound);
|
||||
const newOptions = _.assign({}, defaults, options, {startTx: tx}, bound);
|
||||
return getTransactionsInternal(this.connection, address, newOptions);
|
||||
});
|
||||
}
|
||||
const newOptions = _.assign(defaults, options);
|
||||
const newOptions = _.assign({}, defaults, options);
|
||||
return getTransactionsInternal(this.connection, address, newOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
export type TrustLineSpecification = {
|
||||
currency: string,
|
||||
counterparty: string,
|
||||
limit: string,
|
||||
qualityIn?: number,
|
||||
qualityOut?: number,
|
||||
ripplingDisabled?: boolean,
|
||||
authorized?: boolean,
|
||||
frozen?: boolean
|
||||
}
|
||||
|
||||
export type Trustline = {
|
||||
specification: TrustLineSpecification,
|
||||
counterparty: {
|
||||
limit: string,
|
||||
ripplingDisabled?: boolean,
|
||||
frozen?: boolean,
|
||||
authorized?: boolean
|
||||
},
|
||||
state: {
|
||||
balance: string
|
||||
}
|
||||
}
|
||||
|
||||
export type TrustlinesOptions = {
|
||||
counterparty?: string,
|
||||
currency?: string,
|
||||
limit?: number,
|
||||
ledgerVersion?: number
|
||||
}
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
export type TrustLineSpecification = {
|
||||
currency: string,
|
||||
counterparty: string,
|
||||
limit: string,
|
||||
qualityIn?: number,
|
||||
qualityOut?: number,
|
||||
ripplingDisabled?: boolean,
|
||||
authorized?: boolean,
|
||||
frozen?: boolean
|
||||
}
|
||||
|
||||
export type Trustline = {
|
||||
specification: TrustLineSpecification,
|
||||
counterparty: {
|
||||
limit: string,
|
||||
ripplingDisabled?: boolean,
|
||||
frozen?: boolean,
|
||||
authorized?: boolean
|
||||
},
|
||||
state: {
|
||||
balance: string
|
||||
}
|
||||
}
|
||||
|
||||
export type TrustlinesOptions = {
|
||||
counterparty?: string,
|
||||
currency?: string,
|
||||
limit?: number,
|
||||
ledgerVersion?: number
|
||||
}
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
import type {Amount} from '../common/types.js';
|
||||
|
||||
export type OrdersOptions = {
|
||||
limit?: number,
|
||||
ledgerVersion?: number
|
||||
}
|
||||
|
||||
export type OrderSpecification = {
|
||||
direction: string,
|
||||
quantity: Amount,
|
||||
totalPrice: Amount,
|
||||
immediateOrCancel?: boolean,
|
||||
fillOrKill?: boolean,
|
||||
// If enabled, the offer will not consume offers that exactly match it, and
|
||||
// instead becomes an Offer node in the ledger. It will still consume offers
|
||||
// that cross it.
|
||||
passive?: boolean
|
||||
}
|
||||
|
||||
export type Order = {
|
||||
specification: OrderSpecification,
|
||||
properties: {
|
||||
maker: string,
|
||||
sequence: number,
|
||||
makerExchangeRate: string
|
||||
}
|
||||
}
|
||||
|
||||
export type GetLedger = {
|
||||
accepted: boolean,
|
||||
closed: boolean,
|
||||
stateHash: string,
|
||||
closeTime: number,
|
||||
closeTimeResolution: number,
|
||||
closeFlags: number,
|
||||
ledgerHash: string,
|
||||
ledgerVersion: number,
|
||||
parentLedgerHash: string,
|
||||
parentCloseTime: number,
|
||||
totalDrops: string,
|
||||
transactionHash: string,
|
||||
transactions?: Array<Object>,
|
||||
rawTransactions?: string,
|
||||
transactionHashes?: Array<string>,
|
||||
rawState?: string,
|
||||
stateHashes?: Array<string>
|
||||
}
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
import type {Amount} from '../common/types.js';
|
||||
|
||||
export type OrdersOptions = {
|
||||
limit?: number,
|
||||
ledgerVersion?: number
|
||||
}
|
||||
|
||||
export type OrderSpecification = {
|
||||
direction: string,
|
||||
quantity: Amount,
|
||||
totalPrice: Amount,
|
||||
immediateOrCancel?: boolean,
|
||||
fillOrKill?: boolean,
|
||||
// If enabled, the offer will not consume offers that exactly match it, and
|
||||
// instead becomes an Offer node in the ledger. It will still consume offers
|
||||
// that cross it.
|
||||
passive?: boolean
|
||||
}
|
||||
|
||||
export type Order = {
|
||||
specification: OrderSpecification,
|
||||
properties: {
|
||||
maker: string,
|
||||
sequence: number,
|
||||
makerExchangeRate: string
|
||||
}
|
||||
}
|
||||
|
||||
export type GetLedger = {
|
||||
accepted: boolean,
|
||||
closed: boolean,
|
||||
stateHash: string,
|
||||
closeTime: number,
|
||||
closeTimeResolution: number,
|
||||
closeFlags: number,
|
||||
ledgerHash: string,
|
||||
ledgerVersion: number,
|
||||
parentLedgerHash: string,
|
||||
parentCloseTime: number,
|
||||
totalDrops: string,
|
||||
transactionHash: string,
|
||||
transactions?: Array<Object>,
|
||||
rawTransactions?: string,
|
||||
transactionHashes?: Array<string>,
|
||||
rawState?: string,
|
||||
stateHashes?: Array<string>
|
||||
}
|
||||
|
||||
24
src/offline/generate-address.js
Normal file
24
src/offline/generate-address.js
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
const keypairs = require('ripple-keypairs');
|
||||
const common = require('../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};
|
||||
}
|
||||
|
||||
function generateAddressAPI(options?: Object): Object {
|
||||
validate.generateAddress({options});
|
||||
try {
|
||||
return generateAddress(options);
|
||||
} catch (error) {
|
||||
throw new errors.UnexpectedError(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
generateAddressAPI
|
||||
};
|
||||
39
src/transaction/combine.js
Normal file
39
src/transaction/combine.js
Normal file
@@ -0,0 +1,39 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const binary = require('ripple-binary-codec');
|
||||
const utils = require('./utils');
|
||||
const BigNumber = require('bignumber.js');
|
||||
const {decodeAddress} = require('ripple-address-codec');
|
||||
const {validate} = utils.common;
|
||||
const {computeBinaryTransactionHash} = require('ripple-hashes');
|
||||
|
||||
function addressToBigNumber(address) {
|
||||
const hex = (new Buffer(decodeAddress(address))).toString('hex');
|
||||
return new BigNumber(hex, 16);
|
||||
}
|
||||
|
||||
function compareSigners(a, b) {
|
||||
return addressToBigNumber(a.Signer.Account)
|
||||
.comparedTo(addressToBigNumber(b.Signer.Account));
|
||||
}
|
||||
|
||||
function combine(signedTransactions: Array<string>): Object {
|
||||
validate.combine({signedTransactions});
|
||||
|
||||
const txs = _.map(signedTransactions, binary.decode);
|
||||
const tx = _.omit(txs[0], 'Signers');
|
||||
if (!_.every(txs, _tx => _.isEqual(tx, _.omit(_tx, 'Signers')))) {
|
||||
throw new utils.common.errors.ValidationError(
|
||||
'txJSON is not the same for all signedTransactions');
|
||||
}
|
||||
const unsortedSigners = _.reduce(txs, (accumulator, _tx) =>
|
||||
accumulator.concat(_tx.Signers || []), []);
|
||||
const signers = unsortedSigners.sort(compareSigners);
|
||||
const signedTx = _.assign({}, tx, {Signers: signers});
|
||||
const signedTransaction = binary.encode(signedTx);
|
||||
const id = computeBinaryTransactionHash(signedTransaction);
|
||||
return {signedTransaction, id};
|
||||
}
|
||||
|
||||
module.exports = combine;
|
||||
@@ -64,7 +64,7 @@ function createMaximalAmount(amount: Amount): Amount {
|
||||
const maxXRPValue = '100000000000';
|
||||
const maxIOUValue = '9999999999999999e80';
|
||||
const maxValue = amount.currency === 'XRP' ? maxXRPValue : maxIOUValue;
|
||||
return _.assign(amount, {value: maxValue});
|
||||
return _.assign({}, amount, {value: maxValue});
|
||||
}
|
||||
|
||||
function createPaymentTransaction(address: string, paymentArgument: Payment
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
type SettingPasswordSpent = {
|
||||
passwordSpent?: boolean,
|
||||
}
|
||||
type SettingRequireDestinationTag = {
|
||||
requireDestinationTag?: boolean,
|
||||
}
|
||||
type SettingRequireAuthorization = {
|
||||
requireAuthorization?: boolean,
|
||||
}
|
||||
type SettingDisallowIncomingXRP = {
|
||||
disallowIncomingXRP?: boolean,
|
||||
}
|
||||
type SettingDisableMasterKey = {
|
||||
disableMasterKey?: boolean,
|
||||
}
|
||||
type SettingEnableTransactionIDTracking = {
|
||||
enableTransactionIDTracking?: boolean,
|
||||
}
|
||||
type SettingNoFreeze = {
|
||||
noFreeze?: boolean,
|
||||
}
|
||||
type SettingGlobalFreeze = {
|
||||
globalFreeze?: boolean,
|
||||
}
|
||||
type SettingDefaultRipple = {
|
||||
defaultRipple?: boolean,
|
||||
}
|
||||
type SettingEmailHash = {
|
||||
emailHash?: ?string,
|
||||
}
|
||||
type SettingMessageKey = {
|
||||
messageKey?: string,
|
||||
}
|
||||
type SettingDomain = {
|
||||
domain?: string,
|
||||
}
|
||||
type SettingTransferRate = {
|
||||
transferRate?: ?number,
|
||||
}
|
||||
type SettingRegularKey = {
|
||||
regularKey?: string
|
||||
}
|
||||
|
||||
export type Settings = SettingRegularKey |
|
||||
SettingTransferRate | SettingDomain | SettingMessageKey |
|
||||
SettingEmailHash | SettingDefaultRipple |
|
||||
SettingGlobalFreeze | SettingNoFreeze | SettingEnableTransactionIDTracking |
|
||||
SettingDisableMasterKey | SettingDisallowIncomingXRP |
|
||||
SettingRequireAuthorization | SettingRequireDestinationTag |
|
||||
SettingPasswordSpent
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
type SettingPasswordSpent = {
|
||||
passwordSpent?: boolean,
|
||||
}
|
||||
type SettingRequireDestinationTag = {
|
||||
requireDestinationTag?: boolean,
|
||||
}
|
||||
type SettingRequireAuthorization = {
|
||||
requireAuthorization?: boolean,
|
||||
}
|
||||
type SettingDisallowIncomingXRP = {
|
||||
disallowIncomingXRP?: boolean,
|
||||
}
|
||||
type SettingDisableMasterKey = {
|
||||
disableMasterKey?: boolean,
|
||||
}
|
||||
type SettingEnableTransactionIDTracking = {
|
||||
enableTransactionIDTracking?: boolean,
|
||||
}
|
||||
type SettingNoFreeze = {
|
||||
noFreeze?: boolean,
|
||||
}
|
||||
type SettingGlobalFreeze = {
|
||||
globalFreeze?: boolean,
|
||||
}
|
||||
type SettingDefaultRipple = {
|
||||
defaultRipple?: boolean,
|
||||
}
|
||||
type SettingEmailHash = {
|
||||
emailHash?: ?string,
|
||||
}
|
||||
type SettingMessageKey = {
|
||||
messageKey?: string,
|
||||
}
|
||||
type SettingDomain = {
|
||||
domain?: string,
|
||||
}
|
||||
type SettingTransferRate = {
|
||||
transferRate?: ?number,
|
||||
}
|
||||
type SettingRegularKey = {
|
||||
regularKey?: string
|
||||
}
|
||||
|
||||
export type Settings = SettingRegularKey |
|
||||
SettingTransferRate | SettingDomain | SettingMessageKey |
|
||||
SettingEmailHash | SettingDefaultRipple |
|
||||
SettingGlobalFreeze | SettingNoFreeze | SettingEnableTransactionIDTracking |
|
||||
SettingDisableMasterKey | SettingDisallowIncomingXRP |
|
||||
SettingRequireAuthorization | SettingRequireDestinationTag |
|
||||
SettingPasswordSpent
|
||||
|
||||
@@ -70,7 +70,17 @@ function convertTransferRate(transferRate: number | string): number | string {
|
||||
return (new BigNumber(transferRate)).shift(9).toNumber();
|
||||
}
|
||||
|
||||
function createSettingsTransaction(account: string, settings: Settings
|
||||
function formatSignerEntry(signer: Object): Object {
|
||||
return {
|
||||
SignerEntry: {
|
||||
Account: signer.address,
|
||||
SignerWeight: signer.weight
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createSettingsTransactionWithoutMemos(
|
||||
account: string, settings: Settings
|
||||
): Object {
|
||||
if (settings.regularKey !== undefined) {
|
||||
const removeRegularKey = {
|
||||
@@ -83,15 +93,20 @@ function createSettingsTransaction(account: string, settings: Settings
|
||||
return _.assign({}, removeRegularKey, {RegularKey: settings.regularKey});
|
||||
}
|
||||
|
||||
if (settings.signers !== undefined) {
|
||||
return {
|
||||
TransactionType: 'SignerListSet',
|
||||
Account: account,
|
||||
SignerQuorum: settings.signers.threshold,
|
||||
SignerEntries: _.map(settings.signers.weights, formatSignerEntry)
|
||||
};
|
||||
}
|
||||
|
||||
const txJSON: Object = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: account
|
||||
};
|
||||
|
||||
if (settings.memos !== undefined) {
|
||||
txJSON.Memos = _.map(settings.memos, utils.convertMemo);
|
||||
}
|
||||
|
||||
setTransactionFlags(txJSON, _.omit(settings, 'memos'));
|
||||
setTransactionFields(txJSON, settings);
|
||||
|
||||
@@ -101,6 +116,15 @@ function createSettingsTransaction(account: string, settings: Settings
|
||||
return txJSON;
|
||||
}
|
||||
|
||||
function createSettingsTransaction(account: string, settings: Settings
|
||||
): Object {
|
||||
const txJSON = createSettingsTransactionWithoutMemos(account, settings);
|
||||
if (settings.memos !== undefined) {
|
||||
txJSON.Memos = _.map(settings.memos, utils.convertMemo);
|
||||
}
|
||||
return txJSON;
|
||||
}
|
||||
|
||||
function prepareSettings(address: string, settings: Settings,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
|
||||
@@ -6,23 +6,38 @@ const binary = require('ripple-binary-codec');
|
||||
const {computeBinaryTransactionHash} = require('ripple-hashes');
|
||||
const validate = utils.common.validate;
|
||||
|
||||
function computeSignature(txJSON, privateKey) {
|
||||
const signingData = binary.encodeForSigning(txJSON);
|
||||
function computeSignature(tx: Object, privateKey: string, signAs: ?string) {
|
||||
const signingData = signAs ?
|
||||
binary.encodeForMultisigning(tx, signAs) : binary.encodeForSigning(tx);
|
||||
return keypairs.sign(signingData, privateKey);
|
||||
}
|
||||
|
||||
function sign(txJSON: string, secret: string
|
||||
function sign(txJSON: string, secret: string, options: Object = {}
|
||||
): {signedTransaction: string; id: string} {
|
||||
validate.sign({txJSON, secret});
|
||||
// we can't validate that the secret matches the account because
|
||||
// the secret could correspond to the regular key
|
||||
|
||||
const tx = JSON.parse(txJSON);
|
||||
const keypair = keypairs.deriveKeypair(secret);
|
||||
if (tx.SigningPubKey === undefined) {
|
||||
tx.SigningPubKey = keypair.publicKey;
|
||||
if (tx.TxnSignature || tx.Signers) {
|
||||
throw new utils.common.errors.ValidationError(
|
||||
'txJSON must not contain "TxnSignature" or "Signers" properties');
|
||||
}
|
||||
tx.TxnSignature = computeSignature(tx, keypair.privateKey);
|
||||
|
||||
const keypair = keypairs.deriveKeypair(secret);
|
||||
tx.SigningPubKey = options.signAs ? '' : keypair.publicKey;
|
||||
|
||||
if (options.signAs) {
|
||||
const signer = {
|
||||
Account: options.signAs,
|
||||
SigningPubKey: keypair.publicKey,
|
||||
TxnSignature: computeSignature(tx, keypair.privateKey, options.signAs)
|
||||
};
|
||||
tx.Signers = [{Signer: signer}];
|
||||
} else {
|
||||
tx.TxnSignature = computeSignature(tx, keypair.privateKey);
|
||||
}
|
||||
|
||||
const serialized = binary.encode(tx);
|
||||
return {
|
||||
signedTransaction: serialized,
|
||||
|
||||
@@ -3,15 +3,7 @@
|
||||
const _ = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const {validate} = utils.common;
|
||||
|
||||
type Submit = {
|
||||
success: boolean,
|
||||
engineResult: string,
|
||||
engineResultCode: number,
|
||||
engineResultMessage?: string,
|
||||
txBlob?: string,
|
||||
txJson?: Object
|
||||
}
|
||||
import type {Submit} from './types.js';
|
||||
|
||||
function isImmediateRejection(engineResult: string): boolean {
|
||||
// note: "tel" errors mean the local server refused to process the
|
||||
@@ -23,7 +15,7 @@ function isImmediateRejection(engineResult: string): boolean {
|
||||
return _.startsWith(engineResult, 'tem') || _.startsWith(engineResult, 'tej');
|
||||
}
|
||||
|
||||
function formatResponse(response) {
|
||||
function formatSubmitResponse(response) {
|
||||
const data = {
|
||||
resultCode: response.engine_result,
|
||||
resultMessage: response.engine_result_message
|
||||
@@ -36,11 +28,12 @@ function formatResponse(response) {
|
||||
|
||||
function submit(signedTransaction: string): Promise<Submit> {
|
||||
validate.submit({signedTransaction});
|
||||
|
||||
const request = {
|
||||
command: 'submit',
|
||||
tx_blob: signedTransaction
|
||||
};
|
||||
return this.connection.request(request).then(formatResponse);
|
||||
return this.connection.request(request).then(formatSubmitResponse);
|
||||
}
|
||||
|
||||
module.exports = submit;
|
||||
|
||||
@@ -1,19 +1,29 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
export type Instructions = {
|
||||
sequence?: number,
|
||||
fee?: string,
|
||||
maxFee?: string,
|
||||
maxLedgerVersion?: number,
|
||||
maxLedgerVersionOffset?: number
|
||||
}
|
||||
|
||||
export type Prepare = {
|
||||
txJSON: string,
|
||||
instructions: {
|
||||
fee: string,
|
||||
sequence: number,
|
||||
maxLedgerVersion?: number
|
||||
}
|
||||
}
|
||||
/* @flow */
|
||||
'use strict';
|
||||
|
||||
export type Instructions = {
|
||||
sequence?: number,
|
||||
fee?: string,
|
||||
maxFee?: string,
|
||||
maxLedgerVersion?: number,
|
||||
maxLedgerVersionOffset?: number,
|
||||
signersCount?: number
|
||||
}
|
||||
|
||||
export type Prepare = {
|
||||
txJSON: string,
|
||||
instructions: {
|
||||
fee: string,
|
||||
sequence: number,
|
||||
maxLedgerVersion?: number
|
||||
}
|
||||
}
|
||||
|
||||
export type Submit = {
|
||||
success: boolean,
|
||||
engineResult: string,
|
||||
engineResultCode: number,
|
||||
engineResultMessage?: string,
|
||||
txBlob?: string,
|
||||
txJson?: Object
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ function formatPrepareResponse(txJSON: Object): Object {
|
||||
const instructions = {
|
||||
fee: common.dropsToXrp(txJSON.Fee),
|
||||
sequence: txJSON.Sequence,
|
||||
maxLedgerVersion: txJSON.LastLedgerSequence
|
||||
maxLedgerVersion: txJSON.LastLedgerSequence === undefined ?
|
||||
null : txJSON.LastLedgerSequence
|
||||
};
|
||||
return {
|
||||
txJSON: JSON.stringify(txJSON),
|
||||
@@ -26,6 +27,10 @@ function setCanonicalFlag(txJSON) {
|
||||
txJSON.Flags = txJSON.Flags >>> 0;
|
||||
}
|
||||
|
||||
function scaleValue(value, multiplier) {
|
||||
return (new BigNumber(value)).times(multiplier).toString();
|
||||
}
|
||||
|
||||
function prepareTransaction(txJSON: Object, api: Object,
|
||||
instructions: Instructions
|
||||
): Promise<Prepare> {
|
||||
@@ -36,7 +41,9 @@ function prepareTransaction(txJSON: Object, api: Object,
|
||||
|
||||
function prepareMaxLedgerVersion(): Promise<Object> {
|
||||
if (instructions.maxLedgerVersion !== undefined) {
|
||||
txJSON.LastLedgerSequence = instructions.maxLedgerVersion;
|
||||
if (instructions.maxLedgerVersion !== null) {
|
||||
txJSON.LastLedgerSequence = instructions.maxLedgerVersion;
|
||||
}
|
||||
return Promise.resolve(txJSON);
|
||||
}
|
||||
const offset = instructions.maxLedgerVersionOffset !== undefined ?
|
||||
@@ -48,8 +55,10 @@ function prepareTransaction(txJSON: Object, api: Object,
|
||||
}
|
||||
|
||||
function prepareFee(): Promise<Object> {
|
||||
const multiplier = instructions.signersCount === undefined ? 1 :
|
||||
instructions.signersCount + 1;
|
||||
if (instructions.fee !== undefined) {
|
||||
txJSON.Fee = common.xrpToDrops(instructions.fee);
|
||||
txJSON.Fee = scaleValue(common.xrpToDrops(instructions.fee), multiplier);
|
||||
return Promise.resolve(txJSON);
|
||||
}
|
||||
const cushion = api._feeCushion;
|
||||
@@ -57,9 +66,10 @@ function prepareTransaction(txJSON: Object, api: Object,
|
||||
const feeDrops = common.xrpToDrops(fee);
|
||||
if (instructions.maxFee !== undefined) {
|
||||
const maxFeeDrops = common.xrpToDrops(instructions.maxFee);
|
||||
txJSON.Fee = BigNumber.min(feeDrops, maxFeeDrops).toString();
|
||||
const normalFee = BigNumber.min(feeDrops, maxFeeDrops).toString();
|
||||
txJSON.Fee = scaleValue(normalFee, multiplier);
|
||||
} else {
|
||||
txJSON.Fee = feeDrops;
|
||||
txJSON.Fee = scaleValue(feeDrops, multiplier);
|
||||
}
|
||||
return txJSON;
|
||||
});
|
||||
|
||||
@@ -14,6 +14,9 @@ const address = addresses.ACCOUNT;
|
||||
const utils = RippleAPI._PRIVATE.ledgerUtils;
|
||||
const ledgerClosed = require('./fixtures/rippled/ledger-close-newer');
|
||||
const schemaValidator = RippleAPI._PRIVATE.schemaValidator;
|
||||
assert.options.strict = true;
|
||||
|
||||
const TIMEOUT = 10000; // how long before each test case times out
|
||||
|
||||
function unused() {
|
||||
}
|
||||
@@ -36,6 +39,7 @@ function checkResult(expected, schemaName, response) {
|
||||
|
||||
|
||||
describe('RippleAPI', function() {
|
||||
this.timeout(TIMEOUT);
|
||||
const instructions = {maxLedgerVersionOffset: 100};
|
||||
beforeEach(setupAPI.setup);
|
||||
afterEach(setupAPI.teardown);
|
||||
@@ -182,13 +186,20 @@ describe('RippleAPI', function() {
|
||||
|
||||
it('prepareSettings', function() {
|
||||
return this.api.prepareSettings(
|
||||
address, requests.prepareSettings, instructions).then(
|
||||
address, requests.prepareSettings.domain, instructions).then(
|
||||
_.partial(checkResult, responses.prepareSettings.flags, 'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSettings - no maxLedgerVersion', function() {
|
||||
return this.api.prepareSettings(
|
||||
address, requests.prepareSettings.domain, {maxLedgerVersion: null}).then(
|
||||
_.partial(checkResult, responses.prepareSettings.noMaxLedgerVersion,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSettings - no instructions', function() {
|
||||
return this.api.prepareSettings(
|
||||
address, requests.prepareSettings).then(
|
||||
address, requests.prepareSettings.domain).then(
|
||||
_.partial(
|
||||
checkResult,
|
||||
responses.prepareSettings.noInstructions,
|
||||
@@ -236,6 +247,23 @@ describe('RippleAPI', function() {
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSettings - set signers', function() {
|
||||
const settings = requests.prepareSettings.signers;
|
||||
return this.api.prepareSettings(address, settings, instructions).then(
|
||||
_.partial(checkResult, responses.prepareSettings.signers,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSettings - fee for multisign', function() {
|
||||
const localInstructions = _.defaults({
|
||||
signersCount: 4
|
||||
}, instructions);
|
||||
return this.api.prepareSettings(
|
||||
address, requests.prepareSettings.domain, localInstructions).then(
|
||||
_.partial(checkResult, responses.prepareSettings.flagsMultisign,
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSuspendedPaymentCreation', function() {
|
||||
const localInstructions = _.defaults({
|
||||
maxFee: '0.000012'
|
||||
@@ -304,6 +332,14 @@ describe('RippleAPI', function() {
|
||||
schemaValidator.schemaValidate('sign', result);
|
||||
});
|
||||
|
||||
it('sign - signAs', function() {
|
||||
const txJSON = requests.sign.signAs;
|
||||
const secret = 'snoPBrXtMeMyMHUVTgbuqAfg1SUTb';
|
||||
const signature = this.api.sign(JSON.stringify(txJSON), secret,
|
||||
{signAs: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'});
|
||||
assert.deepEqual(signature, responses.sign.signAs);
|
||||
});
|
||||
|
||||
it('submit', function() {
|
||||
return this.api.submit(responses.sign.normal.signedTransaction).then(
|
||||
_.partial(checkResult, responses.submit, 'submit'));
|
||||
@@ -318,6 +354,11 @@ describe('RippleAPI', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('combine', function() {
|
||||
const combined = this.api.combine(requests.combine.setDomain);
|
||||
checkResult(responses.combine.single, 'sign', combined);
|
||||
});
|
||||
|
||||
describe('RippleAPI', function() {
|
||||
|
||||
it('getBalances', function() {
|
||||
@@ -906,7 +947,11 @@ describe('RippleAPI', function() {
|
||||
});
|
||||
|
||||
it('getServerInfo - error', function() {
|
||||
this.mockRippled.returnErrorOnServerInfo = true;
|
||||
this.api.connection._send(JSON.stringify({
|
||||
command: 'config',
|
||||
data: {returnErrorOnServerInfo: true}
|
||||
}));
|
||||
|
||||
return this.api.getServerInfo().then(() => {
|
||||
assert(false, 'Should throw NetworkError');
|
||||
}).catch(error => {
|
||||
@@ -1004,6 +1049,15 @@ describe('RippleAPI', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('getPaths - no paths source amount', function() {
|
||||
return this.api.getPaths(requests.getPaths.NoPathsSource).then(() => {
|
||||
assert(false, 'Should throw NotFoundError');
|
||||
}).catch(error => {
|
||||
assert(error instanceof this.api.errors.NotFoundError);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('getPaths - no paths with source currencies', function() {
|
||||
const pathfind = requests.getPaths.NoPathsWithCurrencies;
|
||||
return this.api.getPaths(pathfind).then(() => {
|
||||
@@ -1247,7 +1301,7 @@ describe('RippleAPI - offline', function() {
|
||||
it('prepareSettings and sign', function() {
|
||||
const api = new RippleAPI();
|
||||
const secret = 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV';
|
||||
const settings = requests.prepareSettings;
|
||||
const settings = requests.prepareSettings.domain;
|
||||
const instructions = {
|
||||
sequence: 23,
|
||||
maxLedgerVersion: 8820051,
|
||||
|
||||
@@ -26,7 +26,9 @@ describe('RippleAPIBroadcast', function() {
|
||||
|
||||
it('base', function() {
|
||||
const expected = {request_server_info: 1};
|
||||
this.mocks.forEach(mock => mock.expect(_.assign({}, expected)));
|
||||
if (!process.browser) {
|
||||
this.mocks.forEach(mock => mock.expect(_.assign({}, expected)));
|
||||
}
|
||||
assert(this.api.isConnected());
|
||||
return this.api.getServerInfo().then(
|
||||
_.partial(checkResult, responses.getServerInfo, 'getServerInfo'));
|
||||
@@ -39,14 +41,16 @@ describe('RippleAPIBroadcast', function() {
|
||||
});
|
||||
const ledgerNext = _.assign({}, ledgerClosed);
|
||||
ledgerNext.ledger_index++;
|
||||
this.mocks.forEach(mock => mock.socket.send(JSON.stringify(ledgerNext)));
|
||||
|
||||
this.api._apis.forEach(api => api.connection._send(JSON.stringify({
|
||||
command: 'echo',
|
||||
data: ledgerNext
|
||||
})));
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('-- ledgerVersion', this.api.ledgerVersion);
|
||||
assert.strictEqual(gotLedger, 1);
|
||||
done();
|
||||
}, 50);
|
||||
|
||||
}, 250);
|
||||
});
|
||||
|
||||
it('error propagation', function(done) {
|
||||
@@ -55,8 +59,10 @@ describe('RippleAPIBroadcast', function() {
|
||||
assert.strictEqual(info, 'info');
|
||||
done();
|
||||
});
|
||||
this.mocks[1].socket.send(
|
||||
JSON.stringify({error: 'type', error_message: 'info'}));
|
||||
this.api._apis[1].connection._send(JSON.stringify({
|
||||
command: 'echo',
|
||||
data: {error: 'type', error_message: 'info'}
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -7,8 +7,11 @@ const assert = require('assert-diff');
|
||||
const setupAPI = require('./setup-api');
|
||||
const RippleAPI = require('ripple-api').RippleAPI;
|
||||
const utils = RippleAPI._PRIVATE.ledgerUtils;
|
||||
const ledgerClose = require('./fixtures/rippled/ledger-close.json');
|
||||
|
||||
|
||||
const TIMEOUT = 10000; // how long before each test case times out
|
||||
|
||||
function unused() {
|
||||
}
|
||||
|
||||
@@ -26,6 +29,7 @@ function createServer() {
|
||||
}
|
||||
|
||||
describe('Connection', function() {
|
||||
this.timeout(TIMEOUT);
|
||||
beforeEach(setupAPI.setup);
|
||||
afterEach(setupAPI.teardown);
|
||||
|
||||
@@ -46,6 +50,9 @@ describe('Connection', function() {
|
||||
messages.push(message);
|
||||
}
|
||||
};
|
||||
connection._ws = {
|
||||
send: function() {}
|
||||
};
|
||||
connection._onMessage(message1);
|
||||
connection._send(message2);
|
||||
|
||||
@@ -53,6 +60,10 @@ describe('Connection', function() {
|
||||
});
|
||||
|
||||
it('with proxy', function(done) {
|
||||
if (process.browser) {
|
||||
done();
|
||||
return;
|
||||
}
|
||||
createServer().then((server) => {
|
||||
const port = server.address().port;
|
||||
const expect = 'CONNECT localhost';
|
||||
@@ -96,9 +107,10 @@ describe('Connection', function() {
|
||||
});
|
||||
|
||||
it('DisconnectedError', function() {
|
||||
this.api.connection._send = function() {
|
||||
this._ws.close();
|
||||
};
|
||||
this.api.connection._send(JSON.stringify({
|
||||
command: 'config',
|
||||
data: {disconnectOnServerInfo: true}
|
||||
}));
|
||||
return this.api.getServerInfo().then(() => {
|
||||
assert(false, 'Should throw DisconnectedError');
|
||||
}).catch(error => {
|
||||
@@ -227,8 +239,9 @@ describe('Connection', function() {
|
||||
});
|
||||
|
||||
it('invalid message id', function(done) {
|
||||
this.api.on('error', (type, message) => {
|
||||
assert.strictEqual(type, 'badMessage');
|
||||
this.api.on('error', (errorCode, errorMessage, message) => {
|
||||
assert.strictEqual(errorCode, 'badMessage');
|
||||
assert.strictEqual(errorMessage, 'valid id not found in response');
|
||||
assert.strictEqual(message,
|
||||
'{"type":"response","id":"must be integer"}');
|
||||
done();
|
||||
@@ -239,9 +252,10 @@ describe('Connection', function() {
|
||||
});
|
||||
|
||||
it('propagate error message', function(done) {
|
||||
this.api.on('error', (type, message) => {
|
||||
assert.strictEqual(type, 'slowDown');
|
||||
assert.strictEqual(message, 'slow down');
|
||||
this.api.on('error', (errorCode, errorMessage, data) => {
|
||||
assert.strictEqual(errorCode, 'slowDown');
|
||||
assert.strictEqual(errorMessage, 'slow down');
|
||||
assert.deepEqual(data, {error: 'slowDown', error_message: 'slow down'});
|
||||
done();
|
||||
});
|
||||
this.api.connection._onMessage(JSON.stringify({
|
||||
@@ -250,12 +264,22 @@ describe('Connection', function() {
|
||||
});
|
||||
|
||||
it('unrecognized message type', function(done) {
|
||||
this.api.on('error', (type, message) => {
|
||||
assert.strictEqual(type, 'badMessage');
|
||||
this.api.on('error', (errorCode, errorMessage, message) => {
|
||||
assert.strictEqual(errorCode, 'badMessage');
|
||||
assert.strictEqual(errorMessage, 'unrecognized message type: unknown');
|
||||
assert.strictEqual(message, '{"type":"unknown"}');
|
||||
done();
|
||||
});
|
||||
|
||||
this.api.connection._onMessage(JSON.stringify({type: 'unknown'}));
|
||||
});
|
||||
|
||||
it('ledger close without validated_ledgers', function(done) {
|
||||
const message = _.omit(ledgerClose, 'validated_ledgers');
|
||||
this.api.on('ledger', function(ledger) {
|
||||
assert.strictEqual(ledger.ledgerVersion, 8819951);
|
||||
done();
|
||||
});
|
||||
this.api.connection._ws.emit('message', JSON.stringify(message));
|
||||
});
|
||||
});
|
||||
|
||||
3
test/fixtures/addresses.js
vendored
3
test/fixtures/addresses.js
vendored
@@ -6,5 +6,6 @@ module.exports = {
|
||||
FOURTH_ACCOUNT: 'rJnZ4YHCUsHvQu7R6mZohevKJDHFzVD6Zr',
|
||||
ISSUER: 'rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM',
|
||||
NOTFOUND: 'rajTAg3hon5Lcu1RxQQPxTgHvqfhc1EaUS',
|
||||
SECRET: 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV'
|
||||
SECRET: 'shsWGZcmZz6YsWWmcnpfr6fLTdtFV',
|
||||
SOURCE_LOW_FUNDS: 'rhVgDEfS1r1fLyRUZCpab4TdowZcAJwHy2'
|
||||
};
|
||||
|
||||
2
test/fixtures/requests/combine.json
vendored
Normal file
2
test/fixtures/requests/combine.json
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
[ "12000322800000002400000004201B000000116840000000000F42407300770B6578616D706C652E636F6D811407C532442A675C881BA1235354D4AB9D023243A6F3E0107321026C784C1987F83BACBF02CD3E484AFC84ADE5CA6B36ED4DCA06D5BA233B9D382774473045022100E484F54FF909469FA2033E22EFF3DF8EDFE62217062680BB2F3EDF2F185074FE0220350DB29001C710F0450DAF466C5D819DC6D6A3340602DE9B6CB7DA8E17C90F798114FE9337B0574213FA5BCC0A319DBB4A7AC0CCA894E1F1",
|
||||
"12000322800000002400000004201B000000116840000000000F42407300770B6578616D706C652E636F6D811407C532442A675C881BA1235354D4AB9D023243A6F3E01073210287AAAB8FBE8C4C4A47F6F1228C6E5123A7ED844BFE88A9B22C2F7CC34279EEAA74473045022100B09DDF23144595B5A9523B20E605E138DC6549F5CA7B5984D7C32B0E3469DF6B022018845CA6C203D4B6288C87DDA439134C83E7ADF8358BD41A8A9141A9B631419F8114517D9B9609229E0CDFE2428B586738C5B2E84D45E1F1" ]
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"base": {
|
||||
"currency": "USD",
|
||||
"counterparty": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw"
|
||||
},
|
||||
"counter": {
|
||||
"currency": "XRP"
|
||||
}
|
||||
{
|
||||
"base": {
|
||||
"currency": "USD",
|
||||
"counterparty": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw"
|
||||
},
|
||||
"counter": {
|
||||
"currency": "XRP"
|
||||
}
|
||||
}
|
||||
13
test/fixtures/requests/getpaths/no-paths-source-amount.json
vendored
Normal file
13
test/fixtures/requests/getpaths/no-paths-source-amount.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "rhVgDEfS1r1fLyRUZCpab4TdowZcAJwHy2",
|
||||
"amount": {
|
||||
"value": "1000002",
|
||||
"currency": "USD"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {"currency": "USD"}
|
||||
}
|
||||
}
|
||||
24
test/fixtures/requests/getpaths/normal.json
vendored
24
test/fixtures/requests/getpaths/normal.json
vendored
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59"
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"amount": {
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM",
|
||||
"value": "100"
|
||||
}
|
||||
}
|
||||
{
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59"
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"amount": {
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM",
|
||||
"value": "100"
|
||||
}
|
||||
}
|
||||
}
|
||||
30
test/fixtures/requests/getpaths/send-all.json
vendored
30
test/fixtures/requests/getpaths/send-all.json
vendored
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"currency": "USD",
|
||||
"value": "5"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
|
||||
"amount": {
|
||||
"currency": "USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"currency": "USD",
|
||||
"value": "5"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
|
||||
"amount": {
|
||||
"currency": "USD"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
38
test/fixtures/requests/getpaths/usd2usd.json
vendored
38
test/fixtures/requests/getpaths/usd2usd.json
vendored
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"currencies": [
|
||||
{
|
||||
"currency": "LTC"
|
||||
},
|
||||
{
|
||||
"currency": "USD"
|
||||
}
|
||||
]
|
||||
},
|
||||
"destination": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"currency": "USD",
|
||||
"value": "0.000001"
|
||||
}
|
||||
}
|
||||
{
|
||||
"source": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"currencies": [
|
||||
{
|
||||
"currency": "LTC"
|
||||
},
|
||||
{
|
||||
"currency": "USD"
|
||||
}
|
||||
]
|
||||
},
|
||||
"destination": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"currency": "USD",
|
||||
"value": "0.000001"
|
||||
}
|
||||
}
|
||||
}
|
||||
24
test/fixtures/requests/getpaths/xrp2xrp.json
vendored
24
test/fixtures/requests/getpaths/xrp2xrp.json
vendored
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J"
|
||||
},
|
||||
"destination": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"value": "0.000002",
|
||||
"currency": "XRP"
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"source": {
|
||||
"address": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J"
|
||||
},
|
||||
"destination": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"value": "0.000002",
|
||||
"currency": "XRP"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
test/fixtures/requests/index.js
vendored
12
test/fixtures/requests/index.js
vendored
@@ -20,7 +20,10 @@ module.exports = {
|
||||
allOptions: require('./prepare-payment-all-options'),
|
||||
noCounterparty: require('./prepare-payment-no-counterparty')
|
||||
},
|
||||
prepareSettings: require('./prepare-settings'),
|
||||
prepareSettings: {
|
||||
domain: require('./prepare-settings'),
|
||||
signers: require('./prepare-settings-signers')
|
||||
},
|
||||
prepareSuspendedPaymentCreation: {
|
||||
normal: require('./prepare-suspended-payment-creation'),
|
||||
full: require('./prepare-suspended-payment-creation-full')
|
||||
@@ -40,7 +43,8 @@ module.exports = {
|
||||
},
|
||||
sign: {
|
||||
normal: require('./sign'),
|
||||
suspended: require('./sign-suspended.json')
|
||||
suspended: require('./sign-suspended.json'),
|
||||
signAs: require('./sign-as')
|
||||
},
|
||||
getPaths: {
|
||||
normal: require('./getpaths/normal'),
|
||||
@@ -49,6 +53,7 @@ module.exports = {
|
||||
XrpToXrpNotEnough: require('./getpaths/xrp2xrp-not-enough'),
|
||||
NotAcceptCurrency: require('./getpaths/not-accept-currency'),
|
||||
NoPaths: require('./getpaths/no-paths'),
|
||||
NoPathsSource: require('./getpaths/no-paths-source-amount'),
|
||||
NoPathsWithCurrencies: require('./getpaths/no-paths-with-currencies'),
|
||||
sendAll: require('./getpaths/send-all'),
|
||||
invalid: require('./getpaths/invalid'),
|
||||
@@ -61,5 +66,8 @@ module.exports = {
|
||||
computeLedgerHash: {
|
||||
header: require('./compute-ledger-hash'),
|
||||
transactions: require('./compute-ledger-hash-transactions')
|
||||
},
|
||||
combine: {
|
||||
setDomain: require('./combine.json')
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM",
|
||||
"amount": {
|
||||
"value": "0.01",
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"minAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP"
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"source": {
|
||||
"address": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM",
|
||||
"amount": {
|
||||
"value": "0.01",
|
||||
"currency": "USD",
|
||||
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"minAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"minAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP"
|
||||
}
|
||||
},
|
||||
"allowPartialPayment": true
|
||||
}
|
||||
{
|
||||
"source": {
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"amount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP"
|
||||
}
|
||||
},
|
||||
"destination": {
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"minAmount": {
|
||||
"value": "0.01",
|
||||
"currency": "XRP"
|
||||
}
|
||||
},
|
||||
"allowPartialPayment": true
|
||||
}
|
||||
|
||||
19
test/fixtures/requests/prepare-settings-signers.json
vendored
Normal file
19
test/fixtures/requests/prepare-settings-signers.json
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"signers": {
|
||||
"threshold": 2,
|
||||
"weights": [
|
||||
{
|
||||
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
|
||||
"weight": 1
|
||||
},
|
||||
{
|
||||
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
|
||||
"weight": 1
|
||||
},
|
||||
{
|
||||
"address": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J",
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
8
test/fixtures/requests/sign-as.json
vendored
Normal file
8
test/fixtures/requests/sign-as.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Account": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Fee": "50",
|
||||
"Sequence": 2,
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
4
test/fixtures/responses/combine.json
vendored
Normal file
4
test/fixtures/responses/combine.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"signedTransaction": "12000322800000002400000004201B000000116840000000000F42407300770B6578616D706C652E636F6D811407C532442A675C881BA1235354D4AB9D023243A6F3E01073210287AAAB8FBE8C4C4A47F6F1228C6E5123A7ED844BFE88A9B22C2F7CC34279EEAA74473045022100B09DDF23144595B5A9523B20E605E138DC6549F5CA7B5984D7C32B0E3469DF6B022018845CA6C203D4B6288C87DDA439134C83E7ADF8358BD41A8A9141A9B631419F8114517D9B9609229E0CDFE2428B586738C5B2E84D45E1E0107321026C784C1987F83BACBF02CD3E484AFC84ADE5CA6B36ED4DCA06D5BA233B9D382774473045022100E484F54FF909469FA2033E22EFF3DF8EDFE62217062680BB2F3EDF2F185074FE0220350DB29001C710F0450DAF466C5D819DC6D6A3340602DE9B6CB7DA8E17C90F798114FE9337B0574213FA5BCC0A319DBB4A7AC0CCA894E1F1",
|
||||
"id": "8A3BFD2214B4C8271ED62648FCE9ADE4EE82EF01827CF7D1F7ED497549A368CC"
|
||||
}
|
||||
6
test/fixtures/responses/get-server-info.json
vendored
6
test/fixtures/responses/get-server-info.json
vendored
@@ -13,10 +13,10 @@
|
||||
"serverState": "full",
|
||||
"validatedLedger": {
|
||||
"age": 5,
|
||||
"baseFeeXRP": 0.00001,
|
||||
"baseFeeXRP": "0.00001",
|
||||
"hash": "4482DEE5362332F54A4036ED57EE1767C9F33CF7CE5A6670355C16CECE381D46",
|
||||
"reserveBaseXRP": 20,
|
||||
"reserveIncrementXRP": 5,
|
||||
"reserveBaseXRP": "20",
|
||||
"reserveIncrementXRP": "5",
|
||||
"ledgerVersion": 6595042
|
||||
},
|
||||
"validationQuorum": 3
|
||||
|
||||
@@ -31,4 +31,4 @@
|
||||
"ledgerVersion": 14,
|
||||
"indexInLedger": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,4 +32,4 @@
|
||||
"ledgerVersion": 14,
|
||||
"indexInLedger": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
"specification": {
|
||||
"limit": "0",
|
||||
"currency": "ASP",
|
||||
"counterparty": "r3vi7mWxru9rJCxETCyA1CHvzL96eZWx5z"
|
||||
"counterparty": "r3vi7mWxru9rJCxETCyA1CHvzL96eZWx5z",
|
||||
"qualityIn": 1
|
||||
},
|
||||
"counterparty": {
|
||||
"limit": "10"
|
||||
@@ -330,4 +331,4 @@
|
||||
"balance": "0"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
15
test/fixtures/responses/index.js
vendored
15
test/fixtures/responses/index.js
vendored
@@ -71,8 +71,8 @@ module.exports = {
|
||||
},
|
||||
preparePayment: {
|
||||
normal: require('./prepare-payment.json'),
|
||||
minAmountXRP: require('./prepare-payment-min-amont-xrp.json'),
|
||||
minAmountXRPXRP: require('./prepare-payment-min-amont-xrp-xrp.json'),
|
||||
minAmountXRP: require('./prepare-payment-min-amount-xrp.json'),
|
||||
minAmountXRPXRP: require('./prepare-payment-min-amount-xrp-xrp.json'),
|
||||
allOptions: require('./prepare-payment-all-options.json'),
|
||||
noCounterparty: require('./prepare-payment-no-counterparty.json'),
|
||||
minAmount: require('./prepare-payment-min-amount.json')
|
||||
@@ -81,12 +81,15 @@ module.exports = {
|
||||
regularKey: require('./prepare-settings-regular-key.json'),
|
||||
removeRegularKey: require('./prepare-settings-remove-regular-key.json'),
|
||||
flags: require('./prepare-settings.json'),
|
||||
flagsMultisign: require('./prepare-settings-multisign.json'),
|
||||
flagSet: require('./prepare-settings-flag-set.json'),
|
||||
flagClear: require('./prepare-settings-flag-clear.json'),
|
||||
setTransferRate: require('./prepare-settings-set-transfer-rate.json'),
|
||||
fieldClear: require('./prepare-settings-field-clear.json'),
|
||||
noInstructions: require('./prepare-settings-no-instructions.json'),
|
||||
signed: require('./prepare-settings-signed.json')
|
||||
signed: require('./prepare-settings-signed.json'),
|
||||
noMaxLedgerVersion: require('./prepare-settings-no-maxledgerversion.json'),
|
||||
signers: require('./prepare-settings-signers.json')
|
||||
},
|
||||
prepareSuspendedPaymentCreation: {
|
||||
normal: require('./prepare-suspended-payment-creation'),
|
||||
@@ -107,7 +110,11 @@ module.exports = {
|
||||
},
|
||||
sign: {
|
||||
normal: require('./sign.json'),
|
||||
suspended: require('./sign-suspended.json')
|
||||
suspended: require('./sign-suspended.json'),
|
||||
signAs: require('./sign-as')
|
||||
},
|
||||
combine: {
|
||||
single: require('./combine.json')
|
||||
},
|
||||
submit: require('./submit.json'),
|
||||
ledgerEvent: require('./ledger-event.json')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"txJSON": "{\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":\"100000000000000000\",\"Flags\":2147614720,\"SendMax\":{\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\",\"value\":\"0.01\"},\"DeliverMin\":\"100000000000000000\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"txJSON": "{\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":\"100000000000000000\",\"Flags\":2147614720,\"SendMax\":{\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\",\"value\":\"0.01\"},\"DeliverMin\":\"10000\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"txJSON": "{\"Flags\":2147614720,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\",\"Amount\":{\"value\":\"9999999999999999e80\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"SendMax\":{\"value\":\"5\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"DeliverMin\":{\"value\":\"9999999999999999e80\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"Paths\":[[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"},{\"account\":\"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\"}],[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\",\"currency\":\"USD\"},{\"account\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"txJSON": "{\"Flags\":2147614720,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\",\"Amount\":{\"value\":\"9999999999999999e80\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"SendMax\":{\"value\":\"5\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"DeliverMin\":{\"value\":\"4.93463759481038\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"Paths\":[[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"},{\"account\":\"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\"}],[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\",\"currency\":\"USD\"},{\"account\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"txJSON": "{\"Flags\":2147942400,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"LTC\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\"},\"InvoiceID\":\"A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A\",\"SourceTag\":14,\"DestinationTag\":58,\"Memos\":[{\"Memo\":{\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\",\"MemoData\":\"7465787465642064617461\"}}],\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"Paths\":[[{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\"},{\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\"},{\"account\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
"maxLedgerVersion": 8820051
|
||||
}
|
||||
}
|
||||
{
|
||||
"txJSON": "{\"Flags\":2147942400,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"LTC\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\"},\"InvoiceID\":\"A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A\",\"SourceTag\":14,\"DestinationTag\":58,\"Memos\":[{\"Memo\":{\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\",\"MemoData\":\"7465787465642064617461\"}}],\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"Paths\":[[{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\"},{\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\"},{\"account\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
"maxLedgerVersion": 8820051
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"WalletLocator\":\"0\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
"maxLedgerVersion": 8820051
|
||||
}
|
||||
}
|
||||
{
|
||||
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"WalletLocator\":\"0\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
"maxLedgerVersion": 8820051
|
||||
}
|
||||
}
|
||||
|
||||
8
test/fixtures/responses/prepare-settings-multisign.json
vendored
Normal file
8
test/fixtures/responses/prepare-settings-multisign.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"txJSON": "{\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"Domain\":\"726970706C652E636F6D\",\"Flags\":2147483648,\"LastLedgerSequence\":8820051,\"Fee\":\"60\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.00006",
|
||||
"sequence": 23,
|
||||
"maxLedgerVersion": 8820051
|
||||
}
|
||||
}
|
||||
8
test/fixtures/responses/prepare-settings-no-maxledgerversion.json
vendored
Normal file
8
test/fixtures/responses/prepare-settings-no-maxledgerversion.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"txJSON": "{\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"Domain\":\"726970706C652E636F6D\",\"Flags\":2147483648,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
"maxLedgerVersion": null
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransferRate\":1000000000,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
"maxLedgerVersion": 8820051
|
||||
}
|
||||
}
|
||||
{
|
||||
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransferRate\":1000000000,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
"maxLedgerVersion": 8820051
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
{
|
||||
"signedTransaction": "12000322800000002400000017201B0086955368400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402202FBF6A6F74DFDA17C7341D532B66141206BC71A147C08DBDA6A950AA9A1741DC022055859A39F2486A46487F8DA261E3D80B4FDD26178A716A929F26377D1BEC7E43770A726970706C652E636F6D81145E7B112523F68D2F5E879DB4EAC51C6698A69304F9EA7C04746573747D0B74657874656420646174617E0A706C61696E2F74657874E1F1",
|
||||
"id": "4755D26FAC39E3E477870D4E03CC6783DDDF967FFBE240606755D3D03702FC16"
|
||||
}
|
||||
}
|
||||
|
||||
8
test/fixtures/responses/prepare-settings-signers.json
vendored
Normal file
8
test/fixtures/responses/prepare-settings-signers.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"txJSON": "{\"TransactionType\":\"SignerListSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"SignerQuorum\":2,\"SignerEntries\":[{\"SignerEntry\":{\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"SignerWeight\":1}},{\"SignerEntry\":{\"Account\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"SignerWeight\":1}},{\"SignerEntry\":{\"Account\":\"rwBYyfufTzk77zUSKEu4MvixfarC35av1J\",\"SignerWeight\":1}}],\"Flags\":2147483648,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
|
||||
"instructions": {
|
||||
"fee": "0.000012",
|
||||
"sequence": 23,
|
||||
"maxLedgerVersion": 8820051
|
||||
}
|
||||
}
|
||||
4
test/fixtures/responses/sign-as.json
vendored
Normal file
4
test/fixtures/responses/sign-as.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"signedTransaction": "120000240000000261400000003B9ACA00684000000000000032730081142E244E6F20104E57C0C60BD823CB312BF10928C78314B5F762798A53D543A014CAF8B297CFF8F2F937E8F3E01073210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100BB6FC77F26BC88587204CAA79B2230C420D7EC937B8AC3A0CF9B0BE988BAB0D002203BF86893BA3B764375FFFAD9D54A4AAEDABD07C4D72ADB9C1B20C10B4DD712898114B5F762798A53D543A014CAF8B297CFF8F2F937E8E1F1",
|
||||
"id": "AB7632D7C07E591658635CED6A5DDE832B22CA066907CB131DEFAAA925B98185"
|
||||
}
|
||||
2
test/fixtures/rippled/account-lines.js
vendored
2
test/fixtures/rippled/account-lines.js
vendored
@@ -22,7 +22,7 @@ module.exports.normal = function(request, options = {}) {
|
||||
currency: 'ASP',
|
||||
limit: '0',
|
||||
limit_peer: '10',
|
||||
quality_in: 0,
|
||||
quality_in: 1000000000,
|
||||
quality_out: 0
|
||||
},
|
||||
{
|
||||
|
||||
@@ -29,4 +29,4 @@
|
||||
},
|
||||
"status": "success",
|
||||
"type": "response"
|
||||
}
|
||||
}
|
||||
|
||||
3
test/fixtures/rippled/index.js
vendored
3
test/fixtures/rippled/index.js
vendored
@@ -38,7 +38,8 @@ module.exports = {
|
||||
sendUSD: require('./path-find-send-usd'),
|
||||
sendAll: require('./path-find-send-all'),
|
||||
XrpToXrp: require('./path-find-xrp-to-xrp'),
|
||||
srcActNotFound: require('./path-find-srcActNotFound')
|
||||
srcActNotFound: require('./path-find-srcActNotFound'),
|
||||
sourceAmountLow: require('./path-find-srcAmtLow')
|
||||
},
|
||||
tx: {
|
||||
Payment: require('./tx/payment.json'),
|
||||
|
||||
22
test/fixtures/rippled/ledger-close-newer.json
vendored
22
test/fixtures/rippled/ledger-close-newer.json
vendored
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"fee_base": 10,
|
||||
"fee_ref": 10,
|
||||
"ledger_hash": "9141FA171F2C0CE63E609466AF728FF66C12F7ACD4B4B50B0947A7F3409D593A",
|
||||
"ledger_index": 14804627,
|
||||
"ledger_time": 490945840,
|
||||
"reserve_base": 20000000,
|
||||
"reserve_inc": 5000000,
|
||||
"txn_count": 19,
|
||||
"type": "ledgerClosed",
|
||||
"validated_ledgers": "13983423-14804627"
|
||||
{
|
||||
"fee_base": 10,
|
||||
"fee_ref": 10,
|
||||
"ledger_hash": "9141FA171F2C0CE63E609466AF728FF66C12F7ACD4B4B50B0947A7F3409D593A",
|
||||
"ledger_index": 14804627,
|
||||
"ledger_time": 490945840,
|
||||
"reserve_base": 20000000,
|
||||
"reserve_inc": 5000000,
|
||||
"txn_count": 19,
|
||||
"type": "ledgerClosed",
|
||||
"validated_ledgers": "13983423-14804627"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user