mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 12:15:51 +00:00
BREAKING CHANGE: getFee returns promise, express fee in XRP in instructions response, use rawRequest to start decoupling Remote from API
This commit is contained in:
@@ -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(() => {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"trace": {"type": "boolean"},
|
||||
"feeCushion": {"$ref": "value"},
|
||||
"servers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
||||
67
src/api/common/serverinfo.js
Normal file
67
src/api/common/serverinfo.js
Normal file
@@ -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<Object>,
|
||||
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<GetServerInfoResponse> {
|
||||
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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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<Order>
|
||||
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,
|
||||
|
||||
@@ -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<Object> {
|
||||
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<Object> {
|
||||
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
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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<TransactionType>
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Object>,
|
||||
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<number> {
|
||||
return common.promisify(this.remote.getLedgerSequence).call(this.remote);
|
||||
}
|
||||
@@ -86,7 +33,12 @@ function disconnect(): Promise<void> {
|
||||
}
|
||||
|
||||
function getServerInfo(): Promise<GetServerInfoResponse> {
|
||||
return common.promisify(getServerInfoAsync).call(this);
|
||||
return common.serverInfo.getServerInfo(this.remote);
|
||||
}
|
||||
|
||||
function getFee(): Promise<number> {
|
||||
const cushion = this._feeCushion || 1.2;
|
||||
return common.serverInfo.getFee(this.remote, cushion);
|
||||
}
|
||||
|
||||
function rippleTimeToISO8601(rippleTime: string): string {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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() {
|
||||
|
||||
2
test/fixtures/api/requests/sign.json
vendored
2
test/fixtures/api/requests/sign.json
vendored
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user