Compare commits

...

17 Commits

Author SHA1 Message Date
Elliot Lee
dc623cd049 Release 1.0.0-beta.5 2018-08-11 01:38:36 -07:00
Elliot Lee
7cd517268b Fix error TS2307: Cannot find module 2018-08-11 01:35:47 -07:00
Elliot Lee
2438295e70 Release 1.0.0-beta.4 2018-08-10 14:58:19 -07:00
Elliot Lee
f5e1a4a588 Revert "Expose validation methods in public api"
This reverts commit 9e9a0a7d9b.

We should move methods like deriveKeypair and deriveAddress
off of the schemaValidator object.
2018-08-10 14:54:01 -07:00
Mo Morsi
9e9a0a7d9b Expose validation methods in public api
Updated to fix tests
2018-08-06 16:09:04 -07:00
Elliot Lee
1c68283d1e ES6: omit property value since it matches the variable name 2018-07-28 00:42:37 -07:00
Elliot Lee
28796d37cb Update TypeScript to 2.9.2 2018-07-28 00:18:58 -07:00
Elliot Lee
067bc48d4e Add prepareTransaction() (#898)
* Export iso8601ToRippleTime(), txFlags, convertStringToHex()

* Fix a bug that caused fees exceeding 999 to throw an error

e.g. '1,000' would not be recognized as a valid number.
To use 6 decimal places, toFixed should be used instead of toFormat.
2018-07-26 12:24:29 -07:00
Fred K. Schott
b94698df0b Update some API methods to use api.request() internally (#896)
* use any instead of object
2018-07-26 12:23:07 -07:00
Elliot Lee
4f40b5cb6d Update README.md - How to build ripple-lib (#837) 2018-07-25 12:09:55 -07:00
Elliot Lee
14704eee6b Add more tests of getFee (#897) 2018-07-25 01:53:27 -07:00
Elliot Lee
860f6a6cd8 Release 1.0.0-beta.3 2018-07-17 22:39:00 -07:00
Elliot Lee
7a928804ec feat: add payment channel details to tx (2) (#920)
* Bump transactionparser to v0.7.1 and update output schema
* yarn docgen for required `threshold` and `weights`
2018-07-17 22:22:07 -07:00
adrianhopebailie
14444bea3f feat: add payment channel details to tx 2018-07-17 22:20:47 -07:00
Rome Reginelli
47a139fdff Fix text/plain MIMETYPE in examples with memos (#914) 2018-07-03 17:18:46 -07:00
Brandon Wilson
4e30b9b2fa Require threshold and weights in signers settings (#909)
Fixes #908
2018-07-02 16:27:03 -07:00
Elliot Lee
2112d4c0b3 Round XRP fee to 6 decimal places (#912)
* Round XRP fee to 6 decimal places

Fix #911
2018-06-28 17:59:00 -07:00
45 changed files with 734 additions and 124 deletions

View File

@@ -1,5 +1,37 @@
# ripple-lib Release History
## 1.0.0-beta.5 (2018-08-11)
+ [Fix a TypeScript error by importing the `Prepare` type](https://github.com/ripple/ripple-lib/commit/7cd517268bda5fe74b91dad02fedf8b51b7eae9b)
## 1.0.0-beta.4 (2018-08-10)
+ [Add `prepareTransaction()`](https://github.com/ripple/ripple-lib/pull/898)
+ Internal improvements and cleanup
## 1.0.0-beta.3 (2018-07-17)
+ For payment channel transactions, `getTransaction` includes a new
`channelChanges` property that describes the details of the payment channel.
(#920)
### Bug Fixes
+ A bug caused calculated fees to use too many decimal places. This was fixed by
rounding fees to 6 decimal places. (#912)
+ When using the Settings transaction to set up a multi-signing list, the
threshold and weights fields are required. (#909)
+ Docs: Fix the MIMETYPE in examples with memos. (#914)
The SHA-256 checksums for the browser version of this release can be found
below.
```
% shasum -a 256 *
460dbb521e24c44cb53dabc1a74feeca33d031b44d889dd5b51103ca92d51de6 ripple-1.0.0-beta.3-debug.js
cccfd24973c6b7990d9e933a589175dae26249825737fff4f2f73d8558a3f186 ripple-1.0.0-beta.3-min.js
0dc456a58fb078347d9920310621595905085595d73c2b8fe96bea73bcf35450 ripple-1.0.0-beta.3.js
```
## 1.0.0-beta.2 (2018-06-08)
### Breaking Changes

View File

@@ -38,6 +38,24 @@ If you're using the XRP Ledger in production, you should run a [rippled server](
+ [Subscribe to ripple-server](https://groups.google.com/forum/#!forum/ripple-server)
## Development
To build the library for Node.js:
```
$ yarn compile
```
The TypeScript compiler will [output](./tsconfig.json#L7) the resulting JS files in `./dist/npm/`.
To build the library for the browser:
```
$ yarn build
```
Gulp will [output](./Gulpfile.js) the resulting JS files in `./build/`.
For more details, see the `scripts` in `package.json`.
## Running tests
1. Clone the repository

View File

@@ -430,7 +430,7 @@ ripplingDisabled | boolean | *Optional* If true, payments cannot ripple through
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
]
@@ -516,8 +516,8 @@ regularKey | [address](#address),null | *Optional* The public key of a new keypa
requireAuthorization | boolean | *Optional* If set, this account must individually approve other users in order for those users to hold this accounts issuances.
requireDestinationTag | boolean | *Optional* Requires incoming payments to specify a destination tag.
signers | object | *Optional* Settings that determine what sets of accounts can be used to sign a transaction on behalf of this account using multisigning.
*signers.* threshold | integer | *Optional* A target number for the signer weights. A multi-signature from this list is valid only if the sum weights of the signatures provided is equal or greater than this value. To delete the signers setting, use the value `0`.
*signers.* weights | array | *Optional* Weights of signatures for each signer.
*signers.* threshold | integer | A target number for the signer weights. A multi-signature from this list is valid only if the sum weights of the signatures provided is equal or greater than this value. To delete the signers setting, use the value `0`.
*signers.* weights | array | Weights of signatures for each signer.
*signers.* weights[] | object | An association of an address and a weight.
*signers.weights[].* address | [address](#address) | A Ripple account address
*signers.weights[].* weight | integer | The weight that the signature of this account counts as towards the threshold.
@@ -532,7 +532,7 @@ transferRate | number,null | *Optional* The fee to charge when users transfer t
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
]
@@ -1075,6 +1075,8 @@ return api.getServerInfo().then(info => {/* ... */});
Returns the estimated transaction fee for the rippled server the RippleAPI instance is connected to.
This will use the [feeCushion parameter](#parameters) provided to the RippleAPI constructor, or the default value of `1.2`.
### Parameters
Name | Type | Description
@@ -1083,7 +1085,7 @@ cushion | number | *Optional* The fee is the product of the base fee, the `load_
### Return Value
This method returns a promise that resolves with a string encoded floating point value representing the estimated fee to submit a transaction, expressed in XRP.
This method returns a promise that resolves with a string-encoded floating point value representing the estimated fee to submit a transaction, expressed in XRP.
### Example
@@ -1092,7 +1094,7 @@ return api.getFee().then(fee => {/* ... */});
```
```json
"0.012"
"0.000012"
```
## getLedgerVersion
@@ -1153,8 +1155,8 @@ specification | object | A specification that would produce the same outcome as
outcome | object | The outcome of the transaction (what effects it had).
*outcome.* result | string | Result code returned by rippled. See [Transaction Results](https://ripple.com/build/transactions/#full-transaction-response-list) for a complete list.
*outcome.* fee | [value](#value) | The XRP fee that was charged for the transaction.
*outcome.balanceChanges.* \* | array\<[balance](#amount)\> | Key is the ripple address; value is an array of signed amounts representing changes of balances for that address.
*outcome.orderbookChanges.* \* | array | Key is the maker's ripple address; value is an array of changes
*outcome.balanceChanges.* \* | array\<[balance](#amount)\> | Key is the XRP Ledger address; value is an array of signed amounts representing changes of balances for that address.
*outcome.orderbookChanges.* \* | array | Key is the maker's XRP Ledger address; value is an array of changes
*outcome.orderbookChanges.* \*[] | object | A change to an order.
*outcome.orderbookChanges.\*[].* direction | string | Equal to "buy" for buy orders and "sell" for sell orders.
*outcome.orderbookChanges.\*[].* quantity | [amount](#amount) | The amount to be bought or sold by the maker.
@@ -1166,6 +1168,7 @@ outcome | object | The outcome of the transaction (what effects it had).
*outcome.* ledgerVersion | integer | The ledger version that the transaction was validated in.
*outcome.* ledgerVersion | string | The ledger version that the transaction was validated in.
*outcome.* indexInLedger | integer | The ordering index of the transaction in the ledger.
*outcome.* channelChanges | object | *Optional* Properties reflecting the details of the payment channel.
*outcome.* deliveredAmount | [amount](#amount) | *Optional* For payment transactions, it is impossible to reliably compute the actual delivered amount from the balanceChanges due to fixed precision. If the payment is not a partial payment and the transaction succeeded, the deliveredAmount should always be considered to be the amount specified in the transaction.
*outcome.* timestamp | date-time string | *Optional* The timestamp when the transaction was validated. (May be missing when requesting transactions in binary mode.)
@@ -3566,8 +3569,8 @@ regularKey | [address](#address),null | *Optional* The public key of a new keypa
requireAuthorization | boolean | *Optional* If set, this account must individually approve other users in order for those users to hold this accounts issuances.
requireDestinationTag | boolean | *Optional* Requires incoming payments to specify a destination tag.
signers | object | *Optional* Settings that determine what sets of accounts can be used to sign a transaction on behalf of this account using multisigning.
*signers.* threshold | integer | *Optional* A target number for the signer weights. A multi-signature from this list is valid only if the sum weights of the signatures provided is equal or greater than this value. To delete the signers setting, use the value `0`.
*signers.* weights | array | *Optional* Weights of signatures for each signer.
*signers.* threshold | integer | A target number for the signer weights. A multi-signature from this list is valid only if the sum weights of the signatures provided is equal or greater than this value. To delete the signers setting, use the value `0`.
*signers.* weights | array | Weights of signatures for each signer.
*signers.* weights[] | object | An association of an address and a weight.
*signers.weights[].* address | [address](#address) | A Ripple account address
*signers.weights[].* weight | integer | The weight that the signature of this account counts as towards the threshold.
@@ -4217,7 +4220,7 @@ const trustline = {
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
]
@@ -4229,7 +4232,7 @@ return api.prepareTrustline(address, trustline).then(prepared =>
```json
{
"txJSON": "{\"TransactionType\":\"TrustSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"LimitAmount\":{\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\",\"value\":\"10000\"},\"Flags\":2149711872,\"QualityIn\":910000000,\"QualityOut\":870000000,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
"txJSON": "{\"TransactionType\":\"TrustSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"LimitAmount\":{\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\",\"value\":\"10000\"},\"Flags\":2149711872,\"QualityIn\":910000000,\"QualityOut\":870000000,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"746578742F706C61696E\"}}],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
"instructions": {
"fee": "0.000012",
"sequence": 23,
@@ -4400,7 +4403,7 @@ const settings = {
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
]
@@ -4416,7 +4419,7 @@ return api.prepareSettings(address, settings)
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
]

View File

@@ -4,13 +4,15 @@
Returns the estimated transaction fee for the rippled server the RippleAPI instance is connected to.
This will use the [feeCushion parameter](#parameters) provided to the RippleAPI constructor, or the default value of `1.2`.
### Parameters
<%- renderSchema('input/get-fee.json') %>
### Return Value
This method returns a promise that resolves with a string encoded floating point value representing the estimated fee to submit a transaction, expressed in XRP.
This method returns a promise that resolves with a string-encoded floating point value representing the estimated fee to submit a transaction, expressed in XRP.
### Example
@@ -19,5 +21,5 @@ return api.getFee().then(fee => {/* ... */});
```
```json
"0.012"
"0.000012"
```

View File

@@ -1,6 +1,6 @@
{
"name": "ripple-lib",
"version": "1.0.0-beta.2",
"version": "1.0.0-beta.5",
"license": "ISC",
"description": "A JavaScript API for interacting with Ripple in Node.js and the browser",
"files": [
@@ -26,7 +26,7 @@
"ripple-binary-codec": "^0.1.13",
"ripple-hashes": "^0.3.1",
"ripple-keypairs": "^0.10.1",
"ripple-lib-transactionparser": "^0.6.2",
"ripple-lib-transactionparser": "0.7.1",
"ws": "^3.3.1"
},
"devDependencies": {
@@ -53,7 +53,7 @@
"ts-node": "^3.3.0",
"tslint": "^5.8.0",
"tslint-eslint-rules": "^4.1.1",
"typescript": "^2.6.1",
"typescript": "2.9.2",
"uglifyjs-webpack-plugin": "^1.1.4",
"webpack": "^3.10.0",
"yargs": "^8.0.2"

View File

@@ -1,5 +1,13 @@
import {EventEmitter} from 'events'
import {Connection, errors, validate, xrpToDrops, dropsToXrp} from './common'
import {
Connection,
errors,
validate,
xrpToDrops,
dropsToXrp,
iso8601ToRippleTime,
txFlags
} from './common'
import {
connect,
disconnect,
@@ -57,9 +65,11 @@ import {
import RangeSet from './common/rangeset'
import * as ledgerUtils from './ledger/utils'
import * as transactionUtils from './transaction/utils'
import * as schemaValidator from './common/schema-validator'
import {getServerInfo, getFee} from './common/serverinfo'
import {clamp} from './ledger/utils'
import {Instructions, Prepare} from './transaction/types'
export type APIOptions = {
server?: string,
@@ -97,7 +107,7 @@ class RippleAPI extends EventEmitter {
// these are exposed only for use by unit tests; they are not part of the API.
static _PRIVATE = {
validate: validate,
validate,
RangeSet,
ledgerUtils,
schemaValidator
@@ -131,19 +141,16 @@ class RippleAPI extends EventEmitter {
}
/**
* Makes a request to the API with the given command and
* additional request body parameters.
*/
async request(command: 'account_info', params: AccountInfoRequest):
Promise<AccountInfoResponse>
async request(command: 'account_lines', params: AccountLinesRequest):
Promise<AccountLinesResponse>
/**
* Returns objects owned by an account.
* For an account's trust lines and balances,
* see `getTrustlines` and `getBalances`.
*/
async request(command: 'account_objects', params: AccountObjectsRequest):
Promise<AccountObjectsResponse>
async request(command: 'account_offers', params: AccountOffersRequest):
Promise<AccountOffersResponse>
async request(command: 'book_offers', params: BookOffersRequest):
@@ -156,15 +163,9 @@ class RippleAPI extends EventEmitter {
Promise<LedgerEntryResponse>
async request(command: 'server_info', params?: ServerInfoRequest):
Promise<ServerInfoResponse>
async request(command: string, params: object):
Promise<object>
/**
* Makes a request to the API with the given command and
* additional request body parameters.
*/
async request(command: string, params: object = {}): Promise<object> {
async request(command: string, params: any):
Promise<any>
async request(command: string, params: any = {}): Promise<any> {
return this.connection.request({
...params,
command
@@ -199,6 +200,27 @@ class RippleAPI extends EventEmitter {
return this.request(command, nextPageParams)
}
/**
* Prepare a transaction.
*
* You can later submit the transaction with `submit()`.
*/
async prepareTransaction(txJSON: object, instructions: Instructions = {}):
Promise<Prepare> {
return transactionUtils.prepareTransaction(txJSON, this, instructions)
}
/**
* Convert a string to hex.
*
* This can be used to generate `MemoData`, `MemoType`, and `MemoFormat`.
*
* @param string string to convert to hex
*/
convertStringToHex(string: string): string {
return transactionUtils.convertStringToHex(string)
}
/**
* Makes multiple paged requests to the API to return a given number of
* resources. _requestAll() will make multiple requests until the `limit`
@@ -306,6 +328,8 @@ class RippleAPI extends EventEmitter {
xrpToDrops = xrpToDrops
dropsToXrp = dropsToXrp
iso8601ToRippleTime = iso8601ToRippleTime
txFlags = txFlags
}
export {

View File

@@ -93,7 +93,9 @@
"minItems": 1,
"maxItems": 8
}
}
},
"required": ["threshold", "weights"],
"additionalProperties": false
},
"transferRate": {
"description": " The fee to charge when users transfer this accounts issuances, as the decimal amount that must be sent to deliver 1 unit. Has precision up to 9 digits beyond the decimal point. Use `null` to set no fee.",

View File

@@ -25,7 +25,7 @@
"type": "object",
"additionalProperties": {
"type": "array",
"description": "Key is the ripple address; value is an array of signed amounts representing changes of balances for that address.",
"description": "Key is the XRP Ledger address; value is an array of signed amounts representing changes of balances for that address.",
"items": {"$ref": "balance"}
}
},
@@ -33,10 +33,14 @@
"type": "object",
"additionalProperties": {
"type": "array",
"description": "Key is the maker's ripple address; value is an array of changes",
"description": "Key is the maker's XRP Ledger address; value is an array of changes",
"items": {"$ref": "orderChange"}
}
},
"channelChanges": {
"type": "object",
"description": "Properties reflecting the details of the payment channel."
},
"ledgerVersion": {
"$ref": "ledgerVersion",
"description": "The ledger version that the transaction was validated in."

View File

@@ -61,6 +61,8 @@ function getServerInfo(this: RippleAPI): Promise<GetServerInfoResponse> {
})
}
// This is a public API that can be called directly.
// This is not used by the `prepare*` methods. See `src/transaction/utils.ts`
async function getFee(
this: RippleAPI,
cushion?: number
@@ -74,10 +76,12 @@ async function getFee(
const serverInfo = (await this.request('server_info')).info
const baseFeeXrp = new BigNumber(serverInfo.validated_ledger.base_fee_xrp)
const fee = baseFeeXrp.times(serverInfo.load_factor).times(cushion)
let fee = baseFeeXrp.times(serverInfo.load_factor).times(cushion)
// Cap fee to `this._maxFeeXRP`
return BigNumber.min(fee, this._maxFeeXRP).toString(10)
fee = BigNumber.min(fee, this._maxFeeXRP)
// Round fee to 6 decimal places
return (new BigNumber(fee.toFixed(6))).toString(10)
}
export {

View File

@@ -103,6 +103,8 @@ function parseOutcome(tx: any): any|undefined {
}
const balanceChanges = transactionParser.parseBalanceChanges(metadata)
const orderbookChanges = transactionParser.parseOrderbookChanges(metadata)
const channelChanges = transactionParser.parseChannelChanges(metadata)
removeEmptyCounterpartyInBalanceChanges(balanceChanges)
removeEmptyCounterpartyInOrderbookChanges(orderbookChanges)
@@ -112,6 +114,7 @@ function parseOutcome(tx: any): any|undefined {
fee: common.dropsToXrp(tx.Fee),
balanceChanges: balanceChanges,
orderbookChanges: orderbookChanges,
channelChanges: channelChanges,
ledgerVersion: tx.ledger_index,
indexInLedger: tx.meta.TransactionIndex,
deliveredAmount: parseDeliveredAmount(tx)

View File

@@ -18,7 +18,7 @@ type TransactionResponse = FormattedTransactionType & {
function attachTransactionDate(connection: Connection, tx: any
): Promise<FormattedTransactionType> {
): Promise<TransactionResponse> {
if (tx.date) {
return Promise.resolve(tx)
}
@@ -88,26 +88,20 @@ function formatResponse(options: TransactionOptions, tx: TransactionResponse
return parseTransaction(tx)
}
function getTransaction(id: string, options: TransactionOptions = {}
async function getTransaction(id: string, options: TransactionOptions = {}
): Promise<FormattedTransactionType> {
validate.getTransaction({id, options})
const request = {
command: 'tx',
transaction: id,
binary: false
const _options = await utils.ensureLedgerVersion.call(this, options)
try {
const tx = await this.request('tx', {
transaction: id,
binary: false
})
const txWithDate = await attachTransactionDate(this.connection, tx)
return formatResponse(_options, txWithDate)
} catch (error) {
throw (await convertError(this.connection, _options, error))
}
return utils.ensureLedgerVersion.call(this, options).then(_options => {
return this.connection.request(request).then((tx: TransactionResponse) =>
attachTransactionDate(this.connection, tx)
).then(_.partial(formatResponse, _options))
.catch(error => {
return convertError(this.connection, _options, error).then(_error => {
throw _error
})
})
})
}
export default getTransaction

View File

@@ -7,6 +7,7 @@ const ValidationError = utils.common.errors.ValidationError
import {Instructions, Prepare} from './types'
import {Amount, Adjustment, MaxAdjustment,
MinAdjustment, Memo} from '../common/types/objects'
import {xrpToDrops} from '../common'
export interface Payment {
@@ -32,12 +33,12 @@ export interface Payment {
function isMaxAdjustment(
source: Adjustment | MaxAdjustment): source is MaxAdjustment {
return (source as MaxAdjustment).maxAmount !== undefined
return (source as MaxAdjustment).maxAmount !== undefined
}
function isMinAdjustment(
destination: Adjustment | MinAdjustment): destination is MinAdjustment {
return (destination as MinAdjustment).minAmount !== undefined
return (destination as MinAdjustment).minAmount !== undefined
}
function isXRPToXRPPayment(payment: Payment): boolean {
@@ -50,7 +51,7 @@ function isXRPToXRPPayment(payment: Payment): boolean {
}
function isIOUWithoutCounterparty(amount: Amount): boolean {
return amount && amount.currency !== 'XRP'
return amount && amount.currency !== 'XRP' && amount.currency !== 'drops'
&& amount.counterparty === undefined
}
@@ -72,7 +73,14 @@ function applyAnyCounterpartyEncoding(payment: Payment): void {
function createMaximalAmount(amount: Amount): Amount {
const maxXRPValue = '100000000000'
const maxIOUValue = '9999999999999999e80'
const maxValue = amount.currency === 'XRP' ? maxXRPValue : maxIOUValue
let maxValue
if (amount.currency === 'XRP') {
maxValue = maxXRPValue
} else if (amount.currency === 'drops') {
maxValue = xrpToDrops(maxXRPValue)
} else {
maxValue = maxIOUValue
}
return _.assign({}, amount, {value: maxValue})
}

View File

@@ -1,7 +1,12 @@
import * as _ from 'lodash'
import * as utils from './utils'
import {validate} from '../common'
import {Submit} from './types'
import {RippleAPI} from '..'
export interface FormattedSubmitResponse {
resultCode: string,
resultMessage: string
}
function isImmediateRejection(engineResult: string): boolean {
// note: "tel" errors mean the local server refused to process the
@@ -13,7 +18,7 @@ function isImmediateRejection(engineResult: string): boolean {
return _.startsWith(engineResult, 'tem')
}
function formatSubmitResponse(response) {
function formatSubmitResponse(response): FormattedSubmitResponse {
const data = {
resultCode: response.engine_result,
resultMessage: response.engine_result_message
@@ -24,14 +29,15 @@ function formatSubmitResponse(response) {
return data
}
function submit(signedTransaction: string): Promise<Submit> {
async function submit(
this: RippleAPI, signedTransaction: string
): Promise<FormattedSubmitResponse> {
// 1. Validate
validate.submit({signedTransaction})
const request = {
command: 'submit',
tx_blob: signedTransaction
}
return this.connection.request(request).then(formatSubmitResponse)
// 2. Make Request
const response = await this.request('submit', {tx_blob: signedTransaction})
// 3. Return Formatted Response
return formatSubmitResponse(response)
}
export default submit

View File

@@ -22,10 +22,10 @@ export type Instructions = {
export type Prepare = {
txJSON: string,
instructions: {
fee: string,
sequence: number,
maxLedgerVersion?: number
}
fee: string,
sequence: number,
maxLedgerVersion?: number
}
}
export type Submit = {

View File

@@ -94,19 +94,16 @@ function prepareTransaction(txJSON: any, api: RippleAPI,
})
}
function prepareSequence(): Promise<Object> {
async function prepareSequence(): Promise<Object> {
if (instructions.sequence !== undefined) {
txJSON.Sequence = instructions.sequence
return Promise.resolve(txJSON)
}
const request = {
command: 'account_info',
account: account
}
return api.connection.request(request).then(response => {
txJSON.Sequence = response.account_data.Sequence
return txJSON
const response = await api.request('account_info', {
account: account as string
})
txJSON.Sequence = response.account_data.Sequence
return txJSON
}
return Promise.all([

View File

@@ -404,6 +404,23 @@ describe('RippleAPI', function () {
}, /Fee of 2\.1 XRP exceeds max of 2 XRP\. To use this fee, increase `maxFeeXRP` in the RippleAPI constructor\./)
});
it('preparePayment - caps fee at 2 XRP by default', function () {
this.api._feeCushion = 1000000;
const expectedResponse = {
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"2000000\",\"Sequence\":23}",
"instructions": {
"fee": "2",
"sequence": 23,
"maxLedgerVersion": 8820051
}
}
return this.api.preparePayment(
address, requests.preparePayment.normal, instructions).then(
_.partial(checkResult, expectedResponse, 'prepare'));
});
it('preparePayment - allows fee exceeding 2 XRP when maxFeeXRP is higher', function () {
this.api._maxFeeXRP = '2.2'
const localInstructions = _.defaults({
@@ -561,12 +578,26 @@ describe('RippleAPI', function () {
});
it('prepareSettings - set signers', function () {
const settings = requests.prepareSettings.signers;
const settings = requests.prepareSettings.signers.normal;
return this.api.prepareSettings(address, settings, instructions).then(
_.partial(checkResult, responses.prepareSettings.signers,
'prepare'));
});
it('prepareSettings - signers no threshold', function () {
const settings = requests.prepareSettings.signers.noThreshold;
assert.throws(() => {
this.api.prepareSettings(address, settings, instructions);
}, this.api.errors.ValidationError);
});
it('prepareSettings - signers no weights', function () {
const settings = requests.prepareSettings.signers.noWeights;
assert.throws(() => {
this.api.prepareSettings(address, settings, instructions);
}, this.api.errors.ValidationError);
});
it('prepareSettings - fee for multisign', function () {
const localInstructions = _.defaults({
signersCount: 4
@@ -684,6 +715,384 @@ describe('RippleAPI', function () {
'prepare'));
});
describe('prepareTransaction - Payment', function () {
it('normal', function () {
const localInstructions = _.defaults({
maxFee: '0.000012'
}, instructions);
const txJSON = {
TransactionType: 'Payment',
Account: address,
Destination: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo',
Amount: {
currency: 'USD',
issuer: 'rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM',
value: '0.01'
},
SendMax: {
currency: 'USD',
issuer: 'rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM',
value: '0.01'
},
Flags: 0
}
return this.api.prepareTransaction(txJSON, localInstructions).then(
_.partial(checkResult, responses.preparePayment.normal, 'prepare'));
});
// prepareTransaction - Payment
it('min amount xrp', function () {
const localInstructions = _.defaults({
maxFee: '0.000012'
}, instructions);
const txJSON = {
TransactionType: 'Payment',
Account: address,
Destination: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo',
// Max amount to send. Use 100 billion XRP to
// ensure that we send the full SendMax amount.
Amount: '100000000000000000',
SendMax: {
currency: 'USD',
issuer: 'rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM',
value: '0.01'
},
DeliverMin: '10000',
Flags: this.api.txFlags.Payment.PartialPayment
}
return this.api.prepareTransaction(txJSON, localInstructions).then(
_.partial(checkResult,
responses.preparePayment.minAmountXRP, 'prepare'));
});
// prepareTransaction - Payment
it('min amount xrp2xrp', function () {
const txJSON = {
TransactionType: 'Payment',
Account: address,
Destination: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo',
Amount: '10000',
Flags: 0
}
return this.api.prepareTransaction(txJSON, instructions).then(
_.partial(checkResult,
responses.preparePayment.minAmountXRPXRP, 'prepare'));
});
// prepareTransaction - Payment
it('with all options specified', function () {
return this.api.getLedgerVersion().then(ver => {
const localInstructions = {
maxLedgerVersion: ver + 100,
fee: '0.000012'
};
const txJSON = {
TransactionType: 'Payment',
Account: address,
Destination: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo',
Amount: '10000',
InvoiceID: 'A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A',
SourceTag: 14,
DestinationTag: 58,
Memos: [
{
Memo: {
MemoType: this.api.convertStringToHex('test'),
MemoFormat: this.api.convertStringToHex('text/plain'),
MemoData: this.api.convertStringToHex('texted data')
}
}
],
Flags: 0 | this.api.txFlags.Payment.NoRippleDirect | this.api.txFlags.Payment.LimitQuality
}
return this.api.prepareTransaction(txJSON, localInstructions).then(
_.partial(checkResult,
responses.preparePayment.allOptions, 'prepare'));
});
});
// prepareTransaction - Payment
it('fee is capped at default maxFee of 2 XRP', function () {
this.api._feeCushion = 1000000;
const txJSON = {
"Flags": 2147483648,
"TransactionType": "Payment",
"Account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"Destination": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
"Amount": {
"value": "0.01",
"currency": "USD",
"issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
},
"SendMax": {
"value": "0.01",
"currency": "USD",
"issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
},
"LastLedgerSequence": 8820051
}
const localInstructions = {
"maxLedgerVersion": 8820051
}
const expectedResponse = {
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"2000000\",\"Sequence\":23}",
"instructions": {
"fee": "2",
"sequence": 23,
"maxLedgerVersion": 8820051
}
}
return this.api.prepareTransaction(txJSON, localInstructions).then(
_.partial(checkResult,
expectedResponse, 'prepare'));
});
// prepareTransaction - Payment
it('fee is capped to custom maxFeeXRP when maxFee exceeds maxFeeXRP', function () {
this.api._feeCushion = 1000000
this.api._maxFeeXRP = '3'
const localInstructions = _.defaults({
maxFee: '4' // We are testing that this does not matter; fee is still capped to maxFeeXRP
}, instructions);
const txJSON = {
"Flags": 2147483648,
"TransactionType": "Payment",
"Account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"Destination": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
"Amount": {
"value": "0.01",
"currency": "USD",
"issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
},
"SendMax": {
"value": "0.01",
"currency": "USD",
"issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
},
"LastLedgerSequence": 8820051
}
const expectedResponse = {
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"3000000\",\"Sequence\":23}",
"instructions": {
"fee": "3",
"sequence": 23,
"maxLedgerVersion": 8820051
}
}
return this.api.prepareTransaction(txJSON, localInstructions).then(
_.partial(checkResult,
expectedResponse, 'prepare'));
});
// prepareTransaction - Payment
it('fee is capped to maxFee', function () {
this.api._feeCushion = 1000000
this.api._maxFeeXRP = '5'
const localInstructions = _.defaults({
maxFee: '4' // maxFeeXRP does not matter if maxFee is lower than maxFeeXRP
}, instructions);
const txJSON = {
"Flags": 2147483648,
"TransactionType": "Payment",
"Account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"Destination": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
"Amount": {
"value": "0.01",
"currency": "USD",
"issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
},
"SendMax": {
"value": "0.01",
"currency": "USD",
"issuer": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
},
"LastLedgerSequence": 8820051,
}
const expectedResponse = {
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"4000000\",\"Sequence\":23}",
"instructions": {
"fee": "4",
"sequence": 23,
"maxLedgerVersion": 8820051
}
}
return this.api.prepareTransaction(txJSON, localInstructions).then(
_.partial(checkResult,
expectedResponse, 'prepare'));
});
it('fee - calculated fee does not use more than 6 decimal places', function () {
this.api.connection._send(JSON.stringify({
command: 'config',
data: { loadFactor: 5407.96875 }
}));
const expectedResponse = {
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"64896\",\"Sequence\":23}",
"instructions": {
"fee": "0.064896",
"sequence": 23,
"maxLedgerVersion": 8820051
}
}
return this.api.preparePayment(
address, requests.preparePayment.normal, instructions).then(
_.partial(checkResult, expectedResponse, 'prepare'));
});
});
it('prepareTransaction - PaymentChannelCreate', function () {
const localInstructions = _.defaults({
maxFee: '0.000012'
}, instructions);
return this.api.prepareTransaction({
Account: address,
TransactionType: 'PaymentChannelCreate',
Amount: '1000000', // 1 XRP in drops. Use a string-encoded integer.
Destination: 'rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW',
SettleDelay: 86400,
PublicKey: '32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A'
// If cancelAfter is used, you must use RippleTime.
// You can use `iso8601ToRippleTime()` to convert to RippleTime.
// Other fields are available (but not used in this test),
// including `sourceTag` and `destinationTag`.
}, localInstructions).then(
_.partial(checkResult, responses.preparePaymentChannelCreate.normal,
'prepare'));
});
it('prepareTransaction - PaymentChannelCreate full', function () {
const txJSON = {
Account: address,
TransactionType: 'PaymentChannelCreate',
Amount: this.api.xrpToDrops('1'), // or '1000000'
Destination: 'rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW',
SettleDelay: 86400,
// Ensure this is in upper case if it is not already
PublicKey: '32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A'.toUpperCase(),
CancelAfter: this.api.iso8601ToRippleTime('2017-02-17T15:04:57Z'),
SourceTag: 11747,
DestinationTag: 23480
}
return this.api.prepareTransaction(txJSON).then(
_.partial(checkResult, responses.preparePaymentChannelCreate.full,
'prepare'));
});
it('prepareTransaction - PaymentChannelFund', function () {
const localInstructions = _.defaults({
maxFee: '0.000012'
}, instructions);
const txJSON = {
Account: address,
TransactionType: 'PaymentChannelFund',
Channel: 'C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198',
Amount: this.api.xrpToDrops('1') // or '1000000'
}
return this.api.prepareTransaction(txJSON, localInstructions).then(
_.partial(checkResult, responses.preparePaymentChannelFund.normal,
'prepare'));
});
it('prepareTransaction - PaymentChannelFund full', function () {
const txJSON = {
Account: address,
TransactionType: 'PaymentChannelFund',
Channel: 'C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198',
Amount: this.api.xrpToDrops('1'), // or '1000000'
Expiration: this.api.iso8601ToRippleTime('2017-02-17T15:04:57Z')
}
return this.api.prepareTransaction(txJSON).then(
_.partial(checkResult, responses.preparePaymentChannelFund.full,
'prepare'));
});
it('prepareTransaction - PaymentChannelClaim', function () {
const localInstructions = _.defaults({
maxFee: '0.000012'
}, instructions);
const txJSON = {
Account: address,
TransactionType: 'PaymentChannelClaim',
Channel: 'C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198',
Flags: 0
}
return this.api.prepareTransaction(txJSON, localInstructions).then(
_.partial(checkResult, responses.preparePaymentChannelClaim.normal,
'prepare'));
});
it('prepareTransaction - PaymentChannelClaim with renew', function () {
const localInstructions = _.defaults({
maxFee: '0.000012'
}, instructions);
const txJSON = {
Account: address,
TransactionType: 'PaymentChannelClaim',
Channel: 'C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198',
Balance: this.api.xrpToDrops('1'), // or '1000000'
Amount: this.api.xrpToDrops('1'), // or '1000000'
Signature: '30440220718D264EF05CAED7C781FF6DE298DCAC68D002562C9BF3A07C1E721B420C0DAB02203A5A4779EF4D2CCC7BC3EF886676D803A9981B928D3B8ACA483B80ECA3CD7B9B',
PublicKey: '32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A',
Flags: 0
}
txJSON.Flags |= this.api.txFlags.PaymentChannelClaim.Renew
return this.api.prepareTransaction(txJSON, localInstructions).then(
_.partial(checkResult, responses.preparePaymentChannelClaim.renew,
'prepare'));
});
it('prepareTransaction - PaymentChannelClaim with close', function () {
const localInstructions = _.defaults({
maxFee: '0.000012'
}, instructions);
const txJSON = {
Account: address,
TransactionType: 'PaymentChannelClaim',
Channel: 'C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198',
Balance: this.api.xrpToDrops('1'), // or 1000000
Amount: this.api.xrpToDrops('1'), // or 1000000
Signature: '30440220718D264EF05CAED7C781FF6DE298DCAC68D002562C9BF3A07C1E721B420C0DAB02203A5A4779EF4D2CCC7BC3EF886676D803A9981B928D3B8ACA483B80ECA3CD7B9B',
PublicKey: '32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A',
Flags: 0
}
txJSON.Flags |= this.api.txFlags.PaymentChannelClaim.Close
return this.api.prepareTransaction(txJSON, localInstructions).then(
_.partial(checkResult, responses.preparePaymentChannelClaim.close,
'prepare'));
});
it('preparePaymentChannelCreate', function () {
const localInstructions = _.defaults({
maxFee: '0.000012'
@@ -1760,7 +2169,21 @@ describe('RippleAPI', function () {
assert.strictEqual(fee, '2');
});
});
it('getFee - high load_factor with custom maxFeeXRP', function () {
// Ensure that overriding with high maxFeeXRP of '51540' causes no errors.
// (fee will actually be 51539.607552)
this.api._maxFeeXRP = '51540'
this.api.connection._send(JSON.stringify({
command: 'config',
data: { highLoadFactor: true }
}));
return this.api.getFee().then(fee => {
assert.strictEqual(fee, '51539.607552');
});
});
it('fee - default maxFee of 2 XRP', function () {
this.api._feeCushion = 1000000;
@@ -1820,6 +2243,43 @@ describe('RippleAPI', function () {
_.partial(checkResult, expectedResponse, 'prepare'));
});
it('fee - calculated fee does not use more than 6 decimal places', function () {
this.api.connection._send(JSON.stringify({
command: 'config',
data: { loadFactor: 5407.96875 }
}));
const expectedResponse = {
"txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"64896\",\"Sequence\":23}",
"instructions": {
"fee": "0.064896",
"sequence": 23,
"maxLedgerVersion": 8820051
}
}
return this.api.preparePayment(
address, requests.preparePayment.normal, instructions).then(
_.partial(checkResult, expectedResponse, 'prepare'));
});
it('getFee custom cushion', function () {
this.api._feeCushion = 1.4;
return this.api.getFee().then(fee => {
assert.strictEqual(fee, '0.000014');
});
});
// This is not recommended since it may result in attempting to pay
// less than the base fee. However, this test verifies
// the existing behavior.
it('getFee cushion less than 1.0', function () {
this.api._feeCushion = 0.9;
return this.api.getFee().then(fee => {
assert.strictEqual(fee, '0.000009');
});
});
it('disconnect & isConnected', function () {
assert.strictEqual(this.api.isConnected(), true);
return this.api.disconnect().then(() => {

View File

@@ -22,7 +22,11 @@ module.exports = {
},
prepareSettings: {
domain: require('./prepare-settings'),
signers: require('./prepare-settings-signers')
signers: {
normal: require('./prepare-settings-signers'),
noThreshold: require('./prepare-settings-signers-no-threshold'),
noWeights: require('./prepare-settings-signers-no-weights')
}
},
prepareEscrowCreation: {
normal: require('./prepare-escrow-creation'),

View File

@@ -4,7 +4,7 @@
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
]

View File

@@ -4,7 +4,7 @@
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
]

View File

@@ -3,7 +3,7 @@
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
]

View File

@@ -14,7 +14,7 @@
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
]

View File

@@ -18,12 +18,11 @@
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
],
"invoiceID": "A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A",
"noDirectRipple": true,
"limitQuality": true,
"paths": "[[{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\",\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"type\":49,\"type_hex\":\"0000000000000031\"},{\"currency\":\"LTC\",\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"type\":48,\"type_hex\":\"0000000000000030\"},{\"account\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\",\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"type\":49,\"type_hex\":\"0000000000000031\"}]]"
"limitQuality": true
}

View File

@@ -3,8 +3,7 @@
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"amount": {
"value": "0.01",
"currency": "XRP",
"counterparty": "rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM"
"currency": "XRP"
}
},
"destination": {

View File

@@ -18,7 +18,7 @@
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
],

View File

@@ -0,0 +1,18 @@
{
"signers": {
"weights": [
{
"address": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"weight": 1
},
{
"address": "rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo",
"weight": 1
},
{
"address": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J",
"weight": 1
}
]
}
}

View File

@@ -0,0 +1,5 @@
{
"signers": {
"threshold": 2
}
}

View File

@@ -3,7 +3,7 @@
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
]

View File

@@ -9,7 +9,7 @@
"memos": [
{
"type": "test",
"format": "plain/text",
"format": "text/plain",
"data": "texted data"
}
]

View File

@@ -23,6 +23,16 @@
},
"orderbookChanges": {},
"ledgerVersion": 786310,
"indexInLedger": 0
"indexInLedger": 0,
"channelChanges": {
"status": "modified",
"channelId": "43904CBFCDCEC530B4037871F86EE90BF799DF8D2E0EA564BC8A3F332E4F5FB1",
"source": "rfAuMkVuZQnQhvdMcUKg4ndBb9SPDhzNmK",
"destination": "rBmNDZ7vbTCwakKXsX3pDAwDdQuxM7yBRa",
"channelBalanceChangeDrops": "801000",
"channelAmountDrops": "1000000",
"channelBalanceDrops": "801000",
"previousTxnId": "0E9CA3AB1053FC0C1CBAA75F636FE1EC92F118C7056BBEF5D63E4C116458A16D"
}
}
}

View File

@@ -24,6 +24,14 @@
},
"orderbookChanges": {},
"ledgerVersion": 786309,
"indexInLedger": 0
"indexInLedger": 0,
"channelChanges": {
"status": "created",
"channelId": "43904CBFCDCEC530B4037871F86EE90BF799DF8D2E0EA564BC8A3F332E4F5FB1",
"source": "rfAuMkVuZQnQhvdMcUKg4ndBb9SPDhzNmK",
"destination": "rBmNDZ7vbTCwakKXsX3pDAwDdQuxM7yBRa",
"channelAmountDrops": "1000000",
"channelBalanceDrops": "0"
}
}
}

View File

@@ -21,6 +21,16 @@
},
"orderbookChanges": {},
"ledgerVersion": 786310,
"indexInLedger": 1
"indexInLedger": 1,
"channelChanges": {
"status": "modified",
"channelId": "43904CBFCDCEC530B4037871F86EE90BF799DF8D2E0EA564BC8A3F332E4F5FB1",
"source": "rfAuMkVuZQnQhvdMcUKg4ndBb9SPDhzNmK",
"destination": "rBmNDZ7vbTCwakKXsX3pDAwDdQuxM7yBRa",
"channelAmountChangeDrops": "1000000",
"channelAmountDrops": "2000000",
"channelBalanceDrops": "801000",
"previousTxnId": "81B9ECAE7195EB6E8034AEDF44D8415A7A803E14513FDBB34FA984AB37D59563"
}
}
}

View File

@@ -1,5 +1,5 @@
{
"txJSON": "{\"TransactionType\":\"EscrowCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}",
"txJSON": "{\"TransactionType\":\"EscrowCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"746578742F706C61696E\"}}],\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}",
"instructions": {
"fee": "0.000012",
"sequence": 23,

View File

@@ -1,5 +1,5 @@
{
"txJSON": "{\"TransactionType\":\"EscrowFinish\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}",
"txJSON": "{\"TransactionType\":\"EscrowFinish\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"746578742F706C61696E\"}}],\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}",
"instructions": {
"fee": "0.000012",
"sequence": 23,

View File

@@ -1,5 +1,5 @@
{
"txJSON": "{\"TransactionType\":\"OfferCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":23,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}",
"txJSON": "{\"TransactionType\":\"OfferCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":23,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"746578742F706C61696E\"}}],\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}",
"instructions": {
"fee": "0.000012",
"sequence": 23,

View File

@@ -1,5 +1,5 @@
{
"txJSON": "{\"TransactionType\":\"OfferCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TakerGets\":{\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\",\"value\":\"10.1\"},\"TakerPays\":\"2000000\",\"Flags\":2148139008,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23,\"OfferSequence\":12345}",
"txJSON": "{\"TransactionType\":\"OfferCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TakerGets\":{\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\",\"value\":\"10.1\"},\"TakerPays\":\"2000000\",\"Flags\":2148139008,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"746578742F706C61696E\"}}],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23,\"OfferSequence\":12345}",
"instructions": {
"fee": "0.000012",
"sequence": 23,

View File

@@ -1,5 +1,5 @@
{
"txJSON": "{\"Flags\":2147811328,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":\"10000\",\"InvoiceID\":\"A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A\",\"SourceTag\":14,\"DestinationTag\":58,\"Memos\":[{\"Memo\":{\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\",\"MemoData\":\"7465787465642064617461\"}}],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
"txJSON": "{\"Flags\":2147811328,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":\"10000\",\"InvoiceID\":\"A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A\",\"SourceTag\":14,\"DestinationTag\":58,\"Memos\":[{\"Memo\":{\"MemoType\":\"74657374\",\"MemoFormat\":\"746578742F706C61696E\",\"MemoData\":\"7465787465642064617461\"}}],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
"instructions": {
"fee": "0.000012",
"sequence": 23,

View File

@@ -1,5 +1,5 @@
{
"txJSON": "{\"Flags\":2147942400,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"LTC\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\"},\"InvoiceID\":\"A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A\",\"SourceTag\":14,\"DestinationTag\":58,\"Memos\":[{\"Memo\":{\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\",\"MemoData\":\"7465787465642064617461\"}}],\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"Paths\":[[{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\"},{\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\"},{\"account\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
"txJSON": "{\"Flags\":2147942400,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"LTC\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\"},\"InvoiceID\":\"A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A\",\"SourceTag\":14,\"DestinationTag\":58,\"Memos\":[{\"Memo\":{\"MemoType\":\"74657374\",\"MemoFormat\":\"746578742F706C61696E\",\"MemoData\":\"7465787465642064617461\"}}],\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"Paths\":[[{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\"},{\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\"},{\"account\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
"instructions": {
"fee": "0.000012",
"sequence": 23,

View File

@@ -1,5 +1,5 @@
{
"txJSON": "{\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"Domain\":\"726970706C652E636F6D\",\"Flags\":2147483648,\"LastLedgerSequence\":8820051,\"Fee\":\"60\",\"Sequence\":23}",
"txJSON": "{\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"746578742F706C61696E\"}}],\"Domain\":\"726970706C652E636F6D\",\"Flags\":2147483648,\"LastLedgerSequence\":8820051,\"Fee\":\"60\",\"Sequence\":23}",
"instructions": {
"fee": "0.00006",
"sequence": 23,

View File

@@ -1,5 +1,5 @@
{
"txJSON": "{\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"Domain\":\"726970706C652E636F6D\",\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}",
"txJSON": "{\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"746578742F706C61696E\"}}],\"Domain\":\"726970706C652E636F6D\",\"Flags\":2147483648,\"LastLedgerSequence\":8819954,\"Fee\":\"12\",\"Sequence\":23}",
"instructions": {
"fee": "0.000012",
"sequence": 23,

View File

@@ -1,5 +1,5 @@
{
"txJSON": "{\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"Domain\":\"726970706C652E636F6D\",\"Flags\":2147483648,\"Fee\":\"12\",\"Sequence\":23}",
"txJSON": "{\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"746578742F706C61696E\"}}],\"Domain\":\"726970706C652E636F6D\",\"Flags\":2147483648,\"Fee\":\"12\",\"Sequence\":23}",
"instructions": {
"fee": "0.000012",
"sequence": 23,

View File

@@ -1,4 +1,4 @@
{
"signedTransaction": "12000322800000002400000017201B0086955368400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D87446304402202FBF6A6F74DFDA17C7341D532B66141206BC71A147C08DBDA6A950AA9A1741DC022055859A39F2486A46487F8DA261E3D80B4FDD26178A716A929F26377D1BEC7E43770A726970706C652E636F6D81145E7B112523F68D2F5E879DB4EAC51C6698A69304F9EA7C04746573747D0B74657874656420646174617E0A706C61696E2F74657874E1F1",
"id": "4755D26FAC39E3E477870D4E03CC6783DDDF967FFBE240606755D3D03702FC16"
"signedTransaction": "12000322800000002400000017201B0086955368400000000000000C732102F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D874463044022047E8275DD2D9796E1A749DD8613B512AB3F5800A4B4738F97CD6904701E185D9022062736A12F5AD9135D188EF20DA3995D8C8F3823FB52B9659E6B74DFF797DADFD770A726970706C652E636F6D81145E7B112523F68D2F5E879DB4EAC51C6698A69304F9EA7C04746573747D0B74657874656420646174617E0A746578742F706C61696EE1F1",
"id": "00731CDA974C125217CAD6DFA8D733BDBD35F3F722D5FE4710634A3FD7A0339C"
}

View File

@@ -1,5 +1,5 @@
{
"txJSON": "{\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"Domain\":\"726970706C652E636F6D\",\"Flags\":2147483648,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
"txJSON": "{\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"746578742F706C61696E\"}}],\"Domain\":\"726970706C652E636F6D\",\"Flags\":2147483648,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
"instructions": {
"fee": "0.000012",
"sequence": 23,

View File

@@ -1,5 +1,5 @@
{
"txJSON": "{\"TransactionType\":\"TrustSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"LimitAmount\":{\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\",\"value\":\"10000\"},\"Flags\":2149711872,\"QualityIn\":910000000,\"QualityOut\":870000000,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\"}}],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
"txJSON": "{\"TransactionType\":\"TrustSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"LimitAmount\":{\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\",\"value\":\"10000\"},\"Flags\":2149711872,\"QualityIn\":910000000,\"QualityOut\":870000000,\"Memos\":[{\"Memo\":{\"MemoData\":\"7465787465642064617461\",\"MemoType\":\"74657374\",\"MemoFormat\":\"746578742F706C61696E\"}}],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}",
"instructions": {
"fee": "0.000012",
"sequence": 23,

View File

@@ -152,7 +152,7 @@ module.exports = function createMockRippled(port) {
mock.on('request_server_info', function (request, conn) {
assert.strictEqual(request.command, 'server_info');
if (conn.config.highLoadFactor) {
if (conn.config.highLoadFactor || conn.config.loadFactor) {
const response = {
"id": 0,
"status": "success",
@@ -167,7 +167,7 @@ module.exports = function createMockRippled(port) {
"converge_time_s": 2.007,
"proposers": 4
},
"load_factor": 4294967296,
"load_factor": conn.config.loadFactor || 4294967296,
"peers": 53,
"pubkey_node": "n94wWvFUmaKGYrKUGgpv1DyYgDeXRGdACkNQaSe7zJiy5Znio7UC",
"server_state": "full",

View File

@@ -4164,9 +4164,9 @@ ripple-keypairs@^0.10.1:
hash.js "^1.0.3"
ripple-address-codec "^2.0.1"
ripple-lib-transactionparser@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/ripple-lib-transactionparser/-/ripple-lib-transactionparser-0.6.2.tgz#eb117834816cab3398445a74ec3cacec95b6b5fa"
ripple-lib-transactionparser@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/ripple-lib-transactionparser/-/ripple-lib-transactionparser-0.7.1.tgz#5ececb1e03d65d05605343f4b9dbb76d1089145b"
dependencies:
bignumber.js "^4.1.0"
lodash "^4.17.4"
@@ -4803,9 +4803,9 @@ typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
typescript@^2.6.1:
version "2.8.1"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.1.tgz#6160e4f8f195d5ba81d4876f9c0cc1fbc0820624"
typescript@2.9.2:
version "2.9.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
uglify-es@^3.3.4:
version "3.3.9"