Merge branch 'develop' into connection-timeout

This commit is contained in:
Fred K. Schott
2019-10-23 00:32:03 -07:00
39 changed files with 1067 additions and 2271 deletions

25
.eslintrc.json Normal file
View File

@@ -0,0 +1,25 @@
{
"env": {
"browser": true,
"es6": true,
"node": true,
"mocha": true
},
"extends": [
"eslint:recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"no-useless-constructor": 0,
"no-unused-vars": 0,
"no-prototype-builtins": 0,
"require-atomic-updates": 0
}
}

View File

@@ -1,5 +1,13 @@
# ripple-lib Release History # ripple-lib Release History
## 1.3.4 (2019-10-18)
* Update ripple-lib-transactionparser
* Improve error message when signing fails (e.g. due to trailing zeros)
* Integrate ripple-hashes (in TypeScript with improved naming and docs)
* Add multi-signing example to sign() method docs
* Update TypeScript
## 1.3.3 (2019-09-10) ## 1.3.3 (2019-09-10)
* Expand node version compatibility to support Node.js 12 ([ripple-binary-codec#32](https://github.com/ripple/ripple-binary-codec/issues/32)) * Expand node version compatibility to support Node.js 12 ([ripple-binary-codec#32](https://github.com/ripple/ripple-binary-codec/issues/32))

View File

@@ -5403,6 +5403,8 @@ options | object | *Optional* Options that control the type of signature that wi
*options.* signAs | [address](#address) | *Optional* The account that the signature should count for in multisigning. *options.* signAs | [address](#address) | *Optional* The account that the signature should count for in multisigning.
secret | secret string | *Optional* The secret of the account that is initiating the transaction. (This field cannot be used with keypair). secret | secret string | *Optional* The secret of the account that is initiating the transaction. (This field cannot be used with keypair).
Please note that when this method is used for multisigning, the `options` parameter is not *Optional* anymore. It will be compulsory. See the multisigning example in this section for more details.
### Return Value ### Return Value
This method returns an object with the following structure: This method returns an object with the following structure:
@@ -5429,6 +5431,93 @@ return api.sign(txJSON, secret); // or: api.sign(txJSON, keypair);
} }
``` ```
### Example (multisigning)
```javascript
const RippleAPI = require('ripple-lib').RippleAPI;
// jon's address will have a multi-signing setup with a quorum of 2
const jon = {
account: 'rJKpme4m2zBQceBuU89d7vLMzgoUw2Ptj',
secret: 'sh4Va7b1wQof8knHFV2sxwX12fSgK'
};
const aya = {
account: 'rnrPdBjs98fFFfmRpL6hM7exT788SWQPFN',
secret: 'snaMuMrXeVc2Vd4NYvHofeGNjgYoe'
};
const bran = {
account: 'rJ93RLnT1t5A8fCr7HTScw7WtfKJMRXodH',
secret: 'shQtQ8Um5MS218yvEU3Ehy1eZQKqH'
};
// Setup the signers list with a quorum of 2
const multiSignSetupTransaction = {
"Flags": 0,
"TransactionType": "SignerListSet",
"Account": "rJKpme4m2zBQceBuU89d7vLMzgoUw2Ptj",
"Fee": "120",
"SignerQuorum": 2,
"SignerEntries": [
{
"SignerEntry": {
"Account": "rnrPdBjs98fFFfmRpL6hM7exT788SWQPFN",
"SignerWeight": 2
}
},
{
"SignerEntry": {
"Account": "rJ93RLnT1t5A8fCr7HTScw7WtfKJMRXodH",
"SignerWeight": 1
}
},
]
};
// a transaction which requires multi signing
const multiSignPaymentTransaction = {
TransactionType: 'Payment',
Account: 'rJKpme4m2zBQceBuU89d7vLMzgoUw2Ptj',
Destination: 'rJ93RLnT1t5A8fCr7HTScw7WtfKJMRXodH',
Amount: '88000000'
};
const api = new RippleAPI({
server: 'wss://s.altnet.rippletest.net:51233'
});
api.connect().then(() => {
// adding the multi signing feature to jon's account
api.prepareTransaction(multiSignSetupTransaction).then((prepared) => {
console.log(prepared);
jonSign = api.sign(prepared.txJSON, jon.secret).signedTransaction;
api.submit(jonSign).then( response => {
console.log(response.resultCode, response.resultMessage);
// multi sign a transaction
api.prepareTransaction(multiSignPaymentTransaction).then(prepared => {
console.log(prepared);
// Aya and Bran sign it too but with 'signAs' set to their own account
let ayaSign = api.sign(prepared.txJSON, aya.secret, {'signAs': aya.account}).signedTransaction;
let branSign = api.sign(prepared.txJSON, bran.secret, {'signAs': bran.account}).signedTransaction;
// signatures are combined and submitted
let combinedTx = api.combine([ayaSign, branSign]);
api.submit(combinedTx.signedTransaction).then(response => {
console.log(response.tx_json.hash);
return api.disconnect();
}).catch(console.error);
}).catch(console.error);
}).catch(console.error)
}).catch(console.error);
}).catch(console.error);
```
Assuming the multisigning account was setup properly, the above example will respond with `resultCode: 'tesSUCCESS'` and the hash for the transaction.
If any of `{signAs: some_address}` options were missing the code will return a validation error as follow:
```
[ValidationError(txJSON is not the same for all signedTransactions)]
```
## combine ## combine

View File

@@ -1,6 +1,6 @@
{ {
"name": "ripple-lib", "name": "ripple-lib",
"version": "1.3.3", "version": "1.3.4",
"license": "ISC", "license": "ISC",
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser", "description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
"files": [ "files": [
@@ -20,9 +20,10 @@
"@types/lodash": "^4.14.136", "@types/lodash": "^4.14.136",
"@types/ws": "^3.2.0", "@types/ws": "^3.2.0",
"bignumber.js": "^4.1.0", "bignumber.js": "^4.1.0",
"https-proxy-agent": "2.2.1", "https-proxy-agent": "^3.0.0",
"jsonschema": "1.2.2", "jsonschema": "1.2.2",
"lodash": "^4.17.4", "lodash": "^4.17.4",
"lodash.isequal": "^4.5.0",
"ripple-address-codec": "^3.0.4", "ripple-address-codec": "^3.0.4",
"ripple-binary-codec": "^0.2.4", "ripple-binary-codec": "^0.2.4",
"ripple-keypairs": "^0.10.1", "ripple-keypairs": "^0.10.1",
@@ -31,9 +32,12 @@
}, },
"devDependencies": { "devDependencies": {
"@types/node": "11.13.0", "@types/node": "11.13.0",
"@typescript-eslint/eslint-plugin": "^2.3.3",
"@typescript-eslint/parser": "^2.3.3",
"assert-diff": "^1.0.1", "assert-diff": "^1.0.1",
"doctoc": "^0.15.0", "doctoc": "^0.15.0",
"ejs": "^2.3.4", "ejs": "^2.3.4",
"eslint": "^6.5.1",
"eventemitter2": "^0.4.14", "eventemitter2": "^0.4.14",
"gulp": "^4.0.2", "gulp": "^4.0.2",
"json-loader": "^0.5.2", "json-loader": "^0.5.2",
@@ -45,9 +49,7 @@
"source-map-support": "0.5.12", "source-map-support": "0.5.12",
"ts-loader": "^3.2.0", "ts-loader": "^3.2.0",
"ts-node": "8.0.3", "ts-node": "8.0.3",
"tslint": "^5.8.0", "typescript": "^3.6.4",
"tslint-eslint-rules": "^4.1.1",
"typescript": "3.4.2",
"uglifyjs-webpack-plugin": "^1.1.4", "uglifyjs-webpack-plugin": "^1.1.4",
"webpack": "3.12.0" "webpack": "3.12.0"
}, },
@@ -56,11 +58,11 @@
"doctoc": "doctoc docs/index.md --title '# RippleAPI Reference' --github --maxlevel 2", "doctoc": "doctoc docs/index.md --title '# RippleAPI Reference' --github --maxlevel 2",
"docgen": "node --harmony scripts/build_docs.js", "docgen": "node --harmony scripts/build_docs.js",
"clean": "rm -rf dist/npm", "clean": "rm -rf dist/npm",
"compile": "mkdir -p dist/npm/common/js && cp -r src/common/js/ dist/npm/common/js/ && mkdir -p dist/npm/common && cp -r src/common/schemas dist/npm/common/ && tsc --build", "compile": "mkdir -p dist/npm/common && cp -r src/common/schemas dist/npm/common/ && tsc --build",
"watch": "tsc -w", "watch": "tsc -w",
"prepublish": "npm run clean && npm run compile && npm run build", "prepublish": "npm run clean && npm run compile && npm run build",
"test": "TS_NODE_PROJECT=src/tsconfig.json nyc mocha --exit", "test": "TS_NODE_PROJECT=src/tsconfig.json nyc mocha --exit",
"lint": "tslint -p ./", "lint": "eslint src/**/*.ts 'test/*-test.{ts,js}'",
"perf": "./scripts/perf_test.sh", "perf": "./scripts/perf_test.sh",
"start": "node scripts/http.js" "start": "node scripts/http.js"
}, },

View File

@@ -1,7 +1,7 @@
import * as _ from 'lodash' import * as _ from 'lodash'
import {EventEmitter} from 'events' import {EventEmitter} from 'events'
import {parse as parseUrl} from 'url' import {parse as parseUrl} from 'url'
import * as WebSocket from 'ws' import WebSocket from 'ws'
import RangeSet from './rangeset' import RangeSet from './rangeset'
import {RippledError, DisconnectedError, NotConnectedError, import {RippledError, DisconnectedError, NotConnectedError,
TimeoutError, ResponseFormatError, ConnectionError, TimeoutError, ResponseFormatError, ConnectionError,

View File

@@ -0,0 +1,49 @@
# XRP Ledger Hashes
Methods to hash XRP Ledger objects
## Methods
### computeBinaryTransactionHash = (txBlobHex: string): string
Compute the hash of a binary transaction blob.
### computeTransactionHash = (txJSON: any): string
Compute the hash of a transaction in txJSON format.
### computeBinaryTransactionSigningHash = (txBlobHex: string): string
### computeTransactionSigningHash = (txJSON: any): string
### computeAccountHash = (address: string): string
Compute the hash of an account, given the account's classic address (starting with `r`).
### computeSignerListHash = (address: string): string
Compute the hash of an account's SignerList.
### computeOrderHash = (address: string, sequence: number): string
Compute the hash of an order, given the owner's classic address (starting with `r`) and the account sequence number of the `OfferCreate` order transaction.
### computeTrustlineHash = (address1: string, address2: string, currency: string): string
Compute the hash of a trustline, given the two parties' classic addresses (starting with `r`) and the currency code.
### computeTransactionTreeHash = (transactions: any[]): string
### computeStateTreeHash = (entries: any[]): string
### computeLedgerHash = (ledgerHeader): string
Compute the hash of a ledger.
### computeEscrowHash = (address, sequence): string
Compute the hash of an escrow, given the owner's classic address (starting with `r`) and the account sequence number of the `EscrowCreate` escrow transaction.
### computePaymentChannelHash = (address, dstAddress, sequence): string
Compute the hash of a payment channel, given the owner's classic address (starting with `r`), the classic address of the destination, and the account sequence number of the `PaymentChannelCreate` payment channel transaction.

File diff suppressed because it is too large Load Diff

View File

@@ -35,7 +35,7 @@ class RangeSet {
} }
addRange(start: number, end: number) { addRange(start: number, end: number) {
assert(start <= end, `invalid range ${start} <= ${end}`) assert.ok(start <= end, `invalid range ${start} <= ${end}`)
this.ranges = mergeIntervals(this.ranges.concat([[start, end]])) this.ranges = mergeIntervals(this.ranges.concat([[start, end]]))
} }

View File

@@ -121,7 +121,7 @@ function loadSchemas() {
] ]
const titles = schemas.map(schema => schema.title) const titles = schemas.map(schema => schema.title)
const duplicates = _.keys(_.pickBy(_.countBy(titles), count => count > 1)) const duplicates = _.keys(_.pickBy(_.countBy(titles), count => count > 1))
assert(duplicates.length === 0, 'Duplicate schemas for: ' + duplicates) assert.ok(duplicates.length === 0, 'Duplicate schemas for: ' + duplicates)
const validator = new Validator() const validator = new Validator()
// Register custom format validators that ignore undefined instances // Register custom format validators that ignore undefined instances
// since jsonschema will still call the format validator on a missing // since jsonschema will still call the format validator on a missing

View File

@@ -17,7 +17,7 @@ function dropsToXrp(drops: string | BigNumber): string {
if (typeof drops === 'string') { if (typeof drops === 'string') {
if (!drops.match(/^-?[0-9]*\.?[0-9]*$/)) { if (!drops.match(/^-?[0-9]*\.?[0-9]*$/)) {
throw new ValidationError(`dropsToXrp: invalid value '${drops}',` + throw new ValidationError(`dropsToXrp: invalid value '${drops}',` +
` should be a number matching (^-?[0-9]*\.?[0-9]*$).`) ` should be a number matching (^-?[0-9]*\\.?[0-9]*$).`)
} else if (drops === '.') { } else if (drops === '.') {
throw new ValidationError(`dropsToXrp: invalid value '${drops}',` + throw new ValidationError(`dropsToXrp: invalid value '${drops}',` +
` should be a BigNumber or string-encoded number.`) ` should be a BigNumber or string-encoded number.`)
@@ -51,7 +51,7 @@ function xrpToDrops(xrp: string | BigNumber): string {
if (typeof xrp === 'string') { if (typeof xrp === 'string') {
if (!xrp.match(/^-?[0-9]*\.?[0-9]*$/)) { if (!xrp.match(/^-?[0-9]*\.?[0-9]*$/)) {
throw new ValidationError(`xrpToDrops: invalid value '${xrp}',` + throw new ValidationError(`xrpToDrops: invalid value '${xrp}',` +
` should be a number matching (^-?[0-9]*\.?[0-9]*$).`) ` should be a number matching (^-?[0-9]*\\.?[0-9]*$).`)
} else if (xrp === '.') { } else if (xrp === '.') {
throw new ValidationError(`xrpToDrops: invalid value '${xrp}',` + throw new ValidationError(`xrpToDrops: invalid value '${xrp}',` +
` should be a BigNumber or string-encoded number.`) ` should be a BigNumber or string-encoded number.`)

View File

@@ -1,7 +1,7 @@
import * as assert from 'assert' import * as assert from 'assert'
function parseOrderCancellation(tx: any): object { function parseOrderCancellation(tx: any): object {
assert(tx.TransactionType === 'OfferCancel') assert.ok(tx.TransactionType === 'OfferCancel')
return { return {
orderSequence: tx.OfferSequence orderSequence: tx.OfferSequence
} }

View File

@@ -8,7 +8,7 @@ export type FormattedCheckCancel = {
} }
function parseCheckCancel(tx: any): FormattedCheckCancel { function parseCheckCancel(tx: any): FormattedCheckCancel {
assert(tx.TransactionType === 'CheckCancel') assert.ok(tx.TransactionType === 'CheckCancel')
return removeUndefined({ return removeUndefined({
checkID: tx.CheckID checkID: tx.CheckID

View File

@@ -23,7 +23,7 @@ export type FormattedCheckCash = {
} }
function parseCheckCash(tx: any): FormattedCheckCash { function parseCheckCash(tx: any): FormattedCheckCash {
assert(tx.TransactionType === 'CheckCash') assert.ok(tx.TransactionType === 'CheckCash')
return removeUndefined({ return removeUndefined({
checkID: tx.CheckID, checkID: tx.CheckID,

View File

@@ -24,7 +24,7 @@ export type FormattedCheckCreate = {
} }
function parseCheckCreate(tx: any): FormattedCheckCreate { function parseCheckCreate(tx: any): FormattedCheckCreate {
assert(tx.TransactionType === 'CheckCreate') assert.ok(tx.TransactionType === 'CheckCreate')
return removeUndefined({ return removeUndefined({
destination: tx.Destination, destination: tx.Destination,

View File

@@ -10,7 +10,7 @@ export type FormattedDepositPreauth = {
} }
function parseDepositPreauth(tx: any): FormattedDepositPreauth { function parseDepositPreauth(tx: any): FormattedDepositPreauth {
assert(tx.TransactionType === 'DepositPreauth') assert.ok(tx.TransactionType === 'DepositPreauth')
return removeUndefined({ return removeUndefined({
authorize: tx.Authorize, authorize: tx.Authorize,

View File

@@ -3,7 +3,7 @@ import {parseMemos} from './utils'
import {removeUndefined} from '../../common' import {removeUndefined} from '../../common'
function parseEscrowCancellation(tx: any): object { function parseEscrowCancellation(tx: any): object {
assert(tx.TransactionType === 'EscrowCancel') assert.ok(tx.TransactionType === 'EscrowCancel')
return removeUndefined({ return removeUndefined({
memos: parseMemos(tx), memos: parseMemos(tx),

View File

@@ -4,7 +4,7 @@ import {parseTimestamp, parseMemos} from './utils'
import {removeUndefined} from '../../common' import {removeUndefined} from '../../common'
function parseEscrowCreation(tx: any): object { function parseEscrowCreation(tx: any): object {
assert(tx.TransactionType === 'EscrowCreate') assert.ok(tx.TransactionType === 'EscrowCreate')
return removeUndefined({ return removeUndefined({
amount: parseAmount(tx.Amount).value, amount: parseAmount(tx.Amount).value,

View File

@@ -3,7 +3,7 @@ import {parseMemos} from './utils'
import {removeUndefined} from '../../common' import {removeUndefined} from '../../common'
function parseEscrowExecution(tx: any): object { function parseEscrowExecution(tx: any): object {
assert(tx.TransactionType === 'EscrowFinish') assert.ok(tx.TransactionType === 'EscrowFinish')
return removeUndefined({ return removeUndefined({
memos: parseMemos(tx), memos: parseMemos(tx),

View File

@@ -10,7 +10,7 @@ import {
const flags = txFlags.OfferCreate const flags = txFlags.OfferCreate
function parseOrder(tx: OfferCreateTransaction): FormattedOrderSpecification { function parseOrder(tx: OfferCreateTransaction): FormattedOrderSpecification {
assert(tx.TransactionType === 'OfferCreate') assert.ok(tx.TransactionType === 'OfferCreate')
const direction = (tx.Flags & flags.Sell) === 0 ? 'buy' : 'sell' const direction = (tx.Flags & flags.Sell) === 0 ? 'buy' : 'sell'
const takerGetsAmount = parseAmount(tx.TakerGets) const takerGetsAmount = parseAmount(tx.TakerGets)

View File

@@ -4,7 +4,7 @@ import parseAmount from './amount'
const claimFlags = txFlags.PaymentChannelClaim const claimFlags = txFlags.PaymentChannelClaim
function parsePaymentChannelClaim(tx: any): object { function parsePaymentChannelClaim(tx: any): object {
assert(tx.TransactionType === 'PaymentChannelClaim') assert.ok(tx.TransactionType === 'PaymentChannelClaim')
return removeUndefined({ return removeUndefined({
channel: tx.Channel, channel: tx.Channel,

View File

@@ -4,7 +4,7 @@ import {removeUndefined} from '../../common'
import parseAmount from './amount' import parseAmount from './amount'
function parsePaymentChannelCreate(tx: any): object { function parsePaymentChannelCreate(tx: any): object {
assert(tx.TransactionType === 'PaymentChannelCreate') assert.ok(tx.TransactionType === 'PaymentChannelCreate')
return removeUndefined({ return removeUndefined({
amount: parseAmount(tx.Amount).value, amount: parseAmount(tx.Amount).value,

View File

@@ -4,7 +4,7 @@ import {removeUndefined} from '../../common'
import parseAmount from './amount' import parseAmount from './amount'
function parsePaymentChannelFund(tx: any): object { function parsePaymentChannelFund(tx: any): object {
assert(tx.TransactionType === 'PaymentChannelFund') assert.ok(tx.TransactionType === 'PaymentChannelFund')
return removeUndefined({ return removeUndefined({
channel: tx.Channel, channel: tx.Channel,

View File

@@ -19,7 +19,7 @@ function removeGenericCounterparty(amount, address) {
// Payment specification // Payment specification
function parsePayment(tx: any): object { function parsePayment(tx: any): object {
assert(tx.TransactionType === 'Payment') assert.ok(tx.TransactionType === 'Payment')
const source = { const source = {
address: tx.Account, address: tx.Account,

View File

@@ -7,7 +7,7 @@ import parseFields from './fields'
function getAccountRootModifiedNode(tx: any) { function getAccountRootModifiedNode(tx: any) {
const modifiedNodes = tx.meta.AffectedNodes.filter(node => const modifiedNodes = tx.meta.AffectedNodes.filter(node =>
node.ModifiedNode.LedgerEntryType === 'AccountRoot') node.ModifiedNode.LedgerEntryType === 'AccountRoot')
assert(modifiedNodes.length === 1) assert.ok(modifiedNodes.length === 1)
return modifiedNodes[0].ModifiedNode return modifiedNodes[0].ModifiedNode
} }
@@ -51,7 +51,7 @@ function parseFlags(tx: any): any {
function parseSettings(tx: any) { function parseSettings(tx: any) {
const txType = tx.TransactionType const txType = tx.TransactionType
assert(txType === 'AccountSet' || txType === 'SetRegularKey' || assert.ok(txType === 'AccountSet' || txType === 'SetRegularKey' ||
txType === 'SignerListSet') txType === 'SignerListSet')
return _.assign({}, parseFlags(tx), parseFields(tx)) return _.assign({}, parseFlags(tx), parseFields(tx))

View File

@@ -14,7 +14,7 @@ function parseFlag(flagsValue, trueValue, falseValue) {
} }
function parseTrustline(tx: any): object { function parseTrustline(tx: any): object {
assert(tx.TransactionType === 'TrustSet') assert.ok(tx.TransactionType === 'TrustSet')
return removeUndefined({ return removeUndefined({
limit: tx.LimitAmount.value, limit: tx.LimitAmount.value,

View File

@@ -1,5 +1,5 @@
import * as _ from 'lodash' import * as _ from 'lodash'
import transactionParser = require('ripple-lib-transactionparser') import transactionParser from 'ripple-lib-transactionparser'
import BigNumber from 'bignumber.js' import BigNumber from 'bignumber.js'
import * as common from '../../common' import * as common from '../../common'
import parseAmount from './amount' import parseAmount from './amount'

View File

@@ -30,8 +30,12 @@ function attachTransactionDate(connection: Connection, tx: any
if (!ledgerVersion) { if (!ledgerVersion) {
return new Promise(() => { return new Promise(() => {
throw new errors.NotFoundError( const error = new errors.NotFoundError(
'ledger_index and LedgerSequence not found in tx') 'Transaction has not been validated yet; try again later')
error.data = {
details: '(ledger_index and LedgerSequence not found in tx)'
}
throw error
}) })
} }

View File

@@ -1,5 +1,5 @@
import * as _ from 'lodash' import * as _ from 'lodash'
import binary = require('ripple-binary-codec') import binary from 'ripple-binary-codec';
import {computeTransactionHash} from '../common/hashes' import {computeTransactionHash} from '../common/hashes'
import * as utils from './utils' import * as utils from './utils'
import parseTransaction from './parse/transaction' import parseTransaction from './parse/transaction'

View File

@@ -4,7 +4,7 @@ import * as common from '../common'
import {Connection} from '../common' import {Connection} from '../common'
import {FormattedTransactionType} from '../transaction/types' import {FormattedTransactionType} from '../transaction/types'
import {Issue} from '../common/types/objects' import {Issue} from '../common/types/objects'
import {RippleAPI} from '..' import {RippleAPI} from '..'
export type RecursiveData = { export type RecursiveData = {
marker: string, marker: string,
@@ -14,7 +14,7 @@ export type RecursiveData = {
export type Getter = (marker?: string, limit?: number) => Promise<RecursiveData> export type Getter = (marker?: string, limit?: number) => Promise<RecursiveData>
function clamp(value: number, min: number, max: number): number { function clamp(value: number, min: number, max: number): number {
assert(min <= max, 'Illegal clamp bounds') assert.ok(min <= max, 'Illegal clamp bounds')
return Math.min(Math.max(value, min), max) return Math.min(Math.max(value, min), max)
} }

View File

@@ -1,4 +1,4 @@
import keypairs = require('ripple-keypairs') import keypairs from 'ripple-keypairs'
import * as common from '../common' import * as common from '../common'
const {errors, validate} = common const {errors, validate} = common

View File

@@ -1,6 +1,6 @@
import * as common from '../common' import * as common from '../common'
import keypairs = require('ripple-keypairs') import keypairs from 'ripple-keypairs'
import binary = require('ripple-binary-codec') import binary from 'ripple-binary-codec'
const {validate, xrpToDrops} = common const {validate, xrpToDrops} = common
function signPaymentChannelClaim(channel: string, amount: string, function signPaymentChannelClaim(channel: string, amount: string,

View File

@@ -1,5 +1,5 @@
import keypairs = require('ripple-keypairs') import keypairs from 'ripple-keypairs'
import binary = require('ripple-binary-codec') import binary from 'ripple-binary-codec'
import {validate, xrpToDrops} from '../common' import {validate, xrpToDrops} from '../common'
function verifyPaymentChannelClaim(channel: string, amount: string, function verifyPaymentChannelClaim(channel: string, amount: string,

View File

@@ -1,5 +1,5 @@
import * as _ from 'lodash' import * as _ from 'lodash'
import binary = require('ripple-binary-codec') import binary from 'ripple-binary-codec'
import * as utils from './utils' import * as utils from './utils'
import BigNumber from 'bignumber.js' import BigNumber from 'bignumber.js'
import {decodeAddress} from 'ripple-address-codec' import {decodeAddress} from 'ripple-address-codec'

View File

@@ -10,7 +10,7 @@ import {RippleAPI} from '..'
function setTransactionFlags(txJSON: utils.TransactionJSON, values: FormattedSettings) { function setTransactionFlags(txJSON: utils.TransactionJSON, values: FormattedSettings) {
const keys = Object.keys(values) const keys = Object.keys(values)
assert(keys.length === 1, 'ERROR: can only set one setting per transaction') assert.ok(keys.length === 1, 'ERROR: can only set one setting per transaction')
const flagName = keys[0] const flagName = keys[0]
const value = values[flagName] const value = values[flagName]
const index = AccountFlagIndices[flagName] const index = AccountFlagIndices[flagName]

View File

@@ -1,13 +1,13 @@
import * as isEqual from '../common/js/lodash.isequal' import isEqual from 'lodash.isequal'
import * as utils from './utils' import * as utils from './utils'
import keypairs = require('ripple-keypairs') import keypairs from 'ripple-keypairs'
import binaryCodec = require('ripple-binary-codec') import binaryCodec from 'ripple-binary-codec'
import {computeBinaryTransactionHash} from '../common/hashes' import {computeBinaryTransactionHash} from '../common/hashes'
import {SignOptions, KeyPair} from './types' import {SignOptions, KeyPair} from './types'
import {BigNumber} from 'bignumber.js' import {BigNumber} from 'bignumber.js'
import {xrpToDrops} from '../common' import {xrpToDrops} from '../common'
import {RippleAPI} from '..' import {RippleAPI} from '..'
const validate = utils.common.validate const validate = utils.common.validate
function computeSignature(tx: object, privateKey: string, signAs?: string) { function computeSignature(tx: object, privateKey: string, signAs?: string) {
const signingData = signAs const signingData = signAs

View File

@@ -147,17 +147,17 @@ describe('RippleAPI', function () {
assert.throws(() => { assert.throws(() => {
this.api.xrpToDrops('.') this.api.xrpToDrops('.')
}, /xrpToDrops\: invalid value '\.', should be a BigNumber or string-encoded number\./) }, /xrpToDrops: invalid value '\.', should be a BigNumber or string-encoded number\./)
}) })
it('throws with an amount more than one decimal point', function () { it('throws with an amount more than one decimal point', function () {
assert.throws(() => { assert.throws(() => {
this.api.xrpToDrops('1.0.0') this.api.xrpToDrops('1.0.0')
}, /xrpToDrops:\ invalid\ value\ '1\.0\.0'\,\ should\ be\ a\ number\ matching\ \(\^\-\?\[0\-9\]\*\.\?\[0\-9\]\*\$\)\./) }, /xrpToDrops: invalid value '1\.0\.0', should be a number matching \(\^-\?\[0-9\]\*\.\?\[0-9\]\*\$\)\./)
assert.throws(() => { assert.throws(() => {
this.api.xrpToDrops('...') this.api.xrpToDrops('...')
}, /xrpToDrops:\ invalid\ value\ '\.\.\.'\,\ should\ be\ a\ number\ matching\ \(\^\-\?\[0\-9\]\*\.\?\[0\-9\]\*\$\)\./) }, /xrpToDrops: invalid value '\.\.\.', should be a number matching \(\^-\?\[0-9\]\*\.\?\[0-9\]\*\$\)\./)
}) })
}) })
@@ -261,17 +261,17 @@ describe('RippleAPI', function () {
assert.throws(() => { assert.throws(() => {
this.api.dropsToXrp('.') this.api.dropsToXrp('.')
}, /dropsToXrp\: invalid value '\.', should be a BigNumber or string-encoded number\./) }, /dropsToXrp: invalid value '\.', should be a BigNumber or string-encoded number\./)
}) })
it('throws with an amount more than one decimal point', function () { it('throws with an amount more than one decimal point', function () {
assert.throws(() => { assert.throws(() => {
this.api.dropsToXrp('1.0.0') this.api.dropsToXrp('1.0.0')
}, /dropsToXrp:\ invalid\ value\ '1\.0\.0'\,\ should\ be\ a\ number\ matching\ \(\^\-\?\[0\-9\]\*\.\?\[0\-9\]\*\$\)\./) }, /dropsToXrp: invalid value '1\.0\.0', should be a number matching \(\^-\?\[0-9\]\*\.\?\[0-9\]\*\$\)\./)
assert.throws(() => { assert.throws(() => {
this.api.dropsToXrp('...') this.api.dropsToXrp('...')
}, /dropsToXrp:\ invalid\ value\ '\.\.\.'\,\ should\ be\ a\ number\ matching\ \(\^\-\?\[0\-9\]\*\.\?\[0\-9\]\*\$\)\./) }, /dropsToXrp: invalid value '\.\.\.', should be a number matching \(\^-\?\[0-9\]\*\.\?\[0-9\]\*\$\)\./)
}) })
}) })
@@ -311,7 +311,7 @@ describe('RippleAPI', function () {
it('throws with an invalid secret', function (){ it('throws with an invalid secret', function (){
assert.throws(() => { assert.throws(() => {
this.api.deriveKeypair('...'); this.api.deriveKeypair('...');
}, /^Error\: Non\-base58 character$/) }, /^Error: Non-base58 character$/)
}) })
}) })
@@ -1364,7 +1364,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('rejects promise and does not throw when field is missing', function (done) { it('rejects promise and does not throw when field is missing', function (done) {
@@ -1393,7 +1393,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('rejects promise and does not throw when fee exceeds maxFeeXRP', function (done) { it('rejects promise and does not throw when fee exceeds maxFeeXRP', function (done) {
@@ -1427,7 +1427,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('preparePayment - XRP to XRP no partial', function (done) { it('preparePayment - XRP to XRP no partial', function (done) {
@@ -1442,7 +1442,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('preparePayment - address must match payment.source.address', function (done) { it('preparePayment - address must match payment.source.address', function (done) {
@@ -1457,7 +1457,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('preparePayment - wrong amount', function (done) { it('preparePayment - wrong amount', function (done) {
@@ -1472,7 +1472,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('preparePayment - throws when fee exceeds 2 XRP', function (done) { it('preparePayment - throws when fee exceeds 2 XRP', function (done) {
@@ -1492,7 +1492,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
}); });
@@ -1593,7 +1593,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('prepareOrderCancellation', function () { it('prepareOrderCancellation', function () {
@@ -1632,7 +1632,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('prepareTrustline - simple', function () { it('prepareTrustline - simple', function () {
@@ -1667,7 +1667,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('prepareSettings', function () { it('prepareSettings', function () {
@@ -1764,7 +1764,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('prepareSettings - signers no weights', function () { it('prepareSettings - signers no weights', function () {
@@ -1820,7 +1820,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('prepareEscrowCreation', function () { it('prepareEscrowCreation', function () {
@@ -1855,7 +1855,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('prepareEscrowExecution', function () { it('prepareEscrowExecution', function () {
@@ -1888,7 +1888,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('prepareEscrowExecution - no fulfillment', function (done) { it('prepareEscrowExecution - no fulfillment', function (done) {
@@ -1903,7 +1903,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('prepareEscrowCancellation', function () { it('prepareEscrowCancellation', function () {
@@ -2507,7 +2507,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('rejects Promise on preparePaymentChannelClaim with no signature', function (done) { it('rejects Promise on preparePaymentChannelClaim with no signature', function (done) {
@@ -2522,7 +2522,7 @@ describe('RippleAPI', function () {
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout. }).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
} catch (err) { } catch (err) {
done(new Error('Expected method to reject, but method threw. Thrown: ' + err)); done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
}; }
}); });
it('sign', function () { it('sign', function () {

View File

@@ -1,26 +1,22 @@
{ {
"compilerOptions": { "compilerOptions": {
"pretty": true, "pretty": true,
"lib": [ "target": "es2017",
"es2017" "module": "commonjs",
], "moduleResolution": "node",
"target": "es6",
"declaration": true, "declaration": true,
"declarationMap": true /* Added 2019-04-13 */, "declarationMap": true /* Added 2019-04-13 */,
"sourceMap": true, "sourceMap": true,
"noEmitOnError": true /* Added 2019-04-13 */,
"strict": true /* Enable all strict type-checking options. */,
"strictNullChecks": false, "strictNullChecks": false,
"noImplicitAny": false, "noImplicitAny": false,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,
"removeComments": true, "removeComments": true,
"strict": true /* Enable all strict type-checking options. */,
"preserveConstEnums": false, "preserveConstEnums": false,
"esModuleInterop": true,
"module": "commonjs",
"moduleResolution": "node",
"suppressImplicitAnyIndexErrors": false "suppressImplicitAnyIndexErrors": false
} }
} }

View File

@@ -1,76 +0,0 @@
{
"extends": [
"tslint-eslint-rules"
],
"rules": {
"ban": [true, ["alert"]],
"no-arg": true,
"no-conditional-assignment": true,
"no-console": false,
"no-constant-condition": true,
"no-control-regex": true,
"no-debugger": true,
"no-duplicate-case": true,
"no-empty": true,
"no-empty-character-class": true,
"no-eval": true,
"no-ex-assign": true,
"no-extra-boolean-cast": true,
"no-extra-semi": true,
"no-switch-case-fall-through": true,
"no-inner-declarations": [true, "functions"],
"no-invalid-regexp": true,
// this rule would cause problems with mocha test cases,
"no-invalid-this": false,
"no-irregular-whitespace": true,
"ter-no-irregular-whitespace": true,
"label-position": true,
"indent": [true, "spaces", 2],
"linebreak-style": [true, "unix"],
"no-multi-spaces": true,
"no-consecutive-blank-lines": [true, 2],
"no-unused-expression": true,
"no-construct": true,
"no-duplicate-variable": true,
"no-regex-spaces": true,
"no-shadowed-variable": true,
"ter-no-sparse-arrays": true,
"no-trailing-whitespace": true,
"no-string-throw": true,
"no-unexpected-multiline": true,
"no-unused-variable": [true, {"ignore-pattern": "^_"}],
"no-use-before-declare": true,
"no-var-keyword": true,
"no-magic-numbers": false,
"array-bracket-spacing": [true, "never"],
"ter-arrow-body-style": false,
"ter-arrow-parens": [true, "as-needed"],
"ter-arrow-spacing": true,
"block-spacing": true,
"brace-style": [true, "1tbs", {"allowSingleLine": true}],
"variable-name": false,
"trailing-comma": [true, {"multiline": "never", "singleline": "never"}],
"cyclomatic-complexity": [false, 11],
"curly": [true, "all"],
"switch-default": false,
"eofline": true,
"triple-equals": true,
"forin": false,
"handle-callback-err": true,
"ter-max-len": [true, 120],
"new-parens": true,
"object-curly-spacing": [true, "never"],
"object-literal-shorthand": false,
"one-variable-per-declaration": [true, "ignore-for-loop"],
"ter-prefer-arrow-callback": false,
"prefer-const": true,
"object-literal-key-quotes": false,
"quotemark": [true, "single"],
"radix": true,
"semicolon": [true, "never"],
"space-in-parens": [true, "never"],
"comment-format": [true, "check-space"],
"use-isnan": true,
"valid-typeof": true
}
}

1284
yarn.lock

File diff suppressed because it is too large Load Diff