add more flow annotations to RippleApi

This commit is contained in:
Ivan Tivonenko
2015-10-06 06:47:18 +03:00
parent 462e440d5b
commit d47bb2749a
32 changed files with 685 additions and 158 deletions

55
src/api/common/types.js Normal file
View File

@@ -0,0 +1,55 @@
/* @flow */
'use strict';
export type RippledAmountIOU = {
currency: string,
value: string,
issuer?: string
}
export type RippledAmount = string | RippledAmountIOU
export type Amount = {
value: string,
currency: string,
counterparty?: string
}
// Amount where counterparty and value are optional
export type LaxLaxAmount = {
currency: string,
value?: string,
counterparty?: string
}
// A currency-counterparty pair, or just currency if it's XRP
export type Issue = {
currency: string,
counterparty?: string
}
export type Adjustment = {
address: string,
amount: Amount,
tag?: number
}
export type MaxAdjustment = {
address: string,
maxAmount: Amount,
tag?: number
}
export type MinAdjustment = {
address: string,
minAmount: Amount,
tag?: number
}
export type Memo = {
type?: string,
format?: string,
data?: string
}

View File

@@ -7,7 +7,7 @@ const errors = require('./errors');
const es6promisify = require('es6-promisify');
const keypairs = require('ripple-keypairs');
type Amount = {currency: string, issuer: string, value: string}
import type {Amount, RippledAmount} from './types.js';
function dropsToXrp(drops: string): string {
return (new BigNumber(drops)).dividedBy(1000000.0).toString();
@@ -17,13 +17,14 @@ function xrpToDrops(xrp: string): string {
return (new BigNumber(xrp)).times(1000000.0).floor().toString();
}
function toRippledAmount(amount: Amount): string|Amount {
function toRippledAmount(amount: Amount): RippledAmount {
if (amount.currency === 'XRP') {
return xrpToDrops(amount.value);
}
return {
currency: amount.currency,
issuer: amount.counterparty ? amount.counterparty : amount.issuer,
issuer: amount.counterparty ? amount.counterparty :
(amount.issuer ? amount.issuer : undefined),
value: amount.value
};
}

View File

@@ -1,3 +1,4 @@
/* @flow */
'use strict';
const _ = require('lodash');
@@ -5,8 +6,23 @@ const utils = require('./utils');
const validate = utils.common.validate;
const composeAsync = utils.common.composeAsync;
const convertErrors = utils.common.convertErrors;
import type {Amount} from '../common/types.js';
function formatBalanceSheet(balanceSheet) {
type BalanceSheetOptions = {
excludeAddresses?: Array<string>,
ledgerVersion?: number
}
type GetBalanceSheet = {
balances?: Array<Amount>,
assets?: Array<Amount>,
obligations?: Array<{
currency: string,
value: string
}>
}
function formatBalanceSheet(balanceSheet): GetBalanceSheet {
const result = {};
if (!_.isUndefined(balanceSheet.balances)) {
@@ -33,7 +49,9 @@ function formatBalanceSheet(balanceSheet) {
return result;
}
function getBalanceSheetAsync(address, options, callback) {
function getBalanceSheetAsync(address: string, options: BalanceSheetOptions,
callback
) {
validate.address(address);
validate.getBalanceSheetOptions(options);
@@ -61,7 +79,8 @@ function getBalanceSheetAsync(address, options, callback) {
});
}
function getBalanceSheet(address: string, options = {}) {
function getBalanceSheet(address: string, options: BalanceSheetOptions = {}
): Promise<GetBalanceSheet> {
return utils.promisify(getBalanceSheetAsync).call(this, address, options);
}

View File

@@ -7,11 +7,20 @@ const getTrustlines = require('./trustlines');
const validate = utils.common.validate;
const composeAsync = utils.common.composeAsync;
const convertErrors = utils.common.convertErrors;
import type {Remote} from '../../core/remote';
import type {GetLedgerSequenceCallback} from '../../core/remote';
import type {Remote, GetLedgerSequenceCallback} from '../../core/remote';
import type {TrustlinesOptions, Trustline} from './trustlines-types.js';
function getTrustlineBalanceAmount(trustline) {
type Balance = {
value: string,
currency: string,
counterparty?: string
}
type GetBalances = Array<Balance>
function getTrustlineBalanceAmount(trustline: Trustline) {
return {
currency: trustline.specification.currency,
counterparty: trustline.specification.counterparty,
@@ -28,7 +37,9 @@ function formatBalances(balances) {
balances.trustlines.map(getTrustlineBalanceAmount));
}
function getTrustlinesAsync(account, options, callback) {
function getTrustlinesAsync(account: string, options: TrustlinesOptions,
callback
) {
getTrustlines.call(this, account, options)
.then(data => callback(null, data))
.catch(callback);
@@ -44,7 +55,9 @@ function getLedgerVersionHelper(remote: Remote, optionValue?: number,
}
}
function getBalancesAsync(account, options, callback) {
function getBalancesAsync(account: string, options: TrustlinesOptions,
callback
) {
validate.address(account);
validate.getBalancesOptions(options);
@@ -57,7 +70,8 @@ function getBalancesAsync(account, options, callback) {
}, composeAsync(formatBalances, convertErrors(callback)));
}
function getBalances(account: string, options = {}) {
function getBalances(account: string, options: TrustlinesOptions = {}
): Promise<GetBalances> {
return utils.promisify(getBalancesAsync).call(this, account, options);
}

View File

@@ -5,8 +5,17 @@ const validate = utils.common.validate;
const composeAsync = utils.common.composeAsync;
const convertErrors = utils.common.convertErrors;
const parseLedger = require('./parse/ledger');
import type {GetLedger} from './types.js';
function getLedgerAsync(options, callback) {
type LedgerOptions = {
ledgerVersion?: number,
includeAllData?: boolean,
includeTransactions?: boolean,
includeState?: boolean
}
function getLedgerAsync(options: LedgerOptions, callback) {
validate.getLedgerOptions(options);
const request = {
@@ -21,7 +30,7 @@ function getLedgerAsync(options, callback) {
convertErrors(callback)));
}
function getLedger(options = {}) {
function getLedger(options: LedgerOptions = {}): Promise<GetLedger> {
return utils.promisify(getLedgerAsync).call(this, options);
}

View File

@@ -7,11 +7,40 @@ const validate = utils.common.validate;
const composeAsync = utils.common.composeAsync;
const convertErrors = utils.common.convertErrors;
const parseOrderbookOrder = require('./parse/orderbook-order');
import type {Remote} from '../../core/remote';
import type {OrdersOptions, OrderSpecification} from './types.js';
import type {Amount, Issue} from '../common/types.js';
type Orderbook = {
base: Issue,
counter: Issue
}
type OrderbookItem = {
specification: OrderSpecification,
properties: {
maker: string,
sequence: number,
makerExchangeRate: string
},
state?: {
fundedAmount: Amount,
priceOfFundedAmount: Amount
}
}
type OrderbookOrders = Array<OrderbookItem>
type GetOrderbook = {
bids: OrderbookOrders,
asks: OrderbookOrders
}
// account is to specify a "perspective", which affects which unfunded offers
// are returned
function getBookOffers(remote, account, ledgerVersion, limit,
takerGets, takerPays, callback
function getBookOffers(remote: Remote, account: string,
ledgerVersion?: number, limit?: number, takerGets: Issue,
takerPays: Issue, callback
) {
remote.requestBookOffers(utils.renameCounterpartyToIssuerInOrder({
taker_gets: takerGets,
@@ -22,15 +51,15 @@ function getBookOffers(remote, account, ledgerVersion, limit,
}), composeAsync(data => data.offers, convertErrors(callback)));
}
function isSameIssue(a, b) {
function isSameIssue(a: Amount, b: Amount) {
return a.currency === b.currency && a.counterparty === b.counterparty;
}
function directionFilter(direction, order) {
function directionFilter(direction: string, order: OrderbookItem) {
return order.specification.direction === direction;
}
function flipOrder(order) {
function flipOrder(order: OrderbookItem) {
const specification = order.specification;
const flippedSpecification = {
quantity: specification.totalPrice,
@@ -41,12 +70,12 @@ function flipOrder(order) {
return _.merge({}, order, {specification: newSpecification});
}
function alignOrder(base, order) {
function alignOrder(base: Amount, order: OrderbookItem) {
const quantity = order.specification.quantity;
return isSameIssue(quantity, base) ? order : flipOrder(order);
}
function formatBidsAndAsks(orderbook, offers) {
function formatBidsAndAsks(orderbook: Orderbook, offers) {
// the "base" currency is the currency that you are buying or selling
// the "counter" is the currency that the "base" is priced in
// a "bid"/"ask" is an order to buy/sell the base, respectively
@@ -64,7 +93,9 @@ function formatBidsAndAsks(orderbook, offers) {
return {bids, asks};
}
function getOrderbookAsync(account, orderbook, options, callback) {
function getOrderbookAsync(account: string, orderbook: Orderbook,
options: OrdersOptions, callback
) {
validate.address(account);
validate.orderbook(orderbook);
validate.getOrderbookOptions(options);
@@ -78,7 +109,9 @@ function getOrderbookAsync(account, orderbook, options, callback) {
callback));
}
function getOrderbook(account: string, orderbook: Object, options = {}) {
function getOrderbook(account: string, orderbook: Orderbook,
options: OrdersOptions = {}
): Promise<GetOrderbook> {
return utils.promisify(getOrderbookAsync).call(this,
account, orderbook, options);
}

View File

@@ -7,9 +7,13 @@ const validate = utils.common.validate;
const composeAsync = utils.common.composeAsync;
const convertErrors = utils.common.convertErrors;
const parseAccountOrder = require('./parse/account-order');
import type {Remote} from '../../core/remote';
import type {OrdersOptions, Order} from './types.js';
function requestAccountOffers(remote, address, ledgerVersion, marker, limit,
callback
type GetOrders = Array<Order>
function requestAccountOffers(remote: Remote, address: string,
ledgerVersion: number, marker: string, limit: number, callback
) {
remote.requestAccountOffers({
account: address,
@@ -23,7 +27,7 @@ function requestAccountOffers(remote, address, ledgerVersion, marker, limit,
}), convertErrors(callback)));
}
function getOrdersAsync(account, options, callback) {
function getOrdersAsync(account: string, options: OrdersOptions, callback) {
validate.address(account);
validate.getOrdersOptions(options);
@@ -34,7 +38,8 @@ function getOrdersAsync(account, options, callback) {
(order) => order.properties.sequence), callback));
}
function getOrders(account: string, options = {}) {
function getOrders(account: string, options: OrdersOptions = {}
): Promise<GetOrders> {
return utils.promisify(async.seq(
utils.getLedgerOptionsWithLedgerVersion,
getOrdersAsync)).call(this, account, options);

View File

@@ -1,13 +1,10 @@
/* @flow */
'use strict';
const utils = require('./utils');
import type {Amount, RippledAmount} from '../../common/types.js';
type Amount = string | {currency: string, issuer: string, value: string}
type XRPAmount = {currency: string, value: string}
type IOUAmount = {currency: string, value: string, counterparty: string}
type Output = XRPAmount | IOUAmount
function parseAmount(amount: Amount): Output {
function parseAmount(amount: RippledAmount): Amount {
if (typeof amount === 'string') {
return {
currency: 'XRP',

View File

@@ -3,6 +3,7 @@
const _ = require('lodash');
const removeUndefined = require('./utils').removeUndefined;
const parseTransaction = require('./transaction');
import type {GetLedger} from '../types.js';
function parseTransactions(transactions) {
if (_.isEmpty(transactions)) {
@@ -27,7 +28,7 @@ function parseState(state) {
return {rawState: JSON.stringify(state)};
}
function parseLedger(ledger: Object): Object {
function parseLedger(ledger: Object): GetLedger {
return removeUndefined(_.assign({
accepted: ledger.accepted,
closed: ledger.closed,

View File

@@ -2,13 +2,15 @@
'use strict';
const _ = require('lodash');
const parseAmount = require('./amount');
import type {Amount, RippledAmount} from '../../common/types.js';
import type {GetPaths, RippledPathsResponse} from '../pathfind-types.js';
function parsePaths(paths) {
return paths.map(steps => steps.map(step =>
_.omit(step, ['type', 'type_hex'])));
}
function removeAnyCounterpartyEncoding(address: string, amount: Object) {
function removeAnyCounterpartyEncoding(address: string, amount: Amount) {
return amount.counterparty === address ?
_.omit(amount, 'counterparty') : amount;
}
@@ -21,7 +23,7 @@ function createAdjustment(address: string, adjustmentWithoutAddress: Object) {
}
function parseAlternative(sourceAddress: string, destinationAddress: string,
destinationAmount: Object, alternative: Object
destinationAmount: RippledAmount, alternative: Object
) {
// we use "maxAmount"/"minAmount" here so that the result can be passed
// directly to preparePayment
@@ -38,7 +40,7 @@ function parseAlternative(sourceAddress: string, destinationAddress: string,
};
}
function parsePathfind(pathfindResult: Object): Object {
function parsePathfind(pathfindResult: RippledPathsResponse): GetPaths {
const sourceAddress = pathfindResult.source_account;
const destinationAddress = pathfindResult.destination_account;
const destinationAmount = pathfindResult.destination_amount;

View File

@@ -0,0 +1,54 @@
/* @flow */
'use strict';
import type {Amount, LaxLaxAmount, RippledAmount, Adjustment, MaxAdjustment,
MinAdjustment} from '../common/types.js';
type Path = {
source: Adjustment | MaxAdjustment,
destination: Adjustment | MinAdjustment,
paths: string
}
export type GetPaths = Array<Path>
export type PathFind = {
source: {
address: string,
amount?: Amount,
currencies?: Array<{currency: string, counterparty?:string}>
},
destination: {
address: string,
amount: LaxLaxAmount
}
}
export type PathFindParams = {
src_account: string,
dst_amount: RippledAmount,
dst_account: string,
src_amount?: RippledAmount,
src_currencies?: Array<string>
}
export type RippledPathsResponse = {
alternatives: Array<{
paths_computed: Array<Array<{
type: number,
type_hex: string,
account?: string,
issuer?: string,
currency?: string
}>>,
source_amount: RippledAmount
}>,
type: string,
destination_account: string,
destination_amount: RippledAmount,
destination_currencies?: Array<string>,
source_account?: string,
source_currencies?: Array<{currency: string}>,
full_reply?: boolean
}

View File

@@ -11,27 +11,20 @@ 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,
RippledPathsResponse} from './pathfind-types.js';
type PathFindParams = {
src_currencies?: Array<string>, src_account: string,
dst_amount: string | Object, dst_account?: string,
src_amount?: string | Object
}
function addParams(params: PathFindParams, result: {}) {
return _.assign({}, result, {
function addParams(params: PathFindParams, result: RippledPathsResponse) {
return _.defaults(_.assign({}, result, {
source_account: params.src_account,
source_currencies: params.src_currencies,
destination_amount: params.dst_amount
});
source_currencies: params.src_currencies
}), {destination_amount: params.dst_amount});
}
type PathFind = {
source: {address: string, currencies: Array<string>},
destination: {address: string, amount: string}
}
function requestPathFind(remote, pathfind: PathFind, callback) {
function requestPathFind(remote: Remote, pathfind: PathFind, callback) {
const destinationAmount = _.assign({value: -1}, pathfind.destination.amount);
const params: PathFindParams = {
src_account: pathfind.source.address,
@@ -65,7 +58,8 @@ function requestPathFind(remote, pathfind: PathFind, callback) {
composeAsync(_.partial(addParams, params), convertErrors(callback)));
}
function addDirectXrpPath(paths, xrpBalance) {
function addDirectXrpPath(paths: RippledPathsResponse, xrpBalance: string
): RippledPathsResponse {
// Add XRP "path" only if the source acct has enough XRP to make the payment
const destinationAmount = paths.destination_amount;
if ((new BigNumber(xrpBalance)).greaterThanOrEqualTo(destinationAmount)) {
@@ -77,13 +71,15 @@ function addDirectXrpPath(paths, xrpBalance) {
return paths;
}
function isRippledIOUAmount(amount) {
function isRippledIOUAmount(amount: RippledAmount) {
// rippled XRP amounts are specified as decimal strings
return (typeof amount === 'object') &&
amount.currency && (amount.currency !== 'XRP');
}
function conditionallyAddDirectXRPPath(remote, address, paths, callback) {
function conditionallyAddDirectXRPPath(remote: Remote, address: string,
paths: RippledPathsResponse, callback
) {
if (isRippledIOUAmount(paths.destination_amount)
|| !_.includes(paths.destination_currencies, 'XRP')) {
callback(null, paths);
@@ -93,7 +89,7 @@ function conditionallyAddDirectXRPPath(remote, address, paths, callback) {
}
}
function formatResponse(pathfind, paths) {
function formatResponse(pathfind: PathFind, paths: RippledPathsResponse) {
if (paths.alternatives && paths.alternatives.length > 0) {
return parsePathfind(paths);
}
@@ -118,7 +114,7 @@ function formatResponse(pathfind, paths) {
}
}
function getPathsAsync(pathfind, callback) {
function getPathsAsync(pathfind: PathFind, callback) {
validate.pathfind(pathfind);
const address = pathfind.source.address;
@@ -128,7 +124,7 @@ function getPathsAsync(pathfind, callback) {
], composeAsync(_.partial(formatResponse, pathfind), callback));
}
function getPaths(pathfind: Object) {
function getPaths(pathfind: PathFind): Promise<GetPaths> {
return utils.promisify(getPathsAsync).call(this, pathfind);
}

View File

@@ -8,6 +8,31 @@ const composeAsync = utils.common.composeAsync;
const AccountFlags = utils.common.constants.AccountFlags;
const convertErrors = utils.common.convertErrors;
type SettingsOptions = {
ledgerVersion?: number
}
type GetSettings = {
passwordSpent?: boolean,
requireDestinationTag?: boolean,
requireAuthorization?: boolean,
disallowIncomingXRP?: boolean,
disableMasterKey?: boolean,
enableTransactionIDTracking?: boolean,
noFreeze?: boolean,
globalFreeze?: boolean,
defaultRipple?: boolean,
emailHash?: ?string,
walletLocator?: ?string,
walletSize?: ?number,
messageKey?: string,
domain?: string,
transferRate?: ?number,
signers?: string,
regularKey?: string
}
function parseFlags(value) {
const settings = {};
for (const flagName in AccountFlags) {
@@ -25,7 +50,7 @@ function formatSettings(response) {
return _.assign({}, parsedFlags, parsedFields);
}
function getSettingsAsync(account, options, callback) {
function getSettingsAsync(account: string, options: SettingsOptions, callback) {
validate.address(account);
validate.getSettingsOptions(options);
@@ -38,7 +63,8 @@ function getSettingsAsync(account, options, callback) {
composeAsync(formatSettings, convertErrors(callback)));
}
function getSettings(account: string, options = {}) {
function getSettings(account: string, options: SettingsOptions = {}
): Promise<GetSettings> {
return utils.promisify(getSettingsAsync).call(this, account, options);
}

View File

@@ -1,14 +1,16 @@
/* @flow */
'use strict';
import type {Amount, Memo} from '../common/types.js';
type Outcome = {
result: string,
timestamp?: string,
ledgerVersion: number,
indexInLedger: number,
fee: string,
balanceChanges: Object,
orderbookChanges: Object,
ledgerVersion: number,
indexInLedger: number
timestamp?: string
}
type Adjustment = {
@@ -56,18 +58,6 @@ type OrderCancellation = {
orderSequence: number
}
type Memo = {
type?: string,
format?: string,
data?: string
}
type Amount = {
value: string,
currency: string,
counterparty?: string
}
type Payment = {
source: Adjustment,
destination: Adjustment,
@@ -88,7 +78,7 @@ type PaymentTransaction = {
sequence: number
}
type Order = {
export type Order = {
direction: string,
quantity: Amount,
totalPrice: Amount,
@@ -138,10 +128,10 @@ export type TransactionOptions = {
maxLedgerVersion?: number
}
export type GetTransactionResponse = PaymentTransaction | OrderTransaction |
export type TransactionType = PaymentTransaction | OrderTransaction |
OrderCancellationTransaction | TrustlineTransaction | SettingsTransaction
export type GetTransactionResponseCallback =
(err?: ?Error, data?: GetTransactionResponse) => void
(err?: ?Error, data?: TransactionType) => void
export type CallbackType = (err?: ?Error, data?: Object) => void

View File

@@ -11,7 +11,7 @@ const RippleError = require('../../core/rippleerror').RippleError;
import type {Remote} from '../../core/remote';
import type {CallbackType, GetTransactionResponse,
import type {CallbackType, TransactionType,
GetTransactionResponseCallback, TransactionOptions}
from './transaction-types';
@@ -106,7 +106,7 @@ function getTransactionAsync(identifier: string, options: TransactionOptions,
function getTransaction(identifier: string,
options: TransactionOptions = {}
): Promise<GetTransactionResponse> {
): Promise<TransactionType> {
return utils.promisify(getTransactionAsync).call(this, identifier, options);
}

View File

@@ -9,6 +9,29 @@ const validate = utils.common.validate;
const composeAsync = utils.common.composeAsync;
const convertErrors = utils.common.convertErrors;
import type {Remote} from '../../core/remote';
import type {TransactionType} from './transaction-types';
type TransactionsOptions = {
start?: string,
limit?: number,
minLedgerVersion?: number,
maxLedgerVersion?: number,
earliestFirst?: boolean,
excludeFailures?: boolean,
initiated?: boolean,
counterparty?: string,
types?: Array<string>,
binary?: boolean,
startTx?: TransactionType
}
type GetTransactionsResponse = Array<TransactionType>
type CallbackType = (err?: ?Error, data?: GetTransactionsResponse) => void
function parseAccountTxTransaction(tx) {
// rippled uses a different response format for 'account_tx' than 'tx'
tx.tx.meta = tx.meta;
@@ -16,7 +39,7 @@ function parseAccountTxTransaction(tx) {
return parseTransaction(tx.tx);
}
function counterpartyFilter(filters, tx) {
function counterpartyFilter(filters, tx: TransactionType) {
if (!filters.counterparty) {
return true;
}
@@ -31,7 +54,9 @@ function counterpartyFilter(filters, tx) {
return false;
}
function transactionFilter(address, filters, tx) {
function transactionFilter(address: string, filters: TransactionsOptions,
tx: TransactionType
) {
if (filters.excludeFailures && tx.outcome.result !== 'tesSUCCESS') {
return false;
}
@@ -50,13 +75,15 @@ function transactionFilter(address, filters, tx) {
return true;
}
function orderFilter(options, tx) {
function orderFilter(options: TransactionsOptions, tx: TransactionType) {
return !options.startTx || (options.earliestFirst ?
utils.compareTransactions(tx, options.startTx) > 0 :
utils.compareTransactions(tx, options.startTx) < 0);
}
function formatPartialResponse(address, options, data) {
function formatPartialResponse(address: string,
options: TransactionsOptions, data
) {
return {
marker: data.marker,
results: data.transactions
@@ -67,7 +94,9 @@ function formatPartialResponse(address, options, data) {
};
}
function getAccountTx(remote, address, options, marker, limit, callback) {
function getAccountTx(remote: Remote, address: string,
options: TransactionsOptions, marker: string, limit: number, callback
) {
const params = {
account: address,
// -1 is equivalent to earliest available validated ledger
@@ -85,7 +114,9 @@ function getAccountTx(remote, address, options, marker, limit, callback) {
convertErrors(callback)));
}
function checkForLedgerGaps(remote, options, transactions) {
function checkForLedgerGaps(remote: Remote, options: TransactionsOptions,
transactions: GetTransactionsResponse
) {
let {minLedgerVersion, maxLedgerVersion} = options;
// if we reached the limit on number of transactions, then we can shrink
@@ -105,7 +136,9 @@ function checkForLedgerGaps(remote, options, transactions) {
}
}
function formatResponse(remote, options, transactions) {
function formatResponse(remote: Remote, options: TransactionsOptions,
transactions: GetTransactionsResponse
) {
const compare = options.earliestFirst ? utils.compareTransactions :
_.rearg(utils.compareTransactions, 1, 0);
const sortedTransactions = transactions.sort(compare);
@@ -113,13 +146,17 @@ function formatResponse(remote, options, transactions) {
return sortedTransactions;
}
function getTransactionsInternal(remote, address, options, callback) {
function getTransactionsInternal(remote: Remote, address: string,
options: TransactionsOptions, callback
) {
const getter = _.partial(getAccountTx, remote, address, options);
const format = _.partial(formatResponse, remote, options);
utils.getRecursive(getter, options.limit, composeAsync(format, callback));
}
function getTransactionsAsync(account, options, callback) {
function getTransactionsAsync(account: string,
options: TransactionsOptions, callback: CallbackType
) {
validate.address(account);
validate.getTransactionsOptions(options);
@@ -138,7 +175,8 @@ function getTransactionsAsync(account, options, callback) {
}
}
function getTransactions(account: string, options = {}) {
function getTransactions(account: string, options: TransactionsOptions = {}
): Promise<GetTransactionsResponse> {
return utils.promisify(getTransactionsAsync).call(this, account, options);
}

View File

@@ -0,0 +1,33 @@
/* @flow */
'use strict';
export type TrustLineSpecification = {
currency: string,
counterparty: string,
limit: string,
qualityIn?: number,
qualityOut?: number,
ripplingDisabled?: boolean,
authorized?: boolean,
frozen?: boolean
}
export type Trustline = {
specification: TrustLineSpecification,
counterparty: {
limit: string,
ripplingDisabled?: boolean,
frozen?: boolean,
authorized?: boolean
},
state: {
balance: string
}
}
export type TrustlinesOptions = {
counterparty?: string,
currency?: string,
limit?: number,
ledgerVersion?: number
}

View File

@@ -8,11 +8,17 @@ const composeAsync = utils.common.composeAsync;
const convertErrors = utils.common.convertErrors;
const parseAccountTrustline = require('./parse/account-trustline');
function currencyFilter(currency, trustline) {
import type {Remote} from '../../core/remote';
import type {TrustlinesOptions, Trustline} from './trustlines-types.js';
type GetTrustlinesResponse = Array<Trustline>
function currencyFilter(currency: string, trustline: Trustline) {
return currency === null || trustline.specification.currency === currency;
}
function formatResponse(options, data) {
function formatResponse(options: TrustlinesOptions, data) {
return {
marker: data.marker,
results: data.lines.map(parseAccountTrustline)
@@ -20,8 +26,8 @@ function formatResponse(options, data) {
};
}
function getAccountLines(remote, address, ledgerVersion, options, marker, limit,
callback
function getAccountLines(remote: Remote, address: string, ledgerVersion: number,
options: TrustlinesOptions, marker: string, limit: number, callback
) {
const requestOptions = {
account: address,
@@ -36,8 +42,7 @@ function getAccountLines(remote, address, ledgerVersion, options, marker, limit,
convertErrors(callback)));
}
function getTrustlinesAsync(account: string, options: {currency: string,
counterparty: string, limit: number, ledgerVersion: number},
function getTrustlinesAsync(account: string, options: TrustlinesOptions,
callback: () => void
): void {
validate.address(account);
@@ -48,7 +53,8 @@ function getTrustlinesAsync(account: string, options: {currency: string,
utils.getRecursive(getter, options.limit, callback);
}
function getTrustlines(account: string, options = {}) {
function getTrustlines(account: string, options: TrustlinesOptions = {}
): Promise<GetTrustlinesResponse> {
return utils.promisify(async.seq(
utils.getLedgerOptionsWithLedgerVersion,
getTrustlinesAsync)).call(this, account, options);

50
src/api/ledger/types.js Normal file
View File

@@ -0,0 +1,50 @@
/* @flow */
'use strict';
import type {Amount} from '../common/types.js';
export type OrdersOptions = {
limit?: number,
ledgerVersion?: number
}
export type OrderSpecification = {
direction: string,
quantity: Amount,
totalPrice: Amount,
immediateOrCancel?: boolean,
fillOrKill?: boolean,
// If enabled, the offer will not consume offers that exactly match it, and
// instead becomes an Offer node in the ledger. It will still consume offers
// that cross it.
passive?: boolean
}
export type Order = {
specification: OrderSpecification,
properties: {
maker: string,
sequence: number,
makerExchangeRate: string
}
}
export type GetLedger = {
accepted: boolean,
closed: boolean,
stateHash: string,
closeTime: number,
closeTimeResolution: number,
closeFlags: number,
ledgerHash: string,
ledgerVersion: number,
parentLedgerHash: string,
parentCloseTime: number,
totalDrops: string,
transactionHash: string,
transactions?: Array<Object>,
rawTransactions?: string,
transactionHashes?: Array<string>,
rawState?: string,
stateHashes?: Array<string>
}

View File

@@ -6,9 +6,18 @@ const common = require('../common');
const dropsToXrp = common.dropsToXrp;
const composeAsync = common.composeAsync;
import type {Remote} from '../../core/remote';
import type {TransactionType} from './transaction-types';
import type {Issue} from '../common/types.js';
type Callback = (err: any, data: any) => void
type RecursiveData = {
marker: string,
results: Array<any>
}
type RecursiveCallback = (err: any, data: RecursiveData) => void
function clamp(value: number, min: number, max: number): number {
assert(min <= max, 'Illegal clamp bounds');
return Math.min(Math.max(value, min), max);
@@ -21,7 +30,8 @@ function getXRPBalance(remote: Remote, address: string, ledgerVersion?: number,
composeAsync((data) => dropsToXrp(data.account_data.Balance), callback));
}
type Getter = (marker: ?string, limit: number, callback: Callback) => void
type Getter = (marker: ?string, limit: number,
callback: RecursiveCallback) => void
// If the marker is omitted from a response, you have reached the end
// getter(marker, limit, callback), callback(error, {marker, results})
@@ -48,21 +58,20 @@ function getRecursive(getter: Getter, limit?: number, callback: Callback) {
getRecursiveRecur(getter, undefined, limit || Infinity, callback);
}
type Amount = {counterparty?: string, issuer?: string, value: string}
function renameCounterpartyToIssuer(amount?: Amount): ?{issuer?: string} {
function renameCounterpartyToIssuer(amount?: Issue): ?{issuer?: string} {
if (amount === undefined) {
return undefined;
}
const issuer = amount.counterparty === undefined ?
amount.issuer : amount.counterparty;
(amount.issuer !== undefined ? amount.issuer : undefined) :
amount.counterparty;
const withIssuer = _.assign({}, amount, {issuer: issuer});
return _.omit(withIssuer, 'counterparty');
}
type Order = {taker_gets: Amount, taker_pays: Amount}
type RequestBookOffersArgs = {taker_gets: Issue, taker_pays: Issue}
function renameCounterpartyToIssuerInOrder(order: Order) {
function renameCounterpartyToIssuerInOrder(order: RequestBookOffersArgs) {
const taker_gets = renameCounterpartyToIssuer(order.taker_gets);
const taker_pays = renameCounterpartyToIssuer(order.taker_pays);
const changes = {taker_gets: taker_gets, taker_pays: taker_pays};
@@ -84,9 +93,8 @@ function signum(num) {
* @returns {Number} [-1, 0, 1]
*/
type Outcome = {outcome: {ledgerVersion: number, indexInLedger: number}};
function compareTransactions(first: Outcome, second: Outcome): number {
function compareTransactions(first: TransactionType, second: TransactionType
): number {
if (!first.outcome || !second.outcome) {
return 0;
}

View File

@@ -3,6 +3,8 @@
const utils = require('./utils');
const validate = utils.common.validate;
const Transaction = utils.common.core.Transaction;
import type {Instructions, Prepare} from './types.js';
import type {Order} from '../ledger/transaction-types.js';
const OfferCreateFlags = {
passive: {set: 'Passive'},
@@ -10,7 +12,7 @@ const OfferCreateFlags = {
fillOrKill: {set: 'FillOrKill'}
};
function createOrderTransaction(account, order) {
function createOrderTransaction(account: string, order: Order): Transaction {
validate.address(account);
validate.order(order);
@@ -30,12 +32,16 @@ function createOrderTransaction(account, order) {
return transaction;
}
function prepareOrderAsync(account, order, instructions, callback) {
function prepareOrderAsync(account: string, order: Order,
instructions: Instructions, callback
) {
const transaction = createOrderTransaction(account, order);
utils.prepareTransaction(transaction, this.remote, instructions, callback);
}
function prepareOrder(account: string, order: Object, instructions = {}) {
function prepareOrder(account: string, order: Order,
instructions: Instructions = {}
): Promise<Prepare> {
return utils.promisify(prepareOrderAsync.bind(this))(
account, order, instructions);
}

View File

@@ -3,8 +3,11 @@
const utils = require('./utils');
const validate = utils.common.validate;
const Transaction = utils.common.core.Transaction;
import type {Instructions, Prepare} from './types.js';
function createOrderCancellationTransaction(account, sequence) {
function createOrderCancellationTransaction(account: string,
sequence: number
): Transaction {
validate.address(account);
validate.sequence(sequence);
@@ -13,16 +16,16 @@ function createOrderCancellationTransaction(account, sequence) {
return transaction;
}
function prepareOrderCancellationAsync(account, sequence, instructions,
callback
function prepareOrderCancellationAsync(account: string, sequence: number,
instructions: Instructions, callback
) {
const transaction = createOrderCancellationTransaction(account, sequence);
utils.prepareTransaction(transaction, this.remote, instructions, callback);
}
function prepareOrderCancellation(account: string, sequence: number,
instructions = {}
) {
instructions: Instructions = {}
): Promise<Prepare> {
return utils.promisify(prepareOrderCancellationAsync.bind(this))(
account, sequence, instructions);
}

View File

@@ -6,19 +6,44 @@ const validate = utils.common.validate;
const toRippledAmount = utils.common.toRippledAmount;
const Transaction = utils.common.core.Transaction;
const ValidationError = utils.common.errors.ValidationError;
import type {Instructions, Prepare} from './types.js';
import type {Amount, Adjustment, MaxAdjustment,
MinAdjustment, Memo} from '../common/types.js';
function isXRPToXRPPayment(payment) {
type Payment = {
source: Adjustment | MaxAdjustment,
destination: Adjustment | MinAdjustment,
paths?: string,
memos?: Array<Memo>,
// A 256-bit hash that can be used to identify a particular payment
invoiceID?: string,
// A boolean that, if set to true, indicates that this payment should go
// through even if the whole amount cannot be delivered because of a lack of
// liquidity or funds in the source_account account
allowPartialPayment?: boolean,
// A boolean that can be set to true if paths are specified and the sender
// would like the Ripple Network to disregard any direct paths from
// the source_account to the destination_account. This may be used to take
// advantage of an arbitrage opportunity or by gateways wishing to issue
// balances from a hot wallet to a user who has mistakenly set a trustline
// directly to the hot wallet
noDirectRipple?: boolean,
limitQuality?: boolean
}
function isXRPToXRPPayment(payment: Payment): boolean {
const sourceCurrency = _.get(payment, 'source.maxAmount.currency');
const destinationCurrency = _.get(payment, 'destination.amount.currency');
return sourceCurrency === 'XRP' && destinationCurrency === 'XRP';
}
function isIOUWithoutCounterparty(amount) {
function isIOUWithoutCounterparty(amount: Amount): boolean {
return amount && amount.currency !== 'XRP'
&& amount.counterparty === undefined;
}
function applyAnyCounterpartyEncoding(payment) {
function applyAnyCounterpartyEncoding(payment: Payment): void {
// Convert blank counterparty to sender or receiver's address
// (Ripple convention for 'any counterparty')
// https://ripple.com/build/transactions/
@@ -33,14 +58,15 @@ function applyAnyCounterpartyEncoding(payment) {
});
}
function createMaximalAmount(amount) {
function createMaximalAmount(amount: Amount): Amount {
const maxXRPValue = '100000000000';
const maxIOUValue = '9999999999999999e80';
const maxValue = amount.currency === 'XRP' ? maxXRPValue : maxIOUValue;
return _.assign(amount, {value: maxValue});
}
function createPaymentTransaction(account, paymentArgument) {
function createPaymentTransaction(account: string, paymentArgument: Payment
): Transaction {
const payment = _.cloneDeep(paymentArgument);
applyAnyCounterpartyEncoding(payment);
validate.address(account);
@@ -115,12 +141,16 @@ function createPaymentTransaction(account, paymentArgument) {
return transaction;
}
function preparePaymentAsync(account, payment, instructions, callback) {
function preparePaymentAsync(account: string, payment: Payment,
instructions: Instructions, callback
) {
const transaction = createPaymentTransaction(account, payment);
utils.prepareTransaction(transaction, this.remote, instructions, callback);
}
function preparePayment(account: string, payment: Object, instructions = {}) {
function preparePayment(account: string, payment: Payment,
instructions: Instructions = {}
): Promise<Prepare> {
return utils.promisify(preparePaymentAsync.bind(this))(
account, payment, instructions);
}

View File

@@ -0,0 +1,62 @@
/* @flow */
'use strict';
type SettingPasswordSpent = {
passwordSpent?: boolean,
}
type SettingRequireDestinationTag = {
requireDestinationTag?: boolean,
}
type SettingRequireAuthorization = {
requireAuthorization?: boolean,
}
type SettingDisallowIncomingXRP = {
disallowIncomingXRP?: boolean,
}
type SettingDisableMasterKey = {
disableMasterKey?: boolean,
}
type SettingEnableTransactionIDTracking = {
enableTransactionIDTracking?: boolean,
}
type SettingNoFreeze = {
noFreeze?: boolean,
}
type SettingGlobalFreeze = {
globalFreeze?: boolean,
}
type SettingDefaultRipple = {
defaultRipple?: boolean,
}
type SettingEmailHash = {
emailHash?: ?string,
}
type SettingWalletLocator = {
walletLocator?: ?string,
}
type SettingWalletSize = {
walletSize?: ?number,
}
type SettingMessageKey = {
messageKey?: string,
}
type SettingDomain = {
domain?: string,
}
type SettingTransferRate = {
transferRate?: ?number,
}
type SettingSigners = {
signers?: string,
}
type SettingRegularKey = {
regularKey?: string
}
export type Settings = SettingRegularKey | SettingSigners |
SettingTransferRate | SettingDomain | SettingMessageKey | SettingWalletSize |
SettingWalletLocator | SettingEmailHash | SettingDefaultRipple |
SettingGlobalFreeze | SettingNoFreeze | SettingEnableTransactionIDTracking |
SettingDisableMasterKey | SettingDisallowIncomingXRP |
SettingRequireAuthorization | SettingRequireDestinationTag |
SettingPasswordSpent

View File

@@ -7,11 +7,14 @@ const validate = utils.common.validate;
const AccountFlagIndices = utils.common.constants.AccountFlagIndices;
const AccountFields = utils.common.constants.AccountFields;
const Transaction = utils.common.core.Transaction;
import type {Instructions, Prepare} from './types.js';
import type {Settings} from './settings-types.js';
// Emptry string passed to setting will clear it
const CLEAR_SETTING = null;
function setTransactionFlags(transaction, values) {
function setTransactionFlags(transaction: Transaction, values: Settings) {
const keys = Object.keys(values);
assert(keys.length === 1, 'ERROR: can only set one setting per transaction');
const flagName = keys[0];
@@ -26,7 +29,7 @@ function setTransactionFlags(transaction, values) {
}
}
function setTransactionFields(transaction, input) {
function setTransactionFields(transaction: Transaction, input: Settings) {
const fieldSchema = AccountFields;
for (const fieldName in fieldSchema) {
const field = fieldSchema[fieldName];
@@ -63,11 +66,12 @@ function setTransactionFields(transaction, input) {
* are returned
*/
function convertTransferRate(transferRate) {
function convertTransferRate(transferRate: number | string): number | string {
return (new BigNumber(transferRate)).shift(9).toNumber();
}
function createSettingsTransaction(account, settings) {
function createSettingsTransaction(account: string, settings: Settings
): Transaction {
validate.address(account);
validate.settings(settings);
@@ -90,12 +94,16 @@ function createSettingsTransaction(account, settings) {
return transaction;
}
function prepareSettingsAsync(account, settings, instructions, callback) {
function prepareSettingsAsync(account: string, settings: Settings,
instructions: Instructions, callback
) {
const transaction = createSettingsTransaction(account, settings);
utils.prepareTransaction(transaction, this.remote, instructions, callback);
}
function prepareSettings(account: string, settings: Object, instructions = {}) {
function prepareSettings(account: string, settings: Object,
instructions: Instructions = {}
): Promise<Prepare> {
return utils.promisify(prepareSettingsAsync.bind(this))(
account, settings, instructions);
}

View File

@@ -6,7 +6,16 @@ const validate = utils.common.validate;
const Request = utils.common.core.Request;
const convertErrors = utils.common.convertErrors;
function isImmediateRejection(engineResult) {
type Submit = {
success: boolean,
engineResult: string,
engineResultCode: number,
engineResultMessage?: string,
txBlob?: string,
txJson?: Object
}
function isImmediateRejection(engineResult: string): boolean {
// note: "tel" errors mean the local server refused to process the
// transaction *at that time*, but it could potentially buffer the
// transaction and then process it at a later time, for example
@@ -37,7 +46,7 @@ function submitAsync(txBlob: string, callback: (err: any, data: any) => void
convertSubmitErrors(convertErrors(callback))));
}
function submit(txBlob: string) {
function submit(txBlob: string): Promise<Submit> {
return utils.promisify(submitAsync.bind(this))(txBlob);
}

View File

@@ -4,8 +4,18 @@ const _ = require('lodash');
const utils = require('./utils');
const validate = utils.common.validate;
const Transaction = utils.common.core.Transaction;
import type {Instructions, Prepare} from './types.js';
import type {Memo} from '../common/types.js';
function createSuspendedPaymentCancellationTransaction(account, payment) {
type SuspendedPaymentCancellation = {
owner: string,
paymentSequence: number,
memos?: Array<Memo>
}
function createSuspendedPaymentCancellationTransaction(account: string,
payment: SuspendedPaymentCancellation
): Transaction {
validate.address(account);
validate.suspendedPaymentCancellation(payment);
@@ -24,15 +34,17 @@ function createSuspendedPaymentCancellationTransaction(account, payment) {
return transaction;
}
function prepareSuspendedPaymentCancellationAsync(account, payment,
instructions, callback) {
function prepareSuspendedPaymentCancellationAsync(account: string,
payment: SuspendedPaymentCancellation, instructions: Instructions, callback
) {
const transaction =
createSuspendedPaymentCancellationTransaction(account, payment);
utils.prepareTransaction(transaction, this.remote, instructions, callback);
}
function prepareSuspendedPaymentCancellation(account: string, payment: Object,
instructions = {}) {
function prepareSuspendedPaymentCancellation(account: string,
payment: SuspendedPaymentCancellation, instructions: Instructions = {}
): Promise<Prepare> {
return utils.promisify(prepareSuspendedPaymentCancellationAsync)
.call(this, account, payment, instructions);
}

View File

@@ -5,8 +5,21 @@ const utils = require('./utils');
const validate = utils.common.validate;
const toRippledAmount = utils.common.toRippledAmount;
const Transaction = utils.common.core.Transaction;
import type {Instructions, Prepare} from './types.js';
import type {Adjustment, MaxAdjustment, Memo} from '../common/types.js';
function createSuspendedPaymentCreationTransaction(account, payment) {
type SuspendedPaymentCreation = {
source: MaxAdjustment,
destination: Adjustment,
memos?: Array<Memo>,
digest?: string,
allowCancelAfter?: number,
allowExecuteAfter?: number
}
function createSuspendedPaymentCreationTransaction(account: string,
payment: SuspendedPaymentCreation
): Transaction {
validate.address(account);
validate.suspendedPaymentCreation(payment);
@@ -41,15 +54,17 @@ function createSuspendedPaymentCreationTransaction(account, payment) {
return transaction;
}
function prepareSuspendedPaymentCreationAsync(account, payment, instructions,
callback) {
function prepareSuspendedPaymentCreationAsync(account: string,
payment: SuspendedPaymentCreation, instructions: Instructions, callback
) {
const transaction =
createSuspendedPaymentCreationTransaction(account, payment);
utils.prepareTransaction(transaction, this.remote, instructions, callback);
}
function prepareSuspendedPaymentCreation(account: string, payment: Object,
instructions = {}) {
function prepareSuspendedPaymentCreation(account: string,
payment: SuspendedPaymentCreation, instructions: Instructions = {}
): Promise<Prepare> {
return utils.promisify(prepareSuspendedPaymentCreationAsync)
.call(this, account, payment, instructions);
}

View File

@@ -4,8 +4,21 @@ const _ = require('lodash');
const utils = require('./utils');
const validate = utils.common.validate;
const Transaction = utils.common.core.Transaction;
import type {Instructions, Prepare} from './types.js';
import type {Memo} from '../common/types.js';
function createSuspendedPaymentExecutionTransaction(account, payment) {
type SuspendedPaymentExecution = {
owner: string,
paymentSequence: number,
memos?: Array<Memo>,
method?: number,
digest?: string,
proof?: string
}
function createSuspendedPaymentExecutionTransaction(account: string,
payment: SuspendedPaymentExecution
): Transaction {
validate.address(account);
validate.suspendedPaymentExecution(payment);
@@ -34,15 +47,17 @@ function createSuspendedPaymentExecutionTransaction(account, payment) {
return transaction;
}
function prepareSuspendedPaymentExecutionAsync(account, payment, instructions,
callback) {
function prepareSuspendedPaymentExecutionAsync(account: string,
payment: SuspendedPaymentExecution, instructions: Instructions, callback
) {
const transaction =
createSuspendedPaymentExecutionTransaction(account, payment);
utils.prepareTransaction(transaction, this.remote, instructions, callback);
}
function prepareSuspendedPaymentExecution(account: string, payment: Object,
instructions = {}) {
function prepareSuspendedPaymentExecution(account: string,
payment: SuspendedPaymentExecution, instructions: Instructions = {}
): Promise<Prepare> {
return utils.promisify(prepareSuspendedPaymentExecutionAsync)
.call(this, account, payment, instructions);
}

View File

@@ -4,6 +4,8 @@ const utils = require('./utils');
const validate = utils.common.validate;
const Transaction = utils.common.core.Transaction;
const BigNumber = require('bignumber.js');
import type {Instructions, Prepare} from './types.js';
import type {TrustLineSpecification} from '../ledger/trustlines-types.js';
const TrustSetFlags = {
authorized: {set: 'SetAuth'},
@@ -16,7 +18,9 @@ function convertQuality(quality) {
(new BigNumber(quality)).shift(9).truncated().toNumber();
}
function createTrustlineTransaction(account, trustline) {
function createTrustlineTransaction(account: string,
trustline: TrustLineSpecification
): Transaction {
validate.address(account);
validate.trustline(trustline);
@@ -33,13 +37,16 @@ function createTrustlineTransaction(account, trustline) {
return transaction;
}
function prepareTrustlineAsync(account, trustline, instructions, callback) {
function prepareTrustlineAsync(account: string,
trustline: TrustLineSpecification, instructions: Instructions, callback
) {
const transaction = createTrustlineTransaction(account, trustline);
utils.prepareTransaction(transaction, this.remote, instructions, callback);
}
function prepareTrustline(account: string, trustline: Object, instructions = {}
) {
function prepareTrustline(account: string,
trustline: TrustLineSpecification, instructions: Instructions = {}
): Promise<Prepare> {
return utils.promisify(prepareTrustlineAsync.bind(this))(
account, trustline, instructions);
}

View File

@@ -0,0 +1,19 @@
/* @flow */
'use strict';
export type Instructions = {
sequence?: number,
fee?: string,
maxFee?: string,
maxLedgerVersion?: number,
maxLedgerVersionOffset?: number
}
export type Prepare = {
txJSON: string,
instructions: {
fee: string,
sequence: number,
maxLedgerVersion?: number
}
}

View File

@@ -5,8 +5,12 @@ const async = require('async');
const BigNumber = require('bignumber.js');
const common = require('../common');
const composeAsync = common.composeAsync;
import type {Remote} from '../../core/remote';
import type {Transaction} from '../../core/transaction';
import type {Instructions} from './types.js';
function setTransactionBitFlags(transaction: any, values: any, flags: any
function setTransactionBitFlags(transaction: Transaction, values: any,
flags: any
): void {
for (const flagName in flags) {
const flagValue = values[flagName];
@@ -21,14 +25,14 @@ function setTransactionBitFlags(transaction: any, values: any, flags: any
}
}
function getFeeDrops(remote, callback) {
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) {
function formatPrepareResponse(txJSON: Object): Object {
const instructions = {
fee: txJSON.Fee,
sequence: txJSON.Sequence,
@@ -41,9 +45,9 @@ function formatPrepareResponse(txJSON) {
}
type Callback = (err: ?(typeof Error),
data: {txJSON: string, instructions: any}) => void;
function prepareTransaction(transaction: any, remote: any, instructions: any,
callback: Callback
data: {txJSON: string, instructions: Instructions}) => void;
function prepareTransaction(transaction: Transaction, remote: Remote,
instructions: Instructions, callback: Callback
): void {
common.validate.instructions(instructions);
@@ -54,11 +58,11 @@ function prepareTransaction(transaction: any, remote: any, instructions: any,
function prepareMaxLedgerVersion(callback_) {
if (instructions.maxLedgerVersion !== undefined) {
txJSON.LastLedgerSequence = parseInt(instructions.maxLedgerVersion, 10);
txJSON.LastLedgerSequence = instructions.maxLedgerVersion;
callback_();
} else {
const offset = instructions.maxLedgerVersionOffset !== undefined ?
parseInt(instructions.maxLedgerVersionOffset, 10) : 3;
instructions.maxLedgerVersionOffset : 3;
remote.getLedgerSequence((error, ledgerVersion) => {
txJSON.LastLedgerSequence = ledgerVersion + offset;
callback_(error);
@@ -84,7 +88,7 @@ function prepareTransaction(transaction: any, remote: any, instructions: any,
function prepareSequence(callback_) {
if (instructions.sequence !== undefined) {
txJSON.Sequence = parseInt(instructions.sequence, 10);
txJSON.Sequence = instructions.sequence;
callback_(null, formatPrepareResponse(txJSON));
} else {
remote.findAccount(account).getNextSequence(function(error, sequence) {