mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-22 05:05:48 +00:00
Types cleanup + more API methods onto new request method (#857)
* major types cleanup, more formatted api methods onto new request method - getPaymentChannel() now uses this.request() - getSettings() now uses this.request() - getLedger() now uses this.request() - transaction types cleaned up a bit, but still some work left to do
This commit is contained in:
committed by
Elliot Lee
parent
c175e3f58e
commit
187154a2b0
@@ -49,7 +49,9 @@ import {
|
|||||||
AccountInfoRequest, AccountInfoResponse,
|
AccountInfoRequest, AccountInfoResponse,
|
||||||
AccountLinesRequest, AccountLinesResponse,
|
AccountLinesRequest, AccountLinesResponse,
|
||||||
BookOffersRequest, BookOffersResponse,
|
BookOffersRequest, BookOffersResponse,
|
||||||
GatewayBalancesRequest, GatewayBalancesResponse
|
GatewayBalancesRequest, GatewayBalancesResponse,
|
||||||
|
LedgerRequest, LedgerResponse,
|
||||||
|
LedgerEntryRequest, LedgerEntryResponse
|
||||||
} from './common/types/commands'
|
} from './common/types/commands'
|
||||||
|
|
||||||
|
|
||||||
@@ -154,6 +156,10 @@ class RippleAPI extends EventEmitter {
|
|||||||
Promise<BookOffersResponse>
|
Promise<BookOffersResponse>
|
||||||
async _request(command: 'gateway_balances', params: GatewayBalancesRequest):
|
async _request(command: 'gateway_balances', params: GatewayBalancesRequest):
|
||||||
Promise<GatewayBalancesResponse>
|
Promise<GatewayBalancesResponse>
|
||||||
|
async _request(command: 'ledger', params: LedgerRequest):
|
||||||
|
Promise<LedgerResponse>
|
||||||
|
async _request(command: 'ledger_entry', params: LedgerEntryRequest):
|
||||||
|
Promise<LedgerEntryResponse>
|
||||||
async _request(command: string, params: any = {}) {
|
async _request(command: string, params: any = {}) {
|
||||||
return this.connection.request({
|
return this.connection.request({
|
||||||
...params,
|
...params,
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import {AccountRoot, SignerList} from '../objects'
|
import {
|
||||||
|
AccountRootLedgerEntry,
|
||||||
|
SignerListLedgerEntry,
|
||||||
|
QueueData
|
||||||
|
} from '../objects'
|
||||||
|
|
||||||
export interface AccountInfoRequest {
|
export interface AccountInfoRequest {
|
||||||
account: string,
|
account: string,
|
||||||
@@ -10,27 +14,10 @@ export interface AccountInfoRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AccountInfoResponse {
|
export interface AccountInfoResponse {
|
||||||
account_data: AccountRoot,
|
account_data: AccountRootLedgerEntry,
|
||||||
signer_lists?: SignerList[],
|
signer_lists?: SignerListLedgerEntry[],
|
||||||
ledger_current_index?: number,
|
ledger_current_index?: number,
|
||||||
ledger_index?: number,
|
ledger_index?: number,
|
||||||
queue_data?: QueueData,
|
queue_data?: QueueData,
|
||||||
validated?: boolean
|
validated?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QueueData {
|
|
||||||
txn_count: number,
|
|
||||||
auth_change_queued?: boolean,
|
|
||||||
lowest_sequence?: number,
|
|
||||||
highest_sequence?: number,
|
|
||||||
max_spend_drops_total?: string,
|
|
||||||
transactions?: TransactionData[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TransactionData {
|
|
||||||
auth_change?: boolean,
|
|
||||||
fee?: string,
|
|
||||||
fee_level?: string,
|
|
||||||
max_spend_drops?: string,
|
|
||||||
seq?: number
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
TakerRequestAmount,
|
TakerRequestAmount,
|
||||||
OfferCreateTransaction,
|
RippledAmount,
|
||||||
RippledAmount
|
OfferCreateTransaction
|
||||||
} from '../objects'
|
} from '../objects'
|
||||||
|
|
||||||
export interface BookOffersRequest {
|
export interface BookOffersRequest {
|
||||||
@@ -15,15 +15,15 @@ export interface BookOffersRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface BookOffersResponse {
|
export interface BookOffersResponse {
|
||||||
offers: OrderBookOffer[],
|
offers: BookOffer[],
|
||||||
ledger_hash?: string,
|
ledger_hash?: string,
|
||||||
ledger_current_index?: number,
|
ledger_current_index?: number,
|
||||||
ledger_index?: number,
|
ledger_index?: number,
|
||||||
marker?: any
|
marker?: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OrderBookOffer extends OfferCreateTransaction {
|
export interface BookOffer extends OfferCreateTransaction {
|
||||||
quality?: number
|
quality?: string
|
||||||
owner_funds?: string,
|
owner_funds?: string,
|
||||||
taker_gets_funded?: RippledAmount,
|
taker_gets_funded?: RippledAmount,
|
||||||
taker_pays_funded?: RippledAmount
|
taker_pays_funded?: RippledAmount
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {Amount} from '../objects'
|
import {Amount} from '../objects'
|
||||||
|
|
||||||
|
|
||||||
export interface GatewayBalancesRequest {
|
export interface GatewayBalancesRequest {
|
||||||
account: string,
|
account: string,
|
||||||
strict?: boolean,
|
strict?: boolean,
|
||||||
|
|||||||
@@ -3,3 +3,5 @@ export * from './account_lines'
|
|||||||
export * from './account_offers'
|
export * from './account_offers'
|
||||||
export * from './book_offers'
|
export * from './book_offers'
|
||||||
export * from './gateway_balances'
|
export * from './gateway_balances'
|
||||||
|
export * from './ledger'
|
||||||
|
export * from './ledger_entry'
|
||||||
|
|||||||
20
src/common/types/commands/ledger.ts
Normal file
20
src/common/types/commands/ledger.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import {Ledger, QueueData} from '../objects'
|
||||||
|
|
||||||
|
export interface LedgerRequest {
|
||||||
|
ledger_hash?: string
|
||||||
|
ledger_index?: number | ('validated' | 'closed' | 'current')
|
||||||
|
full?: boolean
|
||||||
|
accounts?: boolean
|
||||||
|
transactions?: boolean
|
||||||
|
expand?: boolean
|
||||||
|
owner_funds?: boolean
|
||||||
|
binary?: boolean
|
||||||
|
queue?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LedgerResponse {
|
||||||
|
ledger_index: number
|
||||||
|
ledger_hash: string
|
||||||
|
ledger: Ledger
|
||||||
|
queue_data?: QueueData
|
||||||
|
}
|
||||||
31
src/common/types/commands/ledger_entry.ts
Normal file
31
src/common/types/commands/ledger_entry.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import {LedgerEntry} from '../objects'
|
||||||
|
|
||||||
|
export interface LedgerEntryRequest {
|
||||||
|
ledger_hash?: string
|
||||||
|
ledger_index?: number | ('validated' | 'closed' | 'current')
|
||||||
|
index?: string,
|
||||||
|
account_root?: string,
|
||||||
|
directory?: string | {
|
||||||
|
sub_index?: number,
|
||||||
|
dir_root: string
|
||||||
|
} | {
|
||||||
|
sub_index?: number,
|
||||||
|
owner: string
|
||||||
|
},
|
||||||
|
offer?: string | {
|
||||||
|
account: string,
|
||||||
|
seq: number
|
||||||
|
},
|
||||||
|
ripple_state?: {
|
||||||
|
accounts: [string, string],
|
||||||
|
currency: string
|
||||||
|
},
|
||||||
|
binary?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LedgerEntryResponse {
|
||||||
|
index: string,
|
||||||
|
ledger_index: number,
|
||||||
|
node_binary?: string,
|
||||||
|
node?: LedgerEntry,
|
||||||
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
export * from './accounts'
|
|
||||||
export * from './adjustments'
|
export * from './adjustments'
|
||||||
export * from './amounts'
|
export * from './amounts'
|
||||||
|
export * from './ledger'
|
||||||
|
export * from './ledger_entries'
|
||||||
export * from './memos'
|
export * from './memos'
|
||||||
|
export * from './orders'
|
||||||
|
export * from './queue_data'
|
||||||
|
export * from './settings'
|
||||||
export * from './signers'
|
export * from './signers'
|
||||||
export * from './transactions'
|
export * from './transactions'
|
||||||
export * from './trustlines'
|
export * from './trustlines'
|
||||||
|
|||||||
26
src/common/types/objects/ledger.ts
Normal file
26
src/common/types/objects/ledger.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
export interface Ledger {
|
||||||
|
account_hash: string,
|
||||||
|
accounts?: any[],
|
||||||
|
close_time: number,
|
||||||
|
close_time_human: string,
|
||||||
|
close_time_resolution: number,
|
||||||
|
closed: boolean,
|
||||||
|
ledger_hash: string,
|
||||||
|
ledger_index: string,
|
||||||
|
parent_hash: string,
|
||||||
|
total_coins: string,
|
||||||
|
transaction_hash: string,
|
||||||
|
transactions: string[] | object[],
|
||||||
|
// @deprecated
|
||||||
|
seqNum?: string,
|
||||||
|
// @deprecated
|
||||||
|
totalCoins?: string,
|
||||||
|
// @deprecated
|
||||||
|
hash?: string,
|
||||||
|
// TODO: undocumented
|
||||||
|
close_flags?: number,
|
||||||
|
// TODO: undocumented
|
||||||
|
parent_close_time?: number,
|
||||||
|
// TODO: undocumented
|
||||||
|
accountState?: any
|
||||||
|
}
|
||||||
56
src/common/types/objects/ledger_entries.ts
Normal file
56
src/common/types/objects/ledger_entries.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import {SignerEntry} from './index'
|
||||||
|
|
||||||
|
export interface PayChannelLedgerEntry {
|
||||||
|
LedgerEntryType: 'PayChannel',
|
||||||
|
Sequence: number,
|
||||||
|
Account: string,
|
||||||
|
Amount: string,
|
||||||
|
Balance: string,
|
||||||
|
PublicKey: string,
|
||||||
|
Destination: string,
|
||||||
|
SettleDelay: number,
|
||||||
|
Expiration?: number,
|
||||||
|
CancelAfter?: number,
|
||||||
|
SourceTag?: number,
|
||||||
|
DestinationTag?: number,
|
||||||
|
OwnerNode: string,
|
||||||
|
PreviousTxnID: string,
|
||||||
|
PreviousTxnLgrSeq: number,
|
||||||
|
index: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AccountRootLedgerEntry {
|
||||||
|
LedgerEntryType: 'AccountRoot',
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SignerListLedgerEntry {
|
||||||
|
LedgerEntryType: 'SignerList',
|
||||||
|
OwnerNode: string,
|
||||||
|
SignerQuorum: number,
|
||||||
|
SignerEntries: SignerEntry[],
|
||||||
|
SignerListID: number,
|
||||||
|
PreviousTxnID: string,
|
||||||
|
PreviousTxnLgrSeq: number
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add the other ledger entry types, then remove the `any` fallback
|
||||||
|
// see https://ripple.com/build/ledger-format/#ledger-object-types
|
||||||
|
export type LedgerEntry =
|
||||||
|
PayChannelLedgerEntry |
|
||||||
|
AccountRootLedgerEntry |
|
||||||
|
SignerListLedgerEntry |
|
||||||
|
any
|
||||||
17
src/common/types/objects/orders.ts
Normal file
17
src/common/types/objects/orders.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import {Amount} from './amounts'
|
||||||
|
import {Memo} from './memos'
|
||||||
|
|
||||||
|
export type FormattedOrderSpecification = {
|
||||||
|
direction: string,
|
||||||
|
quantity: Amount,
|
||||||
|
totalPrice: Amount,
|
||||||
|
immediateOrCancel?: boolean,
|
||||||
|
fillOrKill?: boolean,
|
||||||
|
expirationTime?: string,
|
||||||
|
orderToReplace?: number,
|
||||||
|
memos?: Memo[],
|
||||||
|
// 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
|
||||||
|
}
|
||||||
16
src/common/types/objects/queue_data.ts
Normal file
16
src/common/types/objects/queue_data.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export interface QueueTransaction {
|
||||||
|
auth_change: boolean,
|
||||||
|
fee: string,
|
||||||
|
fee_level: string,
|
||||||
|
max_spend_drops: string,
|
||||||
|
seq: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface QueueData {
|
||||||
|
txn_count: number,
|
||||||
|
auth_change_queued?: boolean,
|
||||||
|
lowest_sequence?: number,
|
||||||
|
highest_sequence?: number,
|
||||||
|
max_spend_drops_total?: string,
|
||||||
|
transactions?: QueueTransaction[]
|
||||||
|
}
|
||||||
30
src/common/types/objects/settings.ts
Normal file
30
src/common/types/objects/settings.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import {Memo} from './memos'
|
||||||
|
|
||||||
|
export type WeightedSigner = {
|
||||||
|
address: string,
|
||||||
|
weight: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Signers = {
|
||||||
|
threshold?: number,
|
||||||
|
weights: WeightedSigner[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FormattedSettings = {
|
||||||
|
passwordSpent?: boolean,
|
||||||
|
requireDestinationTag?: boolean,
|
||||||
|
requireAuthorization?: boolean,
|
||||||
|
disallowIncomingXRP?: boolean,
|
||||||
|
disableMasterKey?: boolean,
|
||||||
|
enableTransactionIDTracking?: boolean,
|
||||||
|
noFreeze?: boolean,
|
||||||
|
globalFreeze?: boolean,
|
||||||
|
defaultRipple?: boolean,
|
||||||
|
emailHash?: string|null,
|
||||||
|
messageKey?: string,
|
||||||
|
domain?: string,
|
||||||
|
transferRate?: number|null,
|
||||||
|
regularKey?: string,
|
||||||
|
signers?: Signers,
|
||||||
|
memos?: Memo[]
|
||||||
|
}
|
||||||
@@ -1,13 +1,3 @@
|
|||||||
export interface SignerList {
|
|
||||||
LedgerEntryType: string,
|
|
||||||
OwnerNode: string,
|
|
||||||
SignerQuorum: number,
|
|
||||||
SignerEntries: SignerEntry[],
|
|
||||||
SignerListID: number,
|
|
||||||
PreviousTxnID: string,
|
|
||||||
PreviousTxnLgrSeq: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SignerEntry {
|
export interface SignerEntry {
|
||||||
Account: string,
|
Account: string,
|
||||||
SignerWeight: number
|
SignerWeight: number
|
||||||
|
|||||||
@@ -1,28 +1,29 @@
|
|||||||
import {validate} from '../common'
|
import {validate} from '../common'
|
||||||
import parseLedger from './parse/ledger'
|
import {FormattedLedger, parseLedger} from './parse/ledger'
|
||||||
import {GetLedger} from './types'
|
import {RippleAPI} from '../api'
|
||||||
|
|
||||||
export type LedgerOptions = {
|
export type GetLedgerOptions = {
|
||||||
ledgerVersion?: number,
|
ledgerVersion?: number,
|
||||||
includeAllData?: boolean,
|
includeAllData?: boolean,
|
||||||
includeTransactions?: boolean,
|
includeTransactions?: boolean,
|
||||||
includeState?: boolean
|
includeState?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getLedger(
|
||||||
function getLedger(options: LedgerOptions = {}): Promise<GetLedger> {
|
this: RippleAPI, options: GetLedgerOptions = {}
|
||||||
|
): Promise<FormattedLedger> {
|
||||||
|
// 1. Validate
|
||||||
validate.getLedger({options})
|
validate.getLedger({options})
|
||||||
|
// 2. Make Request
|
||||||
const request = {
|
const response = await this._request('ledger', {
|
||||||
command: 'ledger',
|
|
||||||
ledger_index: options.ledgerVersion || 'validated',
|
ledger_index: options.ledgerVersion || 'validated',
|
||||||
expand: options.includeAllData,
|
expand: options.includeAllData,
|
||||||
transactions: options.includeTransactions,
|
transactions: options.includeTransactions,
|
||||||
accounts: options.includeState
|
accounts: options.includeState
|
||||||
}
|
})
|
||||||
|
// 3. Return Formatted Response
|
||||||
return this.connection.request(request).then(response =>
|
return parseLedger(response.ledger)
|
||||||
parseLedger(response.ledger))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default getLedger
|
export default getLedger
|
||||||
|
|||||||
@@ -1,51 +1,28 @@
|
|||||||
import * as _ from 'lodash'
|
import * as _ from 'lodash'
|
||||||
import * as utils from './utils'
|
import * as utils from './utils'
|
||||||
import parseOrderbookOrder from './parse/orderbook-order'
|
import {
|
||||||
|
parseOrderbookOrder,
|
||||||
|
FormattedOrderbookOrder
|
||||||
|
} from './parse/orderbook-order'
|
||||||
import {validate} from '../common'
|
import {validate} from '../common'
|
||||||
import {OrderSpecification} from './types'
|
|
||||||
import {Amount, Issue} from '../common/types/objects'
|
import {Amount, Issue} from '../common/types/objects'
|
||||||
|
import {BookOffer} from '../common/types/commands'
|
||||||
import {RippleAPI} from '../api'
|
import {RippleAPI} from '../api'
|
||||||
import {OfferCreateTransaction} from '../common/types/objects'
|
|
||||||
|
|
||||||
export type OrdersOptions = {
|
export type FormattedOrderbook = {
|
||||||
limit?: number,
|
bids: FormattedOrderbookOrder[],
|
||||||
ledgerVersion?: number
|
asks: FormattedOrderbookOrder[]
|
||||||
}
|
|
||||||
|
|
||||||
export type Orderbook = {
|
|
||||||
base: Issue,
|
|
||||||
counter: Issue
|
|
||||||
}
|
|
||||||
|
|
||||||
export type OrderbookItem = {
|
|
||||||
specification: OrderSpecification,
|
|
||||||
properties: {
|
|
||||||
maker: string,
|
|
||||||
sequence: number,
|
|
||||||
makerExchangeRate: string
|
|
||||||
},
|
|
||||||
state?: {
|
|
||||||
fundedAmount: Amount,
|
|
||||||
priceOfFundedAmount: Amount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type OrderbookOrders = Array<OrderbookItem>
|
|
||||||
|
|
||||||
export type GetOrderbook = {
|
|
||||||
bids: OrderbookOrders,
|
|
||||||
asks: OrderbookOrders
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
function directionFilter(direction: string, order: OrderbookItem) {
|
function directionFilter(direction: string, order: FormattedOrderbookOrder) {
|
||||||
return order.specification.direction === direction
|
return order.specification.direction === direction
|
||||||
}
|
}
|
||||||
|
|
||||||
function flipOrder(order: OrderbookItem) {
|
function flipOrder(order: FormattedOrderbookOrder) {
|
||||||
const specification = order.specification
|
const specification = order.specification
|
||||||
const flippedSpecification = {
|
const flippedSpecification = {
|
||||||
quantity: specification.totalPrice,
|
quantity: specification.totalPrice,
|
||||||
@@ -56,13 +33,13 @@ function flipOrder(order: OrderbookItem) {
|
|||||||
return _.merge({}, order, {specification: newSpecification})
|
return _.merge({}, order, {specification: newSpecification})
|
||||||
}
|
}
|
||||||
|
|
||||||
function alignOrder(base: Amount, order: OrderbookItem) {
|
function alignOrder(base: Amount, order: FormattedOrderbookOrder) {
|
||||||
const quantity = order.specification.quantity
|
const quantity = order.specification.quantity
|
||||||
return isSameIssue(quantity, base) ? order : flipOrder(order)
|
return isSameIssue(quantity, base) ? order : flipOrder(order)
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatBidsAndAsks(
|
function formatBidsAndAsks(
|
||||||
orderbook: Orderbook, offers: OfferCreateTransaction[]) {
|
orderbook: OrderbookInfo, offers: BookOffer[]) {
|
||||||
// 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
|
||||||
@@ -83,7 +60,7 @@ function formatBidsAndAsks(
|
|||||||
// account is to specify a "perspective", which affects which unfunded offers
|
// account is to specify a "perspective", which affects which unfunded offers
|
||||||
// are returned
|
// are returned
|
||||||
async function makeRequest(
|
async function makeRequest(
|
||||||
api: RippleAPI, taker: string, options: OrdersOptions,
|
api: RippleAPI, taker: string, options: GetOrderbookOptions,
|
||||||
takerGets: Issue, takerPays: Issue
|
takerGets: Issue, takerPays: Issue
|
||||||
) {
|
) {
|
||||||
const orderData = utils.renameCounterpartyToIssuerInOrder({
|
const orderData = utils.renameCounterpartyToIssuerInOrder({
|
||||||
@@ -99,12 +76,23 @@ async function makeRequest(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type GetOrderbookOptions = {
|
||||||
|
limit?: number,
|
||||||
|
ledgerVersion?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type OrderbookInfo = {
|
||||||
|
base: Issue,
|
||||||
|
counter: Issue
|
||||||
|
}
|
||||||
|
|
||||||
export default async function getOrderbook(
|
export default async function getOrderbook(
|
||||||
this: RippleAPI,
|
this: RippleAPI,
|
||||||
address: string,
|
address: string,
|
||||||
orderbook: Orderbook,
|
orderbook: OrderbookInfo,
|
||||||
options: OrdersOptions = {}
|
options: GetOrderbookOptions = {}
|
||||||
): Promise<GetOrderbook> {
|
): Promise<FormattedOrderbook> {
|
||||||
// 1. Validate
|
// 1. Validate
|
||||||
validate.getOrderbook({address, orderbook, options})
|
validate.getOrderbook({address, orderbook, options})
|
||||||
// 2. Make Request
|
// 2. Make Request
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import * as _ from 'lodash'
|
import * as _ from 'lodash'
|
||||||
import {validate} from '../common'
|
import {validate} from '../common'
|
||||||
import parseAccountOrder from './parse/account-order'
|
import {FormattedAccountOrder, parseAccountOrder} from './parse/account-order'
|
||||||
import {Order} from './types'
|
|
||||||
import {RippleAPI} from '../api'
|
import {RippleAPI} from '../api'
|
||||||
import {AccountOffersResponse} from '../common/types/commands/account_offers'
|
import {AccountOffersResponse} from '../common/types/commands'
|
||||||
|
|
||||||
export type GetOrdersOptions = {
|
export type GetOrdersOptions = {
|
||||||
limit?: number,
|
limit?: number,
|
||||||
@@ -12,8 +11,8 @@ export type GetOrdersOptions = {
|
|||||||
|
|
||||||
function formatResponse(
|
function formatResponse(
|
||||||
address: string, responses: AccountOffersResponse[]
|
address: string, responses: AccountOffersResponse[]
|
||||||
): Order[] {
|
): FormattedAccountOrder[] {
|
||||||
let orders: Order[] = []
|
let orders: FormattedAccountOrder[] = []
|
||||||
for (const response of responses) {
|
for (const response of responses) {
|
||||||
const offers = response.offers.map(offer => {
|
const offers = response.offers.map(offer => {
|
||||||
return parseAccountOrder(address, offer)
|
return parseAccountOrder(address, offer)
|
||||||
@@ -25,7 +24,7 @@ function formatResponse(
|
|||||||
|
|
||||||
export default async function getOrders(
|
export default async function getOrders(
|
||||||
this: RippleAPI, address: string, options: GetOrdersOptions = {}
|
this: RippleAPI, address: string, options: GetOrdersOptions = {}
|
||||||
): Promise<Order[]> {
|
): Promise<FormattedAccountOrder[]> {
|
||||||
// 1. Validate
|
// 1. Validate
|
||||||
validate.getOrders({address, options})
|
validate.getOrders({address, options})
|
||||||
// 2. Make Request
|
// 2. Make Request
|
||||||
|
|||||||
@@ -3,7 +3,16 @@ 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'
|
import {FormattedOrderSpecification} from '../../common/types/objects'
|
||||||
|
|
||||||
|
export type FormattedAccountOrder = {
|
||||||
|
specification: FormattedOrderSpecification,
|
||||||
|
properties: {
|
||||||
|
maker: string,
|
||||||
|
sequence: number,
|
||||||
|
makerExchangeRate: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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) {
|
||||||
@@ -13,7 +22,9 @@ 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): Order {
|
export function parseAccountOrder(
|
||||||
|
address: string, order: any
|
||||||
|
): FormattedAccountOrder {
|
||||||
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)
|
||||||
@@ -43,5 +54,3 @@ function parseAccountOrder(address: string, order: any): Order {
|
|||||||
|
|
||||||
return {specification, properties}
|
return {specification, properties}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default parseAccountOrder
|
|
||||||
|
|||||||
@@ -1,7 +1,28 @@
|
|||||||
import * as _ from 'lodash'
|
import * as _ from 'lodash'
|
||||||
import {removeUndefined, rippleTimeToISO8601} from '../../common'
|
import {removeUndefined, rippleTimeToISO8601} from '../../common'
|
||||||
import parseTransaction from './transaction'
|
import parseTransaction from './transaction'
|
||||||
import {GetLedger} from '../types'
|
import {Ledger} from '../../common/types/objects'
|
||||||
|
|
||||||
|
export type FormattedLedger = {
|
||||||
|
// TODO: properties in type don't match response object. Fix!
|
||||||
|
// accepted: boolean,
|
||||||
|
// closed: boolean,
|
||||||
|
stateHash: string,
|
||||||
|
closeTime: string,
|
||||||
|
closeTimeResolution: number,
|
||||||
|
closeFlags: number,
|
||||||
|
ledgerHash: string,
|
||||||
|
ledgerVersion: number,
|
||||||
|
parentLedgerHash: string,
|
||||||
|
parentCloseTime: string,
|
||||||
|
totalDrops: string,
|
||||||
|
transactionHash: string,
|
||||||
|
transactions?: Array<Object>,
|
||||||
|
rawTransactions?: string,
|
||||||
|
transactionHashes?: Array<string>,
|
||||||
|
rawState?: string,
|
||||||
|
stateHashes?: Array<string>
|
||||||
|
}
|
||||||
|
|
||||||
function parseTransactionWrapper(ledgerVersion, tx) {
|
function parseTransactionWrapper(ledgerVersion, tx) {
|
||||||
const transaction = _.assign({}, _.omit(tx, 'metaData'), {
|
const transaction = _.assign({}, _.omit(tx, 'metaData'), {
|
||||||
@@ -39,7 +60,7 @@ function parseState(state) {
|
|||||||
return {rawState: JSON.stringify(state)}
|
return {rawState: JSON.stringify(state)}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseLedger(ledger: any): GetLedger {
|
export function parseLedger(ledger: Ledger): FormattedLedger {
|
||||||
const ledgerVersion = parseInt(ledger.ledger_index || ledger.seqNum, 10)
|
const ledgerVersion = parseInt(ledger.ledger_index || ledger.seqNum, 10)
|
||||||
return removeUndefined(Object.assign({
|
return removeUndefined(Object.assign({
|
||||||
stateHash: ledger.account_hash,
|
stateHash: ledger.account_hash,
|
||||||
@@ -57,5 +78,3 @@ function parseLedger(ledger: any): GetLedger {
|
|||||||
parseState(ledger.accountState)
|
parseState(ledger.accountState)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
export default parseLedger
|
|
||||||
|
|||||||
@@ -2,9 +2,14 @@ import * as assert from 'assert'
|
|||||||
import {parseTimestamp} from './utils'
|
import {parseTimestamp} from './utils'
|
||||||
import parseAmount from './amount'
|
import parseAmount from './amount'
|
||||||
import {removeUndefined, txFlags} from '../../common'
|
import {removeUndefined, txFlags} from '../../common'
|
||||||
|
import {
|
||||||
|
FormattedOrderSpecification,
|
||||||
|
OfferCreateTransaction
|
||||||
|
} from '../../common/types/objects/index'
|
||||||
|
|
||||||
const flags = txFlags.OfferCreate
|
const flags = txFlags.OfferCreate
|
||||||
|
|
||||||
function parseOrder(tx: any): Object {
|
function parseOrder(tx: OfferCreateTransaction): FormattedOrderSpecification {
|
||||||
assert(tx.TransactionType === 'OfferCreate')
|
assert(tx.TransactionType === 'OfferCreate')
|
||||||
|
|
||||||
const direction = (tx.Flags & flags.Sell) === 0 ? 'buy' : 'sell'
|
const direction = (tx.Flags & flags.Sell) === 0 ? 'buy' : 'sell'
|
||||||
|
|||||||
@@ -4,8 +4,25 @@ import {removeUndefined} from '../../common'
|
|||||||
|
|
||||||
import {orderFlags} from './flags'
|
import {orderFlags} from './flags'
|
||||||
import parseAmount from './amount'
|
import parseAmount from './amount'
|
||||||
|
import {BookOffer} from '../../common/types/commands'
|
||||||
|
import {Amount, FormattedOrderSpecification} from '../../common/types/objects'
|
||||||
|
|
||||||
function parseOrderbookOrder(order: any): Object {
|
export type FormattedOrderbookOrder = {
|
||||||
|
specification: FormattedOrderSpecification,
|
||||||
|
properties: {
|
||||||
|
maker: string,
|
||||||
|
sequence: number,
|
||||||
|
makerExchangeRate: string
|
||||||
|
},
|
||||||
|
state?: {
|
||||||
|
fundedAmount: Amount,
|
||||||
|
priceOfFundedAmount: Amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseOrderbookOrder(
|
||||||
|
order: BookOffer
|
||||||
|
): FormattedOrderbookOrder {
|
||||||
const direction = (order.Flags & orderFlags.Sell) === 0 ? 'buy' : 'sell'
|
const direction = (order.Flags & orderFlags.Sell) === 0 ? 'buy' : 'sell'
|
||||||
const takerGetsAmount = parseAmount(order.TakerGets)
|
const takerGetsAmount = parseAmount(order.TakerGets)
|
||||||
const takerPaysAmount = parseAmount(order.TakerPays)
|
const takerPaysAmount = parseAmount(order.TakerPays)
|
||||||
@@ -14,7 +31,7 @@ function parseOrderbookOrder(order: any): Object {
|
|||||||
|
|
||||||
// note: immediateOrCancel and fillOrKill orders cannot enter the order book
|
// note: immediateOrCancel and fillOrKill orders cannot enter the order book
|
||||||
// so we can omit those flags here
|
// so we can omit those flags here
|
||||||
const specification = removeUndefined({
|
const specification: FormattedOrderSpecification = removeUndefined({
|
||||||
direction: direction,
|
direction: direction,
|
||||||
quantity: quantity,
|
quantity: quantity,
|
||||||
totalPrice: totalPrice,
|
totalPrice: totalPrice,
|
||||||
@@ -40,5 +57,3 @@ function parseOrderbookOrder(order: any): Object {
|
|||||||
const state = _.isEmpty(available) ? undefined : available
|
const state = _.isEmpty(available) ? undefined : available
|
||||||
return removeUndefined({specification, properties, state})
|
return removeUndefined({specification, properties, state})
|
||||||
}
|
}
|
||||||
|
|
||||||
export default parseOrderbookOrder
|
|
||||||
|
|||||||
@@ -1,35 +1,8 @@
|
|||||||
import {parseTimestamp} from './utils'
|
import {parseTimestamp} from './utils'
|
||||||
import {removeUndefined, dropsToXrp} from '../../common'
|
import {removeUndefined, dropsToXrp} from '../../common'
|
||||||
|
import {PayChannelLedgerEntry} from '../../common/types/objects'
|
||||||
|
|
||||||
|
export type FormattedPaymentChannel = {
|
||||||
export type PaymentChannel = {
|
|
||||||
Sequence: number,
|
|
||||||
Account: string,
|
|
||||||
Amount: string,
|
|
||||||
Balance: string,
|
|
||||||
PublicKey: string,
|
|
||||||
Destination: string,
|
|
||||||
SettleDelay: number,
|
|
||||||
Expiration?: number,
|
|
||||||
CancelAfter?: number,
|
|
||||||
SourceTag?: number,
|
|
||||||
DestinationTag?: number,
|
|
||||||
OwnerNode: string,
|
|
||||||
LedgerEntryType: string,
|
|
||||||
PreviousTxnID: string,
|
|
||||||
PreviousTxnLgrSeq: number,
|
|
||||||
index: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type LedgerEntryResponse = {
|
|
||||||
node: PaymentChannel,
|
|
||||||
ledger_current_index?: number,
|
|
||||||
ledger_hash?: string,
|
|
||||||
ledger_index: number,
|
|
||||||
validated: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PaymentChannelResponse = {
|
|
||||||
account: string,
|
account: string,
|
||||||
balance: string,
|
balance: string,
|
||||||
publicKey: string,
|
publicKey: string,
|
||||||
@@ -43,7 +16,9 @@ export type PaymentChannelResponse = {
|
|||||||
previousAffectingTransactionLedgerVersion: number
|
previousAffectingTransactionLedgerVersion: number
|
||||||
}
|
}
|
||||||
|
|
||||||
function parsePaymentChannel(data: PaymentChannel): PaymentChannelResponse {
|
export function parsePaymentChannel(
|
||||||
|
data: PayChannelLedgerEntry
|
||||||
|
): FormattedPaymentChannel {
|
||||||
return removeUndefined({
|
return removeUndefined({
|
||||||
account: data.Account,
|
account: data.Account,
|
||||||
amount: dropsToXrp(data.Amount),
|
amount: dropsToXrp(data.Amount),
|
||||||
@@ -59,5 +34,3 @@ function parsePaymentChannel(data: PaymentChannel): PaymentChannelResponse {
|
|||||||
previousAffectingTransactionLedgerVersion: data.PreviousTxnLgrSeq
|
previousAffectingTransactionLedgerVersion: data.PreviousTxnLgrSeq
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export default parsePaymentChannel
|
|
||||||
|
|||||||
@@ -1,29 +1,35 @@
|
|||||||
import parsePaymentChannel, {
|
import {
|
||||||
LedgerEntryResponse, PaymentChannel
|
parsePaymentChannel,
|
||||||
|
FormattedPaymentChannel
|
||||||
} from './parse/payment-channel'
|
} from './parse/payment-channel'
|
||||||
import {validate, errors} from '../common'
|
import {validate, errors} from '../common'
|
||||||
|
import {RippleAPI} from '../api'
|
||||||
|
import {LedgerEntryResponse} from '../common/types/commands'
|
||||||
const NotFoundError = errors.NotFoundError
|
const NotFoundError = errors.NotFoundError
|
||||||
|
|
||||||
function formatResponse(response: LedgerEntryResponse) {
|
function formatResponse(
|
||||||
if (response.node !== undefined &&
|
response: LedgerEntryResponse
|
||||||
response.node.LedgerEntryType === 'PayChannel') {
|
): FormattedPaymentChannel {
|
||||||
return parsePaymentChannel(response.node)
|
if (response.node === undefined ||
|
||||||
} else {
|
response.node.LedgerEntryType !== 'PayChannel') {
|
||||||
throw new NotFoundError('Payment channel ledger entry not found')
|
throw new NotFoundError('Payment channel ledger entry not found')
|
||||||
}
|
}
|
||||||
|
return parsePaymentChannel(response.node)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPaymentChannel(id: string): Promise<PaymentChannel> {
|
async function getPaymentChannel(
|
||||||
|
this: RippleAPI, id: string
|
||||||
|
): Promise<FormattedPaymentChannel> {
|
||||||
|
// 1. Validate
|
||||||
validate.getPaymentChannel({id})
|
validate.getPaymentChannel({id})
|
||||||
|
// 2. Make Request
|
||||||
const request = {
|
const response = await this._request('ledger_entry', {
|
||||||
command: 'ledger_entry',
|
|
||||||
index: id,
|
index: id,
|
||||||
binary: false,
|
binary: false,
|
||||||
ledger_index: 'validated'
|
ledger_index: 'validated'
|
||||||
}
|
})
|
||||||
|
// 3. Return Formatted Response
|
||||||
return this.connection.request(request).then(formatResponse)
|
return formatResponse(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getPaymentChannel
|
export default getPaymentChannel
|
||||||
|
|||||||
@@ -1,31 +1,15 @@
|
|||||||
import * as _ from 'lodash'
|
import * as _ from 'lodash'
|
||||||
import parseFields from './parse/fields'
|
import parseFields from './parse/fields'
|
||||||
import {validate, constants} from '../common'
|
import {validate, constants} from '../common'
|
||||||
|
import {FormattedSettings} from '../common/types/objects'
|
||||||
|
import {AccountInfoResponse} from '../common/types/commands'
|
||||||
|
import {RippleAPI} from '../api'
|
||||||
const AccountFlags = constants.AccountFlags
|
const AccountFlags = constants.AccountFlags
|
||||||
|
|
||||||
export type SettingsOptions = {
|
export type SettingsOptions = {
|
||||||
ledgerVersion?: number
|
ledgerVersion?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetSettings = {
|
|
||||||
passwordSpent?: boolean,
|
|
||||||
requireDestinationTag?: boolean,
|
|
||||||
requireAuthorization?: boolean,
|
|
||||||
depositAuthorization?: boolean,
|
|
||||||
disallowIncomingXRP?: boolean,
|
|
||||||
disableMasterKey?: boolean,
|
|
||||||
enableTransactionIDTracking?: boolean,
|
|
||||||
noFreeze?: boolean,
|
|
||||||
globalFreeze?: boolean,
|
|
||||||
defaultRipple?: boolean,
|
|
||||||
emailHash?: string|null,
|
|
||||||
messageKey?: string,
|
|
||||||
domain?: string,
|
|
||||||
transferRate?: number|null,
|
|
||||||
regularKey?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function parseFlags(value) {
|
function parseFlags(value) {
|
||||||
const settings = {}
|
const settings = {}
|
||||||
for (const flagName in AccountFlags) {
|
for (const flagName in AccountFlags) {
|
||||||
@@ -36,25 +20,26 @@ function parseFlags(value) {
|
|||||||
return settings
|
return settings
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatSettings(response) {
|
function formatSettings(response: AccountInfoResponse) {
|
||||||
const data = response.account_data
|
const data = response.account_data
|
||||||
const parsedFlags = parseFlags(data.Flags)
|
const parsedFlags = parseFlags(data.Flags)
|
||||||
const parsedFields = parseFields(data)
|
const parsedFields = parseFields(data)
|
||||||
return _.assign({}, parsedFlags, parsedFields)
|
return _.assign({}, parsedFlags, parsedFields)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSettings(address: string, options: SettingsOptions = {}
|
async function getSettings(
|
||||||
): Promise<GetSettings> {
|
this: RippleAPI, address: string, options: SettingsOptions = {}
|
||||||
|
): Promise<FormattedSettings> {
|
||||||
|
// 1. Validate
|
||||||
validate.getSettings({address, options})
|
validate.getSettings({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',
|
||||||
signer_lists: true
|
signer_lists: true
|
||||||
}
|
})
|
||||||
|
// 3. Return Formatted Response
|
||||||
return this.connection.request(request).then(formatSettings)
|
return formatSettings(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default getSettings
|
export default getSettings
|
||||||
|
|||||||
@@ -1,144 +0,0 @@
|
|||||||
|
|
||||||
import {Amount, Memo} from '../common/types/objects'
|
|
||||||
|
|
||||||
export type Outcome = {
|
|
||||||
result: string,
|
|
||||||
ledgerVersion: number,
|
|
||||||
indexInLedger: number,
|
|
||||||
fee: string,
|
|
||||||
balanceChanges: {
|
|
||||||
[key: string]: [{
|
|
||||||
currency: string,
|
|
||||||
counterparty?: string,
|
|
||||||
value: string
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
orderbookChanges: Object,
|
|
||||||
timestamp?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Adjustment = {
|
|
||||||
address: string,
|
|
||||||
amount: {
|
|
||||||
currency: string,
|
|
||||||
counterparty?: string,
|
|
||||||
value: string
|
|
||||||
},
|
|
||||||
tag?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Trustline = {
|
|
||||||
currency: string,
|
|
||||||
counterparty: string,
|
|
||||||
limit: string,
|
|
||||||
qualityIn?: number,
|
|
||||||
qualityOut?: number,
|
|
||||||
ripplingDisabled?: boolean,
|
|
||||||
authorized?: boolean,
|
|
||||||
frozen?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Settings = {
|
|
||||||
passwordSpent?: boolean,
|
|
||||||
requireDestinationTag?: boolean,
|
|
||||||
requireAuthorization?: boolean,
|
|
||||||
depositAuthorization?: boolean,
|
|
||||||
disallowIncomingXRP?: boolean,
|
|
||||||
disableMasterKey?: boolean,
|
|
||||||
enableTransactionIDTracking?: boolean,
|
|
||||||
noFreeze?: boolean,
|
|
||||||
globalFreeze?: boolean,
|
|
||||||
defaultRipple?: boolean,
|
|
||||||
emailHash?: string,
|
|
||||||
messageKey?: string,
|
|
||||||
domain?: string,
|
|
||||||
transferRate?: number,
|
|
||||||
regularKey?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export type OrderCancellation = {
|
|
||||||
orderSequence: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Payment = {
|
|
||||||
source: Adjustment,
|
|
||||||
destination: Adjustment,
|
|
||||||
paths?: string,
|
|
||||||
memos?: Array<Memo>,
|
|
||||||
invoiceID?: string,
|
|
||||||
allowPartialPayment?: boolean,
|
|
||||||
noDirectRipple?: boolean,
|
|
||||||
limitQuality?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PaymentTransaction = {
|
|
||||||
type: string,
|
|
||||||
specification: Payment,
|
|
||||||
outcome: Outcome,
|
|
||||||
id: string,
|
|
||||||
address: string,
|
|
||||||
sequence: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Order = {
|
|
||||||
direction: string,
|
|
||||||
quantity: Amount,
|
|
||||||
totalPrice: Amount,
|
|
||||||
immediateOrCancel?: boolean,
|
|
||||||
fillOrKill?: boolean,
|
|
||||||
passive?: boolean,
|
|
||||||
expirationTime?: string,
|
|
||||||
orderToReplace?: number,
|
|
||||||
memos?: Memo[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type OrderTransaction = {
|
|
||||||
type: string,
|
|
||||||
specification: Order,
|
|
||||||
outcome: Outcome,
|
|
||||||
id: string,
|
|
||||||
address: string,
|
|
||||||
sequence: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type OrderCancellationTransaction = {
|
|
||||||
type: string,
|
|
||||||
specification: OrderCancellation,
|
|
||||||
outcome: Outcome,
|
|
||||||
id: string,
|
|
||||||
address: string,
|
|
||||||
sequence: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TrustlineTransaction = {
|
|
||||||
type: string,
|
|
||||||
specification: Trustline,
|
|
||||||
outcome: Outcome,
|
|
||||||
id: string,
|
|
||||||
address: string,
|
|
||||||
sequence: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SettingsTransaction = {
|
|
||||||
type: string,
|
|
||||||
specification: Settings,
|
|
||||||
outcome: Outcome,
|
|
||||||
id: string,
|
|
||||||
address: string,
|
|
||||||
sequence: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TransactionOptions = {
|
|
||||||
minLedgerVersion?: number,
|
|
||||||
maxLedgerVersion?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TransactionType = PaymentTransaction | OrderTransaction |
|
|
||||||
OrderCancellationTransaction | TrustlineTransaction | SettingsTransaction
|
|
||||||
|
|
||||||
export type TransactionResponse = TransactionType & {
|
|
||||||
hash: string,
|
|
||||||
ledger_index: number,
|
|
||||||
meta: any,
|
|
||||||
validated?: boolean
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,12 +3,22 @@ import * as utils from './utils'
|
|||||||
import parseTransaction from './parse/transaction'
|
import parseTransaction from './parse/transaction'
|
||||||
import {validate, errors} from '../common'
|
import {validate, errors} from '../common'
|
||||||
import {Connection} from '../common'
|
import {Connection} from '../common'
|
||||||
import {
|
import {FormattedTransactionType} from '../transaction/types'
|
||||||
TransactionType, TransactionResponse, TransactionOptions
|
|
||||||
} from './transaction-types'
|
export type TransactionOptions = {
|
||||||
|
minLedgerVersion?: number,
|
||||||
|
maxLedgerVersion?: number
|
||||||
|
}
|
||||||
|
type TransactionResponse = FormattedTransactionType & {
|
||||||
|
hash: string,
|
||||||
|
ledger_index: number,
|
||||||
|
meta: any,
|
||||||
|
validated?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function attachTransactionDate(connection: Connection, tx: any
|
function attachTransactionDate(connection: Connection, tx: any
|
||||||
): Promise<TransactionType> {
|
): Promise<FormattedTransactionType> {
|
||||||
if (tx.date) {
|
if (tx.date) {
|
||||||
return Promise.resolve(tx)
|
return Promise.resolve(tx)
|
||||||
}
|
}
|
||||||
@@ -71,7 +81,7 @@ function convertError(connection: Connection, options: TransactionOptions,
|
|||||||
}
|
}
|
||||||
|
|
||||||
function formatResponse(options: TransactionOptions, tx: TransactionResponse
|
function formatResponse(options: TransactionOptions, tx: TransactionResponse
|
||||||
): TransactionType {
|
): FormattedTransactionType {
|
||||||
if (tx.validated !== true || !isTransactionInRange(tx, options)) {
|
if (tx.validated !== true || !isTransactionInRange(tx, options)) {
|
||||||
throw new errors.NotFoundError('Transaction not found')
|
throw new errors.NotFoundError('Transaction not found')
|
||||||
}
|
}
|
||||||
@@ -79,7 +89,7 @@ function formatResponse(options: TransactionOptions, tx: TransactionResponse
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getTransaction(id: string, options: TransactionOptions = {}
|
function getTransaction(id: string, options: TransactionOptions = {}
|
||||||
): Promise<TransactionType> {
|
): Promise<FormattedTransactionType> {
|
||||||
validate.getTransaction({id, options})
|
validate.getTransaction({id, options})
|
||||||
|
|
||||||
const request = {
|
const request = {
|
||||||
|
|||||||
@@ -4,9 +4,8 @@ const {computeTransactionHash} = require('ripple-hashes')
|
|||||||
import * as utils from './utils'
|
import * as utils from './utils'
|
||||||
import parseTransaction from './parse/transaction'
|
import parseTransaction from './parse/transaction'
|
||||||
import getTransaction from './transaction'
|
import getTransaction from './transaction'
|
||||||
import {validate, errors} from '../common'
|
import {validate, errors, Connection} from '../common'
|
||||||
import {Connection} from '../common'
|
import {FormattedTransactionType} from '../transaction/types'
|
||||||
import {TransactionType} from './transaction-types'
|
|
||||||
|
|
||||||
|
|
||||||
export type TransactionsOptions = {
|
export type TransactionsOptions = {
|
||||||
@@ -20,10 +19,10 @@ export type TransactionsOptions = {
|
|||||||
counterparty?: string,
|
counterparty?: string,
|
||||||
types?: Array<string>,
|
types?: Array<string>,
|
||||||
binary?: boolean,
|
binary?: boolean,
|
||||||
startTx?: TransactionType
|
startTx?: FormattedTransactionType
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GetTransactionsResponse = Array<TransactionType>
|
export type GetTransactionsResponse = Array<FormattedTransactionType>
|
||||||
|
|
||||||
function parseBinaryTransaction(transaction) {
|
function parseBinaryTransaction(transaction) {
|
||||||
const tx = binary.decode(transaction.tx_blob)
|
const tx = binary.decode(transaction.tx_blob)
|
||||||
@@ -43,7 +42,7 @@ function parseAccountTxTransaction(tx) {
|
|||||||
{meta: _tx.meta, validated: _tx.validated}))
|
{meta: _tx.meta, validated: _tx.validated}))
|
||||||
}
|
}
|
||||||
|
|
||||||
function counterpartyFilter(filters, tx: TransactionType) {
|
function counterpartyFilter(filters, tx: FormattedTransactionType) {
|
||||||
if (tx.address === filters.counterparty) {
|
if (tx.address === filters.counterparty) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -57,7 +56,7 @@ function counterpartyFilter(filters, tx: TransactionType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function transactionFilter(address: string, filters: TransactionsOptions,
|
function transactionFilter(address: string, filters: TransactionsOptions,
|
||||||
tx: TransactionType
|
tx: FormattedTransactionType
|
||||||
) {
|
) {
|
||||||
if (filters.excludeFailures && tx.outcome.result !== 'tesSUCCESS') {
|
if (filters.excludeFailures && tx.outcome.result !== 'tesSUCCESS') {
|
||||||
return false
|
return false
|
||||||
@@ -77,7 +76,9 @@ function transactionFilter(address: string, filters: TransactionsOptions,
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
function orderFilter(options: TransactionsOptions, tx: TransactionType) {
|
function orderFilter(
|
||||||
|
options: TransactionsOptions, tx: FormattedTransactionType
|
||||||
|
) {
|
||||||
return !options.startTx || (options.earliestFirst ?
|
return !options.startTx || (options.earliestFirst ?
|
||||||
utils.compareTransactions(tx, options.startTx) > 0 :
|
utils.compareTransactions(tx, options.startTx) > 0 :
|
||||||
utils.compareTransactions(tx, options.startTx) < 0)
|
utils.compareTransactions(tx, options.startTx) < 0)
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
|
|
||||||
import {Amount} from '../common/types/objects'
|
|
||||||
|
|
||||||
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 = {
|
|
||||||
// TODO: properties in type don't match response object. Fix!
|
|
||||||
// accepted: boolean,
|
|
||||||
// closed: boolean,
|
|
||||||
stateHash: string,
|
|
||||||
closeTime: string,
|
|
||||||
closeTimeResolution: number,
|
|
||||||
closeFlags: number,
|
|
||||||
ledgerHash: string,
|
|
||||||
ledgerVersion: number,
|
|
||||||
parentLedgerHash: string,
|
|
||||||
parentCloseTime: string,
|
|
||||||
totalDrops: string,
|
|
||||||
transactionHash: string,
|
|
||||||
transactions?: Array<Object>,
|
|
||||||
rawTransactions?: string,
|
|
||||||
transactionHashes?: Array<string>,
|
|
||||||
rawState?: string,
|
|
||||||
stateHashes?: Array<string>
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@ import * as _ from 'lodash'
|
|||||||
import * as assert from 'assert'
|
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 {FormattedTransactionType} from '../transaction/types'
|
||||||
import {Issue} from '../common/types/objects'
|
import {Issue} from '../common/types/objects'
|
||||||
|
|
||||||
export type RecursiveData = {
|
export type RecursiveData = {
|
||||||
@@ -78,7 +78,8 @@ function signum(num) {
|
|||||||
* them based on TransactionIndex
|
* them based on TransactionIndex
|
||||||
* See: https://ripple.com/build/transactions/
|
* See: https://ripple.com/build/transactions/
|
||||||
*/
|
*/
|
||||||
function compareTransactions(first: TransactionType, second: TransactionType
|
function compareTransactions(
|
||||||
|
first: FormattedTransactionType, second: FormattedTransactionType
|
||||||
): number {
|
): number {
|
||||||
if (!first.outcome || !second.outcome) {
|
if (!first.outcome || !second.outcome) {
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -2,16 +2,18 @@ import * as _ from 'lodash'
|
|||||||
import * as utils from './utils'
|
import * as utils from './utils'
|
||||||
const offerFlags = utils.common.txFlags.OfferCreate
|
const offerFlags = utils.common.txFlags.OfferCreate
|
||||||
import {validate, iso8601ToRippleTime} from '../common'
|
import {validate, iso8601ToRippleTime} from '../common'
|
||||||
import {Instructions, Prepare} from './types'
|
import {Instructions, Prepare, OfferCreateTransaction} from './types'
|
||||||
import {Order} from '../ledger/transaction-types'
|
import {FormattedOrderSpecification} from '../common/types/objects/index'
|
||||||
|
|
||||||
function createOrderTransaction(account: string, order: Order): Object {
|
function createOrderTransaction(
|
||||||
|
account: string, order: FormattedOrderSpecification
|
||||||
|
): OfferCreateTransaction {
|
||||||
const takerPays = utils.common.toRippledAmount(order.direction === 'buy' ?
|
const takerPays = utils.common.toRippledAmount(order.direction === 'buy' ?
|
||||||
order.quantity : order.totalPrice)
|
order.quantity : order.totalPrice)
|
||||||
const takerGets = utils.common.toRippledAmount(order.direction === 'buy' ?
|
const takerGets = utils.common.toRippledAmount(order.direction === 'buy' ?
|
||||||
order.totalPrice : order.quantity)
|
order.totalPrice : order.quantity)
|
||||||
|
|
||||||
const txJSON: any = {
|
const txJSON: Partial<OfferCreateTransaction> = {
|
||||||
TransactionType: 'OfferCreate',
|
TransactionType: 'OfferCreate',
|
||||||
Account: account,
|
Account: account,
|
||||||
TakerGets: takerGets,
|
TakerGets: takerGets,
|
||||||
@@ -39,10 +41,10 @@ function createOrderTransaction(account: string, order: Order): Object {
|
|||||||
if (order.memos !== undefined) {
|
if (order.memos !== undefined) {
|
||||||
txJSON.Memos = _.map(order.memos, utils.convertMemo)
|
txJSON.Memos = _.map(order.memos, utils.convertMemo)
|
||||||
}
|
}
|
||||||
return txJSON
|
return txJSON as OfferCreateTransaction
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareOrder(address: string, order: Order,
|
function prepareOrder(address: string, order: FormattedOrderSpecification,
|
||||||
instructions: Instructions = {}
|
instructions: Instructions = {}
|
||||||
): Promise<Prepare> {
|
): Promise<Prepare> {
|
||||||
validate.prepareOrder({address, order, instructions})
|
validate.prepareOrder({address, order, instructions})
|
||||||
|
|||||||
@@ -6,36 +6,12 @@ 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/objects'
|
import {FormattedSettings, WeightedSigner} from '../common/types/objects'
|
||||||
|
|
||||||
export type WeightedSigner = {address: string, weight: number}
|
|
||||||
export type SettingsSigners = {
|
|
||||||
threshold?: number,
|
|
||||||
weights: WeightedSigner[]
|
|
||||||
}
|
|
||||||
export type Settings = {
|
|
||||||
passwordSpent?: boolean,
|
|
||||||
requireDestinationTag?: boolean,
|
|
||||||
requireAuthorization?: boolean,
|
|
||||||
disallowIncomingXRP?: boolean,
|
|
||||||
disableMasterKey?: boolean,
|
|
||||||
enableTransactionIDTracking?: boolean,
|
|
||||||
noFreeze?: boolean,
|
|
||||||
globalFreeze?: boolean,
|
|
||||||
defaultRipple?: boolean,
|
|
||||||
emailHash?: string,
|
|
||||||
messageKey?: string,
|
|
||||||
domain?: string,
|
|
||||||
transferRate?: number,
|
|
||||||
regularKey?: string,
|
|
||||||
signers?: SettingsSigners,
|
|
||||||
memos?: Memo[]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emptry string passed to setting will clear it
|
// Emptry string passed to setting will clear it
|
||||||
const CLEAR_SETTING = null
|
const CLEAR_SETTING = null
|
||||||
|
|
||||||
function setTransactionFlags(txJSON: any, values: Settings) {
|
function setTransactionFlags(txJSON: any, values: FormattedSettings) {
|
||||||
const keys = Object.keys(values)
|
const keys = Object.keys(values)
|
||||||
assert(keys.length === 1, 'ERROR: can only set one setting per transaction')
|
assert(keys.length === 1, 'ERROR: can only set one setting per transaction')
|
||||||
const flagName = keys[0]
|
const flagName = keys[0]
|
||||||
@@ -50,7 +26,7 @@ function setTransactionFlags(txJSON: any, values: Settings) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setTransactionFields(txJSON: Object, input: Settings) {
|
function setTransactionFields(txJSON: Object, input: FormattedSettings) {
|
||||||
const fieldSchema = AccountFields
|
const fieldSchema = AccountFields
|
||||||
for (const fieldName in fieldSchema) {
|
for (const fieldName in fieldSchema) {
|
||||||
const field = fieldSchema[fieldName]
|
const field = fieldSchema[fieldName]
|
||||||
@@ -101,7 +77,7 @@ function formatSignerEntry(signer: WeightedSigner): Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createSettingsTransactionWithoutMemos(
|
function createSettingsTransactionWithoutMemos(
|
||||||
account: string, settings: Settings
|
account: string, settings: FormattedSettings
|
||||||
): any {
|
): any {
|
||||||
if (settings.regularKey !== undefined) {
|
if (settings.regularKey !== undefined) {
|
||||||
const removeRegularKey = {
|
const removeRegularKey = {
|
||||||
@@ -137,7 +113,7 @@ function createSettingsTransactionWithoutMemos(
|
|||||||
return txJSON
|
return txJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
function createSettingsTransaction(account: string, settings: Settings
|
function createSettingsTransaction(account: string, settings: FormattedSettings
|
||||||
): Object {
|
): Object {
|
||||||
const txJSON = createSettingsTransactionWithoutMemos(account, settings)
|
const txJSON = createSettingsTransactionWithoutMemos(account, settings)
|
||||||
if (settings.memos !== undefined) {
|
if (settings.memos !== undefined) {
|
||||||
@@ -146,7 +122,7 @@ function createSettingsTransaction(account: string, settings: Settings
|
|||||||
return txJSON
|
return txJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareSettings(address: string, settings: Settings,
|
function prepareSettings(address: string, settings: FormattedSettings,
|
||||||
instructions: Instructions = {}
|
instructions: Instructions = {}
|
||||||
): Promise<Prepare> {
|
): Promise<Prepare> {
|
||||||
validate.prepareSettings({address, settings, instructions})
|
validate.prepareSettings({address, settings, instructions})
|
||||||
|
|||||||
@@ -1,4 +1,14 @@
|
|||||||
|
|
||||||
|
import {
|
||||||
|
FormattedOrderSpecification,
|
||||||
|
FormattedTrustline,
|
||||||
|
Adjustment,
|
||||||
|
RippledAmount,
|
||||||
|
Memo,
|
||||||
|
FormattedSettings
|
||||||
|
} from '../common/types/objects'
|
||||||
|
import {ApiMemo} from './utils'
|
||||||
|
|
||||||
export type Instructions = {
|
export type Instructions = {
|
||||||
sequence?: number,
|
sequence?: number,
|
||||||
fee?: string,
|
fee?: string,
|
||||||
@@ -25,3 +35,100 @@ export type Submit = {
|
|||||||
txBlob?: string,
|
txBlob?: string,
|
||||||
txJson?: Object
|
txJson?: Object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface OfferCreateTransaction {
|
||||||
|
TransactionType: 'OfferCreate',
|
||||||
|
Account: string,
|
||||||
|
Fee: string,
|
||||||
|
Flags: number,
|
||||||
|
LastLedgerSequence: number,
|
||||||
|
Sequence: number,
|
||||||
|
TakerGets: RippledAmount,
|
||||||
|
TakerPays: RippledAmount,
|
||||||
|
Expiration?: number,
|
||||||
|
OfferSequence?: number,
|
||||||
|
Memos: {Memo: ApiMemo}[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Outcome = {
|
||||||
|
result: string,
|
||||||
|
ledgerVersion: number,
|
||||||
|
indexInLedger: number,
|
||||||
|
fee: string,
|
||||||
|
balanceChanges: {
|
||||||
|
[key: string]: [{
|
||||||
|
currency: string,
|
||||||
|
counterparty?: string,
|
||||||
|
value: string
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
orderbookChanges: Object,
|
||||||
|
timestamp?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FormattedOrderCancellation = {
|
||||||
|
orderSequence: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FormattedPayment = {
|
||||||
|
source: Adjustment,
|
||||||
|
destination: Adjustment,
|
||||||
|
paths?: string,
|
||||||
|
memos?: Array<Memo>,
|
||||||
|
invoiceID?: string,
|
||||||
|
allowPartialPayment?: boolean,
|
||||||
|
noDirectRipple?: boolean,
|
||||||
|
limitQuality?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FormattedPaymentTransaction = {
|
||||||
|
type: string,
|
||||||
|
specification: FormattedPayment,
|
||||||
|
outcome: Outcome,
|
||||||
|
id: string,
|
||||||
|
address: string,
|
||||||
|
sequence: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FormattedOrderTransaction = {
|
||||||
|
type: string,
|
||||||
|
specification: FormattedOrderSpecification,
|
||||||
|
outcome: Outcome,
|
||||||
|
id: string,
|
||||||
|
address: string,
|
||||||
|
sequence: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FormattedOrderCancellationTransaction = {
|
||||||
|
type: string,
|
||||||
|
specification: FormattedOrderCancellation,
|
||||||
|
outcome: Outcome,
|
||||||
|
id: string,
|
||||||
|
address: string,
|
||||||
|
sequence: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FormattedTrustlineTransaction = {
|
||||||
|
type: string,
|
||||||
|
specification: FormattedTrustline,
|
||||||
|
outcome: Outcome,
|
||||||
|
id: string,
|
||||||
|
address: string,
|
||||||
|
sequence: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FormattedSettingsTransaction = {
|
||||||
|
type: string,
|
||||||
|
specification: FormattedSettings,
|
||||||
|
outcome: Outcome,
|
||||||
|
id: string,
|
||||||
|
address: string,
|
||||||
|
sequence: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FormattedTransactionType =
|
||||||
|
FormattedPaymentTransaction |
|
||||||
|
FormattedOrderTransaction |
|
||||||
|
FormattedOrderCancellationTransaction |
|
||||||
|
FormattedTrustlineTransaction |
|
||||||
|
FormattedSettingsTransaction
|
||||||
|
|||||||
@@ -1124,9 +1124,11 @@ describe('RippleAPI', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('getSettings - invalid options', function () {
|
it('getSettings - invalid options', function () {
|
||||||
assert.throws(() => {
|
return this.api.getSettings(address, { invalid: 'options' }).then(() => {
|
||||||
this.api.getSettings(address, { invalid: 'options' });
|
assert(false, 'Should throw ValidationError');
|
||||||
}, this.api.errors.ValidationError);
|
}).catch(error => {
|
||||||
|
assert(error instanceof this.api.errors.ValidationError);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('getAccountInfo', function () {
|
it('getAccountInfo', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user