mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-12 08:35:48 +00:00
Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb2a497dee | ||
|
|
988381d584 | ||
|
|
0b163eae23 | ||
|
|
fadfd4e06c | ||
|
|
eb521faa8d | ||
|
|
14e6bf5ef9 | ||
|
|
b6bddd3b0e | ||
|
|
d5ed9b6cf5 | ||
|
|
7a9912d4e0 | ||
|
|
4d2ddceb4e | ||
|
|
ae2aed675a | ||
|
|
1d7cb41218 | ||
|
|
76db002eb5 | ||
|
|
ebb64ba177 | ||
|
|
1a685e2b68 | ||
|
|
9c561885a1 | ||
|
|
612e98b198 | ||
|
|
0a41d5ccf1 | ||
|
|
ba8fe1f32c | ||
|
|
0f840876a5 | ||
|
|
ac3900b6f4 | ||
|
|
5e138b9937 | ||
|
|
82d50cd903 | ||
|
|
c5b1d4daac | ||
|
|
b4a30d49d8 | ||
|
|
229360d1b9 | ||
|
|
d627d362af | ||
|
|
7ca7a07942 | ||
|
|
09f81fa3cd | ||
|
|
b03bf9c7f1 | ||
|
|
4d696369fe | ||
|
|
bcb80ea5f5 | ||
|
|
1be2ee5875 | ||
|
|
3554e807df | ||
|
|
5ffbd6e86d | ||
|
|
e2572c61cf | ||
|
|
7df2b74d43 | ||
|
|
f51a69f080 | ||
|
|
c0a2d9fc2b | ||
|
|
51dad19f88 | ||
|
|
3d1a530796 | ||
|
|
f6a22d2121 | ||
|
|
6f2d448059 | ||
|
|
0d5103a3f3 | ||
|
|
4da80028bf | ||
|
|
bb40dbde9d | ||
|
|
50fc36ec3e | ||
|
|
1abcef73a0 | ||
|
|
0d7879b25c | ||
|
|
8278dc5b5b | ||
|
|
c90d486454 | ||
|
|
35f9b7ec8d | ||
|
|
69e621af86 | ||
|
|
0e92e696d4 | ||
|
|
0b1445bfe9 | ||
|
|
db2d7ba1f5 | ||
|
|
d82703f41b | ||
|
|
8213861ab7 | ||
|
|
a842c380cf | ||
|
|
5bf6f1849a | ||
|
|
bfe4877f73 | ||
|
|
63dcddf6f4 | ||
|
|
68735ddb35 | ||
|
|
1fd9ca7ef2 | ||
|
|
2445004333 | ||
|
|
dc148bf954 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,5 +1,9 @@
|
||||
# .gitignore
|
||||
|
||||
# Ignore package locks other than Yarn.
|
||||
package-lock.json
|
||||
npm-shrinkwrap.json
|
||||
|
||||
# Ignore vim swap files.
|
||||
*.swp
|
||||
|
||||
@@ -54,6 +58,9 @@ npm-debug.log
|
||||
# Ignore dist folder, built from tsc
|
||||
dist/
|
||||
|
||||
# TypeScript incremental compilation cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Ignore perf test cache
|
||||
scripts/cache
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ language: node_js
|
||||
node_js:
|
||||
- 6
|
||||
- 8
|
||||
- 9
|
||||
- 10
|
||||
- 11
|
||||
script:
|
||||
- yarn compile
|
||||
- yarn test
|
||||
|
||||
@@ -12,7 +12,7 @@ Warning: Use at your own risk.
|
||||
|
||||
## Data and visualizations
|
||||
|
||||
- **[Wipple - XRP Intelligence](https://wipple.devnull.network/)**
|
||||
- **[xrp1ntel - XRP Intelligence](https://xrp1ntel.com/)**
|
||||
|
||||
Monitor the XRP Network in real time and explore historical statistics.
|
||||
|
||||
@@ -36,6 +36,10 @@ Warning: Use at your own risk.
|
||||
|
||||
List of XRPL validators, nodes, and testnet validators.
|
||||
|
||||
- **[XRP Scan - XRP Ledger explorer](https://http://xrpscan.com)**
|
||||
|
||||
XRP Ledger explorer, metrics and analytics.
|
||||
|
||||
## Send and request payments
|
||||
|
||||
- **[XRP Tip Bot](https://www.xrptipbot.com/)**
|
||||
|
||||
155
Gulpfile.js
155
Gulpfile.js
@@ -6,15 +6,12 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
const assert = require('assert');
|
||||
const gulp = require('gulp');
|
||||
const rename = require('gulp-rename');
|
||||
const webpack = require('webpack');
|
||||
const bump = require('gulp-bump');
|
||||
const argv = require('yargs').argv;
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||
|
||||
var pkg = require('./package.json');
|
||||
const pkg = require('./package.json');
|
||||
|
||||
var uglifyOptions = {
|
||||
const uglifyOptions = {
|
||||
mangle: {
|
||||
reserved: ['_', 'RippleError', 'RippledError', 'UnexpectedError',
|
||||
'LedgerVersionError', 'ConnectionError', 'NotConnectedError',
|
||||
@@ -36,7 +33,7 @@ function getWebpackConfig(extension, overrides) {
|
||||
output: {
|
||||
library: 'ripple',
|
||||
path: path.join(__dirname, 'build/'),
|
||||
filename: ['ripple-', extension].join(pkg.version)
|
||||
filename: `ripple-${pkg.version}${extension}`
|
||||
},
|
||||
plugins: [
|
||||
new webpack.NormalModuleReplacementPlugin(/^ws$/, './wswrapper'),
|
||||
@@ -53,12 +50,13 @@ function getWebpackConfig(extension, overrides) {
|
||||
use: [{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
compilerOptions: {declaration: false}
|
||||
compilerOptions: {
|
||||
composite: false,
|
||||
declaration: false,
|
||||
declarationMap: false
|
||||
}
|
||||
},
|
||||
}],
|
||||
}, {
|
||||
test: /\.json/,
|
||||
use: 'json-loader',
|
||||
}]
|
||||
},
|
||||
resolve: {
|
||||
@@ -68,7 +66,7 @@ function getWebpackConfig(extension, overrides) {
|
||||
return _.assign({}, defaults, overrides);
|
||||
}
|
||||
|
||||
function webpackConfigForWebTest(testFileName, path) {
|
||||
function webpackConfigForWebTest(testFileName) {
|
||||
var match = testFileName.match(/\/?([^\/]*)-test.js$/);
|
||||
if (!match) {
|
||||
assert(false, 'wrong filename:' + testFileName);
|
||||
@@ -82,28 +80,13 @@ function webpackConfigForWebTest(testFileName, path) {
|
||||
entry: testFileName,
|
||||
output: {
|
||||
library: match[1].replace(/-/g, '_'),
|
||||
path: './test-compiled-for-web/' + (path ? path : ''),
|
||||
path: path.join(__dirname, 'test-compiled-for-web/'),
|
||||
filename: match[1] + '-test.js'
|
||||
}
|
||||
};
|
||||
return getWebpackConfig('.js', configOverrides);
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
function createLink(from, to) {
|
||||
if (fs.existsSync(to)) {
|
||||
fs.unlinkSync(to);
|
||||
@@ -119,11 +102,22 @@ function createBuildLink(callback) {
|
||||
};
|
||||
}
|
||||
|
||||
gulp.task('build', function(callback) {
|
||||
webpack(getWebpackConfig('.js'), createBuildLink(callback));
|
||||
});
|
||||
function watch(callback) {
|
||||
gulp.watch('src/*', gulp.series(buildDebug));
|
||||
callback();
|
||||
}
|
||||
|
||||
gulp.task('build-min', function(callback) {
|
||||
function build(callback) {
|
||||
webpack(getWebpackConfig('.js'), createBuildLink(callback));
|
||||
}
|
||||
|
||||
function buildDebug(callback) {
|
||||
const webpackConfig = getWebpackConfig('-debug.js', {devtool: 'eval'});
|
||||
webpackConfig.plugins.unshift(new webpack.LoaderOptionsPlugin({debug: true}));
|
||||
webpack(webpackConfig, callback);
|
||||
}
|
||||
|
||||
function buildMin(callback) {
|
||||
const webpackConfig = getWebpackConfig('-min.js');
|
||||
webpackConfig.plugins.push(new UglifyJsPlugin({uglifyOptions}));
|
||||
webpack(webpackConfig, function() {
|
||||
@@ -131,86 +125,27 @@ gulp.task('build-min', function(callback) {
|
||||
'./build/ripple-latest-min.js');
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('build-debug', function(callback) {
|
||||
const webpackConfig = getWebpackConfig('-debug.js', {devtool: 'eval'});
|
||||
webpackConfig.plugins.unshift(new webpack.LoaderOptionsPlugin({debug: true}));
|
||||
webpack(webpackConfig, callback);
|
||||
});
|
||||
|
||||
/**
|
||||
* Generate a WebPack external for a given unavailable module which replaces
|
||||
* that module's constructor with an error-thrower
|
||||
*/
|
||||
function buildUseError(cons) {
|
||||
return ('var {<CONS>:function(){throw new Error('
|
||||
+ '"Class is unavailable in this build: <CONS>")}}')
|
||||
.replace(new RegExp('<CONS>', 'g'), cons);
|
||||
}
|
||||
|
||||
gulp.task('build-core', function(callback) {
|
||||
var configOverrides = {
|
||||
cache: false,
|
||||
entry: './src/remote.ts',
|
||||
externals: [{
|
||||
'./transaction': buildUseError('Transaction'),
|
||||
'./orderbook': buildUseError('OrderBook'),
|
||||
'./account': buildUseError('Account'),
|
||||
'./serializedobject': buildUseError('SerializedObject')
|
||||
}],
|
||||
plugins: [
|
||||
new UglifyJsPlugin()
|
||||
]
|
||||
};
|
||||
webpack(getWebpackConfig('-core.js', configOverrides), callback);
|
||||
});
|
||||
|
||||
gulp.task('bower-build', ['build'], function() {
|
||||
return gulp.src(['./build/ripple-', '.js'].join(pkg.version))
|
||||
.pipe(rename('ripple.js'))
|
||||
.pipe(gulp.dest('./dist/bower'));
|
||||
});
|
||||
|
||||
gulp.task('bower-build-min', ['build-min'], function() {
|
||||
return gulp.src(['./build/ripple-', '-min.js'].join(pkg.version))
|
||||
.pipe(rename('ripple-min.js'))
|
||||
.pipe(gulp.dest('./dist/bower'));
|
||||
});
|
||||
|
||||
gulp.task('bower-build-debug', ['build-debug'], function() {
|
||||
return gulp.src(['./build/ripple-', '-debug.js'].join(pkg.version))
|
||||
.pipe(rename('ripple-debug.js'))
|
||||
.pipe(gulp.dest('./dist/bower'));
|
||||
});
|
||||
|
||||
gulp.task('bower-version', function() {
|
||||
gulp.src('./dist/bower/bower.json')
|
||||
.pipe(bump({version: pkg.version}))
|
||||
.pipe(gulp.dest('./dist/bower'));
|
||||
});
|
||||
|
||||
gulp.task('bower', ['bower-build', 'bower-build-min', 'bower-build-debug',
|
||||
'bower-version']);
|
||||
|
||||
gulp.task('watch', function() {
|
||||
gulp.watch('src/*', ['build-debug']);
|
||||
});
|
||||
|
||||
gulp.task('version-bump', function() {
|
||||
if (!argv.type) {
|
||||
throw new Error('No type found, pass it in using the --type argument');
|
||||
function buildTests(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.src('./package.json')
|
||||
.pipe(bump({type: argv.type}))
|
||||
.pipe(gulp.dest('./'));
|
||||
});
|
||||
exports.watch = watch;
|
||||
exports.build = build;
|
||||
exports.buildDebug = buildDebug;
|
||||
exports.buildMin = buildMin;
|
||||
exports.buildTests = buildTests;
|
||||
|
||||
gulp.task('version-beta', function() {
|
||||
gulp.src('./package.json')
|
||||
.pipe(bump({version: pkg.version + '-beta'}))
|
||||
.pipe(gulp.dest('./'));
|
||||
});
|
||||
|
||||
gulp.task('default', ['build', 'build-debug', 'build-min']);
|
||||
exports.default = gulp.parallel(build, buildDebug, buildMin);
|
||||
|
||||
295
HISTORY.md
295
HISTORY.md
@@ -1,13 +1,306 @@
|
||||
# ripple-lib Release History
|
||||
|
||||
## 1.3.4 (2019-10-18)
|
||||
|
||||
* Update ripple-lib-transactionparser
|
||||
* Improve error message when signing fails (e.g. due to trailing zeros)
|
||||
* Integrate ripple-hashes (in TypeScript with improved naming and docs)
|
||||
* Add multi-signing example to sign() method docs
|
||||
* Update TypeScript
|
||||
|
||||
## 1.3.3 (2019-09-10)
|
||||
|
||||
* Expand node version compatibility to support Node.js 12 ([ripple-binary-codec#32](https://github.com/ripple/ripple-binary-codec/issues/32))
|
||||
|
||||
## 1.3.2 (2019-09-03)
|
||||
|
||||
* Export and document `rippleTimeToISO8601()` method
|
||||
* Add type for isValidAddress (fixes error TS7016, #1032)
|
||||
* Docs: update recommended Node.js version (#1031)
|
||||
|
||||
When using this release with [rippled](https://github.com/ripple/rippled), we recommend using [rippled version 1.3.1](https://github.com/ripple/rippled/releases/tag/1.3.1) or later.
|
||||
|
||||
## 1.3.1 (2019-08-26)
|
||||
|
||||
* Upgrade to gulp 4 (#1030)
|
||||
* Remove http server (unused)
|
||||
* Update dependencies
|
||||
|
||||
There are no changes in the browser version with this release. The npm package for Node.js should be slightly smaller.
|
||||
|
||||
When using this release with [rippled](https://github.com/ripple/rippled), we recommend using [rippled version 1.3.1](https://github.com/ripple/rippled/releases/tag/1.3.1).
|
||||
|
||||
## 1.3.0 (2019-08-16)
|
||||
|
||||
### Bug fixes:
|
||||
|
||||
* Breaking change: Fix `getServerInfo` (#1012)
|
||||
|
||||
Before:
|
||||
```
|
||||
{
|
||||
// ...
|
||||
"load": {
|
||||
"jobTypes": {
|
||||
"0": {"jobType": "untrustedValidation", "perSecond": 10},
|
||||
"1": {"jobType": "ledgerData", "peakTime": 2, "perSecond": 2},
|
||||
"2": {"inProgress": 1, "jobType": "clientCommand", "perSecond": 1},
|
||||
"3": {"jobType": "transaction", "perSecond": 1},
|
||||
// ...
|
||||
},
|
||||
"threads": 6
|
||||
},
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
After:
|
||||
```
|
||||
{
|
||||
// ...
|
||||
"load": {
|
||||
"jobTypes": [
|
||||
{
|
||||
"jobType": "untrustedValidation",
|
||||
"perSecond": 8
|
||||
},
|
||||
{
|
||||
"avgTime": 2,
|
||||
"jobType": "ledgerData",
|
||||
"peakTime": 72,
|
||||
"perSecond": 2
|
||||
},
|
||||
{
|
||||
"inProgress": 1,
|
||||
"jobType": "clientCommand",
|
||||
"perSecond": 1
|
||||
},
|
||||
{
|
||||
"jobType": "transaction",
|
||||
"perSecond": 1
|
||||
},
|
||||
// ...
|
||||
],
|
||||
"threads": 6
|
||||
},
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
* Sign method - verify accurate encoding (#1026)
|
||||
* In previous versions, the following could be encoded incorrectly:
|
||||
* Amounts of XRP with more than 6 decimal places
|
||||
* Amounts of XRP drops with any decimal places
|
||||
* In versions 1.2.5 and 1.3.0, amounts that are invalid in this way will throw an error
|
||||
* Expand `APIOptions` by extending `ConnectionOptions` (#1018, fixes #1017)
|
||||
* Fix docs for destination.address (#1011)
|
||||
|
||||
### New features:
|
||||
|
||||
* Support removing a signer list (#1021)
|
||||
* Export `setCanonicalFlag` method from `src/transaction/utils`
|
||||
|
||||
### Improvements:
|
||||
|
||||
* Clean up phrasing in schema descriptions (#1023)
|
||||
* Improve docs
|
||||
* Update dependencies
|
||||
|
||||
Since this release fixes a bug that could cause transactions to be serialized incorrectly during the signing process, it has also been simultaneously released as version 1.2.5 (patch release).
|
||||
|
||||
When using this release with [rippled](https://github.com/ripple/rippled), we recommend using [rippled version 1.3.1](https://github.com/ripple/rippled/releases/tag/1.3.1).
|
||||
|
||||
## 1.2.4 (2019-06-06)
|
||||
|
||||
* Update README.md
|
||||
* Clarify docs
|
||||
* Update dependencies
|
||||
* Fix typos
|
||||
|
||||
The SHA-256 checksums for the browser version of this release can be found
|
||||
below.
|
||||
```
|
||||
% shasum -a 256 *
|
||||
4f09c056ccc51bc6cf17b128b559112e9c5adf19cc96ac8f9a06faee185697a7 ripple-1.2.4-debug.js
|
||||
5da1c75a02d76b0b105d98355ee4561f5d5036e8d5d0237efd5960812dcaa1fd ripple-1.2.4-min.js
|
||||
e147f303e880a65db149d2a5b9183b75814bd8145cd00740bcc4679d867192c8 ripple-1.2.4.js
|
||||
```
|
||||
|
||||
## 1.2.3 (2019-04-30)
|
||||
|
||||
* Fix browser builds
|
||||
|
||||
The SHA-256 checksums for the browser version of this release can be found
|
||||
below.
|
||||
```
|
||||
% shasum -a 256 *
|
||||
efb0f29cde94534a015d8a2171abb11b9a4345ba01418bf5b6ab6042a6d51dde ripple-1.2.3-debug.js
|
||||
b86145c0e30099b966ed8d3830ba25988d72877f1f87044d9954d6707be098ac ripple-1.2.3-min.js
|
||||
e027d91c7321d41ba94bb1bdc77dcff0107a5fd9eb833c6dbd06f1bbedef3900 ripple-1.2.3.js
|
||||
```
|
||||
|
||||
## 1.2.2 (2019-04-15)
|
||||
|
||||
* Prevent `prepareTransaction` from overwriting `Fee` and/or `LastLedgerSequence` (#997)
|
||||
* Add `deliveredAmount` as optional field for type `Outcome` (#996)
|
||||
* Fix build failure with TS strict checks (#993)
|
||||
|
||||
Minor changes:
|
||||
|
||||
* Use TypeScript project references
|
||||
* Travis: Drop node 9 and add node 11 for testing
|
||||
* Bump versions of devDependencies
|
||||
|
||||
Note: There is no browser version of this release.
|
||||
|
||||
## 1.2.1 (2019-03-23)
|
||||
|
||||
* Update `ripple-binary-codec` to 0.2.1 to support `tecKILLED`
|
||||
|
||||
The SHA-256 checksums for the browser version of this release can be found
|
||||
below.
|
||||
|
||||
```
|
||||
% shasum -a 256 *
|
||||
531c2a8f4bf6d6b5bd4afe6a40b6a68a77179a343902cfa4210d7e35b5697af0 ripple-1.2.1-debug.js
|
||||
201ee99922b16b7e32afb5317ef4bb9facc23b20c272bb5c4ed7010f5d996cab ripple-1.2.1-min.js
|
||||
c1b984581299bf00e0e3c8ac4e62eadfc9b190bd78a2458a76e59ceb56046148 ripple-1.2.1.js
|
||||
```
|
||||
|
||||
## 1.2.0 (2019-03-19)
|
||||
|
||||
This release:
|
||||
|
||||
* changes the way you handle errors for the `prepare*` methods.
|
||||
* improves the `message` field of `RippledError`s.
|
||||
* allows `Sequence` to be set in the transaction JSON provided to
|
||||
`prepareTransaction`.
|
||||
|
||||
For details, continue reading:
|
||||
|
||||
### [BREAKING CHANGE] `prepare*` methods reject the Promise on error
|
||||
|
||||
The `prepare*` methods now always reject the Promise when an error occurs, instead of throwing.
|
||||
|
||||
Previously, the methods would synchronously throw on validation errors, despite being asynchronous methods that return Promises.
|
||||
|
||||
In other words, to handle errors in the past, you would need to use a try/catch block:
|
||||
|
||||
```
|
||||
// OBSOLETE - no need for try/catch anymore
|
||||
try {
|
||||
api.preparePayment(address, payment, instructions).then(prepared => {
|
||||
res.send(prepared.txJSON);
|
||||
}).catch(error => {
|
||||
// Handle asynchronous error
|
||||
});
|
||||
} catch (error) {
|
||||
// Handle synchronous error
|
||||
}
|
||||
```
|
||||
|
||||
Now, you can rely on the Promise's `catch` handler, which is called with the error when the Promise is rejected:
|
||||
|
||||
```
|
||||
api.preparePayment(address, payment, instructions).then(prepared => {
|
||||
res.send(prepared.txJSON);
|
||||
}).catch(error => {
|
||||
// Handle error
|
||||
});
|
||||
```
|
||||
|
||||
This applies to:
|
||||
* preparePayment
|
||||
* prepareTrustline
|
||||
* prepareOrder
|
||||
* prepareOrderCancellation
|
||||
* prepareSettings
|
||||
* prepareEscrowCreation
|
||||
* prepareEscrowExecution
|
||||
* prepareCheckCreate
|
||||
* prepareCheckCash
|
||||
* prepareCheckCancel
|
||||
* preparePaymentChannelCreate
|
||||
* preparePaymentChannelClaim
|
||||
* preparePaymentChannelFund
|
||||
|
||||
### Improved `RippledError` `message`
|
||||
|
||||
Previously, `RippledErrors` (errors from rippled) used rippled's `error` field as the `message`.
|
||||
|
||||
Now, the `error_message` field is used as the `message`.
|
||||
|
||||
This helps to surface the specific cause of an error.
|
||||
|
||||
For example, before:
|
||||
```
|
||||
[RippledError(invalidParams, { error: 'invalidParams',
|
||||
error_code: 31,
|
||||
error_message: 'Missing field \'account\'.',
|
||||
id: 3,
|
||||
request: { command: 'account_info', id: 3 },
|
||||
status: 'error',
|
||||
type: 'response' })]
|
||||
```
|
||||
|
||||
After:
|
||||
```
|
||||
[RippledError(Missing field 'account'., { error: 'invalidParams',
|
||||
error_code: 31,
|
||||
error_message: 'Missing field \'account\'.',
|
||||
id: 3,
|
||||
request: { command: 'account_info', id: 3 },
|
||||
status: 'error',
|
||||
type: 'response' })]
|
||||
```
|
||||
|
||||
In this case, you can see at a glance that `account` is the missing field.
|
||||
|
||||
The `error` field is still available in `errorObject.data.error`.
|
||||
|
||||
When `error_message` is not set (as with e.g. error 'entryNotFound'), the `error` field is used as the `message`.
|
||||
|
||||
### [BUG FIX] `prepareTransaction` does not overwrite the `Sequence` field
|
||||
|
||||
The `prepareTransaction` method now allows `Sequence` to be set in the Transaction JSON object, instead of overwriting it with the account's expected sequence based on the state of the ledger.
|
||||
|
||||
Previously, you had to use the `sequence` field in the `instructions` object to manually set a transaction's sequence number.
|
||||
|
||||
### New in rippled 1.2.1
|
||||
|
||||
As this is the first release of ripple-lib following the release of rippled 1.2.1, we would like to highlight the following API improvements:
|
||||
|
||||
1. The [`delivered_amount` field](https://developers.ripple.com/partial-payments.html#the-delivered-amount-field) has been added to the `ledger` method, and to transaction subscriptions.
|
||||
|
||||
api.getLedger({includeTransactions: true, includeAllData: true, ledgerVersion: 17718771}).then(...)
|
||||
|
||||
You can also call `ledger` directly:
|
||||
|
||||
request('ledger', {...}).then(...)
|
||||
|
||||
2. [Support for Ed25519 seeds encoded using ripple-lib](https://github.com/ripple/rippled/pull/2734)
|
||||
|
||||
You have access to these improvements when you use a rippled server running version 1.2.1 or later. At the time of writing, we recommend using rippled version **1.2.2** or later.
|
||||
|
||||
The SHA-256 checksums for the browser version of this release can be found
|
||||
below.
|
||||
```
|
||||
% shasum -a 256 *
|
||||
13021fe3efbdd59faf68597b0b18204b39847b285cca82f84c737e3d19922cc2 ripple-1.2.0-debug.js
|
||||
0070225e731afd8c2c0a0976111ebf326c19a96ee1549368de9f016abdd53d2f ripple-1.2.0-min.js
|
||||
d440268397c03ad5137a3294e53a07b959ef93cd23b1990d6f82621c4776ba9f ripple-1.2.0.js
|
||||
```
|
||||
|
||||
## 1.1.2 (2018-12-12)
|
||||
|
||||
+ Update `submit` response (#978)
|
||||
+ Includes the full object returned by rippled, while keeping the existing
|
||||
fields for backward compatibility
|
||||
+ Add `getLedger` option for ledger hash (##980)
|
||||
+ Add `getLedger` option for ledger hash (#980)
|
||||
+ Use the `ledgerHash` option to get a specific ledger by hash
|
||||
|
||||
Thanks to @alexchiriac for the contributions in this release.
|
||||
|
||||
When using `ripple-lib` with `rippled`, we recommend using `rippled` version
|
||||
1.1.2 or later.
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ A JavaScript API for interacting with the XRP Ledger
|
||||
|
||||
## Getting Started
|
||||
|
||||
See also: [RippleAPI Beginners Guide](https://ripple.com/build/rippleapi-beginners-guide/)
|
||||
See also: [RippleAPI Beginners Guide](https://xrpl.org/get-started-with-rippleapi-for-javascript.html)
|
||||
|
||||
### Requirements
|
||||
|
||||
@@ -74,4 +74,5 @@ The continuous integration tests require that the documentation stays up-to-date
|
||||
|
||||
## More Information
|
||||
|
||||
+ [Ripple Developer Center](https://ripple.com/build/)
|
||||
+ [RippleAPI Reference](https://developers.ripple.com/rippleapi-reference.html) - XRP Ledger Dev Portal
|
||||
+ [XRP Ledger Dev Portal](https://developers.ripple.com/)
|
||||
|
||||
9
custom_typings/node.d.ts
vendored
9
custom_typings/node.d.ts
vendored
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* This is an extension of Node's `process` object to include the browser
|
||||
* property, which is added by webpack.
|
||||
*/
|
||||
interface AmbiguousProcess extends NodeJS.Process {
|
||||
browser?: true
|
||||
}
|
||||
|
||||
declare var process: AmbiguousProcess;
|
||||
299
docs/index.md
299
docs/index.md
@@ -91,6 +91,7 @@
|
||||
- [xrpToDrops](#xrptodrops)
|
||||
- [dropsToXrp](#dropstoxrp)
|
||||
- [iso8601ToRippleTime](#iso8601torippletime)
|
||||
- [rippleTimeToISO8601](#rippletimetoiso8601)
|
||||
- [txFlags](#txflags)
|
||||
- [schemaValidator](#schemavalidator)
|
||||
- [schemaValidate](#schemavalidate)
|
||||
@@ -141,7 +142,7 @@ api.connect().then(() => {
|
||||
}).catch(console.error);
|
||||
```
|
||||
|
||||
RippleAPI is designed to work in [Node.js](https://nodejs.org) version **6.11.3**. RippleAPI may work on older Node.js versions if you use [Babel](https://babeljs.io/) for [ECMAScript 6](https://babeljs.io/docs/learn-es2015/) support.
|
||||
RippleAPI is designed to work in [Node.js](https://nodejs.org) version 6 or higher. Ripple recommends Node.js v10 LTS.
|
||||
|
||||
The code samples in this documentation are written with ECMAScript 6 (ES6) features, but `RippleAPI` also works with ECMAScript 5 (ES5). Regardless of whether you use ES5 or ES6, the methods that return Promises return [ES6-style promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
|
||||
|
||||
@@ -273,7 +274,7 @@ A *balance* is an amount than can have a negative value.
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
currency | [currency](#currency) | The three-character code or hexadecimal string used to denote currencies, or "drops" for the smallest unit of XRP.
|
||||
counterparty | [address](#address) | *Optional* The Ripple address of the account that owes or is owed the funds (omitted if `currency` is "XRP" or "drops")
|
||||
counterparty | [address](#address) | *Optional* The XRP Ledger address of the account that owes or is owed the funds (omitted if `currency` is "XRP" or "drops")
|
||||
value | [value](#value) | *Optional* The quantity of the currency, denoted as a string to retain floating point precision
|
||||
|
||||
# Transaction Overview
|
||||
@@ -293,7 +294,7 @@ Type | Description
|
||||
[escrowCancellation](#escrow-cancellation) | An `escrowCancellation` transaction unlocks the funds in an escrow and sends them back to the creator of the escrow, but it will only work after the escrow expires.
|
||||
[escrowExecution](#escrow-execution) | An `escrowExecution` transaction unlocks the funds in an escrow and sends them to the destination of the escrow, but it will only work if the cryptographic condition is provided.
|
||||
[checkCreate](#check-create) | A `checkCreate` transaction creates a check on the ledger, which is a deferred payment that can be cashed by its intended destination.
|
||||
[checkCancel](#check-cancel) | A `checkCancel` transaction cancels an unreedemed Check, removing it from the ledger without sending any money.
|
||||
[checkCancel](#check-cancel) | A `checkCancel` transaction cancels an unredeemed Check, removing it from the ledger without sending any money.
|
||||
[checkCash](#check-cash) | A `checkCash` transaction redeems a Check to receive up to the amount authorized by the corresponding `checkCreate` transaction. Only the `destination` address of a Check can cash it.
|
||||
[paymentChannelCreate](#payment-channel-create) | A `paymentChannelCreate` transaction opens a payment channel between two addresses with XRP set aside for asynchronous payments.
|
||||
[paymentChannelFund](#payment-channel-fund) | A `paymentChannelFund` transaction adds XRP to a payment channel and optionally sets a new expiration for the channel.
|
||||
@@ -321,25 +322,27 @@ Executing a transaction with `RippleAPI` requires the following four steps:
|
||||
|
||||
## Transaction Fees
|
||||
|
||||
Every transaction must destroy a small amount of XRP as a cost to send the transaction. This is also called a *transaction fee*. The transaction cost is designed to increase along with the load on the XRP Ledger, making it very expensive to deliberately or inadvertently overload the peer-to-peer network that powers the XRP Ledger.
|
||||
Every transaction must destroy a small amount of XRP as a cost to apply the transaction to the ledger. This is also called a *transaction fee*. The transaction cost is designed to increase along with the load on the XRP Ledger, making it very expensive to deliberately or inadvertently overload the peer-to-peer network that powers the XRP Ledger.
|
||||
|
||||
You can choose the size of the fee you want to pay or let a default be used. You can get an estimate of the fee required to be included in the next ledger closing with the [getFee](#getfee) method.
|
||||
|
||||
For a multi-signed transaction, ripple-lib automatically multiplies the `fee` by (1 + Number of Signatures Provided). For example, if you set `instructions.fee = '0.000020'` and `instructions.signersCount = 2`, the prepared transaction's `Fee` will be 20 drops × (1 + 2 Signatures) = 60 drops. See [Transaction Cost](https://developers.ripple.com/transaction-cost.html).
|
||||
|
||||
## Transaction Instructions
|
||||
|
||||
Transaction instructions indicate how to execute a transaction, complementary with the [transaction specification](#transaction-specifications).
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
fee | [value](#value) | *Optional* An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information.
|
||||
fee | [value](#value) | *Optional* An exact fee to pay for the transaction, before multiplying for multi-signed transactions. See [Transaction Fees](#transaction-fees) for more information.
|
||||
maxFee | [value](#value) | *Optional* Deprecated: Use `maxFeeXRP` in the RippleAPI constructor instead. The maximum fee to pay for this transaction. If this exceeds `maxFeeXRP`, `maxFeeXRP` will be used instead. See [Transaction Fees](#transaction-fees) for more information.
|
||||
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.
|
||||
maxLedgerVersion | string,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.
|
||||
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. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
maxLedgerVersion | string,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. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
maxLedgerVersionOffset | integer | *Optional* Offset from current validated ledger 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 recommend that you specify a `maxLedgerVersion` so that you can quickly determine that a failed transaction will never succeeed in the future. It is impossible for a transaction to succeed after the XRP Ledger's consensus-validated ledger version exceeds the transaction's `maxLedgerVersion`. If you omit `maxLedgerVersion`, the "prepare\*" method automatically supplies a `maxLedgerVersion` equal to the current ledger plus 3, which it includes in the return value from the "prepare\*" method.
|
||||
We recommend that you specify a `maxLedgerVersion` so that you can quickly determine that a failed transaction will never succeed in the future. It is impossible for a transaction to succeed after the XRP Ledger's consensus-validated ledger version exceeds the transaction's `maxLedgerVersion`. If you omit `maxLedgerVersion`, the "prepare\*" method automatically supplies a `maxLedgerVersion` equal to the current ledger plus 3, which it includes in the return value from the "prepare\*" method.
|
||||
|
||||
## Transaction ID
|
||||
|
||||
@@ -373,15 +376,14 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
source | object | The source of the funds to be sent.
|
||||
*source.* address | [address](#address) | The address to send from.
|
||||
*source.* amount | [laxAmount](#amount) | An exact amount to send. If the counterparty is not specified, amounts with any counterparty may be used. (This field is exclusive with source.maxAmount)
|
||||
*source.* amount | [laxAmount](#amount) | An exact amount to send. If the counterparty is not specified, amounts with any counterparty may be used. (This field cannot be used with source.maxAmount)
|
||||
*source.* tag | integer | *Optional* An arbitrary unsigned 32-bit integer that identifies a reason for payment or a non-Ripple account.
|
||||
*source.* maxAmount | [laxAmount](#amount) | The maximum amount to send. (This field is exclusive with source.amount)
|
||||
*source.* maxAmount | [laxAmount](#amount) | The maximum amount to send. (This field cannot be used with source.amount)
|
||||
destination | object | The destination of the funds to be sent.
|
||||
*destination.* address | [address](#address) | The address to receive at.
|
||||
*destination.* address | [address](#address) | An address representing the destination of the transaction.
|
||||
*destination.* amount | [laxAmount](#amount) | An exact amount to deliver to the recipient. If the counterparty is not specified, amounts with any counterparty may be used. (This field cannot be used with `destination.minAmount`.)
|
||||
*destination.* tag | integer | *Optional* An arbitrary unsigned 32-bit integer that identifies a reason for payment or a non-Ripple account.
|
||||
*destination.* address | [address](#address) | The address to send to.
|
||||
*destination.* minAmount | [laxAmount](#amount) | The minimum amount to be delivered. (This field is exclusive with destination.amount)
|
||||
*destination.* minAmount | [laxAmount](#amount) | The minimum amount to be delivered. (This field cannot be used with destination.amount)
|
||||
allowPartialPayment | boolean | *Optional* If true, this payment should proceed even if the whole amount cannot be delivered due to a lack of liquidity or a lack of funds in the source account.
|
||||
invoiceID | string | *Optional* A 256-bit hash that can be used to identify a particular payment.
|
||||
limitQuality | boolean | *Optional* Only take paths where all the conversions have an input:output ratio that is equal or better than the ratio of destination.amount:source.maxAmount.
|
||||
@@ -519,7 +521,7 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
defaultRipple | boolean | *Optional* Enable [rippling](https://ripple.com/build/understanding-the-noripple-flag/) on this account’s trust lines by default. (New in [rippled 0.27.3](https://github.com/ripple/rippled/releases/tag/0.27.3))
|
||||
depositAuth | boolean | *Optional* Enable [Deposit Authorization](https://ripple.com/build/deposit-authorization/) on this account. If set, transactions cannot send value of any kind to this account unless the sender of those transactions is the account itself. (Requires the [DepositAuth amendment](https://ripple.com/build/known-amendments/#depositauth))
|
||||
disableMasterKey | boolean | *Optional* Disallows use of the master key to sign transactions for this account.
|
||||
disableMasterKey | boolean | *Optional* Disallows use of the master key to sign transactions for this account. To disable the master key, you must authorize the transaction by signing it with the master key pair. You cannot use a regular key pair or a multi-signature. You can re-enable the master key pair using a regular key pair or multi-signature. See [AccountSet](https://developers.ripple.com/accountset.html).
|
||||
disallowIncomingXRP | boolean | *Optional* Indicates that client applications should not send XRP to this account. Not enforced by rippled.
|
||||
domain | string | *Optional* The domain that owns this account, as a hexadecimal string representing the ASCII for the domain in lowercase.
|
||||
emailHash | string,null | *Optional* Hash of an email address to be used for generating an avatar image. Conventionally, clients use Gravatar to display this image. Use `null` to clear.
|
||||
@@ -534,7 +536,7 @@ requireAuthorization | boolean | *Optional* If set, this account must individual
|
||||
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 | 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 | Weights of signatures for each signer.
|
||||
*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](#address) | A Ripple account address
|
||||
*signers.weights[].* weight | integer | The weight that the signature of this account counts as towards the threshold.
|
||||
@@ -1361,7 +1363,7 @@ lastClose | object | Information about the last time the server closed a ledger.
|
||||
loadFactor | number | The load factor the server is currently enforcing, as a multiplier on the base transaction fee. The load factor is determined by the highest of the individual server’s load factor, cluster’s load factor, and the overall network’s load factor.
|
||||
peers | integer | How many other rippled servers the node is currently connected to.
|
||||
pubkeyNode | string | Public key used to verify this node for internal communications; this key is automatically generated by the server the first time it starts up. (If deleted, the node can just create a new pair of keys.)
|
||||
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.
|
||||
serverState | string | A string indicating to what extent the server is participating in the network. See [Possible Server States](https://developers.ripple.com/rippled-server-states.html) 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 | [value](#value) | Base fee, in XRP. This may be represented in scientific notation such as 1e-05 for 0.00005.
|
||||
@@ -1372,7 +1374,7 @@ validatedLedger | object | Information about the fully-validated ledger with the
|
||||
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.
|
||||
*load.* jobTypes | array\<object\> | *(Admin only)* Information about the rate of different types of jobs being performed by the server and how much time it spends on each.
|
||||
*load.* threads | number | *(Admin only)* The number of threads in the server’s main job pool, performing various Ripple Network operations.
|
||||
*load.* threads | number | *(Admin only)* The number of threads in the server’s main job pool, performing various operations.
|
||||
pubkeyValidator | string | *Optional* *(Admin only)* Public key used by this node to sign ledger validations.
|
||||
|
||||
### Example
|
||||
@@ -1476,11 +1478,11 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
id | [transactionHash](#transaction-id) | A hash of a transaction used to identify the transaction, represented in hexadecimal.
|
||||
options | object | *Optional* Options to limit the ledger versions to search and/or to include raw transaction data.
|
||||
*options.* includeRawTransaction | object | *Optional* Include raw transaction data. For advanced users; exercise caution when interpreting this data.
|
||||
*options.* maxLedgerVersion | integer | *Optional* The highest ledger version to search
|
||||
*options.* maxLedgerVersion | string | *Optional* The highest ledger version to search
|
||||
*options.* minLedgerVersion | integer | *Optional* The lowest ledger version to search.
|
||||
*options.* minLedgerVersion | string | *Optional* The lowest ledger version to search.
|
||||
*options.* includeRawTransaction | object | *Optional* Include raw transaction data. For advanced users; exercise caution when interpreting this data.
|
||||
*options.* maxLedgerVersion | integer | *Optional* The highest ledger version to search. This must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*options.* maxLedgerVersion | string | *Optional* The highest ledger version to search. This must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*options.* minLedgerVersion | integer | *Optional* The lowest ledger version to search. This must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*options.* minLedgerVersion | string | *Optional* The lowest ledger version to search. This must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Return Value
|
||||
|
||||
@@ -1494,7 +1496,7 @@ sequence | [sequence](#account-sequence-number) | The account sequence number of
|
||||
type | [transactionType](#transaction-types) | The type of the transaction.
|
||||
specification | object | A specification that would produce the same outcome as this transaction. *Exception:* For payment transactions, this omits the `destination.amount` field, to prevent misunderstanding. The structure of the specification depends on the value of the `type` field (see [Transaction Types](#transaction-types) for details). *Note:* This is **not** necessarily the same as the original specification.
|
||||
outcome | object | The outcome of the transaction (what effects it had).
|
||||
*outcome.* result | string | Result code returned by rippled. See [Transaction Results](https://ripple.com/build/transactions/#full-transaction-response-list) for a complete list.
|
||||
*outcome.* result | string | Result code returned by rippled. See [Transaction Results](https://developers.ripple.com/transaction-results.html) for a complete list.
|
||||
*outcome.* fee | [value](#value) | The XRP fee that was charged for the transaction.
|
||||
*outcome.balanceChanges.* \* | array\<[balance](#amount)\> | Key is the XRP Ledger address; value is an array of signed amounts representing changes of balances for that address.
|
||||
*outcome.orderbookChanges.* \* | array | Key is the maker's XRP Ledger address; value is an array of changes
|
||||
@@ -1637,8 +1639,8 @@ options | object | *Optional* Options to filter the resulting transactions.
|
||||
*options.* limit | integer | *Optional* If specified, return at most this many transactions.
|
||||
*options.* maxLedgerVersion | integer | *Optional* Return only transactions in this ledger version or lower.
|
||||
*options.* maxLedgerVersion | string | *Optional* Return only transactions in this ledger version or lower.
|
||||
*options.* minLedgerVersion | integer | *Optional* Return only transactions in this ledger verion or higher.
|
||||
*options.* minLedgerVersion | string | *Optional* Return only transactions in this ledger verion or higher.
|
||||
*options.* minLedgerVersion | integer | *Optional* Return only transactions in this ledger version or higher.
|
||||
*options.* minLedgerVersion | string | *Optional* Return only transactions in this ledger version or higher.
|
||||
*options.* start | string | *Optional* If specified, this transaction will be the first transaction in the result. You cannot use `start` with `minLedgerVersion` or `maxLedgerVersion`. When `start` is specified, these ledger versions will be determined internally.
|
||||
*options.* types | array\<[transactionType](#transaction-types)\> | *Optional* Only return transactions of the specified [Transaction Types](#transaction-types).
|
||||
|
||||
@@ -2019,7 +2021,7 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
currency | [currency](#currency) | The three-character code or hexadecimal string used to denote currencies
|
||||
value | [signedValue](#value) | The balance on the trustline
|
||||
counterparty | [address](#address) | *Optional* The Ripple address of the account that owes or is owed the funds.
|
||||
counterparty | [address](#address) | *Optional* The XRP Ledger address of the account that owes or is owed the funds.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -2170,7 +2172,7 @@ Returns aggregate balances by currency plus a breakdown of assets and obligation
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
address | [address](#address) | The Ripple address of the account to get the balance sheet of.
|
||||
address | [address](#address) | The XRP Ledger address of the account to get the balance sheet of.
|
||||
options | object | *Optional* Options to determine how the balances will be calculated.
|
||||
*options.* excludeAddresses | array\<[address](#address)\> | *Optional* Addresses to exclude from the balance totals.
|
||||
*options.* ledgerVersion | integer | *Optional* Get the balance sheet as of this historical ledger version.
|
||||
@@ -2268,14 +2270,14 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
pathfind | object | Specification of a pathfind request.
|
||||
*pathfind.* source | object | Properties of the source of funds.
|
||||
*pathfind.source.* address | [address](#address) | The Ripple address of the account where funds will come from.
|
||||
*pathfind.source.* address | [address](#address) | The XRP Ledger address of the account where funds will come from.
|
||||
*pathfind.source.* amount | [laxAmount](#amount) | *Optional* The amount of funds to send.
|
||||
*pathfind.source.* currencies | array | *Optional* An array of currencies (with optional counterparty) that may be used in the payment paths.
|
||||
*pathfind.source.* currencies[] | object | A currency with optional counterparty.
|
||||
*pathfind.source.currencies[].* currency | [currency](#currency) | The three-character code or hexadecimal string used to denote currencies
|
||||
*pathfind.source.currencies[].* counterparty | [address](#address) | *Optional* The counterparty for the currency; if omitted any counterparty may be used.
|
||||
*pathfind.* destination | object | Properties of the destination of funds.
|
||||
*pathfind.destination.* address | [address](#address) | The address to send to.
|
||||
*pathfind.destination.* address | [address](#address) | An address representing the destination of the transaction.
|
||||
*pathfind.destination.* amount | [laxLaxAmount](#amount) | The amount to be received by the receiver (`value` may be ommitted if a source amount is specified).
|
||||
|
||||
### Return Value
|
||||
@@ -2286,15 +2288,14 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
source | object | Properties of the source of the payment.
|
||||
*source.* address | [address](#address) | The address to send from.
|
||||
*source.* amount | [laxAmount](#amount) | An exact amount to send. If the counterparty is not specified, amounts with any counterparty may be used. (This field is exclusive with source.maxAmount)
|
||||
*source.* amount | [laxAmount](#amount) | An exact amount to send. If the counterparty is not specified, amounts with any counterparty may be used. (This field cannot be used with source.maxAmount)
|
||||
*source.* tag | integer | *Optional* An arbitrary unsigned 32-bit integer that identifies a reason for payment or a non-Ripple account.
|
||||
*source.* maxAmount | [laxAmount](#amount) | The maximum amount to send. (This field is exclusive with source.amount)
|
||||
*source.* maxAmount | [laxAmount](#amount) | The maximum amount to send. (This field cannot be used with source.amount)
|
||||
destination | object | Properties of the destination of the payment.
|
||||
*destination.* address | [address](#address) | The address to receive at.
|
||||
*destination.* address | [address](#address) | An address representing the destination of the transaction.
|
||||
*destination.* amount | [laxAmount](#amount) | An exact amount to deliver to the recipient. If the counterparty is not specified, amounts with any counterparty may be used. (This field cannot be used with `destination.minAmount`.)
|
||||
*destination.* tag | integer | *Optional* An arbitrary unsigned 32-bit integer that identifies a reason for payment or a non-Ripple account.
|
||||
*destination.* address | [address](#address) | The address to send to.
|
||||
*destination.* minAmount | [laxAmount](#amount) | The minimum amount to be delivered. (This field is exclusive with destination.amount)
|
||||
*destination.* minAmount | [laxAmount](#amount) | The minimum amount to be delivered. (This field cannot be used with destination.amount)
|
||||
paths | string | The paths of trustlines and orders to use in executing the payment.
|
||||
|
||||
### Example
|
||||
@@ -2388,7 +2389,7 @@ Returns open orders for the specified account. Open orders are orders that have
|
||||
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
address | [address](#address) | The Ripple address of the account to get open orders for.
|
||||
address | [address](#address) | The XRP Ledger address of the account to get open orders for.
|
||||
options | object | *Optional* Options that determine what orders will be returned.
|
||||
*options.* ledgerVersion | integer | *Optional* Return orders as of this historical ledger version.
|
||||
*options.* ledgerVersion | string | *Optional* Return orders as of this historical ledger version.
|
||||
@@ -3888,7 +3889,7 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
defaultRipple | boolean | *Optional* Enable [rippling](https://ripple.com/build/understanding-the-noripple-flag/) on this account’s trust lines by default. (New in [rippled 0.27.3](https://github.com/ripple/rippled/releases/tag/0.27.3))
|
||||
depositAuth | boolean | *Optional* Enable [Deposit Authorization](https://ripple.com/build/deposit-authorization/) on this account. If set, transactions cannot send value of any kind to this account unless the sender of those transactions is the account itself. (Requires the [DepositAuth amendment](https://ripple.com/build/known-amendments/#depositauth))
|
||||
disableMasterKey | boolean | *Optional* Disallows use of the master key to sign transactions for this account.
|
||||
disableMasterKey | boolean | *Optional* Disallows use of the master key to sign transactions for this account. To disable the master key, you must authorize the transaction by signing it with the master key pair. You cannot use a regular key pair or a multi-signature. You can re-enable the master key pair using a regular key pair or multi-signature. See [AccountSet](https://developers.ripple.com/accountset.html).
|
||||
disallowIncomingXRP | boolean | *Optional* Indicates that client applications should not send XRP to this account. Not enforced by rippled.
|
||||
domain | string | *Optional* The domain that owns this account, as a hexadecimal string representing the ASCII for the domain in lowercase.
|
||||
emailHash | string,null | *Optional* Hash of an email address to be used for generating an avatar image. Conventionally, clients use Gravatar to display this image. Use `null` to clear.
|
||||
@@ -3903,7 +3904,7 @@ requireAuthorization | boolean | *Optional* If set, this account must individual
|
||||
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 | 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 | Weights of signatures for each signer.
|
||||
*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](#address) | A Ripple account address
|
||||
*signers.weights[].* weight | integer | The weight that the signature of this account counts as towards the threshold.
|
||||
@@ -4475,7 +4476,7 @@ console.log(JSON.stringify(flags, null, 2))
|
||||
|
||||
## prepareTransaction
|
||||
|
||||
`prepareTransaction(address: string, transaction: object, instructions: object): Promise<object>`
|
||||
`prepareTransaction(transaction: object, instructions: object): Promise<object>`
|
||||
|
||||
Prepare a transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
@@ -4502,10 +4503,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -4557,10 +4558,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -4584,8 +4585,11 @@ const payment = {
|
||||
}
|
||||
}
|
||||
};
|
||||
return api.preparePayment(address, payment).then(prepared =>
|
||||
{/* ... */});
|
||||
return api.preparePayment(address, payment).then(prepared => {
|
||||
/* ... */
|
||||
}).catch(error => {
|
||||
/* ... as with all prepare* methods, use a Promise catch block to handle errors ... */
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
@@ -4627,10 +4631,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -4695,10 +4699,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -4763,10 +4767,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -4816,10 +4820,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -4886,10 +4890,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -4944,10 +4948,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -5000,10 +5004,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -5058,10 +5062,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -5116,10 +5120,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -5171,10 +5175,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -5227,10 +5231,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -5286,10 +5290,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -5341,10 +5345,10 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
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.* fee | [value](#value) | The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide.
|
||||
*instructions.* sequence | [sequence](#account-sequence-number) | The initiating account's sequence number for this transaction.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum.
|
||||
*instructions.* maxLedgerVersion | integer,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
*instructions.* maxLedgerVersion | string,null | The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -5392,12 +5396,14 @@ This method can sign any of [the transaction types supported by ripple-binary-co
|
||||
Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
txJSON | string | Transaction represented as a JSON string in rippled format.
|
||||
keypair | object | *Optional* The private and public key of the account that is initiating the transaction. (This field is exclusive with secret).
|
||||
keypair | object | *Optional* The private and public key of the account that is initiating the transaction. (This field cannot be used with secret).
|
||||
*keypair.* privateKey | privateKey | The uppercase hexadecimal representation of the secp256k1 or Ed25519 private key.
|
||||
*keypair.* publicKey | publicKey | The uppercase hexadecimal representation of the secp256k1 or Ed25519 public key.
|
||||
options | object | *Optional* Options that control the type of signature that will be generated.
|
||||
*options.* signAs | [address](#address) | *Optional* The account that the signature should count for in multisigning.
|
||||
secret | secret string | *Optional* The secret of the account that is initiating the transaction. (This field is exclusive with keypair).
|
||||
secret | secret string | *Optional* The secret of the account that is initiating the transaction. (This field cannot be used with keypair).
|
||||
|
||||
Please note that when this method is used for multisigning, the `options` parameter is not *Optional* anymore. It will be compulsory. See the multisigning example in this section for more details.
|
||||
|
||||
### Return Value
|
||||
|
||||
@@ -5425,6 +5431,93 @@ return api.sign(txJSON, secret); // or: api.sign(txJSON, keypair);
|
||||
}
|
||||
```
|
||||
|
||||
### Example (multisigning)
|
||||
|
||||
```javascript
|
||||
const RippleAPI = require('ripple-lib').RippleAPI;
|
||||
|
||||
// jon's address will have a multi-signing setup with a quorum of 2
|
||||
const jon = {
|
||||
account: 'rJKpme4m2zBQceBuU89d7vLMzgoUw2Ptj',
|
||||
secret: 'sh4Va7b1wQof8knHFV2sxwX12fSgK'
|
||||
};
|
||||
const aya = {
|
||||
account: 'rnrPdBjs98fFFfmRpL6hM7exT788SWQPFN',
|
||||
secret: 'snaMuMrXeVc2Vd4NYvHofeGNjgYoe'
|
||||
};
|
||||
const bran = {
|
||||
account: 'rJ93RLnT1t5A8fCr7HTScw7WtfKJMRXodH',
|
||||
secret: 'shQtQ8Um5MS218yvEU3Ehy1eZQKqH'
|
||||
};
|
||||
|
||||
// Setup the signers list with a quorum of 2
|
||||
const multiSignSetupTransaction = {
|
||||
"Flags": 0,
|
||||
"TransactionType": "SignerListSet",
|
||||
"Account": "rJKpme4m2zBQceBuU89d7vLMzgoUw2Ptj",
|
||||
"Fee": "120",
|
||||
"SignerQuorum": 2,
|
||||
"SignerEntries": [
|
||||
{
|
||||
"SignerEntry": {
|
||||
"Account": "rnrPdBjs98fFFfmRpL6hM7exT788SWQPFN",
|
||||
"SignerWeight": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"SignerEntry": {
|
||||
"Account": "rJ93RLnT1t5A8fCr7HTScw7WtfKJMRXodH",
|
||||
"SignerWeight": 1
|
||||
}
|
||||
},
|
||||
]
|
||||
};
|
||||
|
||||
// a transaction which requires multi signing
|
||||
const multiSignPaymentTransaction = {
|
||||
TransactionType: 'Payment',
|
||||
Account: 'rJKpme4m2zBQceBuU89d7vLMzgoUw2Ptj',
|
||||
Destination: 'rJ93RLnT1t5A8fCr7HTScw7WtfKJMRXodH',
|
||||
Amount: '88000000'
|
||||
};
|
||||
|
||||
const api = new RippleAPI({
|
||||
server: 'wss://s.altnet.rippletest.net:51233'
|
||||
});
|
||||
|
||||
api.connect().then(() => {
|
||||
// adding the multi signing feature to jon's account
|
||||
api.prepareTransaction(multiSignSetupTransaction).then((prepared) => {
|
||||
console.log(prepared);
|
||||
jonSign = api.sign(prepared.txJSON, jon.secret).signedTransaction;
|
||||
api.submit(jonSign).then( response => {
|
||||
console.log(response.resultCode, response.resultMessage);
|
||||
|
||||
// multi sign a transaction
|
||||
api.prepareTransaction(multiSignPaymentTransaction).then(prepared => {
|
||||
console.log(prepared);
|
||||
|
||||
// Aya and Bran sign it too but with 'signAs' set to their own account
|
||||
let ayaSign = api.sign(prepared.txJSON, aya.secret, {'signAs': aya.account}).signedTransaction;
|
||||
let branSign = api.sign(prepared.txJSON, bran.secret, {'signAs': bran.account}).signedTransaction;
|
||||
|
||||
// signatures are combined and submitted
|
||||
let combinedTx = api.combine([ayaSign, branSign]);
|
||||
api.submit(combinedTx.signedTransaction).then(response => {
|
||||
console.log(response.tx_json.hash);
|
||||
return api.disconnect();
|
||||
}).catch(console.error);
|
||||
}).catch(console.error);
|
||||
}).catch(console.error)
|
||||
}).catch(console.error);
|
||||
}).catch(console.error);
|
||||
```
|
||||
|
||||
Assuming the multisigning account was setup properly, the above example will respond with `resultCode: 'tesSUCCESS'` and the hash for the transaction.
|
||||
If any of `{signAs: some_address}` options were missing the code will return a validation error as follow:
|
||||
```
|
||||
[ValidationError(txJSON is not the same for all signedTransactions)]
|
||||
```
|
||||
|
||||
## combine
|
||||
|
||||
@@ -5484,11 +5577,11 @@ Name | Type | Description
|
||||
---- | ---- | -----------
|
||||
resultCode | string | Deprecated: Use `engine_result` instead.
|
||||
resultMessage | string | Deprecated: Use `engine_result_message` instead.
|
||||
engine_result | string | Code indicating the preliminary result of the transaction, for example tesSUCCESS. [List of transaction responses](https://ripple.com/build/transactions/#full-transaction-response-list)
|
||||
engine_result | string | Code indicating the preliminary result of the transaction, for example `tesSUCCESS`. [List of transaction responses](https://developers.ripple.com/transaction-results.html)
|
||||
engine_result_code | integer | Numeric code indicating the preliminary result of the transaction, directly correlated to `engine_result`
|
||||
engine_result_message | string | Human-readable explanation of the transaction's preliminary result.
|
||||
tx_blob | string | The complete transaction in hex string format.
|
||||
tx_json | [tx](https://ripple.com/build/transactions/) | The complete transaction in JSON format.
|
||||
tx_json | [tx-json](https://developers.ripple.com/transaction-formats.html) | The complete transaction in JSON format.
|
||||
|
||||
### Example
|
||||
|
||||
@@ -5857,6 +5950,34 @@ api.iso8601ToRippleTime('2017-02-17T15:04:57Z');
|
||||
540659097
|
||||
```
|
||||
|
||||
## rippleTimeToISO8601
|
||||
|
||||
`rippleTimeToISO8601(rippleTime: number): string`
|
||||
|
||||
This method takes the number of seconds since the "Ripple Epoch" of January 1, 2000 (00:00 UTC) and returns a string representation of a date.
|
||||
|
||||
The Ripple Epoch is 946684800 seconds after the Unix Epoch.
|
||||
|
||||
This method is useful for interpreting timestamps returned by the rippled APIs. The rippled APIs represent time as an unsigned integer of the number of seconds since the Ripple Epoch.
|
||||
|
||||
### Parameters
|
||||
|
||||
`rippleTime`: A number of seconds since the Ripple Epoch.
|
||||
|
||||
### Return Value
|
||||
|
||||
A string representing a date and time, created by calling a `Date` object's `toISOString()` method.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
api.rippleTimeToISO8601(540659097);
|
||||
```
|
||||
|
||||
```json
|
||||
'2017-02-17T15:04:57.000Z'
|
||||
```
|
||||
|
||||
## txFlags
|
||||
|
||||
`txFlags.TRANSACTION_TYPE.FLAG`
|
||||
|
||||
@@ -26,7 +26,7 @@ api.connect().then(() => {
|
||||
}).catch(console.error);
|
||||
```
|
||||
|
||||
RippleAPI is designed to work in [Node.js](https://nodejs.org) version **6.11.3**. RippleAPI may work on older Node.js versions if you use [Babel](https://babeljs.io/) for [ECMAScript 6](https://babeljs.io/docs/learn-es2015/) support.
|
||||
RippleAPI is designed to work in [Node.js](https://nodejs.org) version 6 or higher. Ripple recommends Node.js v10 LTS.
|
||||
|
||||
The code samples in this documentation are written with ECMAScript 6 (ES6) features, but `RippleAPI` also works with ECMAScript 5 (ES5). Regardless of whether you use ES5 or ES6, the methods that return Promises return [ES6-style promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
<% include computeLedgerHash.md.ejs %>
|
||||
<% include xrpToDropsAndDropsToXrp.md.ejs %>
|
||||
<% include iso8601ToRippleTime.md.ejs %>
|
||||
<% include rippleTimeToISO8601.md.ejs %>
|
||||
<% include txFlags.md.ejs %>
|
||||
<% include schemaValidator.md.ejs %>
|
||||
<% include events.md.ejs %>
|
||||
|
||||
@@ -23,8 +23,11 @@ All "prepare*" methods have the same return type.
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const payment = <%- importFile('test/fixtures/requests/prepare-payment.json') %>;
|
||||
return api.preparePayment(address, payment).then(prepared =>
|
||||
{/* ... */});
|
||||
return api.preparePayment(address, payment).then(prepared => {
|
||||
/* ... */
|
||||
}).catch(error => {
|
||||
/* ... as with all prepare* methods, use a Promise catch block to handle errors ... */
|
||||
})
|
||||
```
|
||||
|
||||
<%- renderFixture("responses/prepare-payment.json") %>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## prepareTransaction
|
||||
|
||||
`prepareTransaction(address: string, transaction: object, instructions: object): Promise<object>`
|
||||
`prepareTransaction(transaction: object, instructions: object): Promise<object>`
|
||||
|
||||
Prepare a transaction. The prepared transaction must subsequently be [signed](#sign) and [submitted](#submit).
|
||||
|
||||
|
||||
27
docs/src/rippleTimeToISO8601.md.ejs
Normal file
27
docs/src/rippleTimeToISO8601.md.ejs
Normal file
@@ -0,0 +1,27 @@
|
||||
## rippleTimeToISO8601
|
||||
|
||||
`rippleTimeToISO8601(rippleTime: number): string`
|
||||
|
||||
This method takes the number of seconds since the "Ripple Epoch" of January 1, 2000 (00:00 UTC) and returns a string representation of a date.
|
||||
|
||||
The Ripple Epoch is 946684800 seconds after the Unix Epoch.
|
||||
|
||||
This method is useful for interpreting timestamps returned by the rippled APIs. The rippled APIs represent time as an unsigned integer of the number of seconds since the Ripple Epoch.
|
||||
|
||||
### Parameters
|
||||
|
||||
`rippleTime`: A number of seconds since the Ripple Epoch.
|
||||
|
||||
### Return Value
|
||||
|
||||
A string representing a date and time, created by calling a `Date` object's `toISOString()` method.
|
||||
|
||||
### Example
|
||||
|
||||
```javascript
|
||||
api.rippleTimeToISO8601(540659097);
|
||||
```
|
||||
|
||||
```json
|
||||
'2017-02-17T15:04:57.000Z'
|
||||
```
|
||||
@@ -15,7 +15,7 @@ Type | Description
|
||||
[escrowCancellation](#escrow-cancellation) | An `escrowCancellation` transaction unlocks the funds in an escrow and sends them back to the creator of the escrow, but it will only work after the escrow expires.
|
||||
[escrowExecution](#escrow-execution) | An `escrowExecution` transaction unlocks the funds in an escrow and sends them to the destination of the escrow, but it will only work if the cryptographic condition is provided.
|
||||
[checkCreate](#check-create) | A `checkCreate` transaction creates a check on the ledger, which is a deferred payment that can be cashed by its intended destination.
|
||||
[checkCancel](#check-cancel) | A `checkCancel` transaction cancels an unreedemed Check, removing it from the ledger without sending any money.
|
||||
[checkCancel](#check-cancel) | A `checkCancel` transaction cancels an unredeemed Check, removing it from the ledger without sending any money.
|
||||
[checkCash](#check-cash) | A `checkCash` transaction redeems a Check to receive up to the amount authorized by the corresponding `checkCreate` transaction. Only the `destination` address of a Check can cash it.
|
||||
[paymentChannelCreate](#payment-channel-create) | A `paymentChannelCreate` transaction opens a payment channel between two addresses with XRP set aside for asynchronous payments.
|
||||
[paymentChannelFund](#payment-channel-fund) | A `paymentChannelFund` transaction adds XRP to a payment channel and optionally sets a new expiration for the channel.
|
||||
@@ -43,17 +43,19 @@ Executing a transaction with `RippleAPI` requires the following four steps:
|
||||
|
||||
## Transaction Fees
|
||||
|
||||
Every transaction must destroy a small amount of XRP as a cost to send the transaction. This is also called a *transaction fee*. The transaction cost is designed to increase along with the load on the XRP Ledger, making it very expensive to deliberately or inadvertently overload the peer-to-peer network that powers the XRP Ledger.
|
||||
Every transaction must destroy a small amount of XRP as a cost to apply the transaction to the ledger. This is also called a *transaction fee*. The transaction cost is designed to increase along with the load on the XRP Ledger, making it very expensive to deliberately or inadvertently overload the peer-to-peer network that powers the XRP Ledger.
|
||||
|
||||
You can choose the size of the fee you want to pay or let a default be used. You can get an estimate of the fee required to be included in the next ledger closing with the [getFee](#getfee) method.
|
||||
|
||||
For a multi-signed transaction, ripple-lib automatically multiplies the `fee` by (1 + Number of Signatures Provided). For example, if you set `instructions.fee = '0.000020'` and `instructions.signersCount = 2`, the prepared transaction's `Fee` will be 20 drops × (1 + 2 Signatures) = 60 drops. See [Transaction Cost](https://developers.ripple.com/transaction-cost.html).
|
||||
|
||||
## Transaction Instructions
|
||||
|
||||
Transaction instructions indicate how to execute a transaction, complementary with the [transaction specification](#transaction-specifications).
|
||||
|
||||
<%- renderSchema("objects/instructions.json") %>
|
||||
|
||||
We recommend that you specify a `maxLedgerVersion` so that you can quickly determine that a failed transaction will never succeeed in the future. It is impossible for a transaction to succeed after the XRP Ledger's consensus-validated ledger version exceeds the transaction's `maxLedgerVersion`. If you omit `maxLedgerVersion`, the "prepare\*" method automatically supplies a `maxLedgerVersion` equal to the current ledger plus 3, which it includes in the return value from the "prepare\*" method.
|
||||
We recommend that you specify a `maxLedgerVersion` so that you can quickly determine that a failed transaction will never succeed in the future. It is impossible for a transaction to succeed after the XRP Ledger's consensus-validated ledger version exceeds the transaction's `maxLedgerVersion`. If you omit `maxLedgerVersion`, the "prepare\*" method automatically supplies a `maxLedgerVersion` equal to the current ledger plus 3, which it includes in the return value from the "prepare\*" method.
|
||||
|
||||
## Transaction ID
|
||||
|
||||
|
||||
46
package.json
46
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "1.1.2",
|
||||
"version": "1.3.4",
|
||||
"license": "ISC",
|
||||
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
|
||||
"files": [
|
||||
@@ -10,68 +10,60 @@
|
||||
"main": "dist/npm/",
|
||||
"types": "dist/npm/index.d.ts",
|
||||
"browser": {
|
||||
"ws": "./dist/npm/common/wswrapper.js"
|
||||
"ws": "./dist/npm/common/wswrapper.js",
|
||||
"https-proxy-agent": false
|
||||
},
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/lodash": "^4.14.85",
|
||||
"@types/lodash": "^4.14.136",
|
||||
"@types/ws": "^3.2.0",
|
||||
"bignumber.js": "^4.1.0",
|
||||
"https-proxy-agent": "2.2.1",
|
||||
"jsonschema": "1.2.2",
|
||||
"lodash": "^4.17.4",
|
||||
"ripple-address-codec": "^2.0.1",
|
||||
"ripple-binary-codec": "0.2.0",
|
||||
"ripple-hashes": "^0.3.1",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"ripple-address-codec": "^3.0.4",
|
||||
"ripple-binary-codec": "^0.2.4",
|
||||
"ripple-keypairs": "^0.10.1",
|
||||
"ripple-lib-transactionparser": "0.7.1",
|
||||
"ripple-lib-transactionparser": "0.8.0",
|
||||
"ws": "^3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^8.0.53",
|
||||
"@types/node": "11.13.0",
|
||||
"assert-diff": "^1.0.1",
|
||||
"coveralls": "^2.13.1",
|
||||
"doctoc": "^0.15.0",
|
||||
"ejs": "^2.3.4",
|
||||
"eventemitter2": "^0.4.14",
|
||||
"gulp": "^3.8.10",
|
||||
"gulp-bump": "^0.1.13",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"http-server": "^0.8.5",
|
||||
"jayson": "^1.2.2",
|
||||
"gulp": "^4.0.2",
|
||||
"json-loader": "^0.5.2",
|
||||
"json-schema-to-markdown-table": "^0.4.0",
|
||||
"mocha": "^2.1.0",
|
||||
"mocha-in-sauce": "^0.0.1",
|
||||
"mocha": "6.2.0",
|
||||
"mocha-junit-reporter": "^1.9.1",
|
||||
"null-loader": "^0.1.1",
|
||||
"nyc": "^11.3.0",
|
||||
"source-map-support": "^0.5.0",
|
||||
"nyc": "^14.1.1",
|
||||
"source-map-support": "0.5.12",
|
||||
"ts-loader": "^3.2.0",
|
||||
"ts-node": "^3.3.0",
|
||||
"ts-node": "8.0.3",
|
||||
"tslint": "^5.8.0",
|
||||
"tslint-eslint-rules": "^4.1.1",
|
||||
"typescript": "2.9.2",
|
||||
"typescript": "^3.6.4",
|
||||
"uglifyjs-webpack-plugin": "^1.1.4",
|
||||
"webpack": "3.12.0",
|
||||
"yargs": "^8.0.2"
|
||||
"webpack": "3.12.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp",
|
||||
"doctoc": "doctoc docs/index.md --title '# RippleAPI Reference' --github --maxlevel 2",
|
||||
"docgen": "node --harmony scripts/build_docs.js",
|
||||
"clean": "rm -rf dist/npm",
|
||||
"compile": "mkdir -p dist/npm/common && cp -r src/common/schemas dist/npm/common/ && tsc",
|
||||
"compile": "mkdir -p dist/npm/common && cp -r src/common/schemas dist/npm/common/ && tsc --build",
|
||||
"watch": "tsc -w",
|
||||
"prepublish": "npm run clean && npm run compile && npm run build",
|
||||
"test": "nyc mocha",
|
||||
"coveralls": "cat ./coverage/lcov.info | coveralls",
|
||||
"test": "TS_NODE_PROJECT=src/tsconfig.json nyc mocha --exit",
|
||||
"lint": "tslint -p ./",
|
||||
"perf": "./scripts/perf_test.sh",
|
||||
"start": "node scripts/http.js",
|
||||
"sauce": "node scripts/sauce-runner.js"
|
||||
"start": "node scripts/http.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -16,7 +16,7 @@ unittest() {
|
||||
# test "src"
|
||||
mocha test --reporter mocha-junit-reporter --reporter-options mochaFile=$CIRCLE_TEST_REPORTS/test-results.xml
|
||||
yarn test --coverage
|
||||
yarn run coveralls
|
||||
#yarn run coveralls
|
||||
|
||||
# test compiled version in "dist/npm"
|
||||
$(npm bin)/babel -D --optional runtime --ignore "**/node_modules/**" -d test-compiled/ test/
|
||||
@@ -45,7 +45,6 @@ unittest() {
|
||||
|
||||
integrationtest() {
|
||||
mocha test/integration/integration-test.js
|
||||
mocha test/integration/http-integration-test.js
|
||||
|
||||
# run integration tests in PhantomJS
|
||||
#gulp build-tests build-min
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const createHTTPServer = require('../dist/npm/http').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();
|
||||
@@ -1,100 +0,0 @@
|
||||
|
||||
const _ = require('lodash');
|
||||
const MochaSauce = require('mocha-in-sauce');
|
||||
|
||||
const testUrl = 'http://testripple.circleci.com:8080/test/saucerunner.html';
|
||||
|
||||
|
||||
function main() {
|
||||
// uncomment for more debug info
|
||||
// process.env.DEBUG = '*';
|
||||
|
||||
// configure
|
||||
const config = {
|
||||
name: 'RippleAPI',
|
||||
host: 'localhost',
|
||||
port: 4445,
|
||||
maxDuration: 180000,
|
||||
// the current build name (optional)
|
||||
build: Date.now(),
|
||||
url: testUrl,
|
||||
runSauceConnect: true
|
||||
};
|
||||
|
||||
if (process.env.CIRCLE_BUILD_NUM) {
|
||||
config.build = process.env.CIRCLE_BUILD_NUM;
|
||||
config.tags = [process.env.CIRCLE_BRANCH, process.env.CIRCLE_SHA1];
|
||||
config.tunnelIdentifier = process.env.CIRCLE_BUILD_NUM;
|
||||
}
|
||||
|
||||
const sauce = new MochaSauce(config);
|
||||
|
||||
sauce.concurrency(5);
|
||||
|
||||
// setup what browsers to test with
|
||||
sauce.browser({browserName: 'firefox', platform: 'Linux',
|
||||
version: '43'});
|
||||
sauce.browser({browserName: 'firefox', platform: 'Windows 8.1',
|
||||
version: '43'});
|
||||
sauce.browser({browserName: 'firefox', platform: 'OS X 10.11',
|
||||
version: '43'});
|
||||
sauce.browser({browserName: 'safari', platform: 'OS X 10.11',
|
||||
version: '9'});
|
||||
sauce.browser({browserName: 'safari', platform: 'OS X 10.10',
|
||||
version: '8'});
|
||||
sauce.browser({browserName: 'safari', platform: 'OS X 10.9',
|
||||
version: '7'});
|
||||
sauce.browser({browserName: 'chrome', platform: 'OS X 10.11',
|
||||
version: '47'});
|
||||
sauce.browser({browserName: 'chrome', platform: 'Linux',
|
||||
version: '47'});
|
||||
sauce.browser({browserName: 'chrome', platform: 'Windows 8.1',
|
||||
version: '47'});
|
||||
sauce.browser({browserName: 'internet explorer', platform: 'Windows 10',
|
||||
version: '11'});
|
||||
sauce.browser({browserName: 'MicrosoftEdge', platform: 'Windows 10',
|
||||
version: '20'});
|
||||
|
||||
sauce.on('init', function(browser) {
|
||||
console.log(' init : %s %s', browser.browserName, browser.platform);
|
||||
});
|
||||
|
||||
sauce.on('start', function(browser) {
|
||||
console.log(' start : %s %s', browser.browserName, browser.platform);
|
||||
});
|
||||
|
||||
sauce.on('end', function(browser, res) {
|
||||
console.log(' end : %s %s : %d failures', browser.browserName,
|
||||
browser.platform, res && res.failures);
|
||||
});
|
||||
|
||||
sauce.on('connected', sauceConnectProcess => {
|
||||
sauceConnectProcess.on('exit', function(code, /* signal */) {
|
||||
if (code > 0) {
|
||||
console.log('something wrong - exiting');
|
||||
process.exit();
|
||||
} else {
|
||||
console.log('normal tunnel exit');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
sauce.start(function(err, res) {
|
||||
let failure = false;
|
||||
if (err) {
|
||||
console.log('Error starting Sauce');
|
||||
console.error(err);
|
||||
process.exitCode = 2;
|
||||
} else {
|
||||
console.log('-------------- done --------------');
|
||||
failure = _.some(res, 'failures');
|
||||
console.log('Tests are failed:', failure);
|
||||
if (failure) {
|
||||
process.exitCode = 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
main();
|
||||
17
snippets/src/getTransaction.ts
Normal file
17
snippets/src/getTransaction.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import {RippleAPI} from '../../dist/npm'
|
||||
|
||||
const api = new RippleAPI({
|
||||
server: 'wss://s.altnet.rippletest.net:51233'
|
||||
})
|
||||
|
||||
getTransaction()
|
||||
|
||||
async function getTransaction() {
|
||||
await api.connect()
|
||||
const ledger = await api.getLedger({includeTransactions: true})
|
||||
console.log(ledger)
|
||||
const tx = await api.getTransaction(ledger.transactionHashes[0])
|
||||
console.log(tx)
|
||||
console.log('deliveredAmount:', tx.outcome.deliveredAmount)
|
||||
process.exit(0)
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
const RippleAPI = require('../dist/npm').RippleAPI
|
||||
import {RippleAPI} from '../../dist/npm'
|
||||
|
||||
const api = new RippleAPI({server: 'wss://s.altnet.rippletest.net:51233'})
|
||||
|
||||
parseAccountFlags()
|
||||
@@ -8,4 +9,5 @@ async function parseAccountFlags() {
|
||||
const account_info = await api.request('account_info', {account: 'rKsdkGhyZH6b2Zzd5hNnEqSv2wpznn4n6N'})
|
||||
const flags = api.parseAccountFlags(account_info.account_data.Flags)
|
||||
console.log(JSON.stringify(flags, null, 2))
|
||||
process.exit(0)
|
||||
}
|
||||
13
snippets/tsconfig.json
Normal file
13
snippets/tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"references": [
|
||||
{ "path": "../src" }
|
||||
],
|
||||
"include": [
|
||||
"./src/**/*.ts"
|
||||
]
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
validate,
|
||||
xrpToDrops,
|
||||
dropsToXrp,
|
||||
rippleTimeToISO8601,
|
||||
iso8601ToRippleTime,
|
||||
txFlags
|
||||
} from './common'
|
||||
@@ -71,9 +72,10 @@ import * as transactionUtils from './transaction/utils'
|
||||
import * as schemaValidator from './common/schema-validator'
|
||||
import {getServerInfo, getFee} from './common/serverinfo'
|
||||
import {clamp, renameCounterpartyToIssuer} from './ledger/utils'
|
||||
import {Instructions, Prepare} from './transaction/types'
|
||||
import {TransactionJSON, Instructions, Prepare} from './transaction/types'
|
||||
import {ConnectionOptions} from './common/connection'
|
||||
|
||||
export type APIOptions = {
|
||||
export interface APIOptions extends ConnectionOptions {
|
||||
server?: string,
|
||||
feeCushion?: number,
|
||||
maxFeeXRP?: string,
|
||||
@@ -210,7 +212,7 @@ class RippleAPI extends EventEmitter {
|
||||
*
|
||||
* You can later submit the transaction with `submit()`.
|
||||
*/
|
||||
async prepareTransaction(txJSON: object, instructions: Instructions = {}):
|
||||
async prepareTransaction(txJSON: TransactionJSON, instructions: Instructions = {}):
|
||||
Promise<Prepare> {
|
||||
return transactionUtils.prepareTransaction(txJSON, this, instructions)
|
||||
}
|
||||
@@ -336,6 +338,7 @@ class RippleAPI extends EventEmitter {
|
||||
|
||||
xrpToDrops = xrpToDrops
|
||||
dropsToXrp = dropsToXrp
|
||||
rippleTimeToISO8601 = rippleTimeToISO8601
|
||||
iso8601ToRippleTime = iso8601ToRippleTime
|
||||
txFlags = txFlags
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as _ from 'lodash'
|
||||
import {EventEmitter} from 'events'
|
||||
import {parse as parseUrl} from 'url'
|
||||
import * as WebSocket from 'ws'
|
||||
import WebSocket from 'ws'
|
||||
import RangeSet from './rangeset'
|
||||
import {RippledError, DisconnectedError, NotConnectedError,
|
||||
TimeoutError, ResponseFormatError, ConnectionError,
|
||||
@@ -202,16 +202,10 @@ class Connection extends EventEmitter {
|
||||
|
||||
this._updateLedgerVersions(data)
|
||||
this._updateFees(data)
|
||||
this._rebindOnUnxpectedClose()
|
||||
this._rebindOnUnexpectedClose()
|
||||
|
||||
this._retry = 0
|
||||
this._ws.on('error', error => {
|
||||
// TODO: "type" does not exist on official error type, safe to remove?
|
||||
if (process.browser && error && (<any>error).type === 'error') {
|
||||
// we are in browser, ignore error - `close` event will be fired
|
||||
// after error
|
||||
return
|
||||
}
|
||||
this.emit('error', 'websocket', error.message, error)
|
||||
})
|
||||
|
||||
@@ -222,7 +216,7 @@ class Connection extends EventEmitter {
|
||||
})
|
||||
}
|
||||
|
||||
_rebindOnUnxpectedClose() {
|
||||
_rebindOnUnexpectedClose() {
|
||||
if (this._onUnexpectedCloseBound) {
|
||||
this._ws.removeListener('close', this._onUnexpectedCloseBound)
|
||||
}
|
||||
@@ -231,7 +225,7 @@ class Connection extends EventEmitter {
|
||||
this._ws.once('close', this._onUnexpectedCloseBound)
|
||||
}
|
||||
|
||||
_unbindOnUnxpectedClose() {
|
||||
_unbindOnUnexpectedClose() {
|
||||
if (this._onUnexpectedCloseBound) {
|
||||
this._ws.removeListener('close', this._onUnexpectedCloseBound)
|
||||
}
|
||||
@@ -240,7 +234,7 @@ class Connection extends EventEmitter {
|
||||
|
||||
_onOpenError(reject, error) {
|
||||
this._onOpenErrorBound = null
|
||||
this._unbindOnUnxpectedClose()
|
||||
this._unbindOnUnexpectedClose()
|
||||
reject(new NotConnectedError(error.message, error))
|
||||
}
|
||||
|
||||
@@ -268,7 +262,7 @@ class Connection extends EventEmitter {
|
||||
options.agent = new HttpsProxyAgent(proxyOptions)
|
||||
}
|
||||
if (this._authorization !== undefined) {
|
||||
const base64 = new Buffer(this._authorization).toString('base64')
|
||||
const base64 = Buffer.from(this._authorization).toString('base64')
|
||||
options.headers = {Authorization: `Basic ${base64}`}
|
||||
}
|
||||
const optionsOverrides = _.omitBy({
|
||||
@@ -287,7 +281,7 @@ class Connection extends EventEmitter {
|
||||
return websocket
|
||||
}
|
||||
|
||||
connect() {
|
||||
connect(): Promise<void> {
|
||||
this._clearReconnectTimer()
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._url) {
|
||||
@@ -322,11 +316,11 @@ class Connection extends EventEmitter {
|
||||
})
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
disconnect(): Promise<void> {
|
||||
return this._disconnect(true)
|
||||
}
|
||||
|
||||
_disconnect(calledByUser) {
|
||||
_disconnect(calledByUser): Promise<void> {
|
||||
if (calledByUser) {
|
||||
this._clearReconnectTimer()
|
||||
this._retry = 0
|
||||
@@ -445,7 +439,7 @@ class Connection extends EventEmitter {
|
||||
|
||||
this.once(eventName, response => {
|
||||
if (response.status === 'error') {
|
||||
_reject(new RippledError(response.error, response))
|
||||
_reject(new RippledError(response.error_message || response.error, response))
|
||||
} else if (response.status === 'success') {
|
||||
_resolve(response.result)
|
||||
} else {
|
||||
|
||||
49
src/common/hashes/README.md
Normal file
49
src/common/hashes/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# XRP Ledger Hashes
|
||||
|
||||
Methods to hash XRP Ledger objects
|
||||
|
||||
## Methods
|
||||
|
||||
### computeBinaryTransactionHash = (txBlobHex: string): string
|
||||
|
||||
Compute the hash of a binary transaction blob.
|
||||
|
||||
### computeTransactionHash = (txJSON: any): string
|
||||
|
||||
Compute the hash of a transaction in txJSON format.
|
||||
|
||||
### computeBinaryTransactionSigningHash = (txBlobHex: string): string
|
||||
|
||||
### computeTransactionSigningHash = (txJSON: any): string
|
||||
|
||||
### computeAccountHash = (address: string): string
|
||||
|
||||
Compute the hash of an account, given the account's classic address (starting with `r`).
|
||||
|
||||
### computeSignerListHash = (address: string): string
|
||||
|
||||
Compute the hash of an account's SignerList.
|
||||
|
||||
### computeOrderHash = (address: string, sequence: number): string
|
||||
|
||||
Compute the hash of an order, given the owner's classic address (starting with `r`) and the account sequence number of the `OfferCreate` order transaction.
|
||||
|
||||
### computeTrustlineHash = (address1: string, address2: string, currency: string): string
|
||||
|
||||
Compute the hash of a trustline, given the two parties' classic addresses (starting with `r`) and the currency code.
|
||||
|
||||
### computeTransactionTreeHash = (transactions: any[]): string
|
||||
|
||||
### computeStateTreeHash = (entries: any[]): string
|
||||
|
||||
### computeLedgerHash = (ledgerHeader): string
|
||||
|
||||
Compute the hash of a ledger.
|
||||
|
||||
### computeEscrowHash = (address, sequence): string
|
||||
|
||||
Compute the hash of an escrow, given the owner's classic address (starting with `r`) and the account sequence number of the `EscrowCreate` escrow transaction.
|
||||
|
||||
### computePaymentChannelHash = (address, dstAddress, sequence): string
|
||||
|
||||
Compute the hash of a payment channel, given the owner's classic address (starting with `r`), the classic address of the destination, and the account sequence number of the `PaymentChannelCreate` payment channel transaction.
|
||||
40
src/common/hashes/hash-prefix.ts
Normal file
40
src/common/hashes/hash-prefix.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Prefix for hashing functions.
|
||||
*
|
||||
* These prefixes are inserted before the source material used to
|
||||
* generate various hashes. This is done to put each hash in its own
|
||||
* "space." This way, two different types of objects with the
|
||||
* same binary data will produce different hashes.
|
||||
*
|
||||
* Each prefix is a 4-byte value with the last byte set to zero
|
||||
* and the first three bytes formed from the ASCII equivalent of
|
||||
* some arbitrary string. For example "TXN".
|
||||
*/
|
||||
|
||||
enum HashPrefix {
|
||||
// transaction plus signature to give transaction ID
|
||||
TRANSACTION_ID = 0x54584E00, // 'TXN'
|
||||
|
||||
// transaction plus metadata
|
||||
TRANSACTION_NODE = 0x534E4400, // 'TND'
|
||||
|
||||
// inner node in tree
|
||||
INNER_NODE = 0x4D494E00, // 'MIN'
|
||||
|
||||
// leaf node in tree
|
||||
LEAF_NODE = 0x4D4C4E00, // 'MLN'
|
||||
|
||||
// inner transaction to sign
|
||||
TRANSACTION_SIGN = 0x53545800, // 'STX'
|
||||
|
||||
// inner transaction to sign (TESTNET)
|
||||
TRANSACTION_SIGN_TESTNET = 0x73747800, // 'stx'
|
||||
|
||||
// inner transaction to multisign
|
||||
TRANSACTION_MULTISIGN = 0x534D5400, // 'SMT'
|
||||
|
||||
// ledger
|
||||
LEDGER = 0x4C575200 // 'LWR'
|
||||
}
|
||||
|
||||
export default HashPrefix
|
||||
155
src/common/hashes/index.ts
Normal file
155
src/common/hashes/index.ts
Normal file
@@ -0,0 +1,155 @@
|
||||
import BigNumber from 'bignumber.js'
|
||||
import {decodeAddress} from 'ripple-address-codec'
|
||||
import sha512Half from './sha512Half'
|
||||
import HashPrefix from './hash-prefix'
|
||||
import {SHAMap, NodeType} from './shamap'
|
||||
import {encode} from 'ripple-binary-codec'
|
||||
import ledgerspaces from './ledgerspaces'
|
||||
|
||||
const padLeftZero = (string: string, length: number): string => {
|
||||
return Array(length - string.length + 1).join('0') + string
|
||||
}
|
||||
|
||||
const intToHex = (integer: number, byteLength: number): string => {
|
||||
return padLeftZero(Number(integer).toString(16), byteLength * 2)
|
||||
}
|
||||
|
||||
const bytesToHex = (bytes: number[]): string => {
|
||||
return Buffer.from(bytes).toString('hex')
|
||||
}
|
||||
|
||||
const bigintToHex = (integerString: string | number | BigNumber, byteLength: number): string => {
|
||||
const hex = (new BigNumber(integerString)).toString(16)
|
||||
return padLeftZero(hex, byteLength * 2)
|
||||
}
|
||||
|
||||
const ledgerSpaceHex = (name: string): string => {
|
||||
return intToHex(ledgerspaces[name].charCodeAt(0), 2)
|
||||
}
|
||||
|
||||
const addressToHex = (address: string): string => {
|
||||
return (Buffer.from(decodeAddress(address))).toString('hex')
|
||||
}
|
||||
|
||||
const currencyToHex = (currency: string): string => {
|
||||
if (currency.length === 3) {
|
||||
let bytes = new Array(20 + 1).join('0').split('').map(parseFloat)
|
||||
bytes[12] = currency.charCodeAt(0) & 0xff
|
||||
bytes[13] = currency.charCodeAt(1) & 0xff
|
||||
bytes[14] = currency.charCodeAt(2) & 0xff
|
||||
return bytesToHex(bytes)
|
||||
}
|
||||
return currency
|
||||
}
|
||||
|
||||
const addLengthPrefix = (hex: string): string => {
|
||||
const length = hex.length / 2
|
||||
if (length <= 192) {
|
||||
return bytesToHex([length]) + hex
|
||||
} else if (length <= 12480) {
|
||||
const x = length - 193
|
||||
return bytesToHex([193 + (x >>> 8), x & 0xff]) + hex
|
||||
} else if (length <= 918744) {
|
||||
const x = length - 12481
|
||||
return bytesToHex([241 + (x >>> 16), x >>> 8 & 0xff, x & 0xff]) + hex
|
||||
}
|
||||
throw new Error('Variable integer overflow.')
|
||||
}
|
||||
|
||||
export const computeBinaryTransactionHash = (txBlobHex: string): string => {
|
||||
const prefix = HashPrefix.TRANSACTION_ID.toString(16).toUpperCase()
|
||||
return sha512Half(prefix + txBlobHex)
|
||||
}
|
||||
|
||||
export const computeTransactionHash = (txJSON: any): string => {
|
||||
return computeBinaryTransactionHash(encode(txJSON))
|
||||
}
|
||||
|
||||
export const computeBinaryTransactionSigningHash = (txBlobHex: string): string => {
|
||||
const prefix = HashPrefix.TRANSACTION_SIGN.toString(16).toUpperCase()
|
||||
return sha512Half(prefix + txBlobHex)
|
||||
}
|
||||
|
||||
export const computeTransactionSigningHash = (txJSON: any): string => {
|
||||
return computeBinaryTransactionSigningHash(encode(txJSON))
|
||||
}
|
||||
|
||||
export const computeAccountHash = (address: string): string => {
|
||||
return sha512Half(ledgerSpaceHex('account') + addressToHex(address))
|
||||
}
|
||||
|
||||
export const computeSignerListHash = (address: string): string => {
|
||||
return sha512Half(ledgerSpaceHex('signerList') +
|
||||
addressToHex(address) +
|
||||
'00000000' /* uint32(0) signer list index */)
|
||||
}
|
||||
|
||||
export const computeOrderHash = (address: string, sequence: number): string => {
|
||||
const prefix = '00' + intToHex(ledgerspaces.offer.charCodeAt(0), 1)
|
||||
return sha512Half(prefix + addressToHex(address) + intToHex(sequence, 4))
|
||||
}
|
||||
|
||||
export const computeTrustlineHash = (address1: string, address2: string, currency: string): string => {
|
||||
const address1Hex = addressToHex(address1)
|
||||
const address2Hex = addressToHex(address2)
|
||||
|
||||
const swap = (new BigNumber(address1Hex, 16)).greaterThan(
|
||||
new BigNumber(address2Hex, 16))
|
||||
const lowAddressHex = swap ? address2Hex : address1Hex
|
||||
const highAddressHex = swap ? address1Hex : address2Hex
|
||||
|
||||
const prefix = ledgerSpaceHex('rippleState')
|
||||
return sha512Half(prefix + lowAddressHex + highAddressHex +
|
||||
currencyToHex(currency))
|
||||
}
|
||||
|
||||
export const computeTransactionTreeHash = (transactions: any[]): string => {
|
||||
const shamap = new SHAMap()
|
||||
|
||||
transactions.forEach((txJSON) => {
|
||||
const txBlobHex = encode(txJSON)
|
||||
const metaHex = encode(txJSON.metaData)
|
||||
const txHash = computeBinaryTransactionHash(txBlobHex)
|
||||
const data = addLengthPrefix(txBlobHex) + addLengthPrefix(metaHex)
|
||||
shamap.addItem(txHash, data, NodeType.TRANSACTION_METADATA)
|
||||
})
|
||||
|
||||
return shamap.hash
|
||||
}
|
||||
|
||||
export const computeStateTreeHash = (entries: any[]): string => {
|
||||
const shamap = new SHAMap()
|
||||
|
||||
entries.forEach((ledgerEntry) => {
|
||||
const data = encode(ledgerEntry)
|
||||
shamap.addItem(ledgerEntry.index, data, NodeType.ACCOUNT_STATE)
|
||||
})
|
||||
|
||||
return shamap.hash
|
||||
}
|
||||
|
||||
// see rippled Ledger::updateHash()
|
||||
export const computeLedgerHash = (ledgerHeader): string => {
|
||||
const prefix = HashPrefix.LEDGER.toString(16).toUpperCase()
|
||||
return sha512Half(prefix +
|
||||
intToHex(ledgerHeader.ledger_index, 4) +
|
||||
bigintToHex(ledgerHeader.total_coins, 8) +
|
||||
ledgerHeader.parent_hash +
|
||||
ledgerHeader.transaction_hash +
|
||||
ledgerHeader.account_hash +
|
||||
intToHex(ledgerHeader.parent_close_time, 4) +
|
||||
intToHex(ledgerHeader.close_time, 4) +
|
||||
intToHex(ledgerHeader.close_time_resolution, 1) +
|
||||
intToHex(ledgerHeader.close_flags, 1)
|
||||
)
|
||||
}
|
||||
|
||||
export const computeEscrowHash = (address, sequence): string => {
|
||||
return sha512Half(ledgerSpaceHex('escrow') + addressToHex(address) +
|
||||
intToHex(sequence, 4))
|
||||
}
|
||||
|
||||
export const computePaymentChannelHash = (address, dstAddress, sequence): string => {
|
||||
return sha512Half(ledgerSpaceHex('paychan') + addressToHex(address) +
|
||||
addressToHex(dstAddress) + intToHex(sequence, 4))
|
||||
}
|
||||
25
src/common/hashes/ledgerspaces.ts
Normal file
25
src/common/hashes/ledgerspaces.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
/**
|
||||
* Ripple ledger namespace prefixes.
|
||||
*
|
||||
* The Ripple ledger is a key-value store. In order to avoid name collisions,
|
||||
* names are partitioned into namespaces.
|
||||
*
|
||||
* Each namespace is just a single character prefix.
|
||||
*/
|
||||
export default {
|
||||
account : 'a',
|
||||
dirNode : 'd',
|
||||
generatorMap : 'g',
|
||||
rippleState : 'r',
|
||||
offer : 'o', // Entry for an offer.
|
||||
ownerDir : 'O', // Directory of things owned by an account.
|
||||
bookDir : 'B', // Directory of order books.
|
||||
contract : 'c',
|
||||
skipList : 's',
|
||||
amendment : 'f',
|
||||
feeSettings : 'e',
|
||||
signerList : 'S',
|
||||
escrow : 'u',
|
||||
paychan : 'x'
|
||||
}
|
||||
7
src/common/hashes/sha512Half.ts
Normal file
7
src/common/hashes/sha512Half.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import {createHash} from 'crypto'
|
||||
|
||||
const sha512Half = (hex: string): string => {
|
||||
return createHash('sha512').update(Buffer.from(hex, 'hex')).digest('hex').toUpperCase().slice(0, 64)
|
||||
}
|
||||
|
||||
export default sha512Half
|
||||
173
src/common/hashes/shamap.ts
Normal file
173
src/common/hashes/shamap.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
import hashPrefix from './hash-prefix'
|
||||
import sha512Half from './sha512Half'
|
||||
const HEX_ZERO = '0000000000000000000000000000000000000000000000000000000000000000'
|
||||
|
||||
export enum NodeType {
|
||||
INNER = 1,
|
||||
TRANSACTION_NO_METADATA = 2,
|
||||
TRANSACTION_METADATA = 3,
|
||||
ACCOUNT_STATE = 4
|
||||
}
|
||||
|
||||
export abstract class Node {
|
||||
/**
|
||||
* Abstract constructor representing a node in a SHAMap tree.
|
||||
* Can be either InnerNode or Leaf.
|
||||
* @constructor
|
||||
*/
|
||||
public constructor() {}
|
||||
|
||||
public addItem(_tag: string, _node: Node): void {
|
||||
throw new Error('Called unimplemented virtual method SHAMapTreeNode#addItem.')
|
||||
}
|
||||
public get hash(): string|void {
|
||||
throw new Error('Called unimplemented virtual method SHAMapTreeNode#hash.');
|
||||
}
|
||||
}
|
||||
|
||||
export class InnerNode extends Node {
|
||||
public leaves: { [slot: number]: Node }
|
||||
public type: NodeType
|
||||
public depth: number
|
||||
public empty: boolean
|
||||
|
||||
/**
|
||||
* Define an Inner (non-leaf) node in a SHAMap tree.
|
||||
* @param {number} depth i.e. how many parent inner nodes
|
||||
* @constructor
|
||||
*/
|
||||
public constructor(depth: number = 0) {
|
||||
super()
|
||||
this.leaves = {}
|
||||
this.type = NodeType.INNER
|
||||
this.depth = depth
|
||||
this.empty = true
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} tag equates to a ledger entry `index`
|
||||
* @param {Node} node to add
|
||||
* @return {void}
|
||||
*/
|
||||
public addItem(tag: string, node: Node): void {
|
||||
const existingNode = this.getNode(parseInt(tag[this.depth],16))
|
||||
if (existingNode) {
|
||||
// A node already exists in this slot
|
||||
if (existingNode instanceof InnerNode) {
|
||||
// There is an inner node, so we need to go deeper
|
||||
existingNode.addItem(tag, node)
|
||||
} else if (existingNode instanceof Leaf) {
|
||||
if (existingNode.tag === tag) {
|
||||
// Collision
|
||||
throw new Error(
|
||||
'Tried to add a node to a SHAMap that was already in there.')
|
||||
} else {
|
||||
// Turn it into an inner node
|
||||
const newInnerNode = new InnerNode(this.depth + 1)
|
||||
|
||||
// Parent new and existing node
|
||||
newInnerNode.addItem(existingNode.tag, existingNode)
|
||||
newInnerNode.addItem(tag, node)
|
||||
|
||||
// And place the newly created inner node in the slot
|
||||
this.setNode(parseInt(tag[this.depth], 16), newInnerNode)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Neat, we have a nice open spot for the new node
|
||||
this.setNode(parseInt(tag[this.depth], 16), node)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite the node that is currently in a given slot.
|
||||
* @param {number} slot a number 0-15
|
||||
* @param {Node} node to place
|
||||
* @return {void}
|
||||
*/
|
||||
public setNode(slot: number, node: Node): void {
|
||||
if (slot < 0 || slot > 15) {
|
||||
throw new Error ('Invalid slot: slot must be between 0-15.')
|
||||
}
|
||||
this.leaves[slot] = node
|
||||
this.empty = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the node that is currently in a given slot.
|
||||
* @param {number} slot a number 0-15
|
||||
* @return {Node}
|
||||
*/
|
||||
public getNode(slot: number): Node {
|
||||
if (slot < 0 || slot > 15) {
|
||||
throw new Error ('Invalid slot: slot must be between 0-15.')
|
||||
}
|
||||
return this.leaves[slot]
|
||||
}
|
||||
|
||||
public get hash(): string {
|
||||
if (this.empty) return HEX_ZERO
|
||||
let hex = ''
|
||||
for (let i = 0; i < 16; i++) {
|
||||
hex += this.leaves[i] ? this.leaves[i].hash : HEX_ZERO
|
||||
}
|
||||
const prefix = hashPrefix.INNER_NODE.toString(16)
|
||||
return sha512Half(prefix + hex)
|
||||
}
|
||||
}
|
||||
|
||||
export class Leaf extends Node {
|
||||
public tag: string
|
||||
public type: NodeType
|
||||
public data: string
|
||||
|
||||
/**
|
||||
* Leaf node in a SHAMap tree.
|
||||
* @param {string} tag equates to a ledger entry `index`
|
||||
* @param {string} data hex of account state, transaction etc
|
||||
* @param {number} type one of TYPE_ACCOUNT_STATE, TYPE_TRANSACTION_MD etc
|
||||
* @constructor
|
||||
*/
|
||||
public constructor(tag: string, data: string, type: NodeType) {
|
||||
super()
|
||||
this.tag = tag
|
||||
this.type = type
|
||||
this.data = data
|
||||
}
|
||||
|
||||
public get hash(): string|void {
|
||||
switch (this.type) {
|
||||
case NodeType.ACCOUNT_STATE:
|
||||
const leafPrefix = hashPrefix.LEAF_NODE.toString(16)
|
||||
return sha512Half(leafPrefix + this.data + this.tag)
|
||||
case NodeType.TRANSACTION_NO_METADATA:
|
||||
const txIDPrefix = hashPrefix.TRANSACTION_ID.toString(16)
|
||||
return sha512Half(txIDPrefix + this.data)
|
||||
case NodeType.TRANSACTION_METADATA:
|
||||
const txNodePrefix = hashPrefix.TRANSACTION_NODE.toString(16)
|
||||
return sha512Half(txNodePrefix + this.data + this.tag)
|
||||
default:
|
||||
throw new Error('Tried to hash a SHAMap node of unknown type.')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SHAMap {
|
||||
public root: InnerNode
|
||||
|
||||
/**
|
||||
* SHAMap tree.
|
||||
* @constructor
|
||||
*/
|
||||
public constructor() {
|
||||
this.root = new InnerNode(0)
|
||||
}
|
||||
|
||||
public addItem(tag: string, data: string, type: NodeType): void {
|
||||
this.root.addItem(tag, new Leaf(tag, data, type))
|
||||
}
|
||||
|
||||
public get hash(): string {
|
||||
return this.root.hash
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ class RangeSet {
|
||||
}
|
||||
|
||||
addRange(start: number, end: number) {
|
||||
assert(start <= end, 'invalid range')
|
||||
assert.ok(start <= end, `invalid range ${start} <= ${end}`)
|
||||
this.ranges = mergeIntervals(this.ranges.concat([[start, end]]))
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ function loadSchemas() {
|
||||
]
|
||||
const titles = schemas.map(schema => schema.title)
|
||||
const duplicates = _.keys(_.pickBy(_.countBy(titles), count => count > 1))
|
||||
assert(duplicates.length === 0, 'Duplicate schemas for: ' + duplicates)
|
||||
assert.ok(duplicates.length === 0, 'Duplicate schemas for: ' + duplicates)
|
||||
const validator = new Validator()
|
||||
// Register custom format validators that ignore undefined instances
|
||||
// since jsonschema will still call the format validator on a missing
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The Ripple address of the account to get the balance sheet of."
|
||||
"description": "The XRP Ledger address of the account to get the balance sheet of."
|
||||
},
|
||||
"options": {
|
||||
"properties": {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The Ripple address of the account to get open orders for."
|
||||
"description": "The XRP Ledger address of the account to get open orders for."
|
||||
},
|
||||
"options": {
|
||||
"description": "Options that determine what orders will be returned.",
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The Ripple address of the account where funds will come from."
|
||||
"description": "The XRP Ledger address of the account where funds will come from."
|
||||
},
|
||||
"amount": {
|
||||
"$ref": "laxAmount",
|
||||
@@ -49,7 +49,7 @@
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The address to send to."
|
||||
"description": "An address representing the destination of the transaction."
|
||||
},
|
||||
"amount": {
|
||||
"$ref": "laxLaxAmount",
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
"properties": {
|
||||
"minLedgerVersion": {
|
||||
"$ref": "ledgerVersion",
|
||||
"description": "The lowest ledger version to search."
|
||||
"description": "The lowest ledger version to search. This must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'."
|
||||
},
|
||||
"maxLedgerVersion": {
|
||||
"$ref": "ledgerVersion",
|
||||
"description": "The highest ledger version to search"
|
||||
"description": "The highest ledger version to search. This must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'."
|
||||
},
|
||||
"includeRawTransaction": {
|
||||
"description": "Include raw transaction data. For advanced users; exercise caution when interpreting this data. "
|
||||
"description": "Include raw transaction data. For advanced users; exercise caution when interpreting this data."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
},
|
||||
"minLedgerVersion": {
|
||||
"$ref": "ledgerVersion",
|
||||
"description": "Return only transactions in this ledger verion or higher."
|
||||
"description": "Return only transactions in this ledger version or higher."
|
||||
},
|
||||
"maxLedgerVersion": {
|
||||
"$ref": "ledgerVersion",
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"secret": {
|
||||
"type": "string",
|
||||
"format": "secret",
|
||||
"description": "The secret of the account that is initiating the transaction. (This field is exclusive with keypair)."
|
||||
"description": "The secret of the account that is initiating the transaction. (This field cannot be used with keypair)."
|
||||
},
|
||||
"keypair": {
|
||||
"type": "object",
|
||||
@@ -24,7 +24,7 @@
|
||||
"description": "The uppercase hexadecimal representation of the secp256k1 or Ed25519 public key."
|
||||
}
|
||||
},
|
||||
"description": "The private and public key of the account that is initiating the transaction. (This field is exclusive with secret).",
|
||||
"description": "The private and public key of the account that is initiating the transaction. (This field cannot be used with secret).",
|
||||
"required": ["privateKey", "publicKey"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"$ref": "currency"
|
||||
},
|
||||
"counterparty": {
|
||||
"description": "The Ripple address of the account that owes or is owed the funds (omitted if `currency` is \"XRP\" or \"drops\")",
|
||||
"description": "The XRP Ledger address of the account that owes or is owed the funds (omitted if `currency` is \"XRP\" or \"drops\")",
|
||||
"$ref": "address"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"$ref": "currency"
|
||||
},
|
||||
"counterparty": {
|
||||
"description": "The Ripple address of the account that owes or is owed the funds.",
|
||||
"description": "The XRP Ledger address of the account that owes or is owed the funds.",
|
||||
"$ref": "address"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The address to receive at."
|
||||
"description": "An address representing the destination of the transaction."
|
||||
},
|
||||
"tag": {"$ref": "tag"}
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The address to receive at."
|
||||
"description": "An address representing the destination of the transaction."
|
||||
},
|
||||
"amount": {
|
||||
"$ref": "laxAmount",
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"$ref": "sequence"
|
||||
},
|
||||
"fee": {
|
||||
"description": "An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information.",
|
||||
"description": "An exact fee to pay for the transaction, before multiplying for multi-signed transactions. See [Transaction Fees](#transaction-fees) for more information.",
|
||||
"$ref": "value"
|
||||
},
|
||||
"maxFee": {
|
||||
@@ -18,7 +18,7 @@
|
||||
"$ref": "value"
|
||||
},
|
||||
"maxLedgerVersion": {
|
||||
"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.",
|
||||
"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. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'.",
|
||||
"oneOf": [
|
||||
{"$ref": "ledgerVersion"},
|
||||
{"type": "null"}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"maxAmount": {
|
||||
"$ref": "laxAmount",
|
||||
"description": "The maximum amount to send. (This field is exclusive with source.amount)"
|
||||
"description": "The maximum amount to send. (This field cannot be used with source.amount)"
|
||||
},
|
||||
"tag": {"$ref": "tag"}
|
||||
},
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
"properties": {
|
||||
"address": {
|
||||
"$ref": "address",
|
||||
"description": "The address to send to."
|
||||
"description": "An address representing the destination of the transaction."
|
||||
},
|
||||
"minAmount": {
|
||||
"$ref": "laxAmount",
|
||||
"description": "The minimum amount to be delivered. (This field is exclusive with destination.amount)"
|
||||
"description": "The minimum amount to be delivered. (This field cannot be used with destination.amount)"
|
||||
},
|
||||
"tag": {"$ref": "tag"}
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
},
|
||||
"disableMasterKey": {
|
||||
"type": "boolean",
|
||||
"description": "Disallows use of the master key to sign transactions for this account."
|
||||
"description": "Disallows use of the master key to sign transactions for this account. To disable the master key, you must authorize the transaction by signing it with the master key pair. You cannot use a regular key pair or a multi-signature. You can re-enable the master key pair using a regular key pair or multi-signature. See [AccountSet](https://developers.ripple.com/accountset.html)."
|
||||
},
|
||||
"disallowIncomingXRP": {
|
||||
"type": "boolean",
|
||||
@@ -94,7 +94,7 @@
|
||||
"maxItems": 8
|
||||
}
|
||||
},
|
||||
"required": ["threshold", "weights"],
|
||||
"required": ["threshold"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"transferRate": {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"amount": {
|
||||
"$ref": "laxAmount",
|
||||
"description": "An exact amount to send. If the counterparty is not specified, amounts with any counterparty may be used. (This field is exclusive with source.maxAmount)"
|
||||
"description": "An exact amount to send. If the counterparty is not specified, amounts with any counterparty may be used. (This field cannot be used with source.maxAmount)"
|
||||
},
|
||||
"tag": {"$ref": "tag"}
|
||||
},
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "tx",
|
||||
"link": "https://ripple.com/build/transactions/",
|
||||
"title": "tx-json",
|
||||
"link": "https://developers.ripple.com/transaction-formats.html",
|
||||
"description": "An object in rippled txJSON format",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Account": {"$ref": "address"}
|
||||
"Account": {"$ref": "address"},
|
||||
"TransactionType": {"type": "string"}
|
||||
},
|
||||
"required": ["Account"]
|
||||
"required": ["Account", "TransactionType"]
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
},
|
||||
"threads": {
|
||||
"type": "number",
|
||||
"description": "*(Admin only)* The number of threads in the server’s main job pool, performing various Ripple Network operations."
|
||||
"description": "*(Admin only)* The number of threads in the server’s main job pool, performing various operations."
|
||||
}
|
||||
},
|
||||
"required": ["jobTypes", "threads"]
|
||||
@@ -70,7 +70,7 @@
|
||||
},
|
||||
"serverState": {
|
||||
"type": "string",
|
||||
"description": "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.",
|
||||
"description": "A string indicating to what extent the server is participating in the network. See [Possible Server States](https://developers.ripple.com/rippled-server-states.html) for more details.",
|
||||
"enum": ["disconnected", "connected", "syncing", "tracking", "full", "validating", "proposing"]
|
||||
},
|
||||
"validatedLedger": {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"properties": {
|
||||
"result": {
|
||||
"type": "string",
|
||||
"description": "Result code returned by rippled. See [Transaction Results](https://ripple.com/build/transactions/#full-transaction-response-list) for a complete list."
|
||||
"description": "Result code returned by rippled. See [Transaction Results](https://developers.ripple.com/transaction-results.html) for a complete list."
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "string",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"properties": {
|
||||
"fee": {
|
||||
"$ref": "value",
|
||||
"description": "An exact fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information."
|
||||
"description": "The fee to pay for the transaction. See [Transaction Fees](#transaction-fees) for more information. For multi-signed transactions, this fee will be multiplied by (N+1), where N is the number of signatures you plan to provide."
|
||||
},
|
||||
"sequence": {
|
||||
"$ref": "sequence",
|
||||
@@ -25,7 +25,7 @@
|
||||
{"$ref": "ledgerVersion"},
|
||||
{"type": "null"}
|
||||
],
|
||||
"description": "The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum."
|
||||
"description": "The highest ledger version that the transaction can be included in. Set to `null` if there is no maximum. If not null, this must be an integer greater than 0, or one of the following strings: 'validated', 'closed', 'current'."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
},
|
||||
"engine_result": {
|
||||
"type": "string",
|
||||
"description": "Code indicating the preliminary result of the transaction, for example tesSUCCESS. [List of transaction responses](https://ripple.com/build/transactions/#full-transaction-response-list)"
|
||||
"description": "Code indicating the preliminary result of the transaction, for example `tesSUCCESS`. [List of transaction responses](https://developers.ripple.com/transaction-results.html)"
|
||||
},
|
||||
"engine_result_code": {
|
||||
"type": "integer",
|
||||
@@ -28,7 +28,7 @@
|
||||
"description": "The complete transaction in hex string format."
|
||||
},
|
||||
"tx_json": {
|
||||
"$ref": "tx",
|
||||
"$ref": "tx-json",
|
||||
"description": "The complete transaction in JSON format."
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as _ from 'lodash'
|
||||
import {convertKeysFromSnakeCaseToCamelCase} from './utils'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import {RippleAPI} from '../index'
|
||||
import {RippleAPI} from '..'
|
||||
|
||||
export type GetServerInfoResponse = {
|
||||
buildVersion: string,
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
export type Amount = {
|
||||
value: string,
|
||||
currency: string,
|
||||
issuer?: string,
|
||||
counterparty?: string
|
||||
export interface Amount extends Issue {
|
||||
value: string
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +18,8 @@ export interface TakerRequestAmount {
|
||||
/**
|
||||
* A currency-counterparty pair, or just currency if it's XRP.
|
||||
*/
|
||||
export type Issue = {
|
||||
currency: string,
|
||||
issuer?: string,
|
||||
export interface Issue {
|
||||
currency: string
|
||||
issuer?: string
|
||||
counterparty?: string
|
||||
}
|
||||
|
||||
@@ -18,5 +18,6 @@ export interface Ledger {
|
||||
hash?: string,
|
||||
close_flags?: number,
|
||||
parent_close_time?: number,
|
||||
accountState?: any[]
|
||||
accountState?: any[],
|
||||
validated?: boolean
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ function toRippledAmount(amount: Amount): RippledAmount {
|
||||
|
||||
function convertKeysFromSnakeCaseToCamelCase(obj: any): any {
|
||||
if (typeof obj === 'object') {
|
||||
const accumulator = Array.isArray(obj) ? [] : {}
|
||||
let newKey
|
||||
return _.reduce(obj, (result, value, key) => {
|
||||
newKey = key
|
||||
@@ -113,7 +114,7 @@ function convertKeysFromSnakeCaseToCamelCase(obj: any): any {
|
||||
}
|
||||
result[newKey] = convertKeysFromSnakeCaseToCamelCase(value)
|
||||
return result
|
||||
}, {})
|
||||
}, accumulator)
|
||||
}
|
||||
return obj
|
||||
}
|
||||
@@ -125,7 +126,6 @@ function removeUndefined<T extends object>(obj: T): T {
|
||||
/**
|
||||
* @param {Number} rpepoch (seconds since 1/1/2000 GMT)
|
||||
* @return {Number} ms since unix epoch
|
||||
*
|
||||
*/
|
||||
function rippleToUnixTimestamp(rpepoch: number): number {
|
||||
return (rpepoch + 0x386D4380) * 1000
|
||||
|
||||
@@ -124,3 +124,6 @@ _.partial(schemaValidate, 'api-options')
|
||||
|
||||
export const instructions =
|
||||
_.partial(schemaValidate, 'instructions')
|
||||
|
||||
export const tx_json =
|
||||
_.partial(schemaValidate, 'tx-json')
|
||||
|
||||
84
src/http.ts
84
src/http.ts
@@ -1,84 +0,0 @@
|
||||
/* eslint-disable new-cap */
|
||||
|
||||
import * as assert from 'assert'
|
||||
import * as _ from 'lodash'
|
||||
import * as jayson from 'jayson'
|
||||
import {RippleAPI} from './api'
|
||||
|
||||
|
||||
/* istanbul ignore next */
|
||||
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](...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()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
createHTTPServer
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import {validate, removeUndefined, dropsToXrp} from '../common'
|
||||
import {RippleAPI} from '../api'
|
||||
import {RippleAPI} from '..'
|
||||
import {AccountInfoResponse} from '../common/types/commands/account_info'
|
||||
|
||||
export type GetAccountInfoOptions = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {removeUndefined} from '../common'
|
||||
import {RippleAPI} from '../api'
|
||||
import {RippleAPI} from '..'
|
||||
import {
|
||||
GetAccountObjectsOptions,
|
||||
AccountObjectsResponse
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as _ from 'lodash'
|
||||
import {validate} from '../common'
|
||||
import {Amount} from '../common/types/objects'
|
||||
import {ensureLedgerVersion} from './utils'
|
||||
import {RippleAPI} from '../api'
|
||||
import {RippleAPI} from '..'
|
||||
|
||||
export type BalanceSheetOptions = {
|
||||
excludeAddresses?: Array<string>,
|
||||
|
||||
@@ -3,6 +3,7 @@ import {validate} from '../common'
|
||||
import {Connection} from '../common'
|
||||
import {GetTrustlinesOptions} from './trustlines'
|
||||
import {FormattedTrustline} from '../common/types/objects/trustlines'
|
||||
import {RippleAPI} from '..'
|
||||
|
||||
|
||||
export type Balance = {
|
||||
@@ -47,7 +48,7 @@ function getLedgerVersionHelper(connection: Connection, optionValue?: number
|
||||
return connection.getLedgerVersion()
|
||||
}
|
||||
|
||||
function getBalances(address: string, options: GetTrustlinesOptions = {}
|
||||
function getBalances(this: RippleAPI, address: string, options: GetTrustlinesOptions = {}
|
||||
): Promise<GetBalances> {
|
||||
validate.getTrustlines({address, options})
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {validate} from '../common'
|
||||
import {FormattedLedger, parseLedger} from './parse/ledger'
|
||||
import {RippleAPI} from '../api'
|
||||
import {RippleAPI} from '..'
|
||||
|
||||
export type GetLedgerOptions = {
|
||||
ledgerHash?: string,
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
FormattedOrderbookOrder
|
||||
} from './parse/orderbook-order'
|
||||
import {validate} from '../common'
|
||||
import {Amount, Issue} from '../common/types/objects'
|
||||
import {Issue} from '../common/types/objects'
|
||||
import {BookOffer} from '../common/types/commands'
|
||||
import {RippleAPI} from '../api'
|
||||
import {RippleAPI} from '..'
|
||||
import BigNumber from 'bignumber.js'
|
||||
|
||||
export type FormattedOrderbook = {
|
||||
@@ -15,7 +15,7 @@ export type FormattedOrderbook = {
|
||||
asks: FormattedOrderbookOrder[]
|
||||
}
|
||||
|
||||
function isSameIssue(a: Amount, b: Amount) {
|
||||
function isSameIssue(a: Issue, b: Issue) {
|
||||
return a.currency === b.currency && a.counterparty === b.counterparty
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ function flipOrder(order: FormattedOrderbookOrder) {
|
||||
return _.merge({}, order, {specification: newSpecification})
|
||||
}
|
||||
|
||||
function alignOrder(base: Amount, order: FormattedOrderbookOrder) {
|
||||
function alignOrder(base: Issue, order: FormattedOrderbookOrder): FormattedOrderbookOrder {
|
||||
const quantity = order.specification.quantity
|
||||
return isSameIssue(quantity, base) ? order : flipOrder(order)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as _ from 'lodash'
|
||||
import {validate} from '../common'
|
||||
import {FormattedAccountOrder, parseAccountOrder} from './parse/account-order'
|
||||
import {RippleAPI} from '../api'
|
||||
import {RippleAPI} from '..'
|
||||
import {AccountOffersResponse} from '../common/types/commands'
|
||||
|
||||
export type GetOrdersOptions = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as assert from 'assert'
|
||||
|
||||
function parseOrderCancellation(tx: any): object {
|
||||
assert(tx.TransactionType === 'OfferCancel')
|
||||
assert.ok(tx.TransactionType === 'OfferCancel')
|
||||
return {
|
||||
orderSequence: tx.OfferSequence
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export type FormattedCheckCancel = {
|
||||
}
|
||||
|
||||
function parseCheckCancel(tx: any): FormattedCheckCancel {
|
||||
assert(tx.TransactionType === 'CheckCancel')
|
||||
assert.ok(tx.TransactionType === 'CheckCancel')
|
||||
|
||||
return removeUndefined({
|
||||
checkID: tx.CheckID
|
||||
|
||||
@@ -23,7 +23,7 @@ export type FormattedCheckCash = {
|
||||
}
|
||||
|
||||
function parseCheckCash(tx: any): FormattedCheckCash {
|
||||
assert(tx.TransactionType === 'CheckCash')
|
||||
assert.ok(tx.TransactionType === 'CheckCash')
|
||||
|
||||
return removeUndefined({
|
||||
checkID: tx.CheckID,
|
||||
|
||||
@@ -24,7 +24,7 @@ export type FormattedCheckCreate = {
|
||||
}
|
||||
|
||||
function parseCheckCreate(tx: any): FormattedCheckCreate {
|
||||
assert(tx.TransactionType === 'CheckCreate')
|
||||
assert.ok(tx.TransactionType === 'CheckCreate')
|
||||
|
||||
return removeUndefined({
|
||||
destination: tx.Destination,
|
||||
|
||||
@@ -10,7 +10,7 @@ export type FormattedDepositPreauth = {
|
||||
}
|
||||
|
||||
function parseDepositPreauth(tx: any): FormattedDepositPreauth {
|
||||
assert(tx.TransactionType === 'DepositPreauth')
|
||||
assert.ok(tx.TransactionType === 'DepositPreauth')
|
||||
|
||||
return removeUndefined({
|
||||
authorize: tx.Authorize,
|
||||
|
||||
@@ -3,7 +3,7 @@ import {parseMemos} from './utils'
|
||||
import {removeUndefined} from '../../common'
|
||||
|
||||
function parseEscrowCancellation(tx: any): object {
|
||||
assert(tx.TransactionType === 'EscrowCancel')
|
||||
assert.ok(tx.TransactionType === 'EscrowCancel')
|
||||
|
||||
return removeUndefined({
|
||||
memos: parseMemos(tx),
|
||||
|
||||
@@ -4,7 +4,7 @@ import {parseTimestamp, parseMemos} from './utils'
|
||||
import {removeUndefined} from '../../common'
|
||||
|
||||
function parseEscrowCreation(tx: any): object {
|
||||
assert(tx.TransactionType === 'EscrowCreate')
|
||||
assert.ok(tx.TransactionType === 'EscrowCreate')
|
||||
|
||||
return removeUndefined({
|
||||
amount: parseAmount(tx.Amount).value,
|
||||
|
||||
@@ -3,7 +3,7 @@ import {parseMemos} from './utils'
|
||||
import {removeUndefined} from '../../common'
|
||||
|
||||
function parseEscrowExecution(tx: any): object {
|
||||
assert(tx.TransactionType === 'EscrowFinish')
|
||||
assert.ok(tx.TransactionType === 'EscrowFinish')
|
||||
|
||||
return removeUndefined({
|
||||
memos: parseMemos(tx),
|
||||
|
||||
@@ -5,7 +5,7 @@ const AccountFields = constants.AccountFields
|
||||
|
||||
function parseField(info, value) {
|
||||
if (info.encoding === 'hex' && !info.length) { // e.g. "domain"
|
||||
return new Buffer(value, 'hex').toString('ascii')
|
||||
return Buffer.from(value, 'hex').toString('ascii')
|
||||
}
|
||||
if (info.shift) {
|
||||
return (new BigNumber(value)).shift(-info.shift).toNumber()
|
||||
|
||||
@@ -59,6 +59,11 @@ function parseState(state) {
|
||||
return {rawState: JSON.stringify(state)}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Ledger} ledger must be a *closed* ledger with valid `close_time` and `parent_close_time`
|
||||
* @returns {FormattedLedger} formatted ledger
|
||||
* @throws RangeError: Invalid time value (rippleTimeToISO8601)
|
||||
*/
|
||||
export function parseLedger(ledger: Ledger): FormattedLedger {
|
||||
const ledgerVersion = parseInt(ledger.ledger_index || ledger.seqNum, 10)
|
||||
return removeUndefined(Object.assign(
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
const flags = txFlags.OfferCreate
|
||||
|
||||
function parseOrder(tx: OfferCreateTransaction): FormattedOrderSpecification {
|
||||
assert(tx.TransactionType === 'OfferCreate')
|
||||
assert.ok(tx.TransactionType === 'OfferCreate')
|
||||
|
||||
const direction = (tx.Flags & flags.Sell) === 0 ? 'buy' : 'sell'
|
||||
const takerGetsAmount = parseAmount(tx.TakerGets)
|
||||
|
||||
@@ -4,7 +4,7 @@ import parseAmount from './amount'
|
||||
const claimFlags = txFlags.PaymentChannelClaim
|
||||
|
||||
function parsePaymentChannelClaim(tx: any): object {
|
||||
assert(tx.TransactionType === 'PaymentChannelClaim')
|
||||
assert.ok(tx.TransactionType === 'PaymentChannelClaim')
|
||||
|
||||
return removeUndefined({
|
||||
channel: tx.Channel,
|
||||
|
||||
@@ -4,7 +4,7 @@ import {removeUndefined} from '../../common'
|
||||
import parseAmount from './amount'
|
||||
|
||||
function parsePaymentChannelCreate(tx: any): object {
|
||||
assert(tx.TransactionType === 'PaymentChannelCreate')
|
||||
assert.ok(tx.TransactionType === 'PaymentChannelCreate')
|
||||
|
||||
return removeUndefined({
|
||||
amount: parseAmount(tx.Amount).value,
|
||||
|
||||
@@ -4,7 +4,7 @@ import {removeUndefined} from '../../common'
|
||||
import parseAmount from './amount'
|
||||
|
||||
function parsePaymentChannelFund(tx: any): object {
|
||||
assert(tx.TransactionType === 'PaymentChannelFund')
|
||||
assert.ok(tx.TransactionType === 'PaymentChannelFund')
|
||||
|
||||
return removeUndefined({
|
||||
channel: tx.Channel,
|
||||
|
||||
@@ -4,6 +4,7 @@ import {PayChannelLedgerEntry} from '../../common/types/objects'
|
||||
|
||||
export type FormattedPaymentChannel = {
|
||||
account: string,
|
||||
amount: string,
|
||||
balance: string,
|
||||
publicKey: string,
|
||||
destination: string,
|
||||
|
||||
@@ -19,7 +19,7 @@ function removeGenericCounterparty(amount, address) {
|
||||
|
||||
// Payment specification
|
||||
function parsePayment(tx: any): object {
|
||||
assert(tx.TransactionType === 'Payment')
|
||||
assert.ok(tx.TransactionType === 'Payment')
|
||||
|
||||
const source = {
|
||||
address: tx.Account,
|
||||
|
||||
@@ -7,7 +7,7 @@ import parseFields from './fields'
|
||||
function getAccountRootModifiedNode(tx: any) {
|
||||
const modifiedNodes = tx.meta.AffectedNodes.filter(node =>
|
||||
node.ModifiedNode.LedgerEntryType === 'AccountRoot')
|
||||
assert(modifiedNodes.length === 1)
|
||||
assert.ok(modifiedNodes.length === 1)
|
||||
return modifiedNodes[0].ModifiedNode
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ function parseFlags(tx: any): any {
|
||||
|
||||
function parseSettings(tx: any) {
|
||||
const txType = tx.TransactionType
|
||||
assert(txType === 'AccountSet' || txType === 'SetRegularKey' ||
|
||||
assert.ok(txType === 'AccountSet' || txType === 'SetRegularKey' ||
|
||||
txType === 'SignerListSet')
|
||||
|
||||
return _.assign({}, parseFlags(tx), parseFields(tx))
|
||||
|
||||
@@ -14,7 +14,7 @@ function parseFlag(flagsValue, trueValue, falseValue) {
|
||||
}
|
||||
|
||||
function parseTrustline(tx: any): object {
|
||||
assert(tx.TransactionType === 'TrustSet')
|
||||
assert.ok(tx.TransactionType === 'TrustSet')
|
||||
|
||||
return removeUndefined({
|
||||
limit: tx.LimitAmount.value,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as _ from 'lodash'
|
||||
import transactionParser = require('ripple-lib-transactionparser')
|
||||
import transactionParser from 'ripple-lib-transactionparser'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import * as common from '../../common'
|
||||
import parseAmount from './amount'
|
||||
@@ -122,7 +122,7 @@ function parseOutcome(tx: any): any|undefined {
|
||||
}
|
||||
|
||||
function hexToString(hex: string): string|undefined {
|
||||
return hex ? new Buffer(hex, 'hex').toString('utf-8') : undefined
|
||||
return hex ? Buffer.from(hex, 'hex').toString('utf-8') : undefined
|
||||
}
|
||||
|
||||
function parseMemos(tx: any): Array<Memo>|undefined {
|
||||
|
||||
@@ -14,6 +14,7 @@ import {RippledAmount, Amount} from '../common/types/objects'
|
||||
import {
|
||||
GetPaths, PathFind, RippledPathsResponse, PathFindRequest
|
||||
} from './pathfind-types'
|
||||
import {RippleAPI} from '..'
|
||||
const NotFoundError = errors.NotFoundError
|
||||
const ValidationError = errors.ValidationError
|
||||
|
||||
@@ -46,9 +47,7 @@ function requestPathFind(connection: Connection, pathfind: PathFind
|
||||
&& !request.destination_amount.issuer) {
|
||||
// Convert blank issuer to sender's address
|
||||
// (Ripple convention for 'any issuer')
|
||||
// https://ripple.com/build/transactions/
|
||||
// #special-issuer-values-for-sendmax-and-amount
|
||||
// https://ripple.com/build/ripple-rest/#counterparties-in-payments
|
||||
// https://developers.ripple.com/payment.html#special-issuer-values-for-sendmax-and-amount
|
||||
request.destination_amount.issuer = request.destination_account
|
||||
}
|
||||
if (pathfind.source.currencies && pathfind.source.currencies.length > 0) {
|
||||
@@ -149,7 +148,7 @@ function formatResponse(pathfind: PathFind, paths: RippledPathsResponse) {
|
||||
}
|
||||
}
|
||||
|
||||
function getPaths(pathfind: PathFind): Promise<GetPaths> {
|
||||
function getPaths(this: RippleAPI, pathfind: PathFind): Promise<GetPaths> {
|
||||
validate.getPaths({pathfind})
|
||||
|
||||
const address = pathfind.source.address
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
FormattedPaymentChannel
|
||||
} from './parse/payment-channel'
|
||||
import {validate, errors} from '../common'
|
||||
import {RippleAPI} from '../api'
|
||||
import {RippleAPI} from '..'
|
||||
import {LedgerEntryResponse} from '../common/types/commands'
|
||||
const NotFoundError = errors.NotFoundError
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import parseFields from './parse/fields'
|
||||
import {validate, constants} from '../common'
|
||||
import {FormattedSettings} from '../common/types/objects'
|
||||
import {AccountInfoResponse} from '../common/types/commands'
|
||||
import {RippleAPI} from '../api'
|
||||
import {RippleAPI} from '..'
|
||||
const AccountFlags = constants.AccountFlags
|
||||
|
||||
export type SettingsOptions = {
|
||||
|
||||
@@ -4,6 +4,8 @@ import parseTransaction from './parse/transaction'
|
||||
import {validate, errors} from '../common'
|
||||
import {Connection} from '../common'
|
||||
import {FormattedTransactionType} from '../transaction/types'
|
||||
import {RippledError} from '../common/errors'
|
||||
import {RippleAPI} from '..'
|
||||
|
||||
export type TransactionOptions = {
|
||||
minLedgerVersion?: number,
|
||||
@@ -59,10 +61,16 @@ function isTransactionInRange(tx: any, options: TransactionOptions) {
|
||||
}
|
||||
|
||||
function convertError(connection: Connection, options: TransactionOptions,
|
||||
error: Error
|
||||
error: RippledError
|
||||
): Promise<Error> {
|
||||
const _error = (error.message === 'txnNotFound') ?
|
||||
new errors.NotFoundError('Transaction not found') : error
|
||||
let shouldUseNotFoundError = false
|
||||
if ((error.data && error.data.error === 'txnNotFound') || error.message === 'txnNotFound') {
|
||||
shouldUseNotFoundError = true
|
||||
}
|
||||
|
||||
// In the future, we should deprecate this error, instead passing through the one from rippled.
|
||||
const _error = shouldUseNotFoundError ? new errors.NotFoundError('Transaction not found') : error
|
||||
|
||||
if (_error instanceof errors.NotFoundError) {
|
||||
return utils.hasCompleteLedgerRange(connection, options.minLedgerVersion,
|
||||
options.maxLedgerVersion).then(hasCompleteLedgerRange => {
|
||||
@@ -89,7 +97,7 @@ function formatResponse(options: TransactionOptions, tx: TransactionResponse
|
||||
return parseTransaction(tx, options.includeRawTransaction)
|
||||
}
|
||||
|
||||
async function getTransaction(id: string, options: TransactionOptions = {}
|
||||
async function getTransaction(this: RippleAPI, id: string, options: TransactionOptions = {}
|
||||
): Promise<FormattedTransactionType> {
|
||||
validate.getTransaction({id, options})
|
||||
const _options = await utils.ensureLedgerVersion.call(this, options)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import * as _ from 'lodash'
|
||||
import binary = require('ripple-binary-codec')
|
||||
const {computeTransactionHash} = require('ripple-hashes')
|
||||
import binary from 'ripple-binary-codec';
|
||||
import {computeTransactionHash} from '../common/hashes'
|
||||
import * as utils from './utils'
|
||||
import parseTransaction from './parse/transaction'
|
||||
import getTransaction from './transaction'
|
||||
import {validate, errors, Connection} from '../common'
|
||||
import {FormattedTransactionType} from '../transaction/types'
|
||||
import {RippleAPI} from '..'
|
||||
|
||||
|
||||
export type TransactionsOptions = {
|
||||
@@ -162,7 +163,7 @@ function getTransactionsInternal(connection: Connection, address: string,
|
||||
return utils.getRecursive(getter, options.limit).then(format)
|
||||
}
|
||||
|
||||
function getTransactions(address: string, options: TransactionsOptions = {}
|
||||
function getTransactions(this: RippleAPI, address: string, options: TransactionsOptions = {}
|
||||
): Promise<GetTransactionsResponse> {
|
||||
validate.getTransactions({address, options})
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as _ from 'lodash'
|
||||
import {validate} from '../common'
|
||||
import parseAccountTrustline from './parse/account-trustline'
|
||||
import {RippleAPI} from '../api'
|
||||
import {RippleAPI} from '..'
|
||||
import {FormattedTrustline} from '../common/types/objects/trustlines'
|
||||
|
||||
export type GetTrustlinesOptions = {
|
||||
|
||||
@@ -4,6 +4,7 @@ import * as common from '../common'
|
||||
import {Connection} from '../common'
|
||||
import {FormattedTransactionType} from '../transaction/types'
|
||||
import {Issue} from '../common/types/objects'
|
||||
import {RippleAPI} from '..'
|
||||
|
||||
export type RecursiveData = {
|
||||
marker: string,
|
||||
@@ -13,7 +14,7 @@ export type RecursiveData = {
|
||||
export type Getter = (marker?: string, limit?: number) => Promise<RecursiveData>
|
||||
|
||||
function clamp(value: number, min: number, max: number): number {
|
||||
assert(min <= max, 'Illegal clamp bounds')
|
||||
assert.ok(min <= max, 'Illegal clamp bounds')
|
||||
return Math.min(Math.max(value, min), max)
|
||||
}
|
||||
|
||||
@@ -76,7 +77,7 @@ function signum(num) {
|
||||
* Order two rippled transactions based on their ledger_index.
|
||||
* If two transactions took place in the same ledger, sort
|
||||
* them based on TransactionIndex
|
||||
* See: https://ripple.com/build/transactions/
|
||||
* See: https://developers.ripple.com/transaction-metadata.html
|
||||
*/
|
||||
function compareTransactions(
|
||||
first: FormattedTransactionType, second: FormattedTransactionType
|
||||
@@ -105,7 +106,7 @@ function isPendingLedgerVersion(connection: Connection,
|
||||
ledgerVersion < (maxLedgerVersion || 0))
|
||||
}
|
||||
|
||||
function ensureLedgerVersion(options: any
|
||||
function ensureLedgerVersion(this: RippleAPI, options: any
|
||||
): Promise<object> {
|
||||
if (Boolean(options) && options.ledgerVersion !== undefined &&
|
||||
options.ledgerVersion !== null
|
||||
|
||||
@@ -4,4 +4,3 @@ export {
|
||||
deriveKeypair,
|
||||
deriveAddress
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import keypairs = require('ripple-keypairs')
|
||||
import keypairs from 'ripple-keypairs'
|
||||
import * as common from '../common'
|
||||
const {errors, validate} = common
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as _ from 'lodash'
|
||||
import hashes = require('ripple-hashes')
|
||||
import {computeLedgerHash, computeTransactionTreeHash, computeStateTreeHash} from '../common/hashes'
|
||||
import * as common from '../common'
|
||||
|
||||
function convertLedgerHeader(header): any {
|
||||
@@ -22,11 +22,11 @@ function convertLedgerHeader(header): any {
|
||||
|
||||
function hashLedgerHeader(ledgerHeader) {
|
||||
const header = convertLedgerHeader(ledgerHeader)
|
||||
return hashes.computeLedgerHash(header)
|
||||
return computeLedgerHash(header)
|
||||
}
|
||||
|
||||
function computeTransactionHash(ledger, version,
|
||||
options: ComputeLedgerHashOptions) {
|
||||
function computeTransactionHash(ledger,
|
||||
options: ComputeLedgerHeaderHashOptions) {
|
||||
let transactions: any[]
|
||||
if (ledger.rawTransactions) {
|
||||
transactions = JSON.parse(ledger.rawTransactions)
|
||||
@@ -56,7 +56,7 @@ function computeTransactionHash(ledger, version,
|
||||
tx.meta ? {metaData: tx.meta} : {})
|
||||
return renameMeta
|
||||
})
|
||||
const transactionHash = hashes.computeTransactionTreeHash(txs, version)
|
||||
const transactionHash = computeTransactionTreeHash(txs)
|
||||
if (ledger.transactionHash !== undefined
|
||||
&& ledger.transactionHash !== transactionHash) {
|
||||
throw new common.errors.ValidationError('transactionHash in header'
|
||||
@@ -68,8 +68,8 @@ function computeTransactionHash(ledger, version,
|
||||
return transactionHash
|
||||
}
|
||||
|
||||
function computeStateHash(ledger, version,
|
||||
options: ComputeLedgerHashOptions) {
|
||||
function computeStateHash(ledger,
|
||||
options: ComputeLedgerHeaderHashOptions) {
|
||||
if (ledger.rawState === undefined) {
|
||||
if (options.computeTreeHashes) {
|
||||
throw new common.errors.ValidationError('rawState'
|
||||
@@ -78,7 +78,7 @@ function computeStateHash(ledger, version,
|
||||
return ledger.stateHash
|
||||
}
|
||||
const state = JSON.parse(ledger.rawState)
|
||||
const stateHash = hashes.computeStateTreeHash(state, version)
|
||||
const stateHash = computeStateTreeHash(state)
|
||||
if (ledger.stateHash !== undefined && ledger.stateHash !== stateHash) {
|
||||
throw new common.errors.ValidationError('stateHash in header'
|
||||
+ ' does not match computed hash of state')
|
||||
@@ -86,20 +86,17 @@ function computeStateHash(ledger, version,
|
||||
return stateHash
|
||||
}
|
||||
|
||||
const sLCF_SHAMapV2 = 0x02
|
||||
|
||||
export type ComputeLedgerHashOptions = {
|
||||
export type ComputeLedgerHeaderHashOptions = {
|
||||
computeTreeHashes?: boolean
|
||||
}
|
||||
|
||||
function computeLedgerHash(ledger: any,
|
||||
options: ComputeLedgerHashOptions = {}): string {
|
||||
const version = ((ledger.closeFlags & sLCF_SHAMapV2) === 0) ? 1 : 2
|
||||
function computeLedgerHeaderHash(ledger: any,
|
||||
options: ComputeLedgerHeaderHashOptions = {}): string {
|
||||
const subhashes = {
|
||||
transactionHash: computeTransactionHash(ledger, version, options),
|
||||
stateHash: computeStateHash(ledger, version, options)
|
||||
transactionHash: computeTransactionHash(ledger, options),
|
||||
stateHash: computeStateHash(ledger, options)
|
||||
}
|
||||
return hashLedgerHeader(_.assign({}, ledger, subhashes))
|
||||
}
|
||||
|
||||
export default computeLedgerHash
|
||||
export default computeLedgerHeaderHash
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as common from '../common'
|
||||
import keypairs = require('ripple-keypairs')
|
||||
import binary = require('ripple-binary-codec')
|
||||
import keypairs from 'ripple-keypairs'
|
||||
import binary from 'ripple-binary-codec'
|
||||
const {validate, xrpToDrops} = common
|
||||
|
||||
function signPaymentChannelClaim(channel: string, amount: string,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import keypairs = require('ripple-keypairs')
|
||||
import binary = require('ripple-binary-codec')
|
||||
import keypairs from 'ripple-keypairs'
|
||||
import binary from 'ripple-binary-codec'
|
||||
import {validate, xrpToDrops} from '../common'
|
||||
|
||||
function verifyPaymentChannelClaim(channel: string, amount: string,
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import * as common from '../common'
|
||||
import {RippleAPI} from '..'
|
||||
|
||||
function isConnected(): boolean {
|
||||
function isConnected(this: RippleAPI): boolean {
|
||||
return this.connection.isConnected()
|
||||
}
|
||||
|
||||
function getLedgerVersion(): Promise<number> {
|
||||
function getLedgerVersion(this: RippleAPI): Promise<number> {
|
||||
return this.connection.getLedgerVersion()
|
||||
}
|
||||
|
||||
function connect(): Promise<void> {
|
||||
function connect(this: RippleAPI): Promise<void> {
|
||||
return this.connection.connect()
|
||||
}
|
||||
|
||||
function disconnect(): Promise<void> {
|
||||
function disconnect(this: RippleAPI): Promise<void> {
|
||||
return this.connection.disconnect()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import * as utils from './utils'
|
||||
import {TransactionJSON, prepareTransaction} from './utils'
|
||||
import {validate} from '../common'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {RippleAPI} from '..'
|
||||
|
||||
export type CheckCancel = {
|
||||
export type CheckCancelParameters = {
|
||||
checkID: string
|
||||
}
|
||||
|
||||
function createCheckCancelTransaction(account: string,
|
||||
cancel: CheckCancel
|
||||
): object {
|
||||
cancel: CheckCancelParameters
|
||||
): TransactionJSON {
|
||||
const txJSON = {
|
||||
Account: account,
|
||||
TransactionType: 'CheckCancel',
|
||||
@@ -18,15 +19,19 @@ function createCheckCancelTransaction(account: string,
|
||||
return txJSON
|
||||
}
|
||||
|
||||
function prepareCheckCancel(address: string,
|
||||
checkCancel: CheckCancel,
|
||||
function prepareCheckCancel(this: RippleAPI, address: string,
|
||||
checkCancel: CheckCancelParameters,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareCheckCancel(
|
||||
{address, checkCancel, instructions})
|
||||
const txJSON = createCheckCancelTransaction(
|
||||
address, checkCancel)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareCheckCancel(
|
||||
{address, checkCancel, instructions})
|
||||
const txJSON = createCheckCancelTransaction(
|
||||
address, checkCancel)
|
||||
return prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareCheckCancel
|
||||
|
||||
@@ -2,18 +2,19 @@ import * as utils from './utils'
|
||||
const ValidationError = utils.common.errors.ValidationError
|
||||
const toRippledAmount = utils.common.toRippledAmount
|
||||
import {validate} from '../common'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare, TransactionJSON} from './types'
|
||||
import {Amount} from '../common/types/objects'
|
||||
import {RippleAPI} from '..'
|
||||
|
||||
export type CheckCash = {
|
||||
export type CheckCashParameters = {
|
||||
checkID: string,
|
||||
amount?: Amount,
|
||||
deliverMin?: Amount
|
||||
}
|
||||
|
||||
function createCheckCashTransaction(account: string,
|
||||
checkCash: CheckCash
|
||||
): object {
|
||||
checkCash: CheckCashParameters
|
||||
): TransactionJSON {
|
||||
if (checkCash.amount && checkCash.deliverMin) {
|
||||
throw new ValidationError('"amount" and "deliverMin" properties on '
|
||||
+ 'CheckCash are mutually exclusive')
|
||||
@@ -36,15 +37,19 @@ function createCheckCashTransaction(account: string,
|
||||
return txJSON
|
||||
}
|
||||
|
||||
function prepareCheckCash(address: string,
|
||||
checkCash: CheckCash,
|
||||
function prepareCheckCash(this: RippleAPI, address: string,
|
||||
checkCash: CheckCashParameters,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareCheckCash(
|
||||
{address, checkCash, instructions})
|
||||
const txJSON = createCheckCashTransaction(
|
||||
address, checkCash)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareCheckCash(
|
||||
{address, checkCash, instructions})
|
||||
const txJSON = createCheckCashTransaction(
|
||||
address, checkCash)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareCheckCash
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import * as utils from './utils'
|
||||
const toRippledAmount = utils.common.toRippledAmount
|
||||
import {validate, iso8601ToRippleTime} from '../common'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare, TransactionJSON} from './types'
|
||||
import {Amount} from '../common/types/objects'
|
||||
import {RippleAPI} from '..'
|
||||
|
||||
export type CheckCreate = {
|
||||
export type CheckCreateParameters = {
|
||||
destination: string,
|
||||
sendMax: Amount,
|
||||
destinationTag?: number,
|
||||
@@ -13,8 +14,8 @@ export type CheckCreate = {
|
||||
}
|
||||
|
||||
function createCheckCreateTransaction(account: string,
|
||||
check: CheckCreate
|
||||
): object {
|
||||
check: CheckCreateParameters
|
||||
): TransactionJSON {
|
||||
const txJSON: any = {
|
||||
Account: account,
|
||||
TransactionType: 'CheckCreate',
|
||||
@@ -37,15 +38,19 @@ function createCheckCreateTransaction(account: string,
|
||||
return txJSON
|
||||
}
|
||||
|
||||
function prepareCheckCreate(address: string,
|
||||
checkCreate: CheckCreate,
|
||||
function prepareCheckCreate(this: RippleAPI, address: string,
|
||||
checkCreate: CheckCreateParameters,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareCheckCreate(
|
||||
{address, checkCreate, instructions})
|
||||
const txJSON = createCheckCreateTransaction(
|
||||
address, checkCreate)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareCheckCreate(
|
||||
{address, checkCreate, instructions})
|
||||
const txJSON = createCheckCreateTransaction(
|
||||
address, checkCreate)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareCheckCreate
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import * as _ from 'lodash'
|
||||
import binary = require('ripple-binary-codec')
|
||||
import binary from 'ripple-binary-codec'
|
||||
import * as utils from './utils'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import {decodeAddress} from 'ripple-address-codec'
|
||||
import {validate} from '../common'
|
||||
import {computeBinaryTransactionHash} from 'ripple-hashes'
|
||||
import {computeBinaryTransactionHash} from '../common/hashes'
|
||||
|
||||
function addressToBigNumber(address) {
|
||||
const hex = (new Buffer(decodeAddress(address))).toString('hex')
|
||||
const hex = (Buffer.from(decodeAddress(address))).toString('hex')
|
||||
return new BigNumber(hex, 16)
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user