From cd17d6940f8d7b216e46615bd54d03fecddf3282 Mon Sep 17 00:00:00 2001 From: Chris Clark Date: Wed, 21 Oct 2015 16:04:35 -0700 Subject: [PATCH] BREAKING CHANGE: getFee returns promise, express fee in XRP in instructions response, use rawRequest to start decoupling Remote from API --- src/api/common/connection.js | 63 +++++++++++++++-- src/api/common/index.js | 2 + src/api/common/schemas/remote-options.json | 1 + src/api/common/serverinfo.js | 67 +++++++++++++++++++ src/api/common/utils.js | 7 +- src/api/index.js | 1 + src/api/ledger/accountinfo.js | 10 ++- src/api/ledger/balance-sheet.js | 17 +++-- src/api/ledger/balances.js | 5 +- src/api/ledger/ledger.js | 9 ++- src/api/ledger/orderbook.js | 9 ++- src/api/ledger/orders.js | 9 ++- src/api/ledger/parse/utils.js | 10 +-- src/api/ledger/pathfind.js | 5 +- src/api/ledger/settings.js | 9 ++- src/api/ledger/transaction.js | 15 +++-- src/api/ledger/transactions.js | 30 ++++++--- src/api/ledger/trustlines.js | 11 ++- src/api/ledger/utils.js | 7 +- src/api/server/server.js | 62 ++--------------- src/api/transaction/order.js | 2 +- src/api/transaction/ordercancellation.js | 2 +- src/api/transaction/payment.js | 2 +- src/api/transaction/settings.js | 2 +- .../suspended-payment-cancellation.js | 2 +- .../transaction/suspended-payment-creation.js | 2 +- .../suspended-payment-execution.js | 2 +- src/api/transaction/trustline.js | 2 +- src/api/transaction/utils.js | 33 +++++---- src/core/remote.js | 6 ++ test/api-test.js | 4 +- test/fixtures/api/requests/sign.json | 2 +- .../responses/prepare-order-cancellation.json | 2 +- .../api/responses/prepare-order-sell.json | 2 +- .../fixtures/api/responses/prepare-order.json | 2 +- .../prepare-payment-all-options.json | 2 +- .../responses/prepare-payment-min-amount.json | 2 +- .../prepare-payment-no-counterparty.json | 2 +- .../api/responses/prepare-payment.json | 2 +- .../prepare-settings-field-clear.json | 2 +- .../prepare-settings-flag-clear.json | 2 +- .../responses/prepare-settings-flag-set.json | 2 +- .../prepare-settings-regular-key.json | 2 +- .../prepare-settings-set-transfer-rate.json | 2 +- .../api/responses/prepare-settings.json | 2 +- ...repare-suspended-payment-cancellation.json | 2 +- .../prepare-suspended-payment-creation.json | 2 +- .../prepare-suspended-payment-execution.json | 2 +- .../responses/prepare-trustline-simple.json | 2 +- .../api/responses/prepare-trustline.json | 2 +- test/integration/connection-test.js | 6 +- test/integration/integration-test.js | 9 +-- 52 files changed, 277 insertions(+), 184 deletions(-) create mode 100644 src/api/common/serverinfo.js diff --git a/src/api/common/connection.js b/src/api/common/connection.js index 2b6d78e9..ce3b45f5 100644 --- a/src/api/common/connection.js +++ b/src/api/common/connection.js @@ -26,6 +26,12 @@ class ConnectionError extends Error { } } +class NotConnectedError extends ConnectionError { + constructor(message) { + super(message); + } +} + class DisconnectedError extends ConnectionError { constructor(message) { super(message); @@ -50,6 +56,7 @@ class Connection extends EventEmitter { this._url = url; this._timeout = options.timeout || (20 * 1000); this._ws = null; + this._ledgerVersion = null; this._nextRequestID = 1; } @@ -62,6 +69,9 @@ class Connection extends EventEmitter { } this.emit(data.id.toString(), data); } else if (isStreamMessageType(data.type)) { + if (data.type === 'ledgerClosed') { + this._ledgerVersion = Number(data.ledger_index); + } this.emit(data.type, data); } else if (data.type === undefined && data.error) { this.emit('error', data.error, data.error_message); // e.g. slowDown @@ -77,12 +87,34 @@ class Connection extends EventEmitter { return this._ws ? this._ws.readyState : WebSocket.CLOSED; } + get _shouldBeConnected() { + return this._ws !== null; + } + _onUnexpectedClose() { + this._ledgerVersion = null; this.connect().then(); } + _onOpen() { + const subscribeRequest = { + command: 'subscribe', + streams: ['ledger'] + }; + return this.request(subscribeRequest).then(() => { + const ledgerRequest = { + command: 'ledger', + ledger_index: 'validated' + }; + return this.request(ledgerRequest).then(info => { + this._ledgerVersion = Number(info.ledger.ledger_index); + this.emit('connected'); + }); + }); + } + connect() { - return new Promise((resolve) => { + return new Promise((resolve, reject) => { if (this.state === WebSocket.OPEN) { resolve(); } else if (this.state === WebSocket.CONNECTING) { @@ -91,7 +123,7 @@ class Connection extends EventEmitter { this._ws = new WebSocket(this._url); this._ws.on('message', this._onMessage.bind(this)); this._ws.once('close', () => this._onUnexpectedClose); - this._ws.once('open', resolve); + this._ws.once('open', () => this._onOpen().then(resolve, reject)); } }); } @@ -104,7 +136,11 @@ class Connection extends EventEmitter { this._ws.once('close', resolve); } else { this._ws.removeListener('close', this._onUnexpectedClose); - this._ws.once('close', resolve); + this._ws.once('close', () => { + this._ws = null; + this._ledgerVersion = null; + resolve(); + }); this._ws.close(); } }); @@ -114,6 +150,19 @@ class Connection extends EventEmitter { return this.disconnect().then(() => this.connect()); } + getLedgerVersion() { + return new Promise((resolve, reject) => { + const ledgerVersion = this._ledgerVersion; + if (!this._shouldBeConnected) { + reject(new NotConnectedError()); + } else if (this.state === WebSocket.OPEN && ledgerVersion !== null) { + resolve(ledgerVersion); + } else { + this.once('connected', () => resolve(this._ledgerVersion)); + } + }); + } + _send(message) { return new Promise((resolve, reject) => { this._ws.send(message, undefined, (error, result) => { @@ -131,13 +180,18 @@ class Connection extends EventEmitter { if (this.state === WebSocket.OPEN) { this._send(message).then(resolve, reject); } else { - this._ws.once('open', () => this._send(message).then(resolve, reject)); + this._ws.once('connected', () => + this._send(message).then(resolve, reject)); } }); } request(request, timeout) { return new Promise((resolve, reject) => { + if (!this._shouldBeConnected) { + reject(new NotConnectedError()); + } + let timer = null; const self = this; const id = this._nextRequestID; @@ -179,6 +233,7 @@ class Connection extends EventEmitter { this._ws.once('close', onDisconnect); + // JSON.stringify automatically removes keys with value of 'undefined' const message = JSON.stringify(Object.assign({}, request, {id})); this._sendWhenReady(message).then(() => { diff --git a/src/api/common/index.js b/src/api/common/index.js index 6a4b3586..ef0a74f7 100644 --- a/src/api/common/index.js +++ b/src/api/common/index.js @@ -8,12 +8,14 @@ module.exports = { errors: require('./errors'), validate: require('./validate'), txFlags: require('./txflags').txFlags, + serverInfo: require('./serverinfo'), dropsToXrp: utils.dropsToXrp, xrpToDrops: utils.xrpToDrops, toRippledAmount: utils.toRippledAmount, generateAddress: utils.generateAddress, composeAsync: utils.composeAsync, wrapCatch: utils.wrapCatch, + removeUndefined: utils.removeUndefined, convertErrors: utils.convertErrors, convertExceptions: utils.convertExceptions, convertKeysFromSnakeCaseToCamelCase: diff --git a/src/api/common/schemas/remote-options.json b/src/api/common/schemas/remote-options.json index 0882bb9f..a1cc02be 100644 --- a/src/api/common/schemas/remote-options.json +++ b/src/api/common/schemas/remote-options.json @@ -4,6 +4,7 @@ "type": "object", "properties": { "trace": {"type": "boolean"}, + "feeCushion": {"$ref": "value"}, "servers": { "type": "array", "items": { diff --git a/src/api/common/serverinfo.js b/src/api/common/serverinfo.js new file mode 100644 index 00000000..d209950f --- /dev/null +++ b/src/api/common/serverinfo.js @@ -0,0 +1,67 @@ +'use strict'; +const _ = require('lodash'); +const {RippledNetworkError} = require('./errors'); +const {promisify, convertKeysFromSnakeCaseToCamelCase} = require('./utils'); + +export type GetServerInfoResponse = { + buildVersion: string, + completeLedgers: string, + hostid: string, + ioLatencyMs: number, + load?: { + jobTypes: Array, + threads: number + }, + lastClose: { + convergeTimeS: number, + proposers: number + }, + loadFactor: number, + peers: number, + pubkeyNode: string, + pubkeyValidator?: string, + serverState: string, + validatedLedger: { + age: number, + baseFeeXrp: number, + hash: string, + reserveBaseXrp: number, + reserveIncXrp: number, + seq: number + }, + validationQuorum: number +} + +function getServerInfoAsync(remote, + callback: (err: any, data?: GetServerInfoResponse) => void +): void { + remote.rawRequest({command: 'server_info'}, (error, response) => { + if (error) { + const message = _.get(error, ['remote', 'error_message'], error.message); + callback(new RippledNetworkError(message)); + } else { + callback(null, convertKeysFromSnakeCaseToCamelCase(response.info)); + } + }); +} + +function getServerInfo(remote: Object): Promise { + return promisify(getServerInfoAsync)(remote); +} + +function computeFeeFromServerInfo(cushion: number, + serverInfo: GetServerInfoResponse +): number { + return (Number(serverInfo.validatedLedger.baseFeeXrp) + * Number(serverInfo.loadFactor) * cushion).toString(); +} + +function getFee(remote: Object, cushion: number) { + return getServerInfo(remote).then( + _.partial(computeFeeFromServerInfo, cushion)); +} + +module.exports = { + getServerInfo, + getFee +}; diff --git a/src/api/common/utils.js b/src/api/common/utils.js index 2bb98599..959a6c75 100644 --- a/src/api/common/utils.js +++ b/src/api/common/utils.js @@ -115,6 +115,10 @@ function promisify(asyncFunction: AsyncFunction): Function { return es6promisify(wrapCatch(asyncFunction)); } +function removeUndefined(obj: Object): Object { + return _.omit(obj, _.isUndefined); +} + module.exports = { core, dropsToXrp, @@ -126,5 +130,6 @@ module.exports = { convertExceptions, convertErrors, convertKeysFromSnakeCaseToCamelCase, - promisify + promisify, + removeUndefined }; diff --git a/src/api/index.js b/src/api/index.js index d5a6b983..a3690730 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -47,6 +47,7 @@ function RippleAPI(options: {}) { EventEmitter.call(this); } const _options = _.assign({}, options, {automatic_resubmission: false}); + this._feeCushion = _options.feeCushion || 1.2; this.remote = new common.core.Remote(_options); this.remote.on('ledger_closed', message => { this.emit('ledgerClosed', server.formatLedgerClose(message)); diff --git a/src/api/ledger/accountinfo.js b/src/api/ledger/accountinfo.js index 4fed0754..181d0b4e 100644 --- a/src/api/ledger/accountinfo.js +++ b/src/api/ledger/accountinfo.js @@ -2,10 +2,7 @@ 'use strict'; const utils = require('./utils'); -const removeUndefined = require('./parse/utils').removeUndefined; -const validate = utils.common.validate; -const composeAsync = utils.common.composeAsync; -const convertErrors = utils.common.convertErrors; +const {validate, composeAsync, convertErrors, removeUndefined} = utils.common; type AccountData = { Sequence: number, @@ -62,11 +59,12 @@ function getAccountInfoAsync(account: string, options: AccountInfoOptions, validate.getAccountInfoOptions(options); const request = { + command: 'account_info', account: account, - ledger: options.ledgerVersion || 'validated' + ledger_index: options.ledgerVersion || 'validated' }; - this.remote.requestAccountInfo(request, + this.remote.rawRequest(request, composeAsync(formatAccountInfo, convertErrors(callback))); } diff --git a/src/api/ledger/balance-sheet.js b/src/api/ledger/balance-sheet.js index 75b02478..796ffe63 100644 --- a/src/api/ledger/balance-sheet.js +++ b/src/api/ledger/balance-sheet.js @@ -3,9 +3,7 @@ const _ = require('lodash'); const utils = require('./utils'); -const validate = utils.common.validate; -const composeAsync = utils.common.composeAsync; -const convertErrors = utils.common.convertErrors; +const {validate, composeAsync, convertErrors} = utils.common; import type {Amount} from '../common/types.js'; type BalanceSheetOptions = { @@ -55,12 +53,13 @@ function getBalanceSheetAsync(address: string, options: BalanceSheetOptions, validate.address(address); validate.getBalanceSheetOptions(options); - const requestOptions = Object.assign({}, { + const request = { + command: 'gateway_balances', account: address, strict: true, hotwallet: options.excludeAddresses, - ledger: options.ledgerVersion - }); + ledger_index: options.ledgerVersion + }; const requestCallback = composeAsync( formatBalanceSheet, convertErrors(callback)); @@ -71,11 +70,11 @@ function getBalanceSheetAsync(address: string, options: BalanceSheetOptions, return; } - if (_.isUndefined(requestOptions.ledger)) { - requestOptions.ledger = ledgerVersion; + if (_.isUndefined(request.ledger_index)) { + request.ledger_index = ledgerVersion; } - this.remote.requestGatewayBalances(requestOptions, requestCallback); + this.remote.rawRequest(request, requestCallback); }); } diff --git a/src/api/ledger/balances.js b/src/api/ledger/balances.js index a904b7fe..3c10a3aa 100644 --- a/src/api/ledger/balances.js +++ b/src/api/ledger/balances.js @@ -4,11 +4,8 @@ const _ = require('lodash'); const async = require('async'); const utils = require('./utils'); const getTrustlines = require('./trustlines'); -const validate = utils.common.validate; -const composeAsync = utils.common.composeAsync; -const convertErrors = utils.common.convertErrors; +const {validate, composeAsync, convertErrors} = utils.common; import type {Remote, GetLedgerSequenceCallback} from '../../core/remote'; - import type {TrustlinesOptions, Trustline} from './trustlines-types.js'; diff --git a/src/api/ledger/ledger.js b/src/api/ledger/ledger.js index eba8bcc1..ac874eb5 100644 --- a/src/api/ledger/ledger.js +++ b/src/api/ledger/ledger.js @@ -1,9 +1,7 @@ /* @flow */ 'use strict'; const utils = require('./utils'); -const validate = utils.common.validate; -const composeAsync = utils.common.composeAsync; -const convertErrors = utils.common.convertErrors; +const {validate, composeAsync, convertErrors} = utils.common; const parseLedger = require('./parse/ledger'); import type {GetLedger} from './types.js'; @@ -19,13 +17,14 @@ function getLedgerAsync(options: LedgerOptions, callback) { validate.getLedgerOptions(options); const request = { - ledger: options.ledgerVersion || 'validated', + command: 'ledger', + ledger_index: options.ledgerVersion || 'validated', expand: options.includeAllData, transactions: options.includeTransactions, accounts: options.includeState }; - this.remote.requestLedger(request, + this.remote.rawRequest(request, composeAsync(response => parseLedger(response.ledger), convertErrors(callback))); } diff --git a/src/api/ledger/orderbook.js b/src/api/ledger/orderbook.js index 422c34bd..a469aaff 100644 --- a/src/api/ledger/orderbook.js +++ b/src/api/ledger/orderbook.js @@ -3,9 +3,7 @@ const _ = require('lodash'); const async = require('async'); const utils = require('./utils'); -const validate = utils.common.validate; -const composeAsync = utils.common.composeAsync; -const convertErrors = utils.common.convertErrors; +const {validate, composeAsync, convertErrors} = utils.common; const parseOrderbookOrder = require('./parse/orderbook-order'); import type {Remote} from '../../core/remote'; import type {OrdersOptions, OrderSpecification} from './types.js'; @@ -42,10 +40,11 @@ function getBookOffers(remote: Remote, account: string, ledgerVersion?: number, limit?: number, takerGets: Issue, takerPays: Issue, callback ) { - remote.requestBookOffers(utils.renameCounterpartyToIssuerInOrder({ + remote.rawRequest(utils.renameCounterpartyToIssuerInOrder({ + command: 'book_offers', taker_gets: takerGets, taker_pays: takerPays, - ledger: ledgerVersion || 'validated', + ledger_index: ledgerVersion || 'validated', limit: limit, taker: account }), composeAsync(data => data.offers, convertErrors(callback))); diff --git a/src/api/ledger/orders.js b/src/api/ledger/orders.js index e6d136fc..3db36624 100644 --- a/src/api/ledger/orders.js +++ b/src/api/ledger/orders.js @@ -3,9 +3,7 @@ const _ = require('lodash'); const async = require('async'); const utils = require('./utils'); -const validate = utils.common.validate; -const composeAsync = utils.common.composeAsync; -const convertErrors = utils.common.convertErrors; +const {validate, composeAsync, convertErrors} = utils.common; const parseAccountOrder = require('./parse/account-order'); import type {Remote} from '../../core/remote'; import type {OrdersOptions, Order} from './types.js'; @@ -15,11 +13,12 @@ type GetOrders = Array function requestAccountOffers(remote: Remote, address: string, ledgerVersion: number, marker: string, limit: number, callback ) { - remote.requestAccountOffers({ + remote.rawRequest({ + command: 'account_offers', account: address, marker: marker, limit: utils.clamp(limit, 10, 400), - ledger: ledgerVersion + ledger_index: ledgerVersion }, composeAsync((data) => ({ marker: data.marker, diff --git a/src/api/ledger/parse/utils.js b/src/api/ledger/parse/utils.js index 56a6111f..b8b33263 100644 --- a/src/api/ledger/parse/utils.js +++ b/src/api/ledger/parse/utils.js @@ -22,10 +22,6 @@ function parseTimestamp(tx: {date: string}): string | void { return tx.date ? (new Date(toTimestamp(tx.date))).toISOString() : undefined; } -function removeUndefined(obj: Object): Object { - return _.omit(obj, _.isUndefined); -} - function removeEmptyCounterparty(amount) { if (amount.counterparty === '') { delete amount.counterparty; @@ -76,7 +72,7 @@ function parseMemos(tx: Object): ?Array { return undefined; } return tx.Memos.map((m) => { - return removeUndefined({ + return utils.common.removeUndefined({ type: m.Memo.parsed_memo_type || hexToString(m.Memo.MemoType), format: m.Memo.parsed_memo_format || hexToString(m.Memo.MemoFormat), data: m.Memo.parsed_memo_data || hexToString(m.Memo.MemoData) @@ -87,10 +83,10 @@ function parseMemos(tx: Object): ?Array { module.exports = { parseOutcome, parseMemos, - removeUndefined, adjustQualityForXRP, dropsToXrp: utils.common.dropsToXrp, constants: utils.common.constants, txFlags: utils.common.txFlags, - core: utils.common.core + core: utils.common.core, + removeUndefined: utils.common.removeUndefined }; diff --git a/src/api/ledger/pathfind.js b/src/api/ledger/pathfind.js index ddf25391..8fbe10f8 100644 --- a/src/api/ledger/pathfind.js +++ b/src/api/ledger/pathfind.js @@ -5,12 +5,9 @@ const async = require('async'); const BigNumber = require('bignumber.js'); const utils = require('./utils'); const parsePathfind = require('./parse/pathfind'); -const validate = utils.common.validate; +const {validate, composeAsync, convertErrors, toRippledAmount} = utils.common; const NotFoundError = utils.common.errors.NotFoundError; const ValidationError = utils.common.errors.ValidationError; -const composeAsync = utils.common.composeAsync; -const convertErrors = utils.common.convertErrors; -const toRippledAmount = utils.common.toRippledAmount; import type {Remote} from '../../core/remote'; import type {RippledAmount} from '../common/types.js'; import type {GetPaths, PathFind, PathFindParams, diff --git a/src/api/ledger/settings.js b/src/api/ledger/settings.js index 6df64423..e71bc6d0 100644 --- a/src/api/ledger/settings.js +++ b/src/api/ledger/settings.js @@ -2,11 +2,9 @@ 'use strict'; const _ = require('lodash'); const utils = require('./utils'); -const validate = utils.common.validate; const parseFields = require('./parse/fields'); -const composeAsync = utils.common.composeAsync; +const {validate, composeAsync, convertErrors} = utils.common; const AccountFlags = utils.common.constants.AccountFlags; -const convertErrors = utils.common.convertErrors; type SettingsOptions = { ledgerVersion?: number @@ -55,11 +53,12 @@ function getSettingsAsync(account: string, options: SettingsOptions, callback) { validate.getSettingsOptions(options); const request = { + command: 'account_info', account: account, - ledger: options.ledgerVersion || 'validated' + ledger_index: options.ledgerVersion || 'validated' }; - this.remote.requestAccountInfo(request, + this.remote.rawRequest(request, composeAsync(formatSettings, convertErrors(callback))); } diff --git a/src/api/ledger/transaction.js b/src/api/ledger/transaction.js index eb0e1900..ba8f467a 100644 --- a/src/api/ledger/transaction.js +++ b/src/api/ledger/transaction.js @@ -4,9 +4,7 @@ const _ = require('lodash'); const async = require('async'); const utils = require('./utils'); const parseTransaction = require('./parse/transaction'); -const validate = utils.common.validate; -const errors = utils.common.errors; -const convertErrors = utils.common.convertErrors; +const {validate, convertErrors, errors} = utils.common; const RippleError = require('../../core/rippleerror').RippleError; import type {Remote} from '../../core/remote'; @@ -27,7 +25,12 @@ function attachTransactionDate(remote: Remote, tx: Object, return; } - remote.requestLedger(tx.ledger_index, (error, data) => { + const request = { + command: 'ledger', + ledger_index: tx.ledger_index + }; + + remote.rawRequest(request, (error, data) => { if (error) { callback(new errors.NotFoundError('Transaction ledger not found')); } else if (typeof data.ledger.close_time === 'number') { @@ -98,8 +101,8 @@ function getTransactionAsync(identifier: string, options: TransactionOptions, } async.waterfall([ - _.partial(remote.requestTx.bind(remote), - {hash: identifier, binary: false}), + _.partial(remote.rawRequest.bind(remote), + {command: 'tx', transaction: identifier, binary: false}), _.partial(attachTransactionDate, remote) ], maxLedgerGetter.bind(this)); } diff --git a/src/api/ledger/transactions.js b/src/api/ledger/transactions.js index f5927cf8..7bdb486e 100644 --- a/src/api/ledger/transactions.js +++ b/src/api/ledger/transactions.js @@ -2,15 +2,13 @@ /* eslint-disable max-params */ 'use strict'; const _ = require('lodash'); +const binary = require('ripple-binary-codec'); +const {computeTransactionHash} = require('ripple-hashes'); const utils = require('./utils'); const parseTransaction = require('./parse/transaction'); const getTransaction = require('./transaction'); -const validate = utils.common.validate; -const composeAsync = utils.common.composeAsync; -const convertErrors = utils.common.convertErrors; - +const {validate, composeAsync, convertErrors} = utils.common; import type {Remote} from '../../core/remote'; - import type {TransactionType} from './transaction-types'; @@ -32,11 +30,22 @@ type GetTransactionsResponse = Array type CallbackType = (err?: ?Error, data?: GetTransactionsResponse) => void +function parseBinaryTransaction(transaction) { + const tx = binary.decode(transaction.tx_blob); + tx.hash = computeTransactionHash(tx); + tx.ledger_index = transaction.ledger_index; + return { + tx: tx, + meta: binary.decode(transaction.meta), + validated: transaction.validated + }; +} + function parseAccountTxTransaction(tx) { + const _tx = tx.tx_blob ? parseBinaryTransaction(tx) : tx; // rippled uses a different response format for 'account_tx' than 'tx' - tx.tx.meta = tx.meta; - tx.tx.validated = tx.validated; - return parseTransaction(tx.tx); + return parseTransaction(_.assign({}, _tx.tx, + {meta: _tx.meta, validated: _tx.validated})); } function counterpartyFilter(filters, tx: TransactionType) { @@ -97,7 +106,8 @@ function formatPartialResponse(address: string, function getAccountTx(remote: Remote, address: string, options: TransactionsOptions, marker: string, limit: number, callback ) { - const params = { + const request = { + command: 'account_tx', account: address, // -1 is equivalent to earliest available validated ledger ledger_index_min: options.minLedgerVersion || -1, @@ -109,7 +119,7 @@ function getAccountTx(remote: Remote, address: string, marker: marker }; - remote.requestAccountTx(params, + remote.rawRequest(request, composeAsync(_.partial(formatPartialResponse, address, options), convertErrors(callback))); } diff --git a/src/api/ledger/trustlines.js b/src/api/ledger/trustlines.js index a8c3420b..1e531764 100644 --- a/src/api/ledger/trustlines.js +++ b/src/api/ledger/trustlines.js @@ -3,9 +3,7 @@ const _ = require('lodash'); const async = require('async'); const utils = require('./utils'); -const validate = utils.common.validate; -const composeAsync = utils.common.composeAsync; -const convertErrors = utils.common.convertErrors; +const {validate, composeAsync, convertErrors} = utils.common; const parseAccountTrustline = require('./parse/account-trustline'); import type {Remote} from '../../core/remote'; @@ -29,15 +27,16 @@ function formatResponse(options: TrustlinesOptions, data) { function getAccountLines(remote: Remote, address: string, ledgerVersion: number, options: TrustlinesOptions, marker: string, limit: number, callback ) { - const requestOptions = { + const request = { + command: 'account_lines', account: address, - ledger: ledgerVersion, + ledger_index: ledgerVersion, marker: marker, limit: utils.clamp(limit, 10, 400), peer: options.counterparty }; - remote.requestAccountLines(requestOptions, + remote.rawRequest(request, composeAsync(_.partial(formatResponse, options), convertErrors(callback))); } diff --git a/src/api/ledger/utils.js b/src/api/ledger/utils.js index 21231803..dfd0abd9 100644 --- a/src/api/ledger/utils.js +++ b/src/api/ledger/utils.js @@ -26,7 +26,12 @@ function clamp(value: number, min: number, max: number): number { function getXRPBalance(remote: Remote, address: string, ledgerVersion?: number, callback: Callback ): void { - remote.requestAccountInfo({account: address, ledger: ledgerVersion}, + const request = { + command: 'account_info', + account: address, + ledger_index: ledgerVersion + }; + remote.rawRequest(request, composeAsync((data) => dropsToXrp(data.account_data.Balance), callback)); } diff --git a/src/api/server/server.js b/src/api/server/server.js index 7b92aae3..3e5a8a32 100644 --- a/src/api/server/server.js +++ b/src/api/server/server.js @@ -1,66 +1,13 @@ /* @flow */ - 'use strict'; - -const _ = require('lodash'); const common = require('../common'); - -type GetServerInfoResponse = { - buildVersion: string, - completeLedgers: string, - hostid: string, - ioLatencyMs: number, - load?: { - jobTypes: Array, - threads: number - }, - lastClose: { - convergeTimeS: number, - proposers: number - }, - loadFactor: number, - peers: number, - pubkeyNode: string, - pubkeyValidator?: string, - serverState: string, - validatedLedger: { - age: number, - baseFeeXrp: number, - hash: string, - reserveBaseXrp: number, - reserveIncXrp: number, - seq: number - }, - validationQuorum: number -} +import type {GetServerInfoResponse} from '../common/serverinfo'; function isConnected(): boolean { const server = this.remote.getServer(); return Boolean(server && server.isConnected()); } -function getServerInfoAsync( - callback: (err: any, data?: GetServerInfoResponse) => void -): void { - this.remote.requestServerInfo((error, response) => { - if (error) { - const message = _.get(error, ['remote', 'error_message'], error.message); - callback(new common.errors.RippledNetworkError(message)); - } else { - callback(null, - common.convertKeysFromSnakeCaseToCamelCase(response.info)); - } - }); -} - -function getFee(): ?number { - if (!this.remote.getConnectedServers().length) { - throw new common.errors.RippledNetworkError('No servers available.'); - } - const fee = this.remote.createTransaction()._computeFee(); - return fee === undefined ? undefined : common.dropsToXrp(fee); -} - function getLedgerVersion(): Promise { return common.promisify(this.remote.getLedgerSequence).call(this.remote); } @@ -86,7 +33,12 @@ function disconnect(): Promise { } function getServerInfo(): Promise { - return common.promisify(getServerInfoAsync).call(this); + return common.serverInfo.getServerInfo(this.remote); +} + +function getFee(): Promise { + const cushion = this._feeCushion || 1.2; + return common.serverInfo.getFee(this.remote, cushion); } function rippleTimeToISO8601(rippleTime: string): string { diff --git a/src/api/transaction/order.js b/src/api/transaction/order.js index 47db05b4..cd5927b6 100644 --- a/src/api/transaction/order.js +++ b/src/api/transaction/order.js @@ -41,7 +41,7 @@ function prepareOrderAsync(account: string, order: Order, instructions: Instructions, callback ) { const txJSON = createOrderTransaction(account, order); - utils.prepareTransaction(txJSON, this.remote, instructions, callback); + utils.prepareTransaction(txJSON, this, instructions, callback); } function prepareOrder(account: string, order: Order, diff --git a/src/api/transaction/ordercancellation.js b/src/api/transaction/ordercancellation.js index ec8cd826..befc4701 100644 --- a/src/api/transaction/ordercancellation.js +++ b/src/api/transaction/ordercancellation.js @@ -21,7 +21,7 @@ function prepareOrderCancellationAsync(account: string, sequence: number, instructions: Instructions, callback ) { const txJSON = createOrderCancellationTransaction(account, sequence); - utils.prepareTransaction(txJSON, this.remote, instructions, callback); + utils.prepareTransaction(txJSON, this, instructions, callback); } function prepareOrderCancellation(account: string, sequence: number, diff --git a/src/api/transaction/payment.js b/src/api/transaction/payment.js index 9b9125c6..74aac4e2 100644 --- a/src/api/transaction/payment.js +++ b/src/api/transaction/payment.js @@ -145,7 +145,7 @@ function preparePaymentAsync(account: string, payment: Payment, instructions: Instructions, callback ) { const txJSON = createPaymentTransaction(account, payment); - utils.prepareTransaction(txJSON, this.remote, instructions, callback); + utils.prepareTransaction(txJSON, this, instructions, callback); } function preparePayment(account: string, payment: Payment, diff --git a/src/api/transaction/settings.js b/src/api/transaction/settings.js index b9e71578..1b6603d7 100644 --- a/src/api/transaction/settings.js +++ b/src/api/transaction/settings.js @@ -99,7 +99,7 @@ function prepareSettingsAsync(account: string, settings: Settings, instructions: Instructions, callback ) { const txJSON = createSettingsTransaction(account, settings); - utils.prepareTransaction(txJSON, this.remote, instructions, callback); + utils.prepareTransaction(txJSON, this, instructions, callback); } function prepareSettings(account: string, settings: Object, diff --git a/src/api/transaction/suspended-payment-cancellation.js b/src/api/transaction/suspended-payment-cancellation.js index be9ba6cb..77271306 100644 --- a/src/api/transaction/suspended-payment-cancellation.js +++ b/src/api/transaction/suspended-payment-cancellation.js @@ -35,7 +35,7 @@ function prepareSuspendedPaymentCancellationAsync(account: string, ) { const txJSON = createSuspendedPaymentCancellationTransaction(account, payment); - utils.prepareTransaction(txJSON, this.remote, instructions, callback); + utils.prepareTransaction(txJSON, this, instructions, callback); } function prepareSuspendedPaymentCancellation(account: string, diff --git a/src/api/transaction/suspended-payment-creation.js b/src/api/transaction/suspended-payment-creation.js index 7400934e..d2854d02 100644 --- a/src/api/transaction/suspended-payment-creation.js +++ b/src/api/transaction/suspended-payment-creation.js @@ -54,7 +54,7 @@ function prepareSuspendedPaymentCreationAsync(account: string, payment: SuspendedPaymentCreation, instructions: Instructions, callback ) { const txJSON = createSuspendedPaymentCreationTransaction(account, payment); - utils.prepareTransaction(txJSON, this.remote, instructions, callback); + utils.prepareTransaction(txJSON, this, instructions, callback); } function prepareSuspendedPaymentCreation(account: string, diff --git a/src/api/transaction/suspended-payment-execution.js b/src/api/transaction/suspended-payment-execution.js index 86245914..92eda0b2 100644 --- a/src/api/transaction/suspended-payment-execution.js +++ b/src/api/transaction/suspended-payment-execution.js @@ -47,7 +47,7 @@ function prepareSuspendedPaymentExecutionAsync(account: string, payment: SuspendedPaymentExecution, instructions: Instructions, callback ) { const txJSON = createSuspendedPaymentExecutionTransaction(account, payment); - utils.prepareTransaction(txJSON, this.remote, instructions, callback); + utils.prepareTransaction(txJSON, this, instructions, callback); } function prepareSuspendedPaymentExecution(account: string, diff --git a/src/api/transaction/trustline.js b/src/api/transaction/trustline.js index 77ec4d9f..842153e0 100644 --- a/src/api/transaction/trustline.js +++ b/src/api/transaction/trustline.js @@ -54,7 +54,7 @@ function prepareTrustlineAsync(account: string, trustline: TrustLineSpecification, instructions: Instructions, callback ) { const txJSON = createTrustlineTransaction(account, trustline); - utils.prepareTransaction(txJSON, this.remote, instructions, callback); + utils.prepareTransaction(txJSON, this, instructions, callback); } function prepareTrustline(account: string, diff --git a/src/api/transaction/utils.js b/src/api/transaction/utils.js index 8c9cf649..6447af58 100644 --- a/src/api/transaction/utils.js +++ b/src/api/transaction/utils.js @@ -4,25 +4,16 @@ const _ = require('lodash'); const async = require('async'); const BigNumber = require('bignumber.js'); const common = require('../common'); -const composeAsync = common.composeAsync; const txFlags = common.txFlags; -import type {Remote} from '../../core/remote'; import type {Instructions} from './types.js'; function removeUndefined(obj: Object): Object { return _.omit(obj, _.isUndefined); } -function getFeeDrops(remote: Remote, callback) { - const feeUnits = 10; // all transactions currently have a fee of 10 fee units - remote.feeTxAsync(feeUnits, (err, data) => { - callback(err, data ? data.to_text() : undefined); - }); -} - function formatPrepareResponse(txJSON: Object): Object { const instructions = { - fee: txJSON.Fee, + fee: common.dropsToXrp(txJSON.Fee), sequence: txJSON.Sequence, maxLedgerVersion: txJSON.LastLedgerSequence }; @@ -42,7 +33,7 @@ function setCanonicalFlag(txJSON) { type Callback = (err: ?(typeof Error), data: {txJSON: string, instructions: Instructions}) => void; -function prepareTransaction(txJSON: Object, remote: Remote, +function prepareTransaction(txJSON: Object, api: Object, instructions: Instructions, callback: Callback ): void { common.validate.instructions(instructions); @@ -57,7 +48,7 @@ function prepareTransaction(txJSON: Object, remote: Remote, } else { const offset = instructions.maxLedgerVersionOffset !== undefined ? instructions.maxLedgerVersionOffset : 3; - remote.getLedgerSequence((error, ledgerVersion) => { + api.remote.getLedgerSequence((error, ledgerVersion) => { txJSON.LastLedgerSequence = ledgerVersion + offset; callback_(error); }); @@ -69,14 +60,16 @@ function prepareTransaction(txJSON: Object, remote: Remote, txJSON.Fee = common.xrpToDrops(instructions.fee); callback_(); } else { - getFeeDrops(remote, composeAsync((serverFeeDrops) => { + common.serverInfo.getFee(api.remote, api._feeCushion).then(fee => { + const feeDrops = common.xrpToDrops(fee); if (instructions.maxFee !== undefined) { const maxFeeDrops = common.xrpToDrops(instructions.maxFee); - txJSON.Fee = BigNumber.min(serverFeeDrops, maxFeeDrops).toString(); + txJSON.Fee = BigNumber.min(feeDrops, maxFeeDrops).toString(); } else { - txJSON.Fee = serverFeeDrops; + txJSON.Fee = feeDrops; } - }, callback_)); + callback_(); + }); } } @@ -85,8 +78,12 @@ function prepareTransaction(txJSON: Object, remote: Remote, txJSON.Sequence = instructions.sequence; callback_(null, formatPrepareResponse(txJSON)); } else { - remote.findAccount(account).getNextSequence(function(error, sequence) { - txJSON.Sequence = sequence; + const request = { + command: 'account_info', + account: account + }; + api.remote.rawRequest(request, function(error, response) { + txJSON.Sequence = response.account_data.Sequence; callback_(error, formatPrepareResponse(txJSON)); }); } diff --git a/src/core/remote.js b/src/core/remote.js index 2961fac3..bdbbf0b4 100644 --- a/src/core/remote.js +++ b/src/core/remote.js @@ -810,6 +810,12 @@ Remote.prototype.request = function(request) { } }; +Remote.prototype.rawRequest = function(message, callback) { + const request = new Request(this, message.command); + _.assign(request.message, _.omit(message, _.isUndefined)); + request.request(callback); +}; + /** * Request ping * diff --git a/test/api-test.js b/test/api-test.js index 7f22d4b8..2eec2cbd 100644 --- a/test/api-test.js +++ b/test/api-test.js @@ -607,7 +607,9 @@ describe('RippleAPI', function() { }); it('getFee', function() { - assert.strictEqual(this.api.getFee(), '0.000012'); + return this.api.getFee().then(fee => { + assert.strictEqual(fee, '0.000012'); + }); }); it('disconnect & isConnected', function() { diff --git a/test/fixtures/api/requests/sign.json b/test/fixtures/api/requests/sign.json index a0a599c1..df9ea7c0 100644 --- a/test/fixtures/api/requests/sign.json +++ b/test/fixtures/api/requests/sign.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Domain\":\"726970706C652E636F6D\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-order-cancellation.json b/test/fixtures/api/responses/prepare-order-cancellation.json index d08fb0f3..ab6781ff 100644 --- a/test/fixtures/api/responses/prepare-order-cancellation.json +++ b/test/fixtures/api/responses/prepare-order-cancellation.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"OfferCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":23,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-order-sell.json b/test/fixtures/api/responses/prepare-order-sell.json index 40d5b6cd..7fb96d11 100644 --- a/test/fixtures/api/responses/prepare-order-sell.json +++ b/test/fixtures/api/responses/prepare-order-sell.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2148139008,\"TransactionType\":\"OfferCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TakerGets\":{\"value\":\"10.1\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"TakerPays\":\"2000000\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-order.json b/test/fixtures/api/responses/prepare-order.json index b6c102a8..72fa4b25 100644 --- a/test/fixtures/api/responses/prepare-order.json +++ b/test/fixtures/api/responses/prepare-order.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147614720,\"TransactionType\":\"OfferCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TakerGets\":\"2000000\",\"TakerPays\":{\"value\":\"10.1\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-payment-all-options.json b/test/fixtures/api/responses/prepare-payment-all-options.json index b8b5bd2a..d85368a0 100644 --- a/test/fixtures/api/responses/prepare-payment-all-options.json +++ b/test/fixtures/api/responses/prepare-payment-all-options.json @@ -1,7 +1,7 @@ { "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}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-payment-min-amount.json b/test/fixtures/api/responses/prepare-payment-min-amount.json index df3edb13..1dd701af 100644 --- a/test/fixtures/api/responses/prepare-payment-min-amount.json +++ b/test/fixtures/api/responses/prepare-payment-min-amount.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147614720,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\",\"Amount\":{\"value\":\"9999999999999999e80\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"SendMax\":{\"value\":\"5\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"DeliverMin\":{\"value\":\"9999999999999999e80\",\"currency\":\"USD\",\"issuer\":\"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"},\"Paths\":[[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"},{\"account\":\"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\"}],[{\"account\":\"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B\"},{\"currency\":\"XRP\"},{\"issuer\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\",\"currency\":\"USD\"},{\"account\":\"rfsEoNBUBbvkf4jPcFe2u9CyaQagLVHGfP\"},{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-payment-no-counterparty.json b/test/fixtures/api/responses/prepare-payment-no-counterparty.json index 4fbd7631..056eb34c 100644 --- a/test/fixtures/api/responses/prepare-payment-no-counterparty.json +++ b/test/fixtures/api/responses/prepare-payment-no-counterparty.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147942400,\"TransactionType\":\"Payment\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"LTC\",\"issuer\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\"},\"InvoiceID\":\"A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A\",\"SourceTag\":14,\"DestinationTag\":58,\"Memos\":[{\"Memo\":{\"MemoType\":\"74657374\",\"MemoFormat\":\"706C61696E2F74657874\",\"MemoData\":\"7465787465642064617461\"}}],\"SendMax\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\"},\"Paths\":[[{\"account\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"issuer\":\"rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q\",\"currency\":\"USD\"},{\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\"},{\"account\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"issuer\":\"rfYv1TXnwgDDK4WQNbFALykYuEBnrR4pDX\",\"currency\":\"LTC\"}]],\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-payment.json b/test/fixtures/api/responses/prepare-payment.json index 08b044b5..e5db1d0f 100644 --- a/test/fixtures/api/responses/prepare-payment.json +++ b/test/fixtures/api/responses/prepare-payment.json @@ -1,7 +1,7 @@ { "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\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-settings-field-clear.json b/test/fixtures/api/responses/prepare-settings-field-clear.json index 299329f0..99eb63b2 100644 --- a/test/fixtures/api/responses/prepare-settings-field-clear.json +++ b/test/fixtures/api/responses/prepare-settings-field-clear.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"WalletLocator\":\"0\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-settings-flag-clear.json b/test/fixtures/api/responses/prepare-settings-flag-clear.json index 78c4b12c..1e22a30d 100644 --- a/test/fixtures/api/responses/prepare-settings-flag-clear.json +++ b/test/fixtures/api/responses/prepare-settings-flag-clear.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"ClearFlag\":1,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-settings-flag-set.json b/test/fixtures/api/responses/prepare-settings-flag-set.json index fe103d5e..46ddf8b2 100644 --- a/test/fixtures/api/responses/prepare-settings-flag-set.json +++ b/test/fixtures/api/responses/prepare-settings-flag-set.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"SetFlag\":1,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-settings-regular-key.json b/test/fixtures/api/responses/prepare-settings-regular-key.json index 306be09d..42fdf5b5 100644 --- a/test/fixtures/api/responses/prepare-settings-regular-key.json +++ b/test/fixtures/api/responses/prepare-settings-regular-key.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"SetRegularKey\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"RegularKey\":\"rAR8rR8sUkBoCZFawhkWzY4Y5YoyuznwD\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-settings-set-transfer-rate.json b/test/fixtures/api/responses/prepare-settings-set-transfer-rate.json index adc6d839..104c4338 100644 --- a/test/fixtures/api/responses/prepare-settings-set-transfer-rate.json +++ b/test/fixtures/api/responses/prepare-settings-set-transfer-rate.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"TransferRate\":1000000000,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-settings.json b/test/fixtures/api/responses/prepare-settings.json index a0a599c1..df9ea7c0 100644 --- a/test/fixtures/api/responses/prepare-settings.json +++ b/test/fixtures/api/responses/prepare-settings.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"AccountSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Domain\":\"726970706C652E636F6D\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-suspended-payment-cancellation.json b/test/fixtures/api/responses/prepare-suspended-payment-cancellation.json index 069b801f..5250731f 100644 --- a/test/fixtures/api/responses/prepare-suspended-payment-cancellation.json +++ b/test/fixtures/api/responses/prepare-suspended-payment-cancellation.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"SuspendedPaymentCancel\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-suspended-payment-creation.json b/test/fixtures/api/responses/prepare-suspended-payment-creation.json index 76cd7c30..202431f7 100644 --- a/test/fixtures/api/responses/prepare-suspended-payment-creation.json +++ b/test/fixtures/api/responses/prepare-suspended-payment-creation.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"SuspendedPaymentCreate\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Destination\":\"rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo\",\"Amount\":{\"value\":\"0.01\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"CancelAfter\":494009529,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-suspended-payment-execution.json b/test/fixtures/api/responses/prepare-suspended-payment-execution.json index 61eb7302..e427a1d2 100644 --- a/test/fixtures/api/responses/prepare-suspended-payment-execution.json +++ b/test/fixtures/api/responses/prepare-suspended-payment-execution.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"SuspendedPaymentFinish\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"Owner\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"OfferSequence\":1234,\"Method\":1,\"Digest\":\"8F434346648F6B96DF89DDA901C5176B10A6D83961DD3C1AC88B59B2DC327AA4\",\"Proof\":\"7768617465766572\",\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-trustline-simple.json b/test/fixtures/api/responses/prepare-trustline-simple.json index db64cca7..6f1b5677 100644 --- a/test/fixtures/api/responses/prepare-trustline-simple.json +++ b/test/fixtures/api/responses/prepare-trustline-simple.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2147483648,\"TransactionType\":\"TrustSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"LimitAmount\":{\"value\":\"0.1\",\"currency\":\"BTC\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/fixtures/api/responses/prepare-trustline.json b/test/fixtures/api/responses/prepare-trustline.json index c32ae279..0aba3f6b 100644 --- a/test/fixtures/api/responses/prepare-trustline.json +++ b/test/fixtures/api/responses/prepare-trustline.json @@ -1,7 +1,7 @@ { "txJSON": "{\"Flags\":2149711872,\"TransactionType\":\"TrustSet\",\"Account\":\"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59\",\"LimitAmount\":{\"value\":\"10000\",\"currency\":\"USD\",\"issuer\":\"rMH4UxPrbuMa1spCBR98hLLyNJp4d8p4tM\"},\"QualityIn\":910000000,\"QualityOut\":870000000,\"LastLedgerSequence\":8820051,\"Fee\":\"12\",\"Sequence\":23}", "instructions": { - "fee": "12", + "fee": "0.000012", "sequence": 23, "maxLedgerVersion": 8820051 } diff --git a/test/integration/connection-test.js b/test/integration/connection-test.js index 6d0c8a71..e2198fdf 100644 --- a/test/integration/connection-test.js +++ b/test/integration/connection-test.js @@ -40,7 +40,11 @@ function main() { makeRequest(connection, request4) ]).then(() => { console.log('Done'); - process.exit(); + }); + connection.getLedgerVersion().then(console.log); + connection.on('ledgerClosed', ledger => { + console.log(ledger); + connection.getLedgerVersion().then(console.log); }); }); } diff --git a/test/integration/integration-test.js b/test/integration/integration-test.js index 1423e700..ed9bd177 100644 --- a/test/integration/integration-test.js +++ b/test/integration/integration-test.js @@ -176,10 +176,11 @@ describe('integration tests', function() { it('getFee', function() { - const fee = this.api.getFee(); - assert.strictEqual(typeof fee, 'string'); - assert(!isNaN(Number(fee))); - assert(parseFloat(fee) === Number(fee)); + return this.api.getFee().then(fee => { + assert.strictEqual(typeof fee, 'string'); + assert(!isNaN(Number(fee))); + assert(parseFloat(fee) === Number(fee)); + }); });