From d47bb2749a29db86dc9ef6aadf92b373a558223a Mon Sep 17 00:00:00 2001 From: Ivan Tivonenko Date: Tue, 6 Oct 2015 06:47:18 +0300 Subject: [PATCH] add more flow annotations to RippleApi --- src/api/common/types.js | 55 ++++++++++++++++ src/api/common/utils.js | 7 ++- src/api/ledger/balance-sheet.js | 25 +++++++- src/api/ledger/balances.js | 26 ++++++-- src/api/ledger/ledger.js | 13 +++- src/api/ledger/orderbook.js | 51 ++++++++++++--- src/api/ledger/orders.js | 13 ++-- src/api/ledger/parse/amount.js | 7 +-- src/api/ledger/parse/ledger.js | 3 +- src/api/ledger/parse/pathfind.js | 8 ++- src/api/ledger/pathfind-types.js | 54 ++++++++++++++++ src/api/ledger/pathfind.js | 40 ++++++------ src/api/ledger/settings.js | 30 ++++++++- src/api/ledger/transaction-types.js | 26 +++----- src/api/ledger/transaction.js | 4 +- src/api/ledger/transactions.js | 58 ++++++++++++++--- src/api/ledger/trustlines-types.js | 33 ++++++++++ src/api/ledger/trustlines.js | 20 +++--- src/api/ledger/types.js | 50 +++++++++++++++ src/api/ledger/utils.js | 28 ++++++--- src/api/transaction/order.js | 12 +++- src/api/transaction/ordercancellation.js | 13 ++-- src/api/transaction/payment.js | 44 ++++++++++--- src/api/transaction/settings-types.js | 62 +++++++++++++++++++ src/api/transaction/settings.js | 20 ++++-- src/api/transaction/submit.js | 13 +++- .../suspended-payment-cancellation.js | 22 +++++-- .../transaction/suspended-payment-creation.js | 25 ++++++-- .../suspended-payment-execution.js | 25 ++++++-- src/api/transaction/trustline.js | 15 +++-- src/api/transaction/types.js | 19 ++++++ src/api/transaction/utils.js | 22 ++++--- 32 files changed, 685 insertions(+), 158 deletions(-) create mode 100644 src/api/common/types.js create mode 100644 src/api/ledger/pathfind-types.js create mode 100644 src/api/ledger/trustlines-types.js create mode 100644 src/api/ledger/types.js create mode 100644 src/api/transaction/settings-types.js create mode 100644 src/api/transaction/types.js diff --git a/src/api/common/types.js b/src/api/common/types.js new file mode 100644 index 00000000..becbe0ae --- /dev/null +++ b/src/api/common/types.js @@ -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 +} diff --git a/src/api/common/utils.js b/src/api/common/utils.js index 30f49874..2bb98599 100644 --- a/src/api/common/utils.js +++ b/src/api/common/utils.js @@ -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 }; } diff --git a/src/api/ledger/balance-sheet.js b/src/api/ledger/balance-sheet.js index 608ae508..75b02478 100644 --- a/src/api/ledger/balance-sheet.js +++ b/src/api/ledger/balance-sheet.js @@ -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, + ledgerVersion?: number +} + +type GetBalanceSheet = { + balances?: Array, + assets?: Array, + 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 { return utils.promisify(getBalanceSheetAsync).call(this, address, options); } diff --git a/src/api/ledger/balances.js b/src/api/ledger/balances.js index 856031bd..071f58c5 100644 --- a/src/api/ledger/balances.js +++ b/src/api/ledger/balances.js @@ -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 + +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 { return utils.promisify(getBalancesAsync).call(this, account, options); } diff --git a/src/api/ledger/ledger.js b/src/api/ledger/ledger.js index 61919ab9..eba8bcc1 100644 --- a/src/api/ledger/ledger.js +++ b/src/api/ledger/ledger.js @@ -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 { return utils.promisify(getLedgerAsync).call(this, options); } diff --git a/src/api/ledger/orderbook.js b/src/api/ledger/orderbook.js index 61cb470b..422c34bd 100644 --- a/src/api/ledger/orderbook.js +++ b/src/api/ledger/orderbook.js @@ -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 + +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 { return utils.promisify(getOrderbookAsync).call(this, account, orderbook, options); } diff --git a/src/api/ledger/orders.js b/src/api/ledger/orders.js index 47e78577..e6d136fc 100644 --- a/src/api/ledger/orders.js +++ b/src/api/ledger/orders.js @@ -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 + +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 { return utils.promisify(async.seq( utils.getLedgerOptionsWithLedgerVersion, getOrdersAsync)).call(this, account, options); diff --git a/src/api/ledger/parse/amount.js b/src/api/ledger/parse/amount.js index 7bd22904..d6b65971 100644 --- a/src/api/ledger/parse/amount.js +++ b/src/api/ledger/parse/amount.js @@ -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', diff --git a/src/api/ledger/parse/ledger.js b/src/api/ledger/parse/ledger.js index 325d839f..f82e765f 100644 --- a/src/api/ledger/parse/ledger.js +++ b/src/api/ledger/parse/ledger.js @@ -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, diff --git a/src/api/ledger/parse/pathfind.js b/src/api/ledger/parse/pathfind.js index 0e996e8e..addffef2 100644 --- a/src/api/ledger/parse/pathfind.js +++ b/src/api/ledger/parse/pathfind.js @@ -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; diff --git a/src/api/ledger/pathfind-types.js b/src/api/ledger/pathfind-types.js new file mode 100644 index 00000000..c497f58d --- /dev/null +++ b/src/api/ledger/pathfind-types.js @@ -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 + +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 +} + +export type RippledPathsResponse = { + alternatives: Array<{ + paths_computed: Array>, + source_amount: RippledAmount + }>, + type: string, + destination_account: string, + destination_amount: RippledAmount, + destination_currencies?: Array, + source_account?: string, + source_currencies?: Array<{currency: string}>, + full_reply?: boolean +} diff --git a/src/api/ledger/pathfind.js b/src/api/ledger/pathfind.js index 29a1e793..ddf25391 100644 --- a/src/api/ledger/pathfind.js +++ b/src/api/ledger/pathfind.js @@ -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, 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}, - 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 { return utils.promisify(getPathsAsync).call(this, pathfind); } diff --git a/src/api/ledger/settings.js b/src/api/ledger/settings.js index e04d285f..6df64423 100644 --- a/src/api/ledger/settings.js +++ b/src/api/ledger/settings.js @@ -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 { return utils.promisify(getSettingsAsync).call(this, account, options); } diff --git a/src/api/ledger/transaction-types.js b/src/api/ledger/transaction-types.js index 9a7f3d18..42a535c9 100644 --- a/src/api/ledger/transaction-types.js +++ b/src/api/ledger/transaction-types.js @@ -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 diff --git a/src/api/ledger/transaction.js b/src/api/ledger/transaction.js index 8d13714e..eb0e1900 100644 --- a/src/api/ledger/transaction.js +++ b/src/api/ledger/transaction.js @@ -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 { +): Promise { return utils.promisify(getTransactionAsync).call(this, identifier, options); } diff --git a/src/api/ledger/transactions.js b/src/api/ledger/transactions.js index 693591bc..f5927cf8 100644 --- a/src/api/ledger/transactions.js +++ b/src/api/ledger/transactions.js @@ -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, + binary?: boolean, + startTx?: TransactionType +} + +type GetTransactionsResponse = Array + +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 { return utils.promisify(getTransactionsAsync).call(this, account, options); } diff --git a/src/api/ledger/trustlines-types.js b/src/api/ledger/trustlines-types.js new file mode 100644 index 00000000..ee2558da --- /dev/null +++ b/src/api/ledger/trustlines-types.js @@ -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 +} diff --git a/src/api/ledger/trustlines.js b/src/api/ledger/trustlines.js index 824de0c6..a8c3420b 100644 --- a/src/api/ledger/trustlines.js +++ b/src/api/ledger/trustlines.js @@ -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 + +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 { return utils.promisify(async.seq( utils.getLedgerOptionsWithLedgerVersion, getTrustlinesAsync)).call(this, account, options); diff --git a/src/api/ledger/types.js b/src/api/ledger/types.js new file mode 100644 index 00000000..66c2e0ea --- /dev/null +++ b/src/api/ledger/types.js @@ -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, + rawTransactions?: string, + transactionHashes?: Array, + rawState?: string, + stateHashes?: Array +} diff --git a/src/api/ledger/utils.js b/src/api/ledger/utils.js index eb0fe5ee..21231803 100644 --- a/src/api/ledger/utils.js +++ b/src/api/ledger/utils.js @@ -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 +} + +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; } diff --git a/src/api/transaction/order.js b/src/api/transaction/order.js index fbe22055..ebf65abb 100644 --- a/src/api/transaction/order.js +++ b/src/api/transaction/order.js @@ -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 { return utils.promisify(prepareOrderAsync.bind(this))( account, order, instructions); } diff --git a/src/api/transaction/ordercancellation.js b/src/api/transaction/ordercancellation.js index 63ddd42e..debd8f86 100644 --- a/src/api/transaction/ordercancellation.js +++ b/src/api/transaction/ordercancellation.js @@ -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 { return utils.promisify(prepareOrderCancellationAsync.bind(this))( account, sequence, instructions); } diff --git a/src/api/transaction/payment.js b/src/api/transaction/payment.js index 6103d907..cf61496e 100644 --- a/src/api/transaction/payment.js +++ b/src/api/transaction/payment.js @@ -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, + // 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 { return utils.promisify(preparePaymentAsync.bind(this))( account, payment, instructions); } diff --git a/src/api/transaction/settings-types.js b/src/api/transaction/settings-types.js new file mode 100644 index 00000000..4f6fbbae --- /dev/null +++ b/src/api/transaction/settings-types.js @@ -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 diff --git a/src/api/transaction/settings.js b/src/api/transaction/settings.js index d5e765d4..372f1f09 100644 --- a/src/api/transaction/settings.js +++ b/src/api/transaction/settings.js @@ -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 { return utils.promisify(prepareSettingsAsync.bind(this))( account, settings, instructions); } diff --git a/src/api/transaction/submit.js b/src/api/transaction/submit.js index c43de2df..f3e80b20 100644 --- a/src/api/transaction/submit.js +++ b/src/api/transaction/submit.js @@ -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 { return utils.promisify(submitAsync.bind(this))(txBlob); } diff --git a/src/api/transaction/suspended-payment-cancellation.js b/src/api/transaction/suspended-payment-cancellation.js index 3748a0e5..ef339ff1 100644 --- a/src/api/transaction/suspended-payment-cancellation.js +++ b/src/api/transaction/suspended-payment-cancellation.js @@ -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 +} + +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 { return utils.promisify(prepareSuspendedPaymentCancellationAsync) .call(this, account, payment, instructions); } diff --git a/src/api/transaction/suspended-payment-creation.js b/src/api/transaction/suspended-payment-creation.js index f9b52659..f6705e83 100644 --- a/src/api/transaction/suspended-payment-creation.js +++ b/src/api/transaction/suspended-payment-creation.js @@ -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, + 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 { return utils.promisify(prepareSuspendedPaymentCreationAsync) .call(this, account, payment, instructions); } diff --git a/src/api/transaction/suspended-payment-execution.js b/src/api/transaction/suspended-payment-execution.js index c8aab156..2ed30635 100644 --- a/src/api/transaction/suspended-payment-execution.js +++ b/src/api/transaction/suspended-payment-execution.js @@ -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, + 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 { return utils.promisify(prepareSuspendedPaymentExecutionAsync) .call(this, account, payment, instructions); } diff --git a/src/api/transaction/trustline.js b/src/api/transaction/trustline.js index 4d1bf01e..ee08633b 100644 --- a/src/api/transaction/trustline.js +++ b/src/api/transaction/trustline.js @@ -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 { return utils.promisify(prepareTrustlineAsync.bind(this))( account, trustline, instructions); } diff --git a/src/api/transaction/types.js b/src/api/transaction/types.js new file mode 100644 index 00000000..9093548f --- /dev/null +++ b/src/api/transaction/types.js @@ -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 + } +} diff --git a/src/api/transaction/utils.js b/src/api/transaction/utils.js index 08636d42..8cc82968 100644 --- a/src/api/transaction/utils.js +++ b/src/api/transaction/utils.js @@ -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) {