mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-29 00:25:48 +00:00
Add new request interface, implement first few request typings (#843)
* Add request interface & typings - src/api: add basic implementation of request/requestAll() - src/ledgers/account_info: refactor to simplify with request() - src/ledgers/balances: refactor to simplify with request() - src/ledgers/orderbook: refactor to simplify with requestAll() - src/ledgers/orders: refactor to simplify with requestAll() - src/ledgers/trustlines: refactor to simplify with requestAll() * standardize on Formatted prefix
This commit is contained in:
committed by
Elliot Lee
parent
4a21360e37
commit
365de6d18a
112
src/api.ts
112
src/api.ts
@@ -39,10 +39,19 @@ import signPaymentChannelClaim from './offline/sign-payment-channel-claim'
|
|||||||
import verifyPaymentChannelClaim from './offline/verify-payment-channel-claim'
|
import verifyPaymentChannelClaim from './offline/verify-payment-channel-claim'
|
||||||
import getLedger from './ledger/ledger'
|
import getLedger from './ledger/ledger'
|
||||||
|
|
||||||
|
import {
|
||||||
|
AccountOffersRequest, AccountOffersResponse,
|
||||||
|
AccountInfoRequest, AccountInfoResponse,
|
||||||
|
AccountLinesRequest, AccountLinesResponse,
|
||||||
|
BookOffersRequest, BookOffersResponse,
|
||||||
|
GatewayBalancesRequest, GatewayBalancesResponse
|
||||||
|
} from './common/types/commands'
|
||||||
|
|
||||||
|
|
||||||
import RangeSet from './common/rangeset'
|
import RangeSet from './common/rangeset'
|
||||||
import * as ledgerUtils from './ledger/utils'
|
import * as ledgerUtils from './ledger/utils'
|
||||||
import * as schemaValidator from './common/schema-validator'
|
import * as schemaValidator from './common/schema-validator'
|
||||||
|
import {clamp} from './ledger/utils'
|
||||||
|
|
||||||
type APIOptions = {
|
type APIOptions = {
|
||||||
server?: string,
|
server?: string,
|
||||||
@@ -52,6 +61,23 @@ type APIOptions = {
|
|||||||
timeout?: number
|
timeout?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the response key / property name that contains the listed data for a
|
||||||
|
* command. This varies from command to command, but we need to know it to
|
||||||
|
* properly count across many requests.
|
||||||
|
*/
|
||||||
|
function getCollectKeyFromCommand(command: string): string|undefined {
|
||||||
|
switch (command) {
|
||||||
|
case 'account_offers':
|
||||||
|
case 'book_offers':
|
||||||
|
return 'offers'
|
||||||
|
case 'account_lines':
|
||||||
|
return 'lines'
|
||||||
|
default:
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// prevent access to non-validated ledger versions
|
// prevent access to non-validated ledger versions
|
||||||
class RestrictedConnection extends Connection {
|
class RestrictedConnection extends Connection {
|
||||||
request(request: any, timeout?: number) {
|
request(request: any, timeout?: number) {
|
||||||
@@ -106,6 +132,92 @@ class RippleAPI extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes a simple request to the API with the given command and any
|
||||||
|
* additional request body parameters.
|
||||||
|
*
|
||||||
|
* NOTE: This command is under development and should not yet be relied
|
||||||
|
* on by external consumers.
|
||||||
|
*/
|
||||||
|
async _request(command: 'account_info', params: AccountInfoRequest):
|
||||||
|
Promise<AccountInfoResponse>
|
||||||
|
async _request(command: 'account_lines', params: AccountLinesRequest):
|
||||||
|
Promise<AccountLinesResponse>
|
||||||
|
async _request(command: 'account_offers', params: AccountOffersRequest):
|
||||||
|
Promise<AccountOffersResponse>
|
||||||
|
async _request(command: 'book_offers', params: BookOffersRequest):
|
||||||
|
Promise<BookOffersResponse>
|
||||||
|
async _request(command: 'gateway_balances', params: GatewayBalancesRequest):
|
||||||
|
Promise<GatewayBalancesResponse>
|
||||||
|
async _request(command: string, params: any = {}) {
|
||||||
|
return this.connection.request({
|
||||||
|
...params,
|
||||||
|
command
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes multiple paged requests to the API to return a given number of
|
||||||
|
* resources. __requestAll() will make multiple requests until the `limit`
|
||||||
|
* number of resources is reached (if no `limit` is provided, a single request
|
||||||
|
* will be made).
|
||||||
|
*
|
||||||
|
* If the command is unknown, an additional `collect` property is required to
|
||||||
|
* know which response key contains the array of resources.
|
||||||
|
*
|
||||||
|
* NOTE: This command is under development and should not yet be relied
|
||||||
|
* on by external consumers.
|
||||||
|
*/
|
||||||
|
async _requestAll(command: 'account_offers', params: AccountOffersRequest):
|
||||||
|
Promise<AccountOffersResponse[]>
|
||||||
|
async _requestAll(command: 'book_offers', params: BookOffersRequest):
|
||||||
|
Promise<BookOffersResponse[]>
|
||||||
|
async _requestAll(command: 'account_lines', params: AccountLinesRequest):
|
||||||
|
Promise<AccountLinesResponse[]>
|
||||||
|
async _requestAll(
|
||||||
|
command: string,
|
||||||
|
params: any = {},
|
||||||
|
options: {collect?: string} = {}): Promise<any[]> {
|
||||||
|
// The data under collection is keyed based on the command. Fail if command
|
||||||
|
// not recognized and collection key not provided.
|
||||||
|
const collectKey = options.collect || getCollectKeyFromCommand(command)
|
||||||
|
if (!collectKey) {
|
||||||
|
throw new errors.ValidationError(`no collect key for command ${command}`)
|
||||||
|
}
|
||||||
|
// If limit is not provided, fetches all data over multiple requests.
|
||||||
|
// NOTE: This may return much more than needed. Set limit when possible.
|
||||||
|
const countTo: number =
|
||||||
|
(params.limit !== undefined) ? params.limit : Infinity
|
||||||
|
let count: number = 0
|
||||||
|
let marker: string = params.marker
|
||||||
|
let lastBatchLength: number
|
||||||
|
const results = []
|
||||||
|
do {
|
||||||
|
const countRemaining = clamp(countTo - count, 10, 400)
|
||||||
|
const repeatProps = {
|
||||||
|
...params,
|
||||||
|
limit: countRemaining,
|
||||||
|
marker
|
||||||
|
}
|
||||||
|
// NOTE: We have to generalize the `this._request()` function signature
|
||||||
|
// here until we add support for unknown commands (since command is some
|
||||||
|
// unknown string).
|
||||||
|
const singleResult = await (<Function>this._request)(command, repeatProps)
|
||||||
|
const collectedData = singleResult[collectKey]
|
||||||
|
marker = singleResult.marker
|
||||||
|
results.push(singleResult)
|
||||||
|
// Make sure we handle when no data (not even an empty array) is returned.
|
||||||
|
const isExpectedFormat = Array.isArray(collectedData)
|
||||||
|
if (isExpectedFormat) {
|
||||||
|
count += collectedData.length
|
||||||
|
lastBatchLength = collectedData.length
|
||||||
|
} else {
|
||||||
|
lastBatchLength = 0
|
||||||
|
}
|
||||||
|
} while(!!marker && count < countTo && lastBatchLength !== 0)
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
connect = connect
|
connect = connect
|
||||||
disconnect = disconnect
|
disconnect = disconnect
|
||||||
isConnected = isConnected
|
isConnected = isConnected
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
|
|
||||||
export type RippledAmountIOU = {
|
|
||||||
currency: string,
|
|
||||||
value: string,
|
|
||||||
issuer?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type RippledAmount = string | RippledAmountIOU
|
|
||||||
|
|
||||||
|
|
||||||
export type Amount = {
|
|
||||||
value: string,
|
|
||||||
currency: string,
|
|
||||||
issuer?: string,
|
|
||||||
counterparty?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Amount where counterparty and value are optional
|
|
||||||
export type LaxLaxAmount = {
|
|
||||||
currency: string,
|
|
||||||
value?: string,
|
|
||||||
issuer?: string,
|
|
||||||
counterparty?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
// A currency-counterparty pair, or just currency if it's XRP
|
|
||||||
export type Issue = {
|
|
||||||
currency: string,
|
|
||||||
issuer?: 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
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ApiMemo = {
|
|
||||||
MemoData?: string,
|
|
||||||
MemoType?: string,
|
|
||||||
MemoFormat?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
36
src/common/types/commands/account_info.ts
Normal file
36
src/common/types/commands/account_info.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import {AccountRoot, SignerList} from '../objects'
|
||||||
|
|
||||||
|
export interface AccountInfoRequest {
|
||||||
|
account: string,
|
||||||
|
strict?: boolean,
|
||||||
|
queue?: boolean,
|
||||||
|
ledger_hash?: string,
|
||||||
|
ledger_index?: number | ('validated' | 'closed' | 'current'),
|
||||||
|
signer_lists?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AccountInfoResponse {
|
||||||
|
account_data: AccountRoot,
|
||||||
|
signer_lists?: SignerList[],
|
||||||
|
ledger_current_index?: number,
|
||||||
|
ledger_index?: number,
|
||||||
|
queue_data?: QueueData,
|
||||||
|
validated?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface QueueData {
|
||||||
|
txn_count: number,
|
||||||
|
auth_change_queued?: boolean,
|
||||||
|
lowest_sequence?: number,
|
||||||
|
highest_sequence?: number,
|
||||||
|
max_spend_drops_total?: string,
|
||||||
|
transactions?: TransactionData[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TransactionData {
|
||||||
|
auth_change?: boolean,
|
||||||
|
fee?: string,
|
||||||
|
fee_level?: string,
|
||||||
|
max_spend_drops?: string,
|
||||||
|
seq?: number
|
||||||
|
}
|
||||||
19
src/common/types/commands/account_lines.ts
Normal file
19
src/common/types/commands/account_lines.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import {Trustline} from '../objects'
|
||||||
|
|
||||||
|
export interface AccountLinesRequest {
|
||||||
|
account: string,
|
||||||
|
ledger_hash?: string,
|
||||||
|
ledger_index?: number | ('validated' | 'closed' | 'current'),
|
||||||
|
peer?: string,
|
||||||
|
limit?: number,
|
||||||
|
marker?: any,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AccountLinesResponse {
|
||||||
|
account: string,
|
||||||
|
lines: Trustline[],
|
||||||
|
ledger_current_index?: number,
|
||||||
|
ledger_index?: number,
|
||||||
|
ledger_hash?: string,
|
||||||
|
marker?: any,
|
||||||
|
}
|
||||||
27
src/common/types/commands/account_offers.ts
Normal file
27
src/common/types/commands/account_offers.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import {RippledAmount} from '../objects'
|
||||||
|
|
||||||
|
export interface AccountOffersRequest {
|
||||||
|
account: string,
|
||||||
|
ledger_hash?: string,
|
||||||
|
ledger_index?: number | ('validated' | 'closed' | 'current'),
|
||||||
|
limit?: number,
|
||||||
|
marker?: any,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AccountOffersResponse {
|
||||||
|
account: string,
|
||||||
|
ledger_hash?: string,
|
||||||
|
ledger_current_index?: number,
|
||||||
|
ledger_index?: number,
|
||||||
|
marker?: any,
|
||||||
|
offers?: AccountOffer[],
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AccountOffer {
|
||||||
|
seq: number,
|
||||||
|
flags: number,
|
||||||
|
taker_gets: RippledAmount,
|
||||||
|
taker_pays: RippledAmount,
|
||||||
|
quality: string,
|
||||||
|
expiration?: number
|
||||||
|
}
|
||||||
30
src/common/types/commands/book_offers.ts
Normal file
30
src/common/types/commands/book_offers.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import {
|
||||||
|
TakerRequestAmount,
|
||||||
|
OfferCreateTransaction,
|
||||||
|
RippledAmount
|
||||||
|
} from '../objects'
|
||||||
|
|
||||||
|
export interface BookOffersRequest {
|
||||||
|
taker?: string,
|
||||||
|
taker_gets: TakerRequestAmount,
|
||||||
|
taker_pays: TakerRequestAmount,
|
||||||
|
ledger_hash?: string,
|
||||||
|
ledger_index?: number | ('validated' | 'closed' | 'current'),
|
||||||
|
limit?: number,
|
||||||
|
marker?: any
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BookOffersResponse {
|
||||||
|
offers: OrderBookOffer[],
|
||||||
|
ledger_hash?: string,
|
||||||
|
ledger_current_index?: number,
|
||||||
|
ledger_index?: number,
|
||||||
|
marker?: any
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OrderBookOffer extends OfferCreateTransaction {
|
||||||
|
quality?: number
|
||||||
|
owner_funds?: string,
|
||||||
|
taker_gets_funded?: RippledAmount,
|
||||||
|
taker_pays_funded?: RippledAmount
|
||||||
|
}
|
||||||
20
src/common/types/commands/gateway_balances.ts
Normal file
20
src/common/types/commands/gateway_balances.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import {Amount} from '../objects'
|
||||||
|
|
||||||
|
|
||||||
|
export interface GatewayBalancesRequest {
|
||||||
|
account: string,
|
||||||
|
strict?: boolean,
|
||||||
|
hotwallet: string|Array<string>,
|
||||||
|
ledger_hash?: string,
|
||||||
|
ledger_index?: number | ('validated' | 'closed' | 'current')
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GatewayBalancesResponse {
|
||||||
|
account: string,
|
||||||
|
obligations?: {[currency: string]: string},
|
||||||
|
balances?: {[address: string]: Amount[]},
|
||||||
|
assets?: {[address: string]: Amount[]},
|
||||||
|
ledger_hash?: string,
|
||||||
|
ledger_current_index?: number,
|
||||||
|
ledger_index?: number
|
||||||
|
}
|
||||||
5
src/common/types/commands/index.ts
Normal file
5
src/common/types/commands/index.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export * from './account_info'
|
||||||
|
export * from './account_lines'
|
||||||
|
export * from './account_offers'
|
||||||
|
export * from './book_offers'
|
||||||
|
export * from './gateway_balances'
|
||||||
17
src/common/types/objects/accounts.ts
Normal file
17
src/common/types/objects/accounts.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
export interface AccountRoot {
|
||||||
|
LedgerEntryType: string,
|
||||||
|
Account: string,
|
||||||
|
Flags: number,
|
||||||
|
Sequence: number,
|
||||||
|
Balance: string,
|
||||||
|
OwnerCount: number,
|
||||||
|
PreviousTxnID: string,
|
||||||
|
PreviousTxnLgrSeq: number,
|
||||||
|
AccountTxnID?: string,
|
||||||
|
RegularKey?: string,
|
||||||
|
EmailHash?: string,
|
||||||
|
MessageKey?: string
|
||||||
|
TickSize?: number,
|
||||||
|
TransferRate?: number,
|
||||||
|
Domain?: string
|
||||||
|
}
|
||||||
19
src/common/types/objects/adjustments.ts
Normal file
19
src/common/types/objects/adjustments.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import {Amount} from './amounts'
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
28
src/common/types/objects/amounts.ts
Normal file
28
src/common/types/objects/amounts.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
export type Amount = {
|
||||||
|
value: string,
|
||||||
|
currency: string,
|
||||||
|
issuer?: string,
|
||||||
|
counterparty?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type RippledAmount = string | Amount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specification of which currency the account taking the offer would pay/
|
||||||
|
* receive, as an object with currency and issuer fields (omit issuer for XRP).
|
||||||
|
* Similar to currency amounts.
|
||||||
|
*/
|
||||||
|
export interface TakerRequestAmount {
|
||||||
|
currency: string
|
||||||
|
issuer?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A currency-counterparty pair, or just currency if it's XRP.
|
||||||
|
*/
|
||||||
|
export type Issue = {
|
||||||
|
currency: string,
|
||||||
|
issuer?: string,
|
||||||
|
counterparty?: string
|
||||||
|
}
|
||||||
7
src/common/types/objects/index.ts
Normal file
7
src/common/types/objects/index.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export * from './accounts'
|
||||||
|
export * from './adjustments'
|
||||||
|
export * from './amounts'
|
||||||
|
export * from './memos'
|
||||||
|
export * from './signers'
|
||||||
|
export * from './transactions'
|
||||||
|
export * from './trustlines'
|
||||||
6
src/common/types/objects/memos.ts
Normal file
6
src/common/types/objects/memos.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
export type Memo = {
|
||||||
|
type?: string,
|
||||||
|
format?: string,
|
||||||
|
data?: string
|
||||||
|
}
|
||||||
14
src/common/types/objects/signers.ts
Normal file
14
src/common/types/objects/signers.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export interface SignerList {
|
||||||
|
LedgerEntryType: string,
|
||||||
|
OwnerNode: string,
|
||||||
|
SignerQuorum: number,
|
||||||
|
SignerEntries: SignerEntry[],
|
||||||
|
SignerListID: number,
|
||||||
|
PreviousTxnID: string,
|
||||||
|
PreviousTxnLgrSeq: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SignerEntry {
|
||||||
|
Account: string,
|
||||||
|
SignerWeight: number
|
||||||
|
}
|
||||||
22
src/common/types/objects/transactions.ts
Normal file
22
src/common/types/objects/transactions.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import {RippledAmount} from './amounts'
|
||||||
|
import {Memo} from './memos'
|
||||||
|
|
||||||
|
export interface OfferCreateTransaction {
|
||||||
|
TransactionType: 'OfferCreate',
|
||||||
|
Account: string,
|
||||||
|
AccountTxnID?: string,
|
||||||
|
Fee: string,
|
||||||
|
Field: any,
|
||||||
|
Flags: number,
|
||||||
|
LastLedgerSequence?: number,
|
||||||
|
Sequence: number,
|
||||||
|
Signers: any[],
|
||||||
|
SigningPubKey: string,
|
||||||
|
SourceTag?: number,
|
||||||
|
TakerGets: RippledAmount,
|
||||||
|
TakerPays: RippledAmount,
|
||||||
|
TxnSignature: string,
|
||||||
|
Expiration?: number,
|
||||||
|
Memos?: Memo[],
|
||||||
|
OfferSequence?: number,
|
||||||
|
}
|
||||||
42
src/common/types/objects/trustlines.ts
Normal file
42
src/common/types/objects/trustlines.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import {Memo} from './memos'
|
||||||
|
|
||||||
|
export interface Trustline {
|
||||||
|
account: string,
|
||||||
|
balance: string,
|
||||||
|
currency: string,
|
||||||
|
limit: string,
|
||||||
|
limit_peer: string,
|
||||||
|
quality_in: number,
|
||||||
|
quality_out: number,
|
||||||
|
no_ripple?: boolean,
|
||||||
|
no_ripple_peer?: boolean,
|
||||||
|
freeze?: boolean,
|
||||||
|
freeze_peer?: boolean,
|
||||||
|
authorized?: boolean,
|
||||||
|
peer_authorized?: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FormattedTrustlineSpecification = {
|
||||||
|
currency: string,
|
||||||
|
counterparty: string,
|
||||||
|
limit: string,
|
||||||
|
qualityIn?: number,
|
||||||
|
qualityOut?: number,
|
||||||
|
ripplingDisabled?: boolean,
|
||||||
|
authorized?: boolean,
|
||||||
|
frozen?: boolean,
|
||||||
|
memos?: Memo[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FormattedTrustline = {
|
||||||
|
specification: FormattedTrustlineSpecification,
|
||||||
|
counterparty: {
|
||||||
|
limit: string,
|
||||||
|
ripplingDisabled?: boolean,
|
||||||
|
frozen?: boolean,
|
||||||
|
authorized?: boolean
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
balance: string
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ import * as _ from 'lodash'
|
|||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
const {deriveKeypair} = require('ripple-keypairs')
|
const {deriveKeypair} = require('ripple-keypairs')
|
||||||
|
|
||||||
import {Amount, RippledAmount} from './types'
|
import {Amount, RippledAmount} from './types/objects'
|
||||||
|
|
||||||
function isValidSecret(secret: string): boolean {
|
function isValidSecret(secret: string): boolean {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,31 +1,12 @@
|
|||||||
import {validate, removeUndefined, dropsToXrp} from '../common'
|
import {validate, removeUndefined, dropsToXrp} from '../common'
|
||||||
|
import {RippleAPI} from '../api'
|
||||||
|
import {AccountInfoResponse} from '../common/types/commands/account_info'
|
||||||
|
|
||||||
type AccountData = {
|
type GetAccountInfoOptions = {
|
||||||
Sequence: number,
|
|
||||||
Account: string,
|
|
||||||
Balance: string,
|
|
||||||
Flags: number,
|
|
||||||
LedgerEntryType: string,
|
|
||||||
OwnerCount: number,
|
|
||||||
PreviousTxnID: string,
|
|
||||||
AccountTxnID?: string,
|
|
||||||
PreviousTxnLgrSeq: number,
|
|
||||||
index: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type AccountDataResponse = {
|
|
||||||
account_data: AccountData,
|
|
||||||
ledger_current_index?: number,
|
|
||||||
ledger_hash?: string,
|
|
||||||
ledger_index: number,
|
|
||||||
validated: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
type AccountInfoOptions = {
|
|
||||||
ledgerVersion?: number
|
ledgerVersion?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
type AccountInfoResponse = {
|
type FormattedGetAccountInfoResponse = {
|
||||||
sequence: number,
|
sequence: number,
|
||||||
xrpBalance: string,
|
xrpBalance: string,
|
||||||
ownerCount: number,
|
ownerCount: number,
|
||||||
@@ -34,7 +15,9 @@ type AccountInfoResponse = {
|
|||||||
previousAffectingTransactionLedgerVersion: number
|
previousAffectingTransactionLedgerVersion: number
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatAccountInfo(response: AccountDataResponse) {
|
function formatAccountInfo(
|
||||||
|
response: AccountInfoResponse
|
||||||
|
): FormattedGetAccountInfoResponse {
|
||||||
const data = response.account_data
|
const data = response.account_data
|
||||||
return removeUndefined({
|
return removeUndefined({
|
||||||
sequence: data.Sequence,
|
sequence: data.Sequence,
|
||||||
@@ -46,17 +29,16 @@ function formatAccountInfo(response: AccountDataResponse) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAccountInfo(address: string, options: AccountInfoOptions = {}
|
export default async function getAccountInfo(
|
||||||
): Promise<AccountInfoResponse> {
|
this: RippleAPI, address: string, options: GetAccountInfoOptions = {}
|
||||||
|
): Promise<FormattedGetAccountInfoResponse> {
|
||||||
|
// 1. Validate
|
||||||
validate.getAccountInfo({address, options})
|
validate.getAccountInfo({address, options})
|
||||||
|
// 2. Make Request
|
||||||
const request = {
|
const response = await this._request('account_info', {
|
||||||
command: 'account_info',
|
|
||||||
account: address,
|
account: address,
|
||||||
ledger_index: options.ledgerVersion || 'validated'
|
ledger_index: options.ledgerVersion || 'validated'
|
||||||
}
|
})
|
||||||
|
// 3. Return Formatted Response
|
||||||
return this.connection.request(request).then(formatAccountInfo)
|
return formatAccountInfo(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getAccountInfo
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import * as _ from 'lodash'
|
import * as _ from 'lodash'
|
||||||
import * as utils from './utils'
|
|
||||||
import {validate} from '../common'
|
import {validate} from '../common'
|
||||||
import {Amount} from '../common/types'
|
import {Amount} from '../common/types/objects'
|
||||||
|
import {ensureLedgerVersion} from './utils'
|
||||||
|
import {RippleAPI} from '../api'
|
||||||
|
|
||||||
type BalanceSheetOptions = {
|
type BalanceSheetOptions = {
|
||||||
excludeAddresses?: Array<string>,
|
excludeAddresses?: Array<string>,
|
||||||
@@ -46,21 +47,21 @@ function formatBalanceSheet(balanceSheet): GetBalanceSheet {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBalanceSheet(address: string, options: BalanceSheetOptions = {}
|
async function getBalanceSheet(
|
||||||
|
this: RippleAPI, address: string, options: BalanceSheetOptions = {}
|
||||||
): Promise<GetBalanceSheet> {
|
): Promise<GetBalanceSheet> {
|
||||||
|
// 1. Validate
|
||||||
validate.getBalanceSheet({address, options})
|
validate.getBalanceSheet({address, options})
|
||||||
|
options = await ensureLedgerVersion.call(this, options)
|
||||||
return utils.ensureLedgerVersion.call(this, options).then(_options => {
|
// 2. Make Request
|
||||||
const request = {
|
const response = await this._request('gateway_balances', {
|
||||||
command: 'gateway_balances',
|
account: address,
|
||||||
account: address,
|
strict: true,
|
||||||
strict: true,
|
hotwallet: options.excludeAddresses,
|
||||||
hotwallet: _options.excludeAddresses,
|
ledger_index: options.ledgerVersion
|
||||||
ledger_index: _options.ledgerVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.connection.request(request).then(formatBalanceSheet)
|
|
||||||
})
|
})
|
||||||
|
// 3. Return Formatted Response
|
||||||
|
return formatBalanceSheet(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getBalanceSheet
|
export default getBalanceSheet
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import * as utils from './utils'
|
import * as utils from './utils'
|
||||||
import {validate} from '../common'
|
import {validate} from '../common'
|
||||||
import {Connection} from '../common'
|
import {Connection} from '../common'
|
||||||
import {TrustlinesOptions, Trustline} from './trustlines-types'
|
import {GetTrustlinesOptions} from './trustlines'
|
||||||
|
import {FormattedTrustline} from '../common/types/objects/trustlines'
|
||||||
|
|
||||||
|
|
||||||
type Balance = {
|
type Balance = {
|
||||||
@@ -12,7 +13,7 @@ type Balance = {
|
|||||||
|
|
||||||
type GetBalances = Array<Balance>
|
type GetBalances = Array<Balance>
|
||||||
|
|
||||||
function getTrustlineBalanceAmount(trustline: Trustline) {
|
function getTrustlineBalanceAmount(trustline: FormattedTrustline) {
|
||||||
return {
|
return {
|
||||||
currency: trustline.specification.currency,
|
currency: trustline.specification.currency,
|
||||||
counterparty: trustline.specification.counterparty,
|
counterparty: trustline.specification.counterparty,
|
||||||
@@ -46,7 +47,7 @@ function getLedgerVersionHelper(connection: Connection, optionValue?: number
|
|||||||
return connection.getLedgerVersion()
|
return connection.getLedgerVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBalances(address: string, options: TrustlinesOptions = {}
|
function getBalances(address: string, options: GetTrustlinesOptions = {}
|
||||||
): Promise<GetBalances> {
|
): Promise<GetBalances> {
|
||||||
validate.getTrustlines({address, options})
|
validate.getTrustlines({address, options})
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,20 @@ import * as _ from 'lodash'
|
|||||||
import * as utils from './utils'
|
import * as utils from './utils'
|
||||||
import parseOrderbookOrder from './parse/orderbook-order'
|
import parseOrderbookOrder from './parse/orderbook-order'
|
||||||
import {validate} from '../common'
|
import {validate} from '../common'
|
||||||
import {Connection} from '../common'
|
import {OrderSpecification} from './types'
|
||||||
import {OrdersOptions, OrderSpecification} from './types'
|
import {Amount, Issue} from '../common/types/objects'
|
||||||
import {Amount, Issue} from '../common/types'
|
import {RippleAPI} from '../api'
|
||||||
|
import {OfferCreateTransaction} from '../common/types/objects'
|
||||||
|
|
||||||
|
export type OrdersOptions = {
|
||||||
|
limit?: number,
|
||||||
|
ledgerVersion?: number
|
||||||
|
}
|
||||||
|
|
||||||
type Orderbook = {
|
type Orderbook = {
|
||||||
base: Issue,
|
base: Issue,
|
||||||
counter: Issue
|
counter: Issue
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderbookItem = {
|
type OrderbookItem = {
|
||||||
specification: OrderSpecification,
|
specification: OrderSpecification,
|
||||||
properties: {
|
properties: {
|
||||||
@@ -31,26 +36,6 @@ type GetOrderbook = {
|
|||||||
asks: OrderbookOrders
|
asks: OrderbookOrders
|
||||||
}
|
}
|
||||||
|
|
||||||
// account is to specify a "perspective", which affects which unfunded offers
|
|
||||||
// are returned
|
|
||||||
function getBookOffers(connection: Connection, account: string,
|
|
||||||
ledgerVersion: number|undefined, limit: number|undefined, takerGets: Issue,
|
|
||||||
takerPays: Issue
|
|
||||||
): Promise<Object[]> {
|
|
||||||
const orderData = utils.renameCounterpartyToIssuerInOrder({
|
|
||||||
taker_gets: takerGets,
|
|
||||||
taker_pays: takerPays
|
|
||||||
})
|
|
||||||
return connection.request({
|
|
||||||
command: 'book_offers',
|
|
||||||
taker_gets: orderData.taker_gets,
|
|
||||||
taker_pays: orderData.taker_pays,
|
|
||||||
ledger_index: ledgerVersion || 'validated',
|
|
||||||
limit: limit,
|
|
||||||
taker: account
|
|
||||||
}).then(data => data.offers)
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSameIssue(a: Amount, b: Amount) {
|
function isSameIssue(a: Amount, b: Amount) {
|
||||||
return a.currency === b.currency && a.counterparty === b.counterparty
|
return a.currency === b.currency && a.counterparty === b.counterparty
|
||||||
}
|
}
|
||||||
@@ -75,7 +60,8 @@ function alignOrder(base: Amount, order: OrderbookItem) {
|
|||||||
return isSameIssue(quantity, base) ? order : flipOrder(order)
|
return isSameIssue(quantity, base) ? order : flipOrder(order)
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatBidsAndAsks(orderbook: Orderbook, offers) {
|
function formatBidsAndAsks(
|
||||||
|
orderbook: Orderbook, offers: OfferCreateTransaction[]) {
|
||||||
// the "base" currency is the currency that you are buying or selling
|
// the "base" currency is the currency that you are buying or selling
|
||||||
// the "counter" is the currency that the "base" is priced in
|
// the "counter" is the currency that the "base" is priced in
|
||||||
// a "bid"/"ask" is an order to buy/sell the base, respectively
|
// a "bid"/"ask" is an order to buy/sell the base, respectively
|
||||||
@@ -93,17 +79,42 @@ function formatBidsAndAsks(orderbook: Orderbook, offers) {
|
|||||||
return {bids, asks}
|
return {bids, asks}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOrderbook(address: string, orderbook: Orderbook,
|
// account is to specify a "perspective", which affects which unfunded offers
|
||||||
options: OrdersOptions = {}
|
// are returned
|
||||||
): Promise<GetOrderbook> {
|
async function makeRequest(
|
||||||
validate.getOrderbook({address, orderbook, options})
|
api: RippleAPI, taker: string, options: OrdersOptions,
|
||||||
|
takerGets: Issue, takerPays: Issue
|
||||||
const getter = _.partial(getBookOffers, this.connection, address,
|
) {
|
||||||
options.ledgerVersion, options.limit)
|
const orderData = utils.renameCounterpartyToIssuerInOrder({
|
||||||
const getOffers = _.partial(getter, orderbook.base, orderbook.counter)
|
taker_gets: takerGets,
|
||||||
const getReverseOffers = _.partial(getter, orderbook.counter, orderbook.base)
|
taker_pays: takerPays
|
||||||
return Promise.all([getOffers(), getReverseOffers()]).then(data =>
|
})
|
||||||
formatBidsAndAsks(orderbook, _.flatten(data)))
|
return api._requestAll('book_offers', {
|
||||||
|
taker_gets: orderData.taker_gets,
|
||||||
|
taker_pays: orderData.taker_pays,
|
||||||
|
ledger_index: options.ledgerVersion || 'validated',
|
||||||
|
limit: options.limit,
|
||||||
|
taker
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getOrderbook
|
export default async function getOrderbook(
|
||||||
|
this: RippleAPI,
|
||||||
|
address: string,
|
||||||
|
orderbook: Orderbook,
|
||||||
|
options: OrdersOptions = {}
|
||||||
|
): Promise<GetOrderbook> {
|
||||||
|
// 1. Validate
|
||||||
|
validate.getOrderbook({address, orderbook, options})
|
||||||
|
// 2. Make Request
|
||||||
|
const [directOfferResults, reverseOfferResults] = await Promise.all([
|
||||||
|
makeRequest(this, address, options, orderbook.base, orderbook.counter),
|
||||||
|
makeRequest(this, address, options, orderbook.counter, orderbook.base)
|
||||||
|
])
|
||||||
|
// 3. Return Formatted Response
|
||||||
|
const directOffers = _.flatMap(directOfferResults,
|
||||||
|
directOfferResult => directOfferResult.offers)
|
||||||
|
const reverseOffers = _.flatMap(reverseOfferResults,
|
||||||
|
reverseOfferResult => reverseOfferResult.offers)
|
||||||
|
return formatBidsAndAsks(orderbook, [...directOffers, ...reverseOffers])
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,37 +1,39 @@
|
|||||||
import * as _ from 'lodash'
|
import * as _ from 'lodash'
|
||||||
import * as utils from './utils'
|
|
||||||
import {validate} from '../common'
|
import {validate} from '../common'
|
||||||
import {Connection} from '../common'
|
|
||||||
import parseAccountOrder from './parse/account-order'
|
import parseAccountOrder from './parse/account-order'
|
||||||
import {OrdersOptions, Order} from './types'
|
import {Order} from './types'
|
||||||
|
import {RippleAPI} from '../api'
|
||||||
|
import {AccountOffersResponse} from '../common/types/commands/account_offers'
|
||||||
|
|
||||||
type GetOrders = Array<Order>
|
export type GetOrdersOptions = {
|
||||||
|
limit?: number,
|
||||||
function requestAccountOffers(connection: Connection, address: string,
|
ledgerVersion?: number
|
||||||
ledgerVersion: number, marker: string, limit: number
|
|
||||||
): Promise<Object> {
|
|
||||||
return connection.request({
|
|
||||||
command: 'account_offers',
|
|
||||||
account: address,
|
|
||||||
marker: marker,
|
|
||||||
limit: utils.clamp(limit, 10, 400),
|
|
||||||
ledger_index: ledgerVersion
|
|
||||||
}).then(data => ({
|
|
||||||
marker: data.marker,
|
|
||||||
results: data.offers.map(_.partial(parseAccountOrder, address))
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOrders(address: string, options: OrdersOptions = {}
|
function formatResponse(
|
||||||
): Promise<GetOrders> {
|
address: string, responses: AccountOffersResponse[]
|
||||||
|
): Order[] {
|
||||||
|
let orders: Order[] = []
|
||||||
|
for (const response of responses) {
|
||||||
|
const offers = response.offers.map(offer => {
|
||||||
|
return parseAccountOrder(address, offer)
|
||||||
|
})
|
||||||
|
orders = orders.concat(offers)
|
||||||
|
}
|
||||||
|
return _.sortBy(orders, order => order.properties.sequence)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function getOrders(
|
||||||
|
this: RippleAPI, address: string, options: GetOrdersOptions = {}
|
||||||
|
): Promise<Order[]> {
|
||||||
|
// 1. Validate
|
||||||
validate.getOrders({address, options})
|
validate.getOrders({address, options})
|
||||||
|
// 2. Make Request
|
||||||
return utils.ensureLedgerVersion.call(this, options).then(_options => {
|
const responses = await this._requestAll('account_offers', {
|
||||||
const getter = _.partial(requestAccountOffers, this.connection, address,
|
account: address,
|
||||||
_options.ledgerVersion)
|
ledger_index: options.ledgerVersion || await this.getLedgerVersion(),
|
||||||
return utils.getRecursive(getter, _options.limit).then(orders =>
|
limit: options.limit
|
||||||
_.sortBy(orders, order => order.properties.sequence))
|
|
||||||
})
|
})
|
||||||
|
// 3. Return Formatted Response
|
||||||
|
return formatResponse(address, responses)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getOrders
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import parseAmount from './amount'
|
|||||||
import {parseTimestamp, adjustQualityForXRP} from './utils'
|
import {parseTimestamp, adjustQualityForXRP} from './utils'
|
||||||
import {removeUndefined} from '../../common'
|
import {removeUndefined} from '../../common'
|
||||||
import {orderFlags} from './flags'
|
import {orderFlags} from './flags'
|
||||||
|
import {Order} from '../types'
|
||||||
|
|
||||||
// TODO: remove this function once rippled provides quality directly
|
// TODO: remove this function once rippled provides quality directly
|
||||||
function computeQuality(takerGets, takerPays) {
|
function computeQuality(takerGets, takerPays) {
|
||||||
@@ -12,7 +13,7 @@ function computeQuality(takerGets, takerPays) {
|
|||||||
|
|
||||||
// rippled 'account_offers' returns a different format for orders than 'tx'
|
// rippled 'account_offers' returns a different format for orders than 'tx'
|
||||||
// the flags are also different
|
// the flags are also different
|
||||||
function parseAccountOrder(address: string, order: any): Object {
|
function parseAccountOrder(address: string, order: any): Order {
|
||||||
const direction = (order.flags & orderFlags.Sell) === 0 ? 'buy' : 'sell'
|
const direction = (order.flags & orderFlags.Sell) === 0 ? 'buy' : 'sell'
|
||||||
const takerGetsAmount = parseAmount(order.taker_gets)
|
const takerGetsAmount = parseAmount(order.taker_gets)
|
||||||
const takerPaysAmount = parseAmount(order.taker_pays)
|
const takerPaysAmount = parseAmount(order.taker_pays)
|
||||||
|
|||||||
@@ -1,24 +1,13 @@
|
|||||||
import {parseQuality} from './utils'
|
import {parseQuality} from './utils'
|
||||||
import {removeUndefined} from '../../common'
|
import {removeUndefined} from '../../common'
|
||||||
|
import {
|
||||||
type Trustline = {
|
Trustline,
|
||||||
account: string, limit: number, currency: string, quality_in: number|null,
|
FormattedTrustline
|
||||||
quality_out: number|null, no_ripple: boolean, freeze: boolean,
|
} from '../../common/types/objects/trustlines'
|
||||||
authorized: boolean, limit_peer: string, no_ripple_peer: boolean,
|
|
||||||
freeze_peer: boolean, peer_authorized: boolean, balance: any
|
|
||||||
}
|
|
||||||
|
|
||||||
type TrustlineSpecification = {}
|
|
||||||
type TrustlineCounterParty = {}
|
|
||||||
type TrustlineState = {balance: number}
|
|
||||||
type AccountTrustline = {
|
|
||||||
specification: TrustlineSpecification, counterparty: TrustlineCounterParty,
|
|
||||||
state: TrustlineState
|
|
||||||
}
|
|
||||||
|
|
||||||
// rippled 'account_lines' returns a different format for
|
// rippled 'account_lines' returns a different format for
|
||||||
// trustlines than 'tx'
|
// trustlines than 'tx'
|
||||||
function parseAccountTrustline(trustline: Trustline): AccountTrustline {
|
function parseAccountTrustline(trustline: Trustline): FormattedTrustline {
|
||||||
const specification = removeUndefined({
|
const specification = removeUndefined({
|
||||||
limit: trustline.limit,
|
limit: trustline.limit,
|
||||||
currency: trustline.currency,
|
currency: trustline.currency,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as common from '../../common'
|
import * as common from '../../common'
|
||||||
import {Amount, RippledAmount} from '../../common/types'
|
import {Amount, RippledAmount} from '../../common/types/objects'
|
||||||
|
|
||||||
|
|
||||||
function parseAmount(amount: RippledAmount): Amount {
|
function parseAmount(amount: RippledAmount): Amount {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as _ from 'lodash'
|
import * as _ from 'lodash'
|
||||||
import parseAmount from './amount'
|
import parseAmount from './amount'
|
||||||
import {Amount, RippledAmount} from '../../common/types'
|
import {Amount, RippledAmount} from '../../common/types/objects'
|
||||||
import {Path, GetPaths, RippledPathsResponse} from '../pathfind-types'
|
import {Path, GetPaths, RippledPathsResponse} from '../pathfind-types'
|
||||||
|
|
||||||
function parsePaths(paths) {
|
function parsePaths(paths) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import BigNumber from 'bignumber.js'
|
|||||||
import * as common from '../../common'
|
import * as common from '../../common'
|
||||||
import parseAmount from './amount'
|
import parseAmount from './amount'
|
||||||
|
|
||||||
import {Amount, Memo} from '../../common/types'
|
import {Amount, Memo} from '../../common/types/objects'
|
||||||
|
|
||||||
function adjustQualityForXRP(
|
function adjustQualityForXRP(
|
||||||
quality: string, takerGetsCurrency: string, takerPaysCurrency: string
|
quality: string, takerGetsCurrency: string, takerPaysCurrency: string
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
|
|
||||||
import {Amount, LaxLaxAmount, RippledAmount, Adjustment, MaxAdjustment,
|
import {Amount, RippledAmount, Adjustment, MaxAdjustment,
|
||||||
MinAdjustment} from '../common/types'
|
MinAdjustment} from '../common/types/objects'
|
||||||
|
|
||||||
|
// Amount where counterparty and value are optional
|
||||||
|
export type LaxLaxAmount = {
|
||||||
|
currency: string,
|
||||||
|
value?: string,
|
||||||
|
issuer?: string,
|
||||||
|
counterparty?: string
|
||||||
|
}
|
||||||
|
|
||||||
export type Path = {
|
export type Path = {
|
||||||
source: Adjustment | MaxAdjustment,
|
source: Adjustment | MaxAdjustment,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {getXRPBalance, renameCounterpartyToIssuer} from './utils'
|
|||||||
import {validate, toRippledAmount, errors} from '../common'
|
import {validate, toRippledAmount, errors} from '../common'
|
||||||
import {Connection} from '../common'
|
import {Connection} from '../common'
|
||||||
import parsePathfind from './parse/pathfind'
|
import parsePathfind from './parse/pathfind'
|
||||||
import {RippledAmount, Amount} from '../common/types'
|
import {RippledAmount, Amount} from '../common/types/objects'
|
||||||
import {
|
import {
|
||||||
GetPaths, PathFind, RippledPathsResponse, PathFindRequest
|
GetPaths, PathFind, RippledPathsResponse, PathFindRequest
|
||||||
} from './pathfind-types'
|
} from './pathfind-types'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
import {Amount, Memo} from '../common/types'
|
import {Amount, Memo} from '../common/types/objects'
|
||||||
|
|
||||||
type Outcome = {
|
type Outcome = {
|
||||||
result: string,
|
result: string,
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
import {Memo} from '../common/types'
|
|
||||||
|
|
||||||
export type TrustLineSpecification = {
|
|
||||||
currency: string,
|
|
||||||
counterparty: string,
|
|
||||||
limit: string,
|
|
||||||
qualityIn?: number,
|
|
||||||
qualityOut?: number,
|
|
||||||
ripplingDisabled?: boolean,
|
|
||||||
authorized?: boolean,
|
|
||||||
frozen?: boolean,
|
|
||||||
memos?: Memo[]
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,53 +1,37 @@
|
|||||||
import * as _ from 'lodash'
|
import * as _ from 'lodash'
|
||||||
import * as utils from './utils'
|
|
||||||
import {validate} from '../common'
|
import {validate} from '../common'
|
||||||
import {Connection} from '../common'
|
|
||||||
import parseAccountTrustline from './parse/account-trustline'
|
import parseAccountTrustline from './parse/account-trustline'
|
||||||
import {TrustlinesOptions, Trustline} from './trustlines-types'
|
import {RippleAPI} from '../api'
|
||||||
|
import {FormattedTrustline} from '../common/types/objects/trustlines'
|
||||||
|
|
||||||
|
export type GetTrustlinesOptions = {
|
||||||
type GetTrustlinesResponse = Array<Trustline>
|
counterparty?: string,
|
||||||
interface GetAccountLinesResponse {
|
currency?: string,
|
||||||
marker?: any,
|
limit?: number,
|
||||||
results: Trustline[]
|
ledgerVersion?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
function currencyFilter(currency: string, trustline: Trustline) {
|
function currencyFilter(currency: string, trustline: FormattedTrustline) {
|
||||||
return currency === null || trustline.specification.currency === currency
|
return currency === null || trustline.specification.currency === currency
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatResponse(options: TrustlinesOptions, data: any) {
|
async function getTrustlines(
|
||||||
return {
|
this: RippleAPI, address: string, options: GetTrustlinesOptions = {}
|
||||||
marker: data.marker,
|
): Promise<FormattedTrustline[]> {
|
||||||
results: data.lines.map(parseAccountTrustline)
|
// 1. Validate
|
||||||
.filter(_.partial(currencyFilter, options.currency || null))
|
validate.getTrustlines({address, options})
|
||||||
}
|
const ledgerVersion = await this.getLedgerVersion()
|
||||||
}
|
// 2. Make Request
|
||||||
|
const responses = await this._requestAll('account_lines', {
|
||||||
function getAccountLines(connection: Connection, address: string,
|
|
||||||
ledgerVersion: number, options: TrustlinesOptions, marker: string,
|
|
||||||
limit: number
|
|
||||||
): Promise<GetAccountLinesResponse> {
|
|
||||||
const request = {
|
|
||||||
command: 'account_lines',
|
|
||||||
account: address,
|
account: address,
|
||||||
ledger_index: ledgerVersion,
|
ledger_index: ledgerVersion,
|
||||||
marker: marker,
|
limit: options.limit,
|
||||||
limit: utils.clamp(limit, 10, 400),
|
|
||||||
peer: options.counterparty
|
peer: options.counterparty
|
||||||
}
|
})
|
||||||
|
// 3. Return Formatted Response
|
||||||
return connection.request(request).then(_.partial(formatResponse, options))
|
const trustlines = _.flatMap(responses, response => response.lines)
|
||||||
}
|
return trustlines.map(parseAccountTrustline).filter(trustline => {
|
||||||
|
return currencyFilter(options.currency || null, trustline)
|
||||||
function getTrustlines(address: string, options: TrustlinesOptions = {}
|
|
||||||
): Promise<GetTrustlinesResponse> {
|
|
||||||
validate.getTrustlines({address, options})
|
|
||||||
|
|
||||||
return this.getLedgerVersion().then(ledgerVersion => {
|
|
||||||
const getter = _.partial(getAccountLines, this.connection, address,
|
|
||||||
options.ledgerVersion || ledgerVersion, options)
|
|
||||||
return utils.getRecursive(getter, options.limit)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
|
|
||||||
import {Amount} from '../common/types'
|
import {Amount} from '../common/types/objects'
|
||||||
|
|
||||||
export type OrdersOptions = {
|
|
||||||
limit?: number,
|
|
||||||
ledgerVersion?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type OrderSpecification = {
|
export type OrderSpecification = {
|
||||||
direction: string,
|
direction: string,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as assert from 'assert'
|
|||||||
import * as common from '../common'
|
import * as common from '../common'
|
||||||
import {Connection} from '../common'
|
import {Connection} from '../common'
|
||||||
import {TransactionType} from './transaction-types'
|
import {TransactionType} from './transaction-types'
|
||||||
import {Issue} from '../common/types'
|
import {Issue} from '../common/types/objects'
|
||||||
|
|
||||||
type RecursiveData = {
|
type RecursiveData = {
|
||||||
marker: string,
|
marker: string,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import * as _ from 'lodash'
|
|||||||
import * as utils from './utils'
|
import * as utils from './utils'
|
||||||
const validate = utils.common.validate
|
const validate = utils.common.validate
|
||||||
import {Instructions, Prepare} from './types'
|
import {Instructions, Prepare} from './types'
|
||||||
import {Memo} from '../common/types'
|
import {Memo} from '../common/types/objects'
|
||||||
|
|
||||||
type EscrowCancellation = {
|
type EscrowCancellation = {
|
||||||
owner: string,
|
owner: string,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as utils from './utils'
|
|||||||
import {validate, iso8601ToRippleTime, xrpToDrops} from '../common'
|
import {validate, iso8601ToRippleTime, xrpToDrops} from '../common'
|
||||||
const ValidationError = utils.common.errors.ValidationError
|
const ValidationError = utils.common.errors.ValidationError
|
||||||
import {Instructions, Prepare} from './types'
|
import {Instructions, Prepare} from './types'
|
||||||
import {Memo} from '../common/types'
|
import {Memo} from '../common/types/objects'
|
||||||
|
|
||||||
type EscrowCreation = {
|
type EscrowCreation = {
|
||||||
amount: string,
|
amount: string,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as utils from './utils'
|
|||||||
const validate = utils.common.validate
|
const validate = utils.common.validate
|
||||||
const ValidationError = utils.common.errors.ValidationError
|
const ValidationError = utils.common.errors.ValidationError
|
||||||
import {Instructions, Prepare} from './types'
|
import {Instructions, Prepare} from './types'
|
||||||
import {Memo} from '../common/types'
|
import {Memo} from '../common/types/objects'
|
||||||
|
|
||||||
type EscrowExecution = {
|
type EscrowExecution = {
|
||||||
owner: string,
|
owner: string,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const paymentFlags = utils.common.txFlags.Payment
|
|||||||
const ValidationError = utils.common.errors.ValidationError
|
const ValidationError = utils.common.errors.ValidationError
|
||||||
import {Instructions, Prepare} from './types'
|
import {Instructions, Prepare} from './types'
|
||||||
import {Amount, Adjustment, MaxAdjustment,
|
import {Amount, Adjustment, MaxAdjustment,
|
||||||
MinAdjustment, Memo} from '../common/types'
|
MinAdjustment, Memo} from '../common/types/objects'
|
||||||
|
|
||||||
|
|
||||||
type Payment = {
|
type Payment = {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const validate = utils.common.validate
|
|||||||
const AccountFlagIndices = utils.common.constants.AccountFlagIndices
|
const AccountFlagIndices = utils.common.constants.AccountFlagIndices
|
||||||
const AccountFields = utils.common.constants.AccountFields
|
const AccountFields = utils.common.constants.AccountFields
|
||||||
import {Instructions, Prepare} from './types'
|
import {Instructions, Prepare} from './types'
|
||||||
import {Memo} from '../common/types'
|
import {Memo} from '../common/types/objects'
|
||||||
|
|
||||||
type WeightedSigner = {address: string, weight: number}
|
type WeightedSigner = {address: string, weight: number}
|
||||||
type SettingsSigners = {
|
type SettingsSigners = {
|
||||||
|
|||||||
@@ -4,14 +4,16 @@ import * as utils from './utils'
|
|||||||
const validate = utils.common.validate
|
const validate = utils.common.validate
|
||||||
const trustlineFlags = utils.common.txFlags.TrustSet
|
const trustlineFlags = utils.common.txFlags.TrustSet
|
||||||
import {Instructions, Prepare} from './types'
|
import {Instructions, Prepare} from './types'
|
||||||
import {TrustLineSpecification} from '../ledger/trustlines-types'
|
import {
|
||||||
|
FormattedTrustlineSpecification
|
||||||
|
} from '../common/types/objects/trustlines'
|
||||||
|
|
||||||
function convertQuality(quality) {
|
function convertQuality(quality) {
|
||||||
return (new BigNumber(quality)).shift(9).truncated().toNumber()
|
return (new BigNumber(quality)).shift(9).truncated().toNumber()
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTrustlineTransaction(account: string,
|
function createTrustlineTransaction(account: string,
|
||||||
trustline: TrustLineSpecification
|
trustline: FormattedTrustlineSpecification
|
||||||
): Object {
|
): Object {
|
||||||
const limit = {
|
const limit = {
|
||||||
currency: trustline.currency,
|
currency: trustline.currency,
|
||||||
@@ -49,7 +51,7 @@ function createTrustlineTransaction(account: string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
function prepareTrustline(address: string,
|
function prepareTrustline(address: string,
|
||||||
trustline: TrustLineSpecification, instructions: Instructions = {}
|
trustline: FormattedTrustlineSpecification, instructions: Instructions = {}
|
||||||
): Promise<Prepare> {
|
): Promise<Prepare> {
|
||||||
validate.prepareTrustline({address, trustline, instructions})
|
validate.prepareTrustline({address, trustline, instructions})
|
||||||
const txJSON = createTrustlineTransaction(address, trustline)
|
const txJSON = createTrustlineTransaction(address, trustline)
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import * as common from '../common'
|
import * as common from '../common'
|
||||||
import {Memo, ApiMemo} from '../common/types'
|
import {Memo} from '../common/types/objects'
|
||||||
const txFlags = common.txFlags
|
const txFlags = common.txFlags
|
||||||
import {Instructions, Prepare} from './types'
|
import {Instructions, Prepare} from './types'
|
||||||
import {RippleAPI} from '../api'
|
import {RippleAPI} from '../api'
|
||||||
|
|
||||||
|
export type ApiMemo = {
|
||||||
|
MemoData?: string,
|
||||||
|
MemoType?: string,
|
||||||
|
MemoFormat?: string
|
||||||
|
}
|
||||||
|
|
||||||
function formatPrepareResponse(txJSON: any): Prepare {
|
function formatPrepareResponse(txJSON: any): Prepare {
|
||||||
const instructions = {
|
const instructions = {
|
||||||
fee: common.dropsToXrp(txJSON.Fee),
|
fee: common.dropsToXrp(txJSON.Fee),
|
||||||
|
|||||||
@@ -560,9 +560,11 @@ describe('RippleAPI', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('getBalanceSheet - invalid options', function() {
|
it('getBalanceSheet - invalid options', function() {
|
||||||
assert.throws(() => {
|
return this.api.getBalanceSheet(address, {invalid: 'options'}).then(() => {
|
||||||
this.api.getBalanceSheet(address, {invalid: 'options'});
|
assert(false, 'Should throw ValidationError');
|
||||||
}, this.api.errors.ValidationError);
|
}).catch(error => {
|
||||||
|
assert(error instanceof this.api.errors.ValidationError);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('getBalanceSheet - empty', function() {
|
it('getBalanceSheet - empty', function() {
|
||||||
@@ -1050,9 +1052,11 @@ describe('RippleAPI', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('getAccountInfo - invalid options', function() {
|
it('getAccountInfo - invalid options', function() {
|
||||||
assert.throws(() => {
|
return this.api.getAccountInfo(address, {invalid: 'options'}).then(() => {
|
||||||
this.api.getAccountInfo(address, {invalid: 'options'});
|
assert(false, 'Should throw ValidationError');
|
||||||
}, this.api.errors.ValidationError);
|
}).catch(error => {
|
||||||
|
assert(error instanceof this.api.errors.ValidationError);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('getOrders', function() {
|
it('getOrders', function() {
|
||||||
@@ -1060,31 +1064,36 @@ describe('RippleAPI', function() {
|
|||||||
_.partial(checkResult, responses.getOrders, 'getOrders'));
|
_.partial(checkResult, responses.getOrders, 'getOrders'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('getOrders', function() {
|
it('getOrders - limit', function() {
|
||||||
return this.api.getOrders(address, undefined).then(
|
return this.api.getOrders(address, {limit: 20}).then(
|
||||||
_.partial(checkResult, responses.getOrders, 'getOrders'));
|
_.partial(checkResult, responses.getOrders, 'getOrders'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('getOrders - invalid options', function() {
|
it('getOrders - invalid options', function() {
|
||||||
assert.throws(() => {
|
return this.api.getOrders(address, {invalid: 'options'}).then(() => {
|
||||||
this.api.getOrders(address, {invalid: 'options'});
|
assert(false, 'Should throw ValidationError');
|
||||||
}, this.api.errors.ValidationError);
|
}).catch(error => {
|
||||||
|
assert(error instanceof this.api.errors.ValidationError);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getOrderbook', function() {
|
describe('getOrderbook', function() {
|
||||||
|
|
||||||
it('normal', function() {
|
it('normal', function() {
|
||||||
return this.api.getOrderbook(address,
|
return this.api.getOrderbook(address,
|
||||||
requests.getOrderbook.normal, undefined).then(
|
requests.getOrderbook.normal, {limit: 20}).then(
|
||||||
_.partial(checkResult,
|
_.partial(checkResult,
|
||||||
responses.getOrderbook.normal, 'getOrderbook'));
|
responses.getOrderbook.normal, 'getOrderbook'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('invalid options', function() {
|
it('invalid options', function() {
|
||||||
assert.throws(() => {
|
return this.api.getOrderbook(
|
||||||
this.api.getOrderbook(address, requests.getOrderbook.normal,
|
address, requests.getOrderbook.normal, {invalid: 'options'}
|
||||||
{invalid: 'options'});
|
).then(() => {
|
||||||
}, this.api.errors.ValidationError);
|
assert(false, 'Should throw ValidationError');
|
||||||
|
}).catch(error => {
|
||||||
|
assert(error instanceof this.api.errors.ValidationError);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with XRP', function() {
|
it('with XRP', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user