mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-04 21:15:47 +00:00
Convert from Flow to Typescript (#816)
* convert to typescript * add docs for custom node typing * update webpack, gulpfile
This commit is contained in:
committed by
Elliot Lee
parent
5979ff6197
commit
8204f6c648
73
Gulpfile.js
73
Gulpfile.js
@@ -1,21 +1,22 @@
|
||||
/* eslint-disable no-var, no-param-reassign */
|
||||
/* these eslint rules are disabled because gulp does not support babel yet */
|
||||
'use strict';
|
||||
var _ = require('lodash');
|
||||
var gulp = require('gulp');
|
||||
var uglify = require('gulp-uglify');
|
||||
var rename = require('gulp-rename');
|
||||
var webpack = require('webpack');
|
||||
var bump = require('gulp-bump');
|
||||
var argv = require('yargs').argv;
|
||||
var assert = require('assert');
|
||||
var fs = require('fs');
|
||||
const _ = require('lodash');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const assert = require('assert');
|
||||
const gulp = require('gulp');
|
||||
const rename = require('gulp-rename');
|
||||
const webpack = require('webpack');
|
||||
const bump = require('gulp-bump');
|
||||
const argv = require('yargs').argv;
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
||||
|
||||
var pkg = require('./package.json');
|
||||
|
||||
var uglifyOptions = {
|
||||
mangle: {
|
||||
except: ['_', 'RippleError', 'RippledError', 'UnexpectedError',
|
||||
reserved: ['_', 'RippleError', 'RippledError', 'UnexpectedError',
|
||||
'LedgerVersionError', 'ConnectionError', 'NotConnectedError',
|
||||
'DisconnectedError', 'TimeoutError', 'ResponseFormatError',
|
||||
'ValidationError', 'NotFoundError', 'MissingLedgerHistoryError',
|
||||
@@ -24,17 +25,17 @@ var uglifyOptions = {
|
||||
}
|
||||
};
|
||||
|
||||
function webpackConfig(extension, overrides) {
|
||||
function getWebpackConfig(extension, overrides) {
|
||||
overrides = overrides || {};
|
||||
var defaults = {
|
||||
let defaults = {
|
||||
cache: true,
|
||||
externals: [{
|
||||
'lodash': '_'
|
||||
}],
|
||||
entry: './src/index.js',
|
||||
entry: './src/index.ts',
|
||||
output: {
|
||||
library: 'ripple',
|
||||
path: './build/',
|
||||
path: path.join(__dirname, 'build/'),
|
||||
filename: ['ripple-', extension].join(pkg.version)
|
||||
},
|
||||
plugins: [
|
||||
@@ -44,18 +45,21 @@ function webpackConfig(extension, overrides) {
|
||||
'./setup-api-web')
|
||||
],
|
||||
module: {
|
||||
loaders: [{
|
||||
rules: [{
|
||||
test: /jayson/,
|
||||
loader: 'null'
|
||||
use: 'null',
|
||||
}, {
|
||||
test: /\.js$/,
|
||||
exclude: [/node_modules/],
|
||||
loader: 'babel-loader'
|
||||
test: /\.ts$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
}, {
|
||||
test: /\.json/,
|
||||
loader: 'json-loader'
|
||||
use: 'json-loader',
|
||||
}]
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
extensions: [ '.ts', '.js' ]
|
||||
},
|
||||
};
|
||||
return _.assign({}, defaults, overrides);
|
||||
}
|
||||
@@ -78,7 +82,7 @@ function webpackConfigForWebTest(testFileName, path) {
|
||||
filename: match[1] + '-test.js'
|
||||
}
|
||||
};
|
||||
return webpackConfig('.js', configOverrides);
|
||||
return getWebpackConfig('.js', configOverrides);
|
||||
}
|
||||
|
||||
gulp.task('build-tests', function(callback) {
|
||||
@@ -112,30 +116,29 @@ function createBuildLink(callback) {
|
||||
}
|
||||
|
||||
gulp.task('build', function(callback) {
|
||||
webpack(webpackConfig('.js'), createBuildLink(callback));
|
||||
webpack(getWebpackConfig('.js'), createBuildLink(callback));
|
||||
});
|
||||
|
||||
gulp.task('build-min', ['build'], function() {
|
||||
return gulp.src(['./build/ripple-', '.js'].join(pkg.version))
|
||||
.pipe(uglify(uglifyOptions))
|
||||
.pipe(rename(['ripple-', '-min.js'].join(pkg.version)))
|
||||
.pipe(gulp.dest('./build/'))
|
||||
.on('end', function() {
|
||||
gulp.task('build-min', function(callback) {
|
||||
const webpackConfig = getWebpackConfig('-min.js');
|
||||
webpackConfig.plugins.push(new UglifyJsPlugin({uglifyOptions}));
|
||||
webpack(webpackConfig, function() {
|
||||
createLink('./build/ripple-' + pkg.version + '-min.js',
|
||||
'./build/ripple-latest-min.js');
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('build-debug', function(callback) {
|
||||
var configOverrides = {debug: true, devtool: 'eval'};
|
||||
webpack(webpackConfig('-debug.js', configOverrides), callback);
|
||||
const webpackConfig = getWebpackConfig('-debug.js', {devtool: 'eval'});
|
||||
webpackConfig.plugins.unshift(new webpack.LoaderOptionsPlugin({debug: true}));
|
||||
webpack(webpackConfig, callback);
|
||||
});
|
||||
|
||||
/**
|
||||
* Generate a WebPack external for a given unavailable module which replaces
|
||||
* that module's constructor with an error-thrower
|
||||
*/
|
||||
|
||||
function buildUseError(cons) {
|
||||
return ('var {<CONS>:function(){throw new Error('
|
||||
+ '"Class is unavailable in this build: <CONS>")}}')
|
||||
@@ -145,7 +148,7 @@ function buildUseError(cons) {
|
||||
gulp.task('build-core', function(callback) {
|
||||
var configOverrides = {
|
||||
cache: false,
|
||||
entry: './src/remote.js',
|
||||
entry: './src/remote.ts',
|
||||
externals: [{
|
||||
'./transaction': buildUseError('Transaction'),
|
||||
'./orderbook': buildUseError('OrderBook'),
|
||||
@@ -153,10 +156,10 @@ gulp.task('build-core', function(callback) {
|
||||
'./serializedobject': buildUseError('SerializedObject')
|
||||
}],
|
||||
plugins: [
|
||||
new webpack.optimize.UglifyJsPlugin()
|
||||
new UglifyJsPlugin()
|
||||
]
|
||||
};
|
||||
webpack(webpackConfig('-core.js', configOverrides), callback);
|
||||
webpack(getWebpackConfig('-core.js', configOverrides), callback);
|
||||
});
|
||||
|
||||
gulp.task('bower-build', ['build'], function() {
|
||||
|
||||
9
custom_typings/node.d.ts
vendored
Normal file
9
custom_typings/node.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* This is an extension of Node's `process` object to include the browser
|
||||
* property, which is added by webpack.
|
||||
*/
|
||||
interface AmbiguousProcess extends NodeJS.Process {
|
||||
browser?: true
|
||||
}
|
||||
|
||||
declare var process: AmbiguousProcess;
|
||||
27
package.json
27
package.json
@@ -15,6 +15,8 @@
|
||||
"test": "test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/lodash": "^4.14.85",
|
||||
"@types/ws": "^3.2.0",
|
||||
"bignumber.js": "^4.1.0",
|
||||
"https-proxy-agent": "^1.0.0",
|
||||
"jsonschema": "^1.1.1",
|
||||
@@ -27,25 +29,16 @@
|
||||
"ws": "^3.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^8.0.53",
|
||||
"assert-diff": "^1.0.1",
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.4.0",
|
||||
"babel-eslint": "^6.0.4",
|
||||
"babel-loader": "^6.2.1",
|
||||
"babel-preset-es2015": "^6.3.13",
|
||||
"babel-preset-flow": "^6.23.0",
|
||||
"babel-preset-stage-1": "^6.3.13",
|
||||
"babel-register": "^6.3.13",
|
||||
"coveralls": "^2.13.1",
|
||||
"doctoc": "^0.15.0",
|
||||
"ejs": "^2.3.4",
|
||||
"eslint": "^2.9.0",
|
||||
"eventemitter2": "^0.4.14",
|
||||
"flow-bin": "^0.59.0",
|
||||
"gulp": "^3.8.10",
|
||||
"gulp-bump": "^0.1.13",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"gulp-uglify": "^1.1.0",
|
||||
"http-server": "^0.8.5",
|
||||
"istanbul": "^1.1.0-alpha.1",
|
||||
"jayson": "^1.2.2",
|
||||
@@ -55,8 +48,12 @@
|
||||
"mocha-in-sauce": "^0.0.1",
|
||||
"mocha-junit-reporter": "^1.9.1",
|
||||
"null-loader": "^0.1.1",
|
||||
"webpack": "^1.5.3",
|
||||
"yargs": "^1.3.1"
|
||||
"ts-loader": "^3.2.0",
|
||||
"ts-node": "^3.3.0",
|
||||
"typescript": "^2.6.1",
|
||||
"uglifyjs-webpack-plugin": "^1.1.4",
|
||||
"webpack": "^3.10.0",
|
||||
"yargs": "^8.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp",
|
||||
@@ -64,11 +61,11 @@
|
||||
"docgen": "node --harmony scripts/build_docs.js",
|
||||
"clean": "rm -rf dist/npm",
|
||||
"typecheck": "flow check",
|
||||
"compile": "babel -D --optional runtime -d dist/npm/ src/",
|
||||
"watch": "babel -w -D --optional runtime -d dist/npm/ src/",
|
||||
"compile": "mkdir -p dist/npm/common && cp -r src/common/schemas dist/npm/common/ && tsc",
|
||||
"watch": "tsc -w",
|
||||
"compile-with-source-maps": "babel -D --optional runtime -s -t -d dist/npm/ src/",
|
||||
"prepublish": "npm run clean && npm run compile",
|
||||
"test": "babel-node ./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha",
|
||||
"test": "istanbul cover _mocha",
|
||||
"coveralls": "cat ./coverage/lcov.info | coveralls",
|
||||
"lint": "if ! [ -f .eslintrc ]; then curl -o .eslintrc 'https://raw.githubusercontent.com/ripple/javascript-style-guide/es6/eslintrc'; echo 'parser: babel-eslint' >> .eslintrc; fi; eslint -c .eslintrc src/",
|
||||
"perf": "./scripts/perf_test.sh",
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import events from 'events'
|
||||
import {EventEmitter} from 'events'
|
||||
import {Connection, errors, validate} from './common'
|
||||
import * as server from './server/server'
|
||||
const connect = server.connect
|
||||
@@ -56,7 +54,7 @@ type APIOptions = {
|
||||
|
||||
// prevent access to non-validated ledger versions
|
||||
class RestrictedConnection extends Connection {
|
||||
request(request, timeout) {
|
||||
request(request: any, timeout?: number) {
|
||||
const ledger_index = request.ledger_index
|
||||
if (ledger_index !== undefined && ledger_index !== 'validated') {
|
||||
if (!_.isNumber(ledger_index) || ledger_index > this._ledgerVersion) {
|
||||
@@ -69,7 +67,7 @@ class RestrictedConnection extends Connection {
|
||||
}
|
||||
}
|
||||
|
||||
class RippleAPI extends events.EventEmitter {
|
||||
class RippleAPI extends EventEmitter {
|
||||
|
||||
_feeCushion: number
|
||||
connection: RestrictedConnection
|
||||
@@ -80,11 +78,11 @@ class RippleAPI extends events.EventEmitter {
|
||||
RangeSet,
|
||||
ledgerUtils,
|
||||
schemaValidator
|
||||
};
|
||||
}
|
||||
|
||||
constructor(options: APIOptions = {}) {
|
||||
validate.apiOptions(options)
|
||||
super()
|
||||
validate.apiOptions(options)
|
||||
this._feeCushion = options.feeCushion || 1.2
|
||||
const serverURL = options.server
|
||||
if (serverURL !== undefined) {
|
||||
@@ -107,51 +105,49 @@ class RippleAPI extends events.EventEmitter {
|
||||
this.connection = new RestrictedConnection(null, options)
|
||||
}
|
||||
}
|
||||
|
||||
connect = connect
|
||||
disconnect = disconnect
|
||||
isConnected = isConnected
|
||||
getServerInfo = getServerInfo
|
||||
getFee = getFee
|
||||
getLedgerVersion = getLedgerVersion
|
||||
|
||||
getTransaction = getTransaction
|
||||
getTransactions = getTransactions
|
||||
getTrustlines = getTrustlines
|
||||
getBalances = getBalances
|
||||
getBalanceSheet = getBalanceSheet
|
||||
getPaths = getPaths
|
||||
getOrders = getOrders
|
||||
getOrderbook = getOrderbook
|
||||
getSettings = getSettings
|
||||
getAccountInfo = getAccountInfo
|
||||
getPaymentChannel = getPaymentChannel
|
||||
getLedger = getLedger
|
||||
|
||||
preparePayment = preparePayment
|
||||
prepareTrustline = prepareTrustline
|
||||
prepareOrder = prepareOrder
|
||||
prepareOrderCancellation = prepareOrderCancellation
|
||||
prepareEscrowCreation = prepareEscrowCreation
|
||||
prepareEscrowExecution = prepareEscrowExecution
|
||||
prepareEscrowCancellation = prepareEscrowCancellation
|
||||
preparePaymentChannelCreate = preparePaymentChannelCreate
|
||||
preparePaymentChannelFund = preparePaymentChannelFund
|
||||
preparePaymentChannelClaim = preparePaymentChannelClaim
|
||||
prepareSettings = prepareSettings
|
||||
sign = sign
|
||||
combine = combine
|
||||
submit = submit
|
||||
|
||||
generateAddress = generateAddressAPI
|
||||
computeLedgerHash = computeLedgerHash
|
||||
signPaymentChannelClaim = signPaymentChannelClaim
|
||||
verifyPaymentChannelClaim = verifyPaymentChannelClaim
|
||||
errors = errors
|
||||
}
|
||||
|
||||
_.assign(RippleAPI.prototype, {
|
||||
connect,
|
||||
disconnect,
|
||||
isConnected,
|
||||
getServerInfo,
|
||||
getFee,
|
||||
getLedgerVersion,
|
||||
|
||||
getTransaction,
|
||||
getTransactions,
|
||||
getTrustlines,
|
||||
getBalances,
|
||||
getBalanceSheet,
|
||||
getPaths,
|
||||
getOrders,
|
||||
getOrderbook,
|
||||
getSettings,
|
||||
getAccountInfo,
|
||||
getPaymentChannel,
|
||||
getLedger,
|
||||
|
||||
preparePayment,
|
||||
prepareTrustline,
|
||||
prepareOrder,
|
||||
prepareOrderCancellation,
|
||||
prepareEscrowCreation,
|
||||
prepareEscrowExecution,
|
||||
prepareEscrowCancellation,
|
||||
preparePaymentChannelCreate,
|
||||
preparePaymentChannelFund,
|
||||
preparePaymentChannelClaim,
|
||||
prepareSettings,
|
||||
sign,
|
||||
combine,
|
||||
submit,
|
||||
|
||||
generateAddress: generateAddressAPI,
|
||||
computeLedgerHash,
|
||||
signPaymentChannelClaim,
|
||||
verifyPaymentChannelClaim,
|
||||
errors
|
||||
})
|
||||
|
||||
export {
|
||||
RippleAPI
|
||||
}
|
||||
@@ -3,11 +3,15 @@ import * as _ from 'lodash'
|
||||
import {RippleAPI} from './api'
|
||||
|
||||
class RippleAPIBroadcast extends RippleAPI {
|
||||
|
||||
// TODO: Should this default to 0, or null/undefined?
|
||||
ledgerVersion: number = 0
|
||||
private _apis: RippleAPI[]
|
||||
|
||||
constructor(servers, options) {
|
||||
super(options)
|
||||
this.ledgerVersion = 0
|
||||
|
||||
const apis = servers.map(server => new RippleAPI(
|
||||
const apis: RippleAPI[] = servers.map(server => new RippleAPI(
|
||||
_.assign({}, options, {server})
|
||||
))
|
||||
|
||||
@@ -21,14 +25,14 @@ class RippleAPIBroadcast extends RippleAPI {
|
||||
})
|
||||
|
||||
// connection methods must be overridden to apply to all api instances
|
||||
this.connect = function() {
|
||||
return Promise.all(apis.map(api => api.connect()))
|
||||
this.connect = async function() {
|
||||
await Promise.all(apis.map(api => api.connect()))
|
||||
}
|
||||
this.disconnect = function() {
|
||||
return Promise.all(apis.map(api => api.disconnect()))
|
||||
this.disconnect = async function() {
|
||||
await Promise.all(apis.map(api => api.disconnect()))
|
||||
}
|
||||
this.isConnected = function() {
|
||||
return _.every(apis.map(api => api.isConnected()))
|
||||
return apis.map(api => api.isConnected()).every(Boolean)
|
||||
}
|
||||
|
||||
// synchronous methods are all passed directly to the first api instance
|
||||
@@ -53,12 +57,11 @@ class RippleAPIBroadcast extends RippleAPI {
|
||||
}
|
||||
|
||||
getMethodNames() {
|
||||
const methodNames = []
|
||||
for (const name in RippleAPI.prototype) {
|
||||
if (RippleAPI.prototype.hasOwnProperty(name)) {
|
||||
if (typeof RippleAPI.prototype[name] === 'function') {
|
||||
methodNames.push(name)
|
||||
}
|
||||
const methodNames: string[] = []
|
||||
const rippleAPI = this._apis[0]
|
||||
for (const name of Object.getOwnPropertyNames(rippleAPI)) {
|
||||
if (typeof rippleAPI[name] === 'function') {
|
||||
methodNames.push(name)
|
||||
}
|
||||
}
|
||||
return methodNames
|
||||
@@ -1,18 +1,17 @@
|
||||
|
||||
|
||||
function setPrototypeOf(object, prototype) {
|
||||
// Object.setPrototypeOf not supported on Internet Explorer 9
|
||||
/* eslint-disable */
|
||||
Object.setPrototypeOf ? Object.setPrototypeOf(object, prototype) :
|
||||
// @ts-ignore: Specifically a fallback for IE9
|
||||
object.__proto__ = prototype
|
||||
/* eslint-enable */
|
||||
}
|
||||
|
||||
function getConstructorName(object) {
|
||||
function getConstructorName(object: Object): string {
|
||||
// hack for internet explorer
|
||||
return process.browser ?
|
||||
object.constructor.toString().match(/^function\s+([^(]*)/)[1] :
|
||||
object.constructor.name
|
||||
if (!object.constructor.name) {
|
||||
return object.constructor.toString().match(/^function\s+([^(]*)/)![1]
|
||||
}
|
||||
return object.constructor.name
|
||||
}
|
||||
|
||||
export {
|
||||
@@ -1,9 +1,7 @@
|
||||
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import events from 'events'
|
||||
import WebSocket from 'ws'
|
||||
import urlLib from 'url'
|
||||
import {EventEmitter} from 'events'
|
||||
import {parse as parseUrl} from 'url'
|
||||
import * as WebSocket from 'ws'
|
||||
import RangeSet from './rangeset'
|
||||
import {RippledError, DisconnectedError, NotConnectedError,
|
||||
TimeoutError, ResponseFormatError, ConnectionError,
|
||||
@@ -15,12 +13,48 @@ function isStreamMessageType(type) {
|
||||
type === 'path_find'
|
||||
}
|
||||
|
||||
class Connection extends events.EventEmitter {
|
||||
constructor(url, options = {}) {
|
||||
interface ConnectionOptions {
|
||||
trace?: boolean,
|
||||
proxy?: string
|
||||
proxyAuthorization?: string
|
||||
authorization?: string
|
||||
trustedCertificates?: string[]
|
||||
key?: string
|
||||
passphrase?: string
|
||||
certificate?: string
|
||||
timeout?: number
|
||||
}
|
||||
|
||||
class Connection extends EventEmitter {
|
||||
|
||||
private _url: string
|
||||
private _trace: boolean
|
||||
private _console?: Console
|
||||
private _proxyURL?: string
|
||||
private _proxyAuthorization?: string
|
||||
private _authorization?: string
|
||||
private _trustedCertificates?: string[]
|
||||
private _key?: string
|
||||
private _passphrase?: string
|
||||
private _certificate?: string
|
||||
private _timeout: number
|
||||
private _isReady: boolean = false
|
||||
private _ws: null|WebSocket = null
|
||||
protected _ledgerVersion: null|number = null
|
||||
private _availableLedgerVersions = new RangeSet()
|
||||
private _nextRequestID: number = 1
|
||||
private _retry: number = 0
|
||||
private _retryTimer: null|NodeJS.Timer = null
|
||||
private _onOpenErrorBound: null| null|((...args: any[]) => void) = null
|
||||
private _onUnexpectedCloseBound: null|((...args: any[]) => void) = null
|
||||
private _fee_base: null|number = null
|
||||
private _fee_ref: null|number = null
|
||||
|
||||
constructor(url, options: ConnectionOptions = {}) {
|
||||
super()
|
||||
this.setMaxListeners(Infinity)
|
||||
this._url = url
|
||||
this._trace = options.trace
|
||||
this._trace = options.trace || false
|
||||
if (this._trace) {
|
||||
// for easier unit testing
|
||||
this._console = console
|
||||
@@ -33,17 +67,6 @@ class Connection extends events.EventEmitter {
|
||||
this._passphrase = options.passphrase
|
||||
this._certificate = options.certificate
|
||||
this._timeout = options.timeout || (20 * 1000)
|
||||
this._isReady = false
|
||||
this._ws = null
|
||||
this._ledgerVersion = null
|
||||
this._availableLedgerVersions = new RangeSet()
|
||||
this._nextRequestID = 1
|
||||
this._retry = 0
|
||||
this._retryTimer = null
|
||||
this._onOpenErrorBound = null
|
||||
this._onUnexpectedCloseBound = null
|
||||
this._fee_base = null
|
||||
this._fee_ref = null
|
||||
}
|
||||
|
||||
_updateLedgerVersions(data) {
|
||||
@@ -63,7 +86,7 @@ class Connection extends events.EventEmitter {
|
||||
}
|
||||
|
||||
// return value is array of arguments to Connection.emit
|
||||
_parseMessage(message) {
|
||||
_parseMessage(message): [string, Object] | ['error', string, string, Object] {
|
||||
const data = JSON.parse(message)
|
||||
if (data.type === 'response') {
|
||||
if (!(Number.isInteger(data.id) && data.id >= 0)) {
|
||||
@@ -83,10 +106,10 @@ class Connection extends events.EventEmitter {
|
||||
}
|
||||
|
||||
_onMessage(message) {
|
||||
let parameters
|
||||
if (this._trace) {
|
||||
this._console.log(message)
|
||||
this._console!.log(message)
|
||||
}
|
||||
let parameters
|
||||
try {
|
||||
parameters = this._parseMessage(message)
|
||||
} catch (error) {
|
||||
@@ -95,7 +118,7 @@ class Connection extends events.EventEmitter {
|
||||
}
|
||||
// we don't want this inside the try/catch or exceptions in listener
|
||||
// will be caught
|
||||
this.emit(...parameters)
|
||||
this.emit.apply(this, parameters)
|
||||
}
|
||||
|
||||
get _state() {
|
||||
@@ -112,11 +135,11 @@ class Connection extends events.EventEmitter {
|
||||
|
||||
_onUnexpectedClose(beforeOpen, resolve, reject, code) {
|
||||
if (this._onOpenErrorBound) {
|
||||
this._ws.removeListener('error', this._onOpenErrorBound)
|
||||
this._ws!.removeListener('error', this._onOpenErrorBound)
|
||||
this._onOpenErrorBound = null
|
||||
}
|
||||
// just in case
|
||||
this._ws.removeAllListeners('open')
|
||||
this._ws!.removeAllListeners('open')
|
||||
this._ws = null
|
||||
this._isReady = false
|
||||
if (beforeOpen) {
|
||||
@@ -155,8 +178,10 @@ class Connection extends events.EventEmitter {
|
||||
}
|
||||
|
||||
_clearReconnectTimer() {
|
||||
clearTimeout(this._retryTimer)
|
||||
this._retryTimer = null
|
||||
if (this._retryTimer !== null) {
|
||||
clearTimeout(this._retryTimer)
|
||||
this._retryTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
_onOpen() {
|
||||
@@ -172,7 +197,7 @@ class Connection extends events.EventEmitter {
|
||||
command: 'subscribe',
|
||||
streams: ['ledger']
|
||||
}
|
||||
return this.request(request).then(data => {
|
||||
return this.request(request).then((data: any) => {
|
||||
if (_.isEmpty(data) || !data.ledger_index) {
|
||||
// rippled instance doesn't have validated ledgers
|
||||
return this._disconnect(false).then(() => {
|
||||
@@ -186,7 +211,8 @@ class Connection extends events.EventEmitter {
|
||||
|
||||
this._retry = 0
|
||||
this._ws.on('error', error => {
|
||||
if (process.browser && error && error.type === '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
|
||||
@@ -223,11 +249,11 @@ class Connection extends events.EventEmitter {
|
||||
reject(new NotConnectedError(error && error.message))
|
||||
}
|
||||
|
||||
_createWebSocket() {
|
||||
const options = {}
|
||||
_createWebSocket(): WebSocket {
|
||||
const options: WebSocket.ClientOptions = {}
|
||||
if (this._proxyURL !== undefined) {
|
||||
const parsedURL = urlLib.parse(this._url)
|
||||
const parsedProxyURL = urlLib.parse(this._proxyURL)
|
||||
const parsedURL = parseUrl(this._url)
|
||||
const parsedProxyURL = parseUrl(this._proxyURL)
|
||||
const proxyOverrides = _.omitBy({
|
||||
secureEndpoint: (parsedURL.protocol === 'wss:'),
|
||||
secureProxy: (parsedProxyURL.protocol === 'https:'),
|
||||
@@ -337,7 +363,7 @@ class Connection extends events.EventEmitter {
|
||||
return this.disconnect().then(() => this.connect())
|
||||
}
|
||||
|
||||
_whenReady(promise) {
|
||||
_whenReady<T>(promise: Promise<T>): Promise<T> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._shouldBeConnected) {
|
||||
reject(new NotConnectedError())
|
||||
@@ -349,44 +375,44 @@ class Connection extends events.EventEmitter {
|
||||
})
|
||||
}
|
||||
|
||||
getLedgerVersion() {
|
||||
return this._whenReady(Promise.resolve(this._ledgerVersion))
|
||||
getLedgerVersion(): Promise<number> {
|
||||
return this._whenReady(Promise.resolve(this._ledgerVersion!))
|
||||
}
|
||||
|
||||
hasLedgerVersions(lowLedgerVersion, highLedgerVersion) {
|
||||
hasLedgerVersions(lowLedgerVersion, highLedgerVersion): Promise<boolean> {
|
||||
return this._whenReady(Promise.resolve(
|
||||
this._availableLedgerVersions.containsRange(
|
||||
lowLedgerVersion, highLedgerVersion || this._ledgerVersion)))
|
||||
}
|
||||
|
||||
hasLedgerVersion(ledgerVersion) {
|
||||
hasLedgerVersion(ledgerVersion): Promise<boolean> {
|
||||
return this.hasLedgerVersions(ledgerVersion, ledgerVersion)
|
||||
}
|
||||
|
||||
getFeeBase() {
|
||||
getFeeBase(): Promise<number> {
|
||||
return this._whenReady(Promise.resolve(Number(this._fee_base)))
|
||||
}
|
||||
|
||||
getFeeRef() {
|
||||
getFeeRef(): Promise<number> {
|
||||
return this._whenReady(Promise.resolve(Number(this._fee_ref)))
|
||||
}
|
||||
|
||||
_send(message) {
|
||||
_send(message: string): Promise<void> {
|
||||
if (this._trace) {
|
||||
this._console.log(message)
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this._ws.send(message, undefined, (error, result) => {
|
||||
this._ws.send(message, undefined, error => {
|
||||
if (error) {
|
||||
reject(new DisconnectedError(error.message))
|
||||
} else {
|
||||
resolve(result)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
request(request, timeout) {
|
||||
request(request, timeout?: number): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._shouldBeConnected) {
|
||||
reject(new NotConnectedError())
|
||||
@@ -1,33 +1,28 @@
|
||||
|
||||
import util from 'util'
|
||||
import {inspect} from 'util'
|
||||
import * as browserHacks from './browser-hacks'
|
||||
|
||||
// this is needed because extending builtins doesn't work in babel 6.x
|
||||
function extendableBuiltin(cls) {
|
||||
function ExtendableBuiltin() {
|
||||
cls.apply(this, arguments)
|
||||
}
|
||||
ExtendableBuiltin.prototype = Object.create(cls.prototype)
|
||||
browserHacks.setPrototypeOf(ExtendableBuiltin, cls)
|
||||
return ExtendableBuiltin
|
||||
}
|
||||
class RippleError extends Error {
|
||||
|
||||
class RippleError extends extendableBuiltin(Error) {
|
||||
constructor(message, data) {
|
||||
name: string
|
||||
message: string
|
||||
data?: any
|
||||
|
||||
constructor(message = '', data?: any) {
|
||||
super(message)
|
||||
|
||||
this.name = browserHacks.getConstructorName(this)
|
||||
this.message = message
|
||||
this.data = data
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor.name)
|
||||
Error.captureStackTrace(this, this.constructor)
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
let result = '[' + this.name + '(' + this.message
|
||||
if (this.data) {
|
||||
result += ', ' + util.inspect(this.data)
|
||||
result += ', ' + inspect(this.data)
|
||||
}
|
||||
result += ')]'
|
||||
return result
|
||||
@@ -62,21 +57,21 @@ class ResponseFormatError extends ConnectionError {}
|
||||
class ValidationError extends RippleError {}
|
||||
|
||||
class NotFoundError extends RippleError {
|
||||
constructor(message) {
|
||||
super(message || 'Not found')
|
||||
constructor(message = 'Not found') {
|
||||
super(message)
|
||||
}
|
||||
}
|
||||
|
||||
class MissingLedgerHistoryError extends RippleError {
|
||||
constructor(message) {
|
||||
constructor(message?: string) {
|
||||
super(message || 'Server is missing ledger history in the specified range')
|
||||
}
|
||||
}
|
||||
|
||||
class PendingLedgerVersionError extends RippleError {
|
||||
constructor(message) {
|
||||
super(message || 'maxLedgerVersion is greater than server\'s'
|
||||
+ ' most recent validated ledger')
|
||||
constructor(message?: string) {
|
||||
super(message || 'maxLedgerVersion is greater than server\'s most recent ' +
|
||||
' validated ledger')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
|
||||
function mergeIntervals(intervals: Array<[number, number]>) {
|
||||
const stack = [[-Infinity, -Infinity]]
|
||||
_.forEach(_.sortBy(intervals, x => x[0]), interval => {
|
||||
const lastInterval = stack.pop()
|
||||
type Interval = [number, number]
|
||||
|
||||
function mergeIntervals(intervals: Interval[]): Interval[] {
|
||||
const stack: Interval[] = [[-Infinity, -Infinity]]
|
||||
_.sortBy(intervals, x => x[0]).forEach(interval => {
|
||||
const lastInterval: Interval = stack.pop()!
|
||||
if (interval[0] <= lastInterval[1] + 1) {
|
||||
stack.push([lastInterval[0], Math.max(interval[1], lastInterval[1])])
|
||||
} else {
|
||||
@@ -1,9 +1,6 @@
|
||||
// flow is disabled for this file until support for requiring json is added:
|
||||
// https://github.com/facebook/flow/issues/167
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import assert from 'assert'
|
||||
import {Validator} from 'jsonschema'
|
||||
import * as assert from 'assert'
|
||||
const {Validator} = require('jsonschema')
|
||||
import {ValidationError} from './errors'
|
||||
import {isValidAddress} from 'ripple-address-codec'
|
||||
import {isValidSecret} from './utils'
|
||||
@@ -111,20 +108,20 @@ function loadSchemas() {
|
||||
require('./schemas/input/verify-payment-channel-claim.json'),
|
||||
require('./schemas/input/combine.json')
|
||||
]
|
||||
const titles = _.map(schemas, schema => schema.title)
|
||||
const duplicates = _.keys(_.pick(_.countBy(titles), count => count > 1))
|
||||
const titles = schemas.map(schema => schema.title)
|
||||
const duplicates = _.keys(_.pickBy(_.countBy(titles), count => count > 1))
|
||||
assert(duplicates.length === 0, 'Duplicate schemas for: ' + duplicates)
|
||||
const v = new Validator()
|
||||
const validator = new Validator()
|
||||
// Register custom format validators that ignore undefined instances
|
||||
// since jsonschema will still call the format validator on a missing
|
||||
// (optional) property
|
||||
v.customFormats.address = function(instance) {
|
||||
validator.customFormats.address = function(instance) {
|
||||
if (instance === undefined) {
|
||||
return true
|
||||
}
|
||||
return isValidAddress(instance)
|
||||
}
|
||||
v.customFormats.secret = function(instance) {
|
||||
validator.customFormats.secret = function(instance) {
|
||||
if (instance === undefined) {
|
||||
return true
|
||||
}
|
||||
@@ -132,19 +129,19 @@ function loadSchemas() {
|
||||
}
|
||||
|
||||
// Register under the root URI '/'
|
||||
_.forEach(schemas, schema => v.addSchema(schema, '/' + schema.title))
|
||||
return v
|
||||
_.forEach(schemas, schema => validator.addSchema(schema, '/' + schema.title))
|
||||
return validator
|
||||
}
|
||||
|
||||
const v = loadSchemas()
|
||||
const schemaValidator = loadSchemas()
|
||||
|
||||
function schemaValidate(schemaName: string, object: any): void {
|
||||
// Lookup under the root URI '/'
|
||||
const schema = v.getSchema('/' + schemaName)
|
||||
const schema = schemaValidator.getSchema('/' + schemaName)
|
||||
if (schema === undefined) {
|
||||
throw new ValidationError('no schema for ' + schemaName)
|
||||
}
|
||||
const result = v.validate(object, schema)
|
||||
const result = schemaValidator.validate(object, schema)
|
||||
if (!result.valid) {
|
||||
throw new ValidationError(result.errors.join())
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as _ from 'lodash'
|
||||
import {convertKeysFromSnakeCaseToCamelCase} from './utils'
|
||||
import type Connection from './connection'
|
||||
import Connection from './connection'
|
||||
|
||||
export type GetServerInfoResponse = {
|
||||
buildVersion: string,
|
||||
@@ -60,16 +60,19 @@ function getServerInfo(connection: Connection): Promise<GetServerInfoResponse> {
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: This was originally annotated to return a number, but actually
|
||||
// returned a toString'ed number. Should this actually be returning a number?
|
||||
function computeFeeFromServerInfo(cushion: number,
|
||||
serverInfo: GetServerInfoResponse
|
||||
): number {
|
||||
): string {
|
||||
return (Number(serverInfo.validatedLedger.baseFeeXRP)
|
||||
* Number(serverInfo.loadFactor) * cushion).toString()
|
||||
}
|
||||
|
||||
function getFee(connection: Connection, cushion: number) {
|
||||
return getServerInfo(connection).then(
|
||||
_.partial(computeFeeFromServerInfo, cushion))
|
||||
function getFee(connection: Connection, cushion: number): Promise<string> {
|
||||
return getServerInfo(connection).then(serverInfo => {
|
||||
return computeFeeFromServerInfo(cushion, serverInfo)
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
@@ -1,5 +1,3 @@
|
||||
/* @flow */
|
||||
|
||||
|
||||
export type RippledAmountIOU = {
|
||||
currency: string,
|
||||
@@ -13,6 +11,7 @@ export type RippledAmount = string | RippledAmountIOU
|
||||
export type Amount = {
|
||||
value: string,
|
||||
currency: string,
|
||||
issuer?: string,
|
||||
counterparty?: string
|
||||
}
|
||||
|
||||
@@ -21,12 +20,14 @@ export type Amount = {
|
||||
export type LaxLaxAmount = {
|
||||
currency: string,
|
||||
value?: string,
|
||||
issuer?: string,
|
||||
counterparty?: string
|
||||
}
|
||||
|
||||
// A currency-counterparty pair, or just currency if it's XRP
|
||||
export type Issue = {
|
||||
currency: string,
|
||||
issuer?: string,
|
||||
counterparty?: string
|
||||
}
|
||||
|
||||
@@ -53,3 +54,10 @@ export type Memo = {
|
||||
format?: string,
|
||||
data?: string
|
||||
}
|
||||
|
||||
export type ApiMemo = {
|
||||
MemoData?: string,
|
||||
MemoType?: string,
|
||||
MemoFormat?: string
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import {deriveKeypair} from 'ripple-keypairs'
|
||||
const {deriveKeypair} = require('ripple-keypairs')
|
||||
|
||||
import type {Amount, RippledAmount} from './types'
|
||||
import {Amount, RippledAmount} from './types'
|
||||
|
||||
function isValidSecret(secret: string): boolean {
|
||||
try {
|
||||
@@ -27,7 +25,6 @@ function toRippledAmount(amount: Amount): RippledAmount {
|
||||
if (amount.currency === 'XRP') {
|
||||
return xrpToDrops(amount.value)
|
||||
}
|
||||
// $FlowFixMe: amount.issuer is not a Amount type property. Safe to remove?
|
||||
return {
|
||||
currency: amount.currency,
|
||||
issuer: amount.counterparty ? amount.counterparty :
|
||||
@@ -53,8 +50,8 @@ function convertKeysFromSnakeCaseToCamelCase(obj: any): any {
|
||||
return obj
|
||||
}
|
||||
|
||||
function removeUndefined(obj: Object): Object {
|
||||
return _.omitBy(obj, _.isUndefined)
|
||||
function removeUndefined<T extends object>(obj: T): T {
|
||||
return _.omitBy(obj, _.isUndefined) as T
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1,5 +1,3 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import {ValidationError} from './errors'
|
||||
import {schemaValidate} from './schema-validator'
|
||||
@@ -1,18 +1,31 @@
|
||||
import {EventEmitter} from 'events'
|
||||
|
||||
|
||||
import events from 'events'
|
||||
|
||||
function unsused() {}
|
||||
// Define the global WebSocket class found on the native browser
|
||||
declare class WebSocket {
|
||||
onclose?: Function
|
||||
onopen?: Function
|
||||
onerror?: Function
|
||||
onmessage?: Function
|
||||
readyState: number
|
||||
constructor(url: string)
|
||||
close()
|
||||
send(message: string)
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides `EventEmitter` interface for native browser `WebSocket`,
|
||||
* same, as `ws` package provides.
|
||||
*/
|
||||
class WSWrapper extends events.EventEmitter {
|
||||
constructor(url, protocols = null, websocketOptions = {}) {
|
||||
class WSWrapper extends EventEmitter {
|
||||
|
||||
private _ws: WebSocket
|
||||
static CONNECTING = 0
|
||||
static OPEN = 1
|
||||
static CLOSING = 2
|
||||
static CLOSED = 3
|
||||
|
||||
constructor(url, _protocols: any, _websocketOptions: any) {
|
||||
super()
|
||||
unsused(protocols)
|
||||
unsused(websocketOptions)
|
||||
this.setMaxListeners(Infinity)
|
||||
|
||||
this._ws = new WebSocket(url)
|
||||
@@ -50,10 +63,5 @@ class WSWrapper extends events.EventEmitter {
|
||||
|
||||
}
|
||||
|
||||
WSWrapper.CONNECTING = 0
|
||||
WSWrapper.OPEN = 1
|
||||
WSWrapper.CLOSING = 2
|
||||
WSWrapper.CLOSED = 3
|
||||
|
||||
export default WSWrapper
|
||||
export = WSWrapper
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable new-cap */
|
||||
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import * as _ from 'lodash'
|
||||
import jayson from 'jayson'
|
||||
import {RippleAPI} from './api'
|
||||
@@ -1,5 +1,3 @@
|
||||
/* @flow */
|
||||
|
||||
import {validate, removeUndefined, dropsToXrp} from '../common'
|
||||
|
||||
type AccountData = {
|
||||
@@ -1,9 +1,7 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
import {validate} from '../common'
|
||||
import type {Amount} from '../common/types'
|
||||
import {Amount} from '../common/types'
|
||||
|
||||
type BalanceSheetOptions = {
|
||||
excludeAddresses?: Array<string>,
|
||||
@@ -20,7 +18,7 @@ type GetBalanceSheet = {
|
||||
}
|
||||
|
||||
function formatBalanceSheet(balanceSheet): GetBalanceSheet {
|
||||
const result = {}
|
||||
const result: GetBalanceSheet = {}
|
||||
|
||||
if (!_.isUndefined(balanceSheet.balances)) {
|
||||
result.balances = []
|
||||
@@ -39,8 +37,10 @@ function formatBalanceSheet(balanceSheet): GetBalanceSheet {
|
||||
})
|
||||
}
|
||||
if (!_.isUndefined(balanceSheet.obligations)) {
|
||||
result.obligations = _.map(balanceSheet.obligations, (value, currency) =>
|
||||
({currency, value}))
|
||||
result.obligations = _.map(
|
||||
balanceSheet.obligations as {[key: string]: string},
|
||||
(value, currency) => ({currency, value})
|
||||
)
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -1,9 +1,7 @@
|
||||
/* @flow */
|
||||
|
||||
import * as utils from './utils'
|
||||
import {validate} from '../common'
|
||||
import type {Connection} from '../common'
|
||||
import type {TrustlinesOptions, Trustline} from './trustlines-types'
|
||||
import {Connection} from '../common'
|
||||
import {TrustlinesOptions, Trustline} from './trustlines-types'
|
||||
|
||||
|
||||
type Balance = {
|
||||
@@ -1,8 +1,6 @@
|
||||
/* @flow */
|
||||
|
||||
import {validate} from '../common'
|
||||
import parseLedger from './parse/ledger'
|
||||
import type {GetLedger} from './types'
|
||||
import {GetLedger} from './types'
|
||||
|
||||
type LedgerOptions = {
|
||||
ledgerVersion?: number,
|
||||
@@ -1,12 +1,10 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
import parseOrderbookOrder from './parse/orderbook-order'
|
||||
import {validate} from '../common'
|
||||
import type {Connection} from '../common'
|
||||
import type {OrdersOptions, OrderSpecification} from './types'
|
||||
import type {Amount, Issue} from '../common/types'
|
||||
import {Connection} from '../common'
|
||||
import {OrdersOptions, OrderSpecification} from './types'
|
||||
import {Amount, Issue} from '../common/types'
|
||||
|
||||
type Orderbook = {
|
||||
base: Issue,
|
||||
@@ -36,21 +34,25 @@ type GetOrderbook = {
|
||||
// account is to specify a "perspective", which affects which unfunded offers
|
||||
// are returned
|
||||
function getBookOffers(connection: Connection, account: string,
|
||||
ledgerVersion?: number, limit?: number, takerGets: Issue,
|
||||
ledgerVersion: number|undefined, limit: number|undefined, takerGets: Issue,
|
||||
takerPays: Issue
|
||||
): Promise<Object[]> {
|
||||
return connection.request(utils.renameCounterpartyToIssuerInOrder({
|
||||
command: 'book_offers',
|
||||
const orderData = utils.renameCounterpartyToIssuerInOrder({
|
||||
taker_gets: takerGets,
|
||||
taker_pays: takerPays,
|
||||
taker_pays: takerPays
|
||||
})
|
||||
return connection.request({
|
||||
command: 'book_offers',
|
||||
taker_gets: orderData.taker_gets,
|
||||
taker_pays: orderData.taker_pays,
|
||||
ledger_index: ledgerVersion || 'validated',
|
||||
limit: limit,
|
||||
taker: account
|
||||
})).then(data => data.offers)
|
||||
}).then(data => data.offers)
|
||||
}
|
||||
|
||||
function isSameIssue(a: Amount, b: Amount) {
|
||||
return a.currency === b.currency && a.counterparty === b.counterparty
|
||||
return a.currency === b.currency && a.issuer === b.issuer
|
||||
}
|
||||
|
||||
function directionFilter(direction: string, order: OrderbookItem) {
|
||||
@@ -1,11 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
import {validate} from '../common'
|
||||
import type {Connection} from '../common'
|
||||
import {Connection} from '../common'
|
||||
import parseAccountOrder from './parse/account-order'
|
||||
import type {OrdersOptions, Order} from './types'
|
||||
import {OrdersOptions, Order} from './types'
|
||||
|
||||
type GetOrders = Array<Order>
|
||||
|
||||
@@ -18,12 +16,10 @@ function requestAccountOffers(connection: Connection, address: string,
|
||||
marker: marker,
|
||||
limit: utils.clamp(limit, 10, 400),
|
||||
ledger_index: ledgerVersion
|
||||
}).then(data => {
|
||||
return {
|
||||
marker: data.marker,
|
||||
results: data.offers.map(_.partial(parseAccountOrder, address))
|
||||
}
|
||||
})
|
||||
}).then(data => ({
|
||||
marker: data.marker,
|
||||
results: data.offers.map(_.partial(parseAccountOrder, address))
|
||||
}))
|
||||
}
|
||||
|
||||
function getOrders(address: string, options: OrdersOptions = {}
|
||||
@@ -1,5 +1,3 @@
|
||||
/* @flow */
|
||||
|
||||
import BigNumber from 'bignumber.js'
|
||||
import parseAmount from './amount'
|
||||
import {parseTimestamp, adjustQualityForXRP} from './utils'
|
||||
@@ -14,7 +12,7 @@ function computeQuality(takerGets, takerPays) {
|
||||
|
||||
// rippled 'account_offers' returns a different format for orders than 'tx'
|
||||
// the flags are also different
|
||||
function parseAccountOrder(address: string, order: Object): Object {
|
||||
function parseAccountOrder(address: string, order: any): Object {
|
||||
const direction = (order.flags & orderFlags.Sell) === 0 ? 'buy' : 'sell'
|
||||
const takerGetsAmount = parseAmount(order.taker_gets)
|
||||
const takerPaysAmount = parseAmount(order.taker_pays)
|
||||
@@ -1,11 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
import {parseQuality} from './utils'
|
||||
import {removeUndefined} from '../../common'
|
||||
|
||||
type Trustline = {
|
||||
account: string, limit: number, currency: string, quality_in: ?number,
|
||||
quality_out: ?number, no_ripple: boolean, freeze: boolean,
|
||||
account: string, limit: number, currency: string, quality_in: number|null,
|
||||
quality_out: number|null, no_ripple: boolean, freeze: boolean,
|
||||
authorized: boolean, limit_peer: string, no_ripple_peer: boolean,
|
||||
freeze_peer: boolean, peer_authorized: boolean, balance: any
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
function parseAmendment(tx: Object) {
|
||||
function parseAmendment(tx: any) {
|
||||
return {
|
||||
amendment: tx.Amendment
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
/* @flow */
|
||||
|
||||
import * as common from '../../common'
|
||||
import type {Amount, RippledAmount} from '../../common/types'
|
||||
import {Amount, RippledAmount} from '../../common/types'
|
||||
|
||||
|
||||
function parseAmount(amount: RippledAmount): Amount {
|
||||
@@ -1,8 +1,6 @@
|
||||
/* @flow */
|
||||
import * as assert from 'assert'
|
||||
|
||||
import assert from 'assert'
|
||||
|
||||
function parseOrderCancellation(tx: Object): Object {
|
||||
function parseOrderCancellation(tx: any): Object {
|
||||
assert(tx.TransactionType === 'OfferCancel')
|
||||
return {
|
||||
orderSequence: tx.OfferSequence
|
||||
@@ -1,10 +1,8 @@
|
||||
/* @flow */
|
||||
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import {parseMemos} from './utils'
|
||||
import {removeUndefined} from '../../common'
|
||||
|
||||
function parseEscrowCancellation(tx: Object): Object {
|
||||
function parseEscrowCancellation(tx: any): Object {
|
||||
assert(tx.TransactionType === 'EscrowCancel')
|
||||
|
||||
return removeUndefined({
|
||||
@@ -1,11 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import parseAmount from './amount'
|
||||
import {parseTimestamp, parseMemos} from './utils'
|
||||
import {removeUndefined} from '../../common'
|
||||
|
||||
function parseEscrowCreation(tx: Object): Object {
|
||||
function parseEscrowCreation(tx: any): Object {
|
||||
assert(tx.TransactionType === 'EscrowCreate')
|
||||
|
||||
return removeUndefined({
|
||||
@@ -1,10 +1,8 @@
|
||||
/* @flow */
|
||||
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import {parseMemos} from './utils'
|
||||
import {removeUndefined} from '../../common'
|
||||
|
||||
function parseEscrowExecution(tx: Object): Object {
|
||||
function parseEscrowExecution(tx: any): Object {
|
||||
assert(tx.TransactionType === 'EscrowFinish')
|
||||
|
||||
return removeUndefined({
|
||||
@@ -2,7 +2,7 @@
|
||||
import BigNumber from 'bignumber.js'
|
||||
import {dropsToXrp} from '../../common'
|
||||
|
||||
function parseFeeUpdate(tx: Object) {
|
||||
function parseFeeUpdate(tx: any) {
|
||||
const baseFeeDrops = (new BigNumber(tx.BaseFee, 16)).toString()
|
||||
return {
|
||||
baseFeeXRP: dropsToXrp(baseFeeDrops),
|
||||
@@ -1,5 +1,3 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import {constants} from '../../common'
|
||||
@@ -15,8 +13,8 @@ function parseField(info, value) {
|
||||
return value
|
||||
}
|
||||
|
||||
function parseFields(data: Object): Object {
|
||||
const settings = {}
|
||||
function parseFields(data: any): Object {
|
||||
const settings: any = {}
|
||||
for (const fieldName in AccountFields) {
|
||||
const fieldValue = data[fieldName]
|
||||
if (fieldValue !== undefined) {
|
||||
@@ -39,7 +37,7 @@ function parseFields(data: Object): Object {
|
||||
if (data.signer_lists[0].SignerEntries) {
|
||||
settings.signers.weights = _.map(
|
||||
data.signer_lists[0].SignerEntries,
|
||||
entry => {
|
||||
(entry: any) => {
|
||||
return {
|
||||
address: entry.SignerEntry.Account,
|
||||
weight: entry.SignerEntry.SignerWeight
|
||||
@@ -1,9 +1,7 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import {removeUndefined, rippleTimeToISO8601} from '../../common'
|
||||
import parseTransaction from './transaction'
|
||||
import type {GetLedger} from '../types'
|
||||
import {GetLedger} from '../types'
|
||||
|
||||
function parseTransactionWrapper(ledgerVersion, tx) {
|
||||
const transaction = _.assign({}, _.omit(tx, 'metaData'), {
|
||||
@@ -41,9 +39,9 @@ function parseState(state) {
|
||||
return {rawState: JSON.stringify(state)}
|
||||
}
|
||||
|
||||
function parseLedger(ledger: Object): GetLedger {
|
||||
function parseLedger(ledger: any): GetLedger {
|
||||
const ledgerVersion = parseInt(ledger.ledger_index || ledger.seqNum, 10)
|
||||
return removeUndefined(_.assign({
|
||||
return removeUndefined(Object.assign({
|
||||
stateHash: ledger.account_hash,
|
||||
closeTime: rippleTimeToISO8601(ledger.close_time),
|
||||
closeTimeResolution: ledger.close_time_resolution,
|
||||
@@ -1,12 +1,10 @@
|
||||
/* @flow */
|
||||
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import {parseTimestamp} from './utils'
|
||||
import parseAmount from './amount'
|
||||
import {removeUndefined, txFlags} from '../../common'
|
||||
const flags = txFlags.OfferCreate
|
||||
|
||||
function parseOrder(tx: Object): Object {
|
||||
function parseOrder(tx: any): Object {
|
||||
assert(tx.TransactionType === 'OfferCreate')
|
||||
|
||||
const direction = (tx.Flags & flags.Sell) === 0 ? 'buy' : 'sell'
|
||||
@@ -1,5 +1,3 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import {parseTimestamp, adjustQualityForXRP} from './utils'
|
||||
import {removeUndefined} from '../../common'
|
||||
@@ -7,7 +5,7 @@ import {removeUndefined} from '../../common'
|
||||
import {orderFlags} from './flags'
|
||||
import parseAmount from './amount'
|
||||
|
||||
function parseOrderbookOrder(order: Object): Object {
|
||||
function parseOrderbookOrder(order: any): Object {
|
||||
const direction = (order.Flags & orderFlags.Sell) === 0 ? 'buy' : 'sell'
|
||||
const takerGetsAmount = parseAmount(order.TakerGets)
|
||||
const takerPaysAmount = parseAmount(order.TakerPays)
|
||||
@@ -1,9 +1,7 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import parseAmount from './amount'
|
||||
import type {Amount, RippledAmount} from '../../common/types'
|
||||
import type {GetPaths, RippledPathsResponse} from '../pathfind-types'
|
||||
import {Amount, RippledAmount} from '../../common/types'
|
||||
import {Path, GetPaths, RippledPathsResponse} from '../pathfind-types'
|
||||
|
||||
function parsePaths(paths) {
|
||||
return paths.map(steps => steps.map(step =>
|
||||
@@ -15,7 +13,8 @@ function removeAnyCounterpartyEncoding(address: string, amount: Amount) {
|
||||
_.omit(amount, 'counterparty') : amount
|
||||
}
|
||||
|
||||
function createAdjustment(address: string, adjustmentWithoutAddress: Object) {
|
||||
function createAdjustment(
|
||||
address: string, adjustmentWithoutAddress: Object): any {
|
||||
const amountKey = _.keys(adjustmentWithoutAddress)[0]
|
||||
const amount = adjustmentWithoutAddress[amountKey]
|
||||
return _.set({address: address}, amountKey,
|
||||
@@ -23,8 +22,8 @@ function createAdjustment(address: string, adjustmentWithoutAddress: Object) {
|
||||
}
|
||||
|
||||
function parseAlternative(sourceAddress: string, destinationAddress: string,
|
||||
destinationAmount: RippledAmount, alternative: Object
|
||||
) {
|
||||
destinationAmount: RippledAmount, alternative: any
|
||||
): Path {
|
||||
// we use "maxAmount"/"minAmount" here so that the result can be passed
|
||||
// directly to preparePayment
|
||||
const amounts = (alternative.destination_amount !== undefined) ?
|
||||
@@ -44,8 +43,8 @@ function parsePathfind(pathfindResult: RippledPathsResponse): GetPaths {
|
||||
const sourceAddress = pathfindResult.source_account
|
||||
const destinationAddress = pathfindResult.destination_account
|
||||
const destinationAmount = pathfindResult.destination_amount
|
||||
return pathfindResult.alternatives.map(_.partial(parseAlternative,
|
||||
sourceAddress, destinationAddress, destinationAmount))
|
||||
return pathfindResult.alternatives.map(alt =>
|
||||
parseAlternative(sourceAddress, destinationAddress, destinationAmount, alt))
|
||||
}
|
||||
|
||||
export default parsePathfind
|
||||
@@ -1,11 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import {removeUndefined, txFlags} from '../../common'
|
||||
import parseAmount from './amount'
|
||||
const claimFlags = txFlags.PaymentChannelClaim
|
||||
|
||||
function parsePaymentChannelClaim(tx: Object): Object {
|
||||
function parsePaymentChannelClaim(tx: any): Object {
|
||||
assert(tx.TransactionType === 'PaymentChannelClaim')
|
||||
|
||||
return removeUndefined({
|
||||
@@ -1,11 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import {parseTimestamp} from './utils'
|
||||
import {removeUndefined} from '../../common'
|
||||
import parseAmount from './amount'
|
||||
|
||||
function parsePaymentChannelCreate(tx: Object): Object {
|
||||
function parsePaymentChannelCreate(tx: any): Object {
|
||||
assert(tx.TransactionType === 'PaymentChannelCreate')
|
||||
|
||||
return removeUndefined({
|
||||
@@ -1,11 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import {parseTimestamp} from './utils'
|
||||
import {removeUndefined} from '../../common'
|
||||
import parseAmount from './amount'
|
||||
|
||||
function parsePaymentChannelFund(tx: Object): Object {
|
||||
function parsePaymentChannelFund(tx: any): Object {
|
||||
assert(tx.TransactionType === 'PaymentChannelFund')
|
||||
|
||||
return removeUndefined({
|
||||
@@ -1,23 +1,49 @@
|
||||
/* @flow */
|
||||
|
||||
import {parseTimestamp} from './utils'
|
||||
import {removeUndefined, dropsToXrp} from '../../common'
|
||||
|
||||
|
||||
export type PaymentChannel = {
|
||||
Sequence: number,
|
||||
Account: string,
|
||||
Amount: string,
|
||||
Balance: string,
|
||||
PublicKey: number,
|
||||
Destination: string,
|
||||
SettleDelay: number,
|
||||
Expiration?: number,
|
||||
CancelAfter?: number,
|
||||
SourceTag?: number,
|
||||
DestinationTag?: number,
|
||||
OwnerNode: string,
|
||||
LedgerEntryType: string,
|
||||
PreviousTxnID: string,
|
||||
PreviousTxnLgrSeq: number,
|
||||
index: string
|
||||
}
|
||||
|
||||
export type LedgerEntryResponse = {
|
||||
node: PaymentChannel,
|
||||
ledger_current_index?: number,
|
||||
ledger_hash?: string,
|
||||
ledger_index: number,
|
||||
validated: boolean
|
||||
}
|
||||
|
||||
type PaymentChannelResponse = {
|
||||
account: string,
|
||||
balance: string,
|
||||
publicKey: number,
|
||||
destination: string,
|
||||
settleDelay: number,
|
||||
expiration?: number,
|
||||
cancelAfter?: number,
|
||||
expiration?: string,
|
||||
cancelAfter?: string,
|
||||
sourceTag?: number,
|
||||
destinationTag?: number,
|
||||
previousAffectingTransactionID: string,
|
||||
previousAffectingTransactionLedgerVersion: number
|
||||
}
|
||||
|
||||
function parsePaymentChannel(data: Object): PaymentChannelResponse {
|
||||
function parsePaymentChannel(data: PaymentChannel): PaymentChannelResponse {
|
||||
return removeUndefined({
|
||||
account: data.Account,
|
||||
amount: dropsToXrp(data.Amount),
|
||||
@@ -1,7 +1,5 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import * as utils from './utils'
|
||||
import {txFlags, removeUndefined} from '../../common'
|
||||
import parseAmount from './amount'
|
||||
@@ -19,7 +17,7 @@ function removeGenericCounterparty(amount, address) {
|
||||
_.omit(amount, 'counterparty') : amount
|
||||
}
|
||||
|
||||
function parsePayment(tx: Object): Object {
|
||||
function parsePayment(tx: any): Object {
|
||||
assert(tx.TransactionType === 'Payment')
|
||||
|
||||
const source = {
|
||||
@@ -1,20 +1,18 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import {constants} from '../../common'
|
||||
const AccountFlags = constants.AccountFlags
|
||||
import parseFields from './fields'
|
||||
|
||||
function getAccountRootModifiedNode(tx: Object) {
|
||||
function getAccountRootModifiedNode(tx: any) {
|
||||
const modifiedNodes = tx.meta.AffectedNodes.filter(node =>
|
||||
node.ModifiedNode.LedgerEntryType === 'AccountRoot')
|
||||
assert(modifiedNodes.length === 1)
|
||||
return modifiedNodes[0].ModifiedNode
|
||||
}
|
||||
|
||||
function parseFlags(tx: Object) {
|
||||
const settings = {}
|
||||
function parseFlags(tx: any): any {
|
||||
const settings: any = {}
|
||||
if (tx.TransactionType !== 'AccountSet') {
|
||||
return settings
|
||||
}
|
||||
@@ -51,7 +49,7 @@ function parseFlags(tx: Object) {
|
||||
return settings
|
||||
}
|
||||
|
||||
function parseSettings(tx: Object) {
|
||||
function parseSettings(tx: any) {
|
||||
const txType = tx.TransactionType
|
||||
assert(txType === 'AccountSet' || txType === 'SetRegularKey' ||
|
||||
txType === 'SignerListSet')
|
||||
@@ -1,6 +1,4 @@
|
||||
/* @flow */
|
||||
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import {parseOutcome} from './utils'
|
||||
import {removeUndefined} from '../../common'
|
||||
import parsePayment from './payment'
|
||||
@@ -38,7 +36,7 @@ function parseTransactionType(type) {
|
||||
return mapping[type] || null
|
||||
}
|
||||
|
||||
function parseTransaction(tx: Object): Object {
|
||||
function parseTransaction(tx: any): any {
|
||||
const type = parseTransactionType(tx.TransactionType)
|
||||
const mapping = {
|
||||
'payment': parsePayment,
|
||||
@@ -55,7 +53,7 @@ function parseTransaction(tx: Object): Object {
|
||||
'feeUpdate': parseFeeUpdate,
|
||||
'amendment': parseAmendment
|
||||
}
|
||||
const parser: Function = (mapping: Object)[type]
|
||||
const parser: Function = mapping[type]
|
||||
assert(parser !== undefined, 'Unrecognized transaction type')
|
||||
const specification = parser(tx)
|
||||
const outcome = parseOutcome(tx)
|
||||
@@ -1,6 +1,4 @@
|
||||
/* @flow */
|
||||
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import {parseQuality} from './utils'
|
||||
import {txFlags, removeUndefined} from '../../common'
|
||||
const flags = txFlags.TrustSet
|
||||
@@ -15,7 +13,7 @@ function parseFlag(flagsValue, trueValue, falseValue) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
function parseTrustline(tx: Object): Object {
|
||||
function parseTrustline(tx: any): Object {
|
||||
assert(tx.TransactionType === 'TrustSet')
|
||||
|
||||
return removeUndefined({
|
||||
@@ -1,12 +1,10 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import transactionParser from 'ripple-lib-transactionparser'
|
||||
import transactionParser = require('ripple-lib-transactionparser')
|
||||
import BigNumber from 'bignumber.js'
|
||||
import * as common from '../../common'
|
||||
import parseAmount from './amount'
|
||||
|
||||
import type {Amount} from '../../common/types'
|
||||
import {Amount, Memo} from '../../common/types'
|
||||
|
||||
function adjustQualityForXRP(
|
||||
quality: string, takerGetsCurrency: string, takerPaysCurrency: string
|
||||
@@ -20,15 +18,18 @@ function adjustQualityForXRP(
|
||||
(new BigNumber(quality)).shift(shift).toString()
|
||||
}
|
||||
|
||||
function parseQuality(quality: ?number) {
|
||||
if (typeof quality === 'number') {
|
||||
return (new BigNumber(quality)).shift(-9).toNumber()
|
||||
function parseQuality(quality?: number|null): number|undefined {
|
||||
if (typeof quality !== 'number') {
|
||||
return undefined
|
||||
}
|
||||
return undefined
|
||||
return (new BigNumber(quality)).shift(-9).toNumber()
|
||||
}
|
||||
|
||||
function parseTimestamp(rippleTime: number): string | void {
|
||||
return rippleTime ? common.rippleTimeToISO8601(rippleTime) : undefined
|
||||
function parseTimestamp(rippleTime?: number|null): string|undefined {
|
||||
if (typeof rippleTime !== 'number') {
|
||||
return undefined
|
||||
}
|
||||
return common.rippleTimeToISO8601(rippleTime)
|
||||
}
|
||||
|
||||
function removeEmptyCounterparty(amount) {
|
||||
@@ -51,11 +52,11 @@ function removeEmptyCounterpartyInOrderbookChanges(orderbookChanges) {
|
||||
})
|
||||
}
|
||||
|
||||
function isPartialPayment(tx: Object) {
|
||||
function isPartialPayment(tx: any) {
|
||||
return (tx.Flags & common.txFlags.Payment.PartialPayment) !== 0
|
||||
}
|
||||
|
||||
function parseDeliveredAmount(tx: Object): Amount | void {
|
||||
function parseDeliveredAmount(tx: any): Amount | void {
|
||||
|
||||
if (tx.TransactionType !== 'Payment' ||
|
||||
tx.meta.TransactionResult !== 'tesSUCCESS') {
|
||||
@@ -95,7 +96,7 @@ function parseDeliveredAmount(tx: Object): Amount | void {
|
||||
return undefined
|
||||
}
|
||||
|
||||
function parseOutcome(tx: Object): ?Object {
|
||||
function parseOutcome(tx: any): any|undefined {
|
||||
const metadata = tx.meta || tx.metaData
|
||||
if (!metadata) {
|
||||
return undefined
|
||||
@@ -117,11 +118,11 @@ function parseOutcome(tx: Object): ?Object {
|
||||
})
|
||||
}
|
||||
|
||||
function hexToString(hex: string): ?string {
|
||||
function hexToString(hex: string): string|undefined {
|
||||
return hex ? new Buffer(hex, 'hex').toString('utf-8') : undefined
|
||||
}
|
||||
|
||||
function parseMemos(tx: Object): ?Array<Object> {
|
||||
function parseMemos(tx: any): Array<Memo>|undefined {
|
||||
if (!Array.isArray(tx.Memos) || tx.Memos.length === 0) {
|
||||
return undefined
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
|
||||
import type {Amount, LaxLaxAmount, RippledAmount, Adjustment, MaxAdjustment,
|
||||
import {Amount, LaxLaxAmount, RippledAmount, Adjustment, MaxAdjustment,
|
||||
MinAdjustment} from '../common/types'
|
||||
|
||||
|
||||
type Path = {
|
||||
export type Path = {
|
||||
source: Adjustment | MaxAdjustment,
|
||||
destination: Adjustment | MinAdjustment,
|
||||
paths: string
|
||||
@@ -30,7 +28,7 @@ export type PathFindRequest = {
|
||||
source_account: string,
|
||||
destination_amount: RippledAmount,
|
||||
destination_account: string,
|
||||
source_currencies?: Array<string>,
|
||||
source_currencies?: {currency: string, issuer?: string}[],
|
||||
send_max?: RippledAmount
|
||||
}
|
||||
|
||||
@@ -49,7 +47,7 @@ export type RippledPathsResponse = {
|
||||
destination_account: string,
|
||||
destination_amount: RippledAmount,
|
||||
destination_currencies?: Array<string>,
|
||||
source_account?: string,
|
||||
source_account: string,
|
||||
source_currencies?: Array<{currency: string}>,
|
||||
full_reply?: boolean
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import {getXRPBalance} from './utils'
|
||||
import {getXRPBalance, renameCounterpartyToIssuer} from './utils'
|
||||
import {validate, toRippledAmount, errors} from '../common'
|
||||
import type {Connection} from '../common'
|
||||
import {Connection} from '../common'
|
||||
import parsePathfind from './parse/pathfind'
|
||||
import type {RippledAmount} from '../common/types'
|
||||
import type {
|
||||
import {RippledAmount, Amount} from '../common/types'
|
||||
import {
|
||||
GetPaths, PathFind, RippledPathsResponse, PathFindRequest
|
||||
} from './pathfind-types'
|
||||
const NotFoundError = errors.NotFoundError
|
||||
@@ -24,7 +22,10 @@ function addParams(request: PathFindRequest, result: RippledPathsResponse
|
||||
|
||||
function requestPathFind(connection: Connection, pathfind: PathFind
|
||||
): Promise<RippledPathsResponse> {
|
||||
const destinationAmount = _.assign({value: -1}, pathfind.destination.amount)
|
||||
const destinationAmount: Amount = _.assign(
|
||||
{value: '-1'},
|
||||
pathfind.destination.amount
|
||||
)
|
||||
const request: PathFindRequest = {
|
||||
command: 'ripple_path_find',
|
||||
source_account: pathfind.source.address,
|
||||
@@ -41,8 +42,8 @@ function requestPathFind(connection: Connection, pathfind: PathFind
|
||||
request.destination_amount.issuer = request.destination_account
|
||||
}
|
||||
if (pathfind.source.currencies && pathfind.source.currencies.length > 0) {
|
||||
request.source_currencies = pathfind.source.currencies.map(amount =>
|
||||
_.omit(toRippledAmount(amount), 'value'))
|
||||
request.source_currencies = pathfind.source.currencies.map(
|
||||
amount => renameCounterpartyToIssuer(amount))
|
||||
}
|
||||
if (pathfind.source.amount) {
|
||||
if (pathfind.destination.amount.value !== undefined) {
|
||||
@@ -50,7 +51,7 @@ function requestPathFind(connection: Connection, pathfind: PathFind
|
||||
+ ' and destination.amount.value in getPaths')
|
||||
}
|
||||
request.send_max = toRippledAmount(pathfind.source.amount)
|
||||
if (request.send_max.currency && !request.send_max.issuer) {
|
||||
if (typeof request.send_max !== 'string' && !request.send_max.issuer) {
|
||||
request.send_max.issuer = pathfind.source.address
|
||||
}
|
||||
}
|
||||
@@ -62,6 +63,7 @@ function addDirectXrpPath(paths: RippledPathsResponse, xrpBalance: string
|
||||
): RippledPathsResponse {
|
||||
// Add XRP "path" only if the source acct has enough XRP to make the payment
|
||||
const destinationAmount = paths.destination_amount
|
||||
// @ts-ignore: destinationAmount can be a currency amount object! Fix!
|
||||
if ((new BigNumber(xrpBalance)).greaterThanOrEqualTo(destinationAmount)) {
|
||||
paths.alternatives.unshift({
|
||||
paths_computed: [],
|
||||
@@ -93,11 +95,13 @@ function filterSourceFundsLowPaths(pathfind: PathFind,
|
||||
): RippledPathsResponse {
|
||||
if (pathfind.source.amount &&
|
||||
pathfind.destination.amount.value === undefined && paths.alternatives) {
|
||||
paths.alternatives = _.filter(paths.alternatives, alt => {
|
||||
return alt.source_amount &&
|
||||
pathfind.source.amount &&
|
||||
paths.alternatives = _.filter(paths.alternatives, alt =>
|
||||
!!alt.source_amount &&
|
||||
!!pathfind.source.amount &&
|
||||
// TODO: Returns false when alt.source_amount is a string. Fix?
|
||||
typeof alt.source_amount !== 'string' &&
|
||||
new BigNumber(alt.source_amount.value).eq(pathfind.source.amount.value)
|
||||
})
|
||||
)
|
||||
}
|
||||
return paths
|
||||
}
|
||||
@@ -1,35 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
import parsePaymentChannel from './parse/payment-channel'
|
||||
import parsePaymentChannel, {
|
||||
LedgerEntryResponse, PaymentChannel
|
||||
} from './parse/payment-channel'
|
||||
import {validate, errors} from '../common'
|
||||
const NotFoundError = errors.NotFoundError
|
||||
|
||||
type PaymentChannel = {
|
||||
Sequence: number,
|
||||
Account: string,
|
||||
Balance: string,
|
||||
PublicKey: number,
|
||||
Destination: string,
|
||||
SettleDelay: number,
|
||||
Expiration?: number,
|
||||
CancelAfter?: number,
|
||||
SourceTag?: number,
|
||||
DestinationTag?: number,
|
||||
OwnerNode: string,
|
||||
LedgerEntryType: string,
|
||||
PreviousTxnID: string,
|
||||
PreviousTxnLgrSeq: number,
|
||||
index: string
|
||||
}
|
||||
|
||||
type LedgerEntryResponse = {
|
||||
node: PaymentChannel,
|
||||
ledger_current_index?: number,
|
||||
ledger_hash?: string,
|
||||
ledger_index: number,
|
||||
validated: boolean
|
||||
}
|
||||
|
||||
function formatResponse(response: LedgerEntryResponse) {
|
||||
if (response.node !== undefined &&
|
||||
response.node.LedgerEntryType === 'PayChannel') {
|
||||
@@ -1,5 +1,3 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import parseFields from './parse/fields'
|
||||
import {validate, constants} from '../common'
|
||||
@@ -19,10 +17,10 @@ type GetSettings = {
|
||||
noFreeze?: boolean,
|
||||
globalFreeze?: boolean,
|
||||
defaultRipple?: boolean,
|
||||
emailHash?: ?string,
|
||||
emailHash?: string|null,
|
||||
messageKey?: string,
|
||||
domain?: string,
|
||||
transferRate?: ?number,
|
||||
transferRate?: number|null,
|
||||
regularKey?: string
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/* @flow */
|
||||
|
||||
|
||||
import type {Amount, Memo} from '../common/types'
|
||||
import {Amount, Memo} from '../common/types'
|
||||
|
||||
type Outcome = {
|
||||
result: string,
|
||||
@@ -87,7 +85,10 @@ export type Order = {
|
||||
totalPrice: Amount,
|
||||
immediateOrCancel?: boolean,
|
||||
fillOrKill?: boolean,
|
||||
passive?: boolean
|
||||
passive?: boolean,
|
||||
expirationTime?: string,
|
||||
orderToReplace?: number,
|
||||
memos?: Memo[]
|
||||
}
|
||||
|
||||
type OrderTransaction = {
|
||||
@@ -133,3 +134,10 @@ export type TransactionOptions = {
|
||||
|
||||
export type TransactionType = PaymentTransaction | OrderTransaction |
|
||||
OrderCancellationTransaction | TrustlineTransaction | SettingsTransaction
|
||||
|
||||
export type TransactionResponse = TransactionType & {
|
||||
hash: string,
|
||||
ledger_index: number,
|
||||
meta: any,
|
||||
validated?: boolean
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
import parseTransaction from './parse/transaction'
|
||||
import {validate, errors} from '../common'
|
||||
import type {Connection} from '../common'
|
||||
import type {TransactionType, TransactionOptions} from './transaction-types'
|
||||
import {Connection} from '../common'
|
||||
import {
|
||||
TransactionType, TransactionResponse, TransactionOptions
|
||||
} from './transaction-types'
|
||||
|
||||
function attachTransactionDate(connection: Connection, tx: Object
|
||||
function attachTransactionDate(connection: Connection, tx: any
|
||||
): Promise<TransactionType> {
|
||||
if (tx.date) {
|
||||
return Promise.resolve(tx)
|
||||
@@ -40,7 +40,7 @@ function attachTransactionDate(connection: Connection, tx: Object
|
||||
})
|
||||
}
|
||||
|
||||
function isTransactionInRange(tx: Object, options: TransactionOptions) {
|
||||
function isTransactionInRange(tx: any, options: TransactionOptions) {
|
||||
return (!options.minLedgerVersion
|
||||
|| tx.ledger_index >= options.minLedgerVersion)
|
||||
&& (!options.maxLedgerVersion
|
||||
@@ -70,10 +70,10 @@ function convertError(connection: Connection, options: TransactionOptions,
|
||||
return Promise.resolve(_error)
|
||||
}
|
||||
|
||||
function formatResponse(options: TransactionOptions, tx: TransactionType
|
||||
function formatResponse(options: TransactionOptions, tx: TransactionResponse
|
||||
): TransactionType {
|
||||
if (tx.validated !== true || !isTransactionInRange(tx, options)) {
|
||||
throw new errors.NotFoundError('Transaction not found')
|
||||
throw new errors.NotFoundError('Transaction not found')
|
||||
}
|
||||
return parseTransaction(tx)
|
||||
}
|
||||
@@ -89,7 +89,7 @@ function getTransaction(id: string, options: TransactionOptions = {}
|
||||
}
|
||||
|
||||
return utils.ensureLedgerVersion.call(this, options).then(_options => {
|
||||
return this.connection.request(request).then(tx =>
|
||||
return this.connection.request(request).then((tx: TransactionResponse) =>
|
||||
attachTransactionDate(this.connection, tx)
|
||||
).then(_.partial(formatResponse, _options))
|
||||
.catch(error => {
|
||||
@@ -1,14 +1,12 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import binary from 'ripple-binary-codec'
|
||||
import {computeTransactionHash} from 'ripple-hashes'
|
||||
import binary = require('ripple-binary-codec')
|
||||
const {computeTransactionHash} = require('ripple-hashes')
|
||||
import * as utils from './utils'
|
||||
import parseTransaction from './parse/transaction'
|
||||
import getTransaction from './transaction'
|
||||
import {validate, errors} from '../common'
|
||||
import type {Connection} from '../common'
|
||||
import type {TransactionType} from './transaction-types'
|
||||
import {Connection} from '../common'
|
||||
import {TransactionType} from './transaction-types'
|
||||
|
||||
|
||||
type TransactionsOptions = {
|
||||
@@ -46,14 +44,15 @@ function parseAccountTxTransaction(tx) {
|
||||
}
|
||||
|
||||
function counterpartyFilter(filters, tx: TransactionType) {
|
||||
if (tx.address === filters.counterparty || (
|
||||
tx.specification && (
|
||||
(tx.specification.destination &&
|
||||
tx.specification.destination.address === filters.counterparty) ||
|
||||
(tx.specification.counterparty === filters.counterparty)
|
||||
))) {
|
||||
if (tx.address === filters.counterparty) {
|
||||
return true
|
||||
}
|
||||
const specification: any = tx.specification
|
||||
if (specification && ((specification.destination &&
|
||||
specification.destination.address === filters.counterparty) ||
|
||||
(specification.counterparty === filters.counterparty))) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -127,9 +126,9 @@ function checkForLedgerGaps(connection: Connection,
|
||||
// the range of ledgers spanned by those transactions
|
||||
if (options.limit && transactions.length === options.limit) {
|
||||
if (options.earliestFirst) {
|
||||
maxLedgerVersion = _.last(transactions).outcome.ledgerVersion
|
||||
maxLedgerVersion = _.last(transactions)!.outcome.ledgerVersion
|
||||
} else {
|
||||
minLedgerVersion = _.last(transactions).outcome.ledgerVersion
|
||||
minLedgerVersion = _.last(transactions)!.outcome.ledgerVersion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,8 +168,8 @@ function getTransactions(address: string, options: TransactionsOptions = {}
|
||||
const ledgerVersion = tx.outcome.ledgerVersion
|
||||
const bound = options.earliestFirst ?
|
||||
{minLedgerVersion: ledgerVersion} : {maxLedgerVersion: ledgerVersion}
|
||||
const newOptions = _.assign({}, defaults, options, {startTx: tx}, bound)
|
||||
return getTransactionsInternal(this.connection, address, newOptions)
|
||||
const startOptions = _.assign({}, defaults, options, {startTx: tx}, bound)
|
||||
return getTransactionsInternal(this.connection, address, startOptions)
|
||||
})
|
||||
}
|
||||
const newOptions = _.assign({}, defaults, options)
|
||||
@@ -1,5 +1,4 @@
|
||||
/* @flow */
|
||||
|
||||
import {Memo} from '../common/types'
|
||||
|
||||
export type TrustLineSpecification = {
|
||||
currency: string,
|
||||
@@ -9,7 +8,8 @@ export type TrustLineSpecification = {
|
||||
qualityOut?: number,
|
||||
ripplingDisabled?: boolean,
|
||||
authorized?: boolean,
|
||||
frozen?: boolean
|
||||
frozen?: boolean,
|
||||
memos?: Memo[]
|
||||
}
|
||||
|
||||
export type Trustline = {
|
||||
@@ -1,20 +1,22 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
import {validate} from '../common'
|
||||
import type {Connection} from '../common'
|
||||
import {Connection} from '../common'
|
||||
import parseAccountTrustline from './parse/account-trustline'
|
||||
import type {TrustlinesOptions, Trustline} from './trustlines-types'
|
||||
import {TrustlinesOptions, Trustline} from './trustlines-types'
|
||||
|
||||
|
||||
type GetTrustlinesResponse = Array<Trustline>
|
||||
interface GetAccountLinesResponse {
|
||||
marker?: any,
|
||||
results: Trustline[]
|
||||
}
|
||||
|
||||
function currencyFilter(currency: string, trustline: Trustline) {
|
||||
return currency === null || trustline.specification.currency === currency
|
||||
}
|
||||
|
||||
function formatResponse(options: TrustlinesOptions, data) {
|
||||
function formatResponse(options: TrustlinesOptions, data: any) {
|
||||
return {
|
||||
marker: data.marker,
|
||||
results: data.lines.map(parseAccountTrustline)
|
||||
@@ -25,7 +27,7 @@ function formatResponse(options: TrustlinesOptions, data) {
|
||||
function getAccountLines(connection: Connection, address: string,
|
||||
ledgerVersion: number, options: TrustlinesOptions, marker: string,
|
||||
limit: number
|
||||
): Promise<GetTrustlinesResponse> {
|
||||
): Promise<GetAccountLinesResponse> {
|
||||
const request = {
|
||||
command: 'account_lines',
|
||||
account: address,
|
||||
@@ -1,7 +1,5 @@
|
||||
/* @flow */
|
||||
|
||||
|
||||
import type {Amount} from '../common/types'
|
||||
import {Amount} from '../common/types'
|
||||
|
||||
export type OrdersOptions = {
|
||||
limit?: number,
|
||||
@@ -30,16 +28,17 @@ export type Order = {
|
||||
}
|
||||
|
||||
export type GetLedger = {
|
||||
accepted: boolean,
|
||||
closed: boolean,
|
||||
// TODO: properties in type don't match response object. Fix!
|
||||
// accepted: boolean,
|
||||
// closed: boolean,
|
||||
stateHash: string,
|
||||
closeTime: number,
|
||||
closeTime: string,
|
||||
closeTimeResolution: number,
|
||||
closeFlags: number,
|
||||
ledgerHash: string,
|
||||
ledgerVersion: number,
|
||||
parentLedgerHash: string,
|
||||
parentCloseTime: number,
|
||||
parentCloseTime: string,
|
||||
totalDrops: string,
|
||||
transactionHash: string,
|
||||
transactions?: Array<Object>,
|
||||
@@ -1,18 +1,16 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import * as common from '../common'
|
||||
import type {Connection} from '../common'
|
||||
import type {TransactionType} from './transaction-types'
|
||||
import type {Issue} from '../common/types'
|
||||
import {Connection} from '../common'
|
||||
import {TransactionType} from './transaction-types'
|
||||
import {Issue} from '../common/types'
|
||||
|
||||
type RecursiveData = {
|
||||
marker: string,
|
||||
results: Array<any>
|
||||
}
|
||||
|
||||
type Getter = (marker: ?string, limit: number) => Promise<RecursiveData>
|
||||
type Getter = (marker?: string, limit?: number) => Promise<RecursiveData>
|
||||
|
||||
function clamp(value: number, min: number, max: number): number {
|
||||
assert(min <= max, 'Illegal clamp bounds')
|
||||
@@ -32,7 +30,8 @@ function getXRPBalance(connection: Connection, address: string,
|
||||
}
|
||||
|
||||
// If the marker is omitted from a response, you have reached the end
|
||||
function getRecursiveRecur(getter: Getter, marker?: string, limit: number
|
||||
function getRecursiveRecur(
|
||||
getter: Getter, marker: string | undefined, limit: number
|
||||
): Promise<Array<any>> {
|
||||
return getter(marker, limit).then(data => {
|
||||
const remaining = limit - data.results.length
|
||||
@@ -49,15 +48,15 @@ function getRecursive(getter: Getter, limit?: number): Promise<Array<any>> {
|
||||
return getRecursiveRecur(getter, undefined, limit || Infinity)
|
||||
}
|
||||
|
||||
function renameCounterpartyToIssuer(amount?: Issue): ?{issuer?: string} {
|
||||
if (amount === undefined) {
|
||||
return undefined
|
||||
}
|
||||
const issuer = amount.counterparty === undefined ?
|
||||
(amount.issuer !== undefined ? amount.issuer : undefined) :
|
||||
amount.counterparty
|
||||
const withIssuer = _.assign({}, amount, {issuer: issuer})
|
||||
return _.omit(withIssuer, 'counterparty')
|
||||
function renameCounterpartyToIssuer<T>(
|
||||
obj: T & {counterparty?: string, issuer?: string}
|
||||
): (T & {issuer?: string}) {
|
||||
const issuer = (obj.counterparty !== undefined) ?
|
||||
obj.counterparty :
|
||||
((obj.issuer !== undefined) ? obj.issuer : undefined)
|
||||
const withIssuer = Object.assign({}, obj, {issuer})
|
||||
delete withIssuer.counterparty
|
||||
return withIssuer
|
||||
}
|
||||
|
||||
type RequestBookOffersArgs = {taker_gets: Issue, taker_pays: Issue}
|
||||
@@ -65,7 +64,7 @@ type RequestBookOffersArgs = {taker_gets: Issue, taker_pays: Issue}
|
||||
function renameCounterpartyToIssuerInOrder(order: RequestBookOffersArgs) {
|
||||
const taker_gets = renameCounterpartyToIssuer(order.taker_gets)
|
||||
const taker_pays = renameCounterpartyToIssuer(order.taker_pays)
|
||||
const changes = {taker_gets: taker_gets, taker_pays: taker_pays}
|
||||
const changes = {taker_gets, taker_pays}
|
||||
return _.assign({}, order, _.omitBy(changes, _.isUndefined))
|
||||
}
|
||||
|
||||
@@ -78,12 +77,7 @@ function signum(num) {
|
||||
* If two transactions took place in the same ledger, sort
|
||||
* them based on TransactionIndex
|
||||
* See: https://ripple.com/build/transactions/
|
||||
*
|
||||
* @param {Object} first
|
||||
* @param {Object} second
|
||||
* @returns {Number} [-1, 0, 1]
|
||||
*/
|
||||
|
||||
function compareTransactions(first: TransactionType, second: TransactionType
|
||||
): number {
|
||||
if (!first.outcome || !second.outcome) {
|
||||
@@ -104,13 +98,13 @@ function hasCompleteLedgerRange(connection: Connection,
|
||||
}
|
||||
|
||||
function isPendingLedgerVersion(connection: Connection,
|
||||
maxLedgerVersion: ?number
|
||||
maxLedgerVersion?: number
|
||||
): Promise<boolean> {
|
||||
return connection.getLedgerVersion().then(ledgerVersion =>
|
||||
ledgerVersion < (maxLedgerVersion || 0))
|
||||
}
|
||||
|
||||
function ensureLedgerVersion(options: Object
|
||||
function ensureLedgerVersion(options: any
|
||||
): Promise<Object> {
|
||||
if (Boolean(options) && options.ledgerVersion !== undefined &&
|
||||
options.ledgerVersion !== null
|
||||
@@ -125,6 +119,7 @@ export {
|
||||
getXRPBalance,
|
||||
ensureLedgerVersion,
|
||||
compareTransactions,
|
||||
renameCounterpartyToIssuer,
|
||||
renameCounterpartyToIssuerInOrder,
|
||||
getRecursive,
|
||||
hasCompleteLedgerRange,
|
||||
@@ -1,6 +1,4 @@
|
||||
/* @flow */
|
||||
|
||||
import keypairs from 'ripple-keypairs'
|
||||
import keypairs = require('ripple-keypairs')
|
||||
import * as common from '../common'
|
||||
const {errors, validate} = common
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import hashes = require('ripple-hashes')
|
||||
import * as common from '../common'
|
||||
import hashes from 'ripple-hashes'
|
||||
|
||||
function convertLedgerHeader(header) {
|
||||
function convertLedgerHeader(header): any {
|
||||
return {
|
||||
account_hash: header.stateHash,
|
||||
close_time: common.iso8601ToRippleTime(header.closeTime),
|
||||
@@ -31,7 +29,7 @@ function computeTransactionHash(ledger, version) {
|
||||
if (ledger.rawTransactions === undefined) {
|
||||
return ledger.transactionHash
|
||||
}
|
||||
const transactions = JSON.parse(ledger.rawTransactions)
|
||||
const transactions: any[] = JSON.parse(ledger.rawTransactions)
|
||||
const txs = _.map(transactions, tx => {
|
||||
const mergeTx = _.assign({}, _.omit(tx, 'tx'), tx.tx || {})
|
||||
const renameMeta = _.assign({}, _.omit(mergeTx, 'meta'),
|
||||
@@ -62,7 +60,7 @@ function computeStateHash(ledger, version) {
|
||||
|
||||
const sLCF_SHAMapV2 = 0x02
|
||||
|
||||
function computeLedgerHash(ledger: Object): string {
|
||||
function computeLedgerHash(ledger: any): string {
|
||||
const version = ((ledger.closeFlags & sLCF_SHAMapV2) === 0) ? 1 : 2
|
||||
const subhashes = {
|
||||
transactionHash: computeTransactionHash(ledger, version),
|
||||
@@ -1,8 +1,6 @@
|
||||
/* @flow */
|
||||
|
||||
import * as common from '../common'
|
||||
import keypairs from 'ripple-keypairs'
|
||||
import binary from 'ripple-binary-codec'
|
||||
import keypairs = require('ripple-keypairs')
|
||||
import binary = require('ripple-binary-codec')
|
||||
const {validate, xrpToDrops} = common
|
||||
|
||||
function signPaymentChannelClaim(channel: string, amount: string,
|
||||
@@ -1,9 +1,6 @@
|
||||
/* @flow */
|
||||
|
||||
import * as common from '../common'
|
||||
import keypairs from 'ripple-keypairs'
|
||||
import binary from 'ripple-binary-codec'
|
||||
const {validate, xrpToDrops} = common
|
||||
import keypairs = require('ripple-keypairs')
|
||||
import binary = require('ripple-binary-codec')
|
||||
import {validate, xrpToDrops} from '../common'
|
||||
|
||||
function verifyPaymentChannelClaim(channel: string, amount: string,
|
||||
signature: string, publicKey: string
|
||||
@@ -1,7 +1,5 @@
|
||||
/* @flow */
|
||||
|
||||
import * as common from '../common'
|
||||
import type {GetServerInfoResponse} from '../common/serverinfo'
|
||||
import {GetServerInfoResponse} from '../common/serverinfo'
|
||||
|
||||
function isConnected(): boolean {
|
||||
return this.connection.isConnected()
|
||||
@@ -23,12 +21,12 @@ function getServerInfo(): Promise<GetServerInfoResponse> {
|
||||
return common.serverInfo.getServerInfo(this.connection)
|
||||
}
|
||||
|
||||
function getFee(): Promise<number> {
|
||||
function getFee(): Promise<string> {
|
||||
const cushion = this._feeCushion || 1.2
|
||||
return common.serverInfo.getFee(this.connection, cushion)
|
||||
}
|
||||
|
||||
function formatLedgerClose(ledgerClose: Object): Object {
|
||||
function formatLedgerClose(ledgerClose: any): Object {
|
||||
return {
|
||||
baseFeeXRP: common.dropsToXrp(ledgerClose.fee_base),
|
||||
ledgerHash: ledgerClose.ledger_hash,
|
||||
@@ -1,7 +1,5 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import binary from 'ripple-binary-codec'
|
||||
import binary = require('ripple-binary-codec')
|
||||
import * as utils from './utils'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import {decodeAddress} from 'ripple-address-codec'
|
||||
@@ -21,7 +19,9 @@ function compareSigners(a, b) {
|
||||
function combine(signedTransactions: Array<string>): Object {
|
||||
validate.combine({signedTransactions})
|
||||
|
||||
const txs = _.map(signedTransactions, binary.decode)
|
||||
// TODO: signedTransactions is an array of strings in the documentation, but
|
||||
// tests and this code handle it as an array of objects. Fix!
|
||||
const txs: any[] = _.map(signedTransactions, binary.decode)
|
||||
const tx = _.omit(txs[0], 'Signers')
|
||||
if (!_.every(txs, _tx => _.isEqual(tx, _.omit(_tx, 'Signers')))) {
|
||||
throw new utils.common.errors.ValidationError(
|
||||
@@ -1,10 +1,8 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
const validate = utils.common.validate
|
||||
import type {Instructions, Prepare} from './types'
|
||||
import type {Memo} from '../common/types'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Memo} from '../common/types'
|
||||
|
||||
type EscrowCancellation = {
|
||||
owner: string,
|
||||
@@ -15,7 +13,7 @@ type EscrowCancellation = {
|
||||
function createEscrowCancellationTransaction(account: string,
|
||||
payment: EscrowCancellation
|
||||
): Object {
|
||||
const txJSON: Object = {
|
||||
const txJSON: any = {
|
||||
TransactionType: 'EscrowCancel',
|
||||
Account: account,
|
||||
Owner: payment.owner,
|
||||
@@ -1,11 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
import {validate, iso8601ToRippleTime, xrpToDrops} from '../common'
|
||||
const ValidationError = utils.common.errors.ValidationError
|
||||
import type {Instructions, Prepare} from './types'
|
||||
import type {Memo} from '../common/types'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Memo} from '../common/types'
|
||||
|
||||
type EscrowCreation = {
|
||||
amount: string,
|
||||
@@ -21,7 +19,7 @@ type EscrowCreation = {
|
||||
function createEscrowCreationTransaction(account: string,
|
||||
payment: EscrowCreation
|
||||
): Object {
|
||||
const txJSON: Object = {
|
||||
const txJSON: any = {
|
||||
TransactionType: 'EscrowCreate',
|
||||
Account: account,
|
||||
Destination: payment.destination,
|
||||
@@ -1,11 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
const validate = utils.common.validate
|
||||
const ValidationError = utils.common.errors.ValidationError
|
||||
import type {Instructions, Prepare} from './types'
|
||||
import type {Memo} from '../common/types'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Memo} from '../common/types'
|
||||
|
||||
type EscrowExecution = {
|
||||
owner: string,
|
||||
@@ -18,7 +16,7 @@ type EscrowExecution = {
|
||||
function createEscrowExecutionTransaction(account: string,
|
||||
payment: EscrowExecution
|
||||
): Object {
|
||||
const txJSON: Object = {
|
||||
const txJSON: any = {
|
||||
TransactionType: 'EscrowFinish',
|
||||
Account: account,
|
||||
Owner: payment.owner,
|
||||
@@ -1,11 +1,9 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
const offerFlags = utils.common.txFlags.OfferCreate
|
||||
import {validate, iso8601ToRippleTime} from '../common'
|
||||
import type {Instructions, Prepare} from './types'
|
||||
import type {Order} from '../ledger/transaction-types'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Order} from '../ledger/transaction-types'
|
||||
|
||||
function createOrderTransaction(account: string, order: Order): Object {
|
||||
const takerPays = utils.common.toRippledAmount(order.direction === 'buy' ?
|
||||
@@ -13,7 +11,7 @@ function createOrderTransaction(account: string, order: Order): Object {
|
||||
const takerGets = utils.common.toRippledAmount(order.direction === 'buy' ?
|
||||
order.totalPrice : order.quantity)
|
||||
|
||||
const txJSON: Object = {
|
||||
const txJSON: any = {
|
||||
TransactionType: 'OfferCreate',
|
||||
Account: account,
|
||||
TakerGets: takerGets,
|
||||
@@ -1,14 +1,12 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
const validate = utils.common.validate
|
||||
import type {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare} from './types'
|
||||
|
||||
function createOrderCancellationTransaction(account: string,
|
||||
orderCancellation: Object
|
||||
orderCancellation: any
|
||||
): Object {
|
||||
const txJSON: Object = {
|
||||
const txJSON: any = {
|
||||
TransactionType: 'OfferCancel',
|
||||
Account: account,
|
||||
OfferSequence: orderCancellation.orderSequence
|
||||
@@ -1,10 +1,8 @@
|
||||
/* @flow */
|
||||
|
||||
import * as utils from './utils'
|
||||
const ValidationError = utils.common.errors.ValidationError
|
||||
const claimFlags = utils.common.txFlags.PaymentChannelClaim
|
||||
import {validate, xrpToDrops} from '../common'
|
||||
import type {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare} from './types'
|
||||
|
||||
type PaymentChannelClaim = {
|
||||
channel: string,
|
||||
@@ -19,7 +17,7 @@ type PaymentChannelClaim = {
|
||||
function createPaymentChannelClaimTransaction(account: string,
|
||||
claim: PaymentChannelClaim
|
||||
): Object {
|
||||
const txJSON: Object = {
|
||||
const txJSON: any = {
|
||||
Account: account,
|
||||
TransactionType: 'PaymentChannelClaim',
|
||||
Channel: claim.channel,
|
||||
@@ -1,8 +1,6 @@
|
||||
/* @flow */
|
||||
|
||||
import * as utils from './utils'
|
||||
import {validate, iso8601ToRippleTime, xrpToDrops} from '../common'
|
||||
import type {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare} from './types'
|
||||
|
||||
type PaymentChannelCreate = {
|
||||
amount: string,
|
||||
@@ -17,7 +15,7 @@ type PaymentChannelCreate = {
|
||||
function createPaymentChannelCreateTransaction(account: string,
|
||||
paymentChannel: PaymentChannelCreate
|
||||
): Object {
|
||||
const txJSON: Object = {
|
||||
const txJSON: any = {
|
||||
Account: account,
|
||||
TransactionType: 'PaymentChannelCreate',
|
||||
Amount: xrpToDrops(paymentChannel.amount),
|
||||
@@ -1,8 +1,6 @@
|
||||
/* @flow */
|
||||
|
||||
import * as utils from './utils'
|
||||
import {validate, iso8601ToRippleTime, xrpToDrops} from '../common'
|
||||
import type {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare} from './types'
|
||||
|
||||
type PaymentChannelFund = {
|
||||
channel: string,
|
||||
@@ -13,7 +11,7 @@ type PaymentChannelFund = {
|
||||
function createPaymentChannelFundTransaction(account: string,
|
||||
fund: PaymentChannelFund
|
||||
): Object {
|
||||
const txJSON: Object = {
|
||||
const txJSON: any = {
|
||||
Account: account,
|
||||
TransactionType: 'PaymentChannelFund',
|
||||
Channel: fund.channel,
|
||||
@@ -1,19 +1,17 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
const validate = utils.common.validate
|
||||
const toRippledAmount = utils.common.toRippledAmount
|
||||
const paymentFlags = utils.common.txFlags.Payment
|
||||
const ValidationError = utils.common.errors.ValidationError
|
||||
import type {Instructions, Prepare} from './types'
|
||||
import type {Amount, Adjustment, MaxAdjustment,
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Amount, Adjustment, MaxAdjustment,
|
||||
MinAdjustment, Memo} from '../common/types'
|
||||
|
||||
|
||||
type Payment = {
|
||||
source: Adjustment | MaxAdjustment,
|
||||
destination: Adjustment | MinAdjustment,
|
||||
source: Adjustment & MaxAdjustment,
|
||||
destination: Adjustment & MinAdjustment,
|
||||
paths?: string,
|
||||
memos?: Array<Memo>,
|
||||
// A 256-bit hash that can be used to identify a particular payment
|
||||
@@ -92,7 +90,7 @@ function createPaymentTransaction(address: string, paymentArgument: Payment
|
||||
createMaximalAmount(payment.destination.minAmount) :
|
||||
(payment.destination.amount || payment.destination.minAmount)
|
||||
|
||||
const txJSON: Object = {
|
||||
const txJSON: any = {
|
||||
TransactionType: 'Payment',
|
||||
Account: payment.source.address,
|
||||
Destination: payment.destination.address,
|
||||
@@ -1,14 +1,18 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import assert from 'assert'
|
||||
import * as assert from 'assert'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import * as utils from './utils'
|
||||
const validate = utils.common.validate
|
||||
const AccountFlagIndices = utils.common.constants.AccountFlagIndices
|
||||
const AccountFields = utils.common.constants.AccountFields
|
||||
import type {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {Memo} from '../common/types'
|
||||
|
||||
type WeightedSigner = {address: string, weight: number}
|
||||
type SettingsSigners = {
|
||||
threshold?: number,
|
||||
weights: WeightedSigner[]
|
||||
}
|
||||
type Settings = {
|
||||
passwordSpent?: boolean,
|
||||
requireDestinationTag?: boolean,
|
||||
@@ -19,25 +23,23 @@ type Settings = {
|
||||
noFreeze?: boolean,
|
||||
globalFreeze?: boolean,
|
||||
defaultRipple?: boolean,
|
||||
emailHash?: ?string,
|
||||
emailHash?: string,
|
||||
messageKey?: string,
|
||||
domain?: string,
|
||||
transferRate?: ?number,
|
||||
transferRate?: number,
|
||||
regularKey?: string,
|
||||
signers?: {
|
||||
threshold?: number,
|
||||
weights: {address: string, weight: number}[],
|
||||
},
|
||||
signers?: SettingsSigners,
|
||||
memos?: Memo[]
|
||||
}
|
||||
|
||||
// Emptry string passed to setting will clear it
|
||||
const CLEAR_SETTING = null
|
||||
|
||||
function setTransactionFlags(txJSON: Object, values: Settings) {
|
||||
function setTransactionFlags(txJSON: any, values: Settings) {
|
||||
const keys = Object.keys(values)
|
||||
assert(keys.length === 1, 'ERROR: can only set one setting per transaction')
|
||||
const flagName = keys[0]
|
||||
const value = (values: Object)[flagName]
|
||||
const value = values[flagName]
|
||||
const index = AccountFlagIndices[flagName]
|
||||
if (index !== undefined) {
|
||||
if (value) {
|
||||
@@ -89,7 +91,7 @@ function convertTransferRate(transferRate: number | string): number | string {
|
||||
return (new BigNumber(transferRate)).shift(9).toNumber()
|
||||
}
|
||||
|
||||
function formatSignerEntry(signer: Object): Object {
|
||||
function formatSignerEntry(signer: WeightedSigner): Object {
|
||||
return {
|
||||
SignerEntry: {
|
||||
Account: signer.address,
|
||||
@@ -100,7 +102,7 @@ function formatSignerEntry(signer: Object): Object {
|
||||
|
||||
function createSettingsTransactionWithoutMemos(
|
||||
account: string, settings: Settings
|
||||
): Object {
|
||||
): any {
|
||||
if (settings.regularKey !== undefined) {
|
||||
const removeRegularKey = {
|
||||
TransactionType: 'SetRegularKey',
|
||||
@@ -121,7 +123,7 @@ function createSettingsTransactionWithoutMemos(
|
||||
}
|
||||
}
|
||||
|
||||
const txJSON: Object = {
|
||||
const txJSON: any = {
|
||||
TransactionType: 'AccountSet',
|
||||
Account: account
|
||||
}
|
||||
@@ -1,18 +1,16 @@
|
||||
/* @flow */
|
||||
|
||||
import * as utils from './utils'
|
||||
import keypairs from 'ripple-keypairs'
|
||||
import binary from 'ripple-binary-codec'
|
||||
import keypairs = require('ripple-keypairs')
|
||||
import binary = require('ripple-binary-codec')
|
||||
import {computeBinaryTransactionHash} from 'ripple-hashes'
|
||||
const validate = utils.common.validate
|
||||
|
||||
function computeSignature(tx: Object, privateKey: string, signAs: ?string) {
|
||||
function computeSignature(tx: Object, privateKey: string, signAs?: string) {
|
||||
const signingData = signAs ?
|
||||
binary.encodeForMultisigning(tx, signAs) : binary.encodeForSigning(tx)
|
||||
return keypairs.sign(signingData, privateKey)
|
||||
}
|
||||
|
||||
function sign(txJSON: string, secret: string, options: Object = {}
|
||||
function sign(txJSON: string, secret: string, options: {signAs?: string} = {}
|
||||
): {signedTransaction: string; id: string} {
|
||||
validate.sign({txJSON, secret})
|
||||
// we can't validate that the secret matches the account because
|
||||
@@ -1,9 +1,7 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import * as utils from './utils'
|
||||
import {validate} from '../common'
|
||||
import type {Submit} from './types'
|
||||
import {Submit} from './types'
|
||||
|
||||
function isImmediateRejection(engineResult: string): boolean {
|
||||
// note: "tel" errors mean the local server refused to process the
|
||||
@@ -1,12 +1,10 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import * as utils from './utils'
|
||||
const validate = utils.common.validate
|
||||
const trustlineFlags = utils.common.txFlags.TrustSet
|
||||
import type {Instructions, Prepare} from './types'
|
||||
import type {TrustLineSpecification} from '../ledger/trustlines-types'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {TrustLineSpecification} from '../ledger/trustlines-types'
|
||||
|
||||
function convertQuality(quality) {
|
||||
return (new BigNumber(quality)).shift(9).truncated().toNumber()
|
||||
@@ -21,7 +19,7 @@ function createTrustlineTransaction(account: string,
|
||||
value: trustline.limit
|
||||
}
|
||||
|
||||
const txJSON: Object = {
|
||||
const txJSON: any = {
|
||||
TransactionType: 'TrustSet',
|
||||
Account: account,
|
||||
LimitAmount: limit,
|
||||
@@ -1,5 +1,3 @@
|
||||
/* @flow */
|
||||
|
||||
|
||||
export type Instructions = {
|
||||
sequence?: number,
|
||||
@@ -1,12 +1,11 @@
|
||||
/* @flow */
|
||||
|
||||
import * as _ from 'lodash'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import * as common from '../common'
|
||||
import {Memo, ApiMemo} from '../common/types'
|
||||
const txFlags = common.txFlags
|
||||
import type {Instructions, Prepare} from './types'
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {RippleAPI} from '../api'
|
||||
|
||||
function formatPrepareResponse(txJSON: Object): Object {
|
||||
function formatPrepareResponse(txJSON: any): Prepare {
|
||||
const instructions = {
|
||||
fee: common.dropsToXrp(txJSON.Fee),
|
||||
sequence: txJSON.Sequence,
|
||||
@@ -15,7 +14,7 @@ function formatPrepareResponse(txJSON: Object): Object {
|
||||
}
|
||||
return {
|
||||
txJSON: JSON.stringify(txJSON),
|
||||
instructions: _.omitBy(instructions, _.isUndefined)
|
||||
instructions
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +30,7 @@ function scaleValue(value, multiplier, extra = 0) {
|
||||
return (new BigNumber(value)).times(multiplier).plus(extra).toString()
|
||||
}
|
||||
|
||||
function prepareTransaction(txJSON: Object, api: Object,
|
||||
function prepareTransaction(txJSON: any, api: RippleAPI,
|
||||
instructions: Instructions
|
||||
): Promise<Prepare> {
|
||||
common.validate.instructions(instructions)
|
||||
@@ -104,17 +103,16 @@ function prepareTransaction(txJSON: Object, api: Object,
|
||||
]).then(() => formatPrepareResponse(txJSON))
|
||||
}
|
||||
|
||||
function convertStringToHex(string: string) {
|
||||
return string ? (new Buffer(string, 'utf8')).toString('hex').toUpperCase() :
|
||||
undefined
|
||||
function convertStringToHex(string: string): string {
|
||||
return new Buffer(string, 'utf8').toString('hex').toUpperCase()
|
||||
}
|
||||
|
||||
function convertMemo(memo: Object): Object {
|
||||
function convertMemo(memo: Memo): {Memo: ApiMemo} {
|
||||
return {
|
||||
Memo: common.removeUndefined({
|
||||
MemoData: convertStringToHex(memo.data),
|
||||
MemoType: convertStringToHex(memo.type),
|
||||
MemoFormat: convertStringToHex(memo.format)
|
||||
MemoData: memo.data ? convertStringToHex(memo.data) : undefined,
|
||||
MemoType: memo.type ? convertStringToHex(memo.type) : undefined,
|
||||
MemoFormat: memo.format ? convertStringToHex(memo.format) : undefined
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1455,9 +1455,14 @@ describe('RippleAPI', function() {
|
||||
});
|
||||
|
||||
it('ledger utils - renameCounterpartyToIssuerInOrder', function() {
|
||||
const order = {taker_gets: {issuer: '1'}};
|
||||
const expected = {taker_gets: {issuer: '1'}};
|
||||
|
||||
const order = {
|
||||
taker_gets: {counterparty: '1'},
|
||||
taker_pays: {counterparty: '1'}
|
||||
};
|
||||
const expected = {
|
||||
taker_gets: {issuer: '1'},
|
||||
taker_pays: {issuer: '1'}
|
||||
};
|
||||
assert.deepEqual(utils.renameCounterpartyToIssuerInOrder(order), expected);
|
||||
});
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
--reporter spec --timeout 5000 --slow 500 --compilers js:babel-register
|
||||
--reporter spec --timeout 5000 --slow 500 --require ts-node/register
|
||||
|
||||
26
tsconfig.json
Normal file
26
tsconfig.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"lib": [
|
||||
"es2017"
|
||||
],
|
||||
"outDir": "dist/npm",
|
||||
"rootDir": "src",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"strictNullChecks": false,
|
||||
"noImplicitAny": false,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"removeComments": false,
|
||||
"preserveConstEnums": false,
|
||||
"suppressImplicitAnyIndexErrors": false,
|
||||
"declaration": false,
|
||||
"sourceMap": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"custom_typings/**/*.ts",
|
||||
"src/**/*.ts"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user