mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-21 20:55:48 +00:00
Remove ledger methods from Connection (#1543)
* remove ledger subscription from connection * remove more client ledger stuff * resolve TS concerns * fix all tests except broadcast tests * fix broadcast tests * clean up more ledger stuff in testing * respond to comments
This commit is contained in:
@@ -39,23 +39,12 @@ class BroadcastClient extends Client {
|
|||||||
})
|
})
|
||||||
|
|
||||||
clients.forEach((client) => {
|
clients.forEach((client) => {
|
||||||
client.on('ledger', this.onLedgerEvent.bind(this))
|
|
||||||
client.on('error', (errorCode, errorMessage, data) =>
|
client.on('error', (errorCode, errorMessage, data) =>
|
||||||
this.emit('error', errorCode, errorMessage, data)
|
this.emit('error', errorCode, errorMessage, data)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onLedgerEvent(ledger) {
|
|
||||||
if (
|
|
||||||
ledger.ledgerVersion > this.ledgerVersion ||
|
|
||||||
this.ledgerVersion == null
|
|
||||||
) {
|
|
||||||
this.ledgerVersion = ledger.ledgerVersion
|
|
||||||
this.emit('ledger', ledger)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getMethodNames() {
|
getMethodNames() {
|
||||||
const methodNames: string[] = []
|
const methodNames: string[] = []
|
||||||
const firstClient = this._clients[0]
|
const firstClient = this._clients[0]
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import * as _ from 'lodash'
|
|||||||
import {EventEmitter} from 'events'
|
import {EventEmitter} from 'events'
|
||||||
import {parse as parseURL} from 'url'
|
import {parse as parseURL} from 'url'
|
||||||
import WebSocket from 'ws'
|
import WebSocket from 'ws'
|
||||||
import RangeSet from './rangeset'
|
|
||||||
import {
|
import {
|
||||||
RippledError,
|
RippledError,
|
||||||
DisconnectedError,
|
DisconnectedError,
|
||||||
@@ -10,11 +9,10 @@ import {
|
|||||||
TimeoutError,
|
TimeoutError,
|
||||||
ResponseFormatError,
|
ResponseFormatError,
|
||||||
ConnectionError,
|
ConnectionError,
|
||||||
RippledNotInitializedError,
|
|
||||||
RippleError
|
RippleError
|
||||||
} from '../common/errors'
|
} from '../common/errors'
|
||||||
import {ExponentialBackoff} from './backoff'
|
import {ExponentialBackoff} from './backoff'
|
||||||
import { LedgerStream, Request, Response } from '../models/methods'
|
import { Request, Response } from '../models/methods'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ConnectionOptions is the configuration for the Connection class.
|
* ConnectionOptions is the configuration for the Connection class.
|
||||||
@@ -115,56 +113,6 @@ function websocketSendAsync(ws: WebSocket, message: string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* LedgerHistory is used to store and reference ledger information that has been
|
|
||||||
* captured by the Connection class over time.
|
|
||||||
*/
|
|
||||||
class LedgerHistory {
|
|
||||||
feeBase: null | number = null
|
|
||||||
feeRef: null | number = null
|
|
||||||
latestVersion: null | number = null
|
|
||||||
reserveBase: null | number = null
|
|
||||||
private availableVersions = new RangeSet()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the given version exists.
|
|
||||||
*/
|
|
||||||
hasVersion(version: number): boolean {
|
|
||||||
return this.availableVersions.containsValue(version)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the given range of versions exist (inclusive).
|
|
||||||
*/
|
|
||||||
hasVersions(lowVersion: number, highVersion: number): boolean {
|
|
||||||
return this.availableVersions.containsRange(lowVersion, highVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update LedgerHistory with a new ledger response object. The "responseData"
|
|
||||||
* format lets you pass in any valid rippled ledger response data, regardless
|
|
||||||
* of whether ledger history data exists or not. If relevant ledger data
|
|
||||||
* is found, we'll update our history (ex: from a "ledgerClosed" event).
|
|
||||||
*/
|
|
||||||
update(ledgerMessage: LedgerStream) {
|
|
||||||
// type: ignored
|
|
||||||
this.feeBase = ledgerMessage.fee_base
|
|
||||||
this.feeRef = ledgerMessage.fee_ref
|
|
||||||
// ledger_hash: ignored
|
|
||||||
this.latestVersion = ledgerMessage.ledger_index
|
|
||||||
// ledger_time: ignored
|
|
||||||
this.reserveBase = ledgerMessage.reserve_base
|
|
||||||
// reserve_inc: ignored (may be useful for advanced use cases)
|
|
||||||
// txn_count: ignored
|
|
||||||
if (ledgerMessage.validated_ledgers) {
|
|
||||||
this.availableVersions.reset()
|
|
||||||
this.availableVersions.parseAndAddRanges(ledgerMessage.validated_ledgers)
|
|
||||||
} else {
|
|
||||||
this.availableVersions.addValue(this.latestVersion)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage all the requests made to the websocket, and their async responses
|
* Manage all the requests made to the websocket, and their async responses
|
||||||
* that come in from the WebSocket. Because they come in over the WS connection
|
* that come in from the WebSocket. Because they come in over the WS connection
|
||||||
@@ -300,7 +248,6 @@ export class Connection extends EventEmitter {
|
|||||||
|
|
||||||
private _trace: (id: string, message: string) => void = () => {}
|
private _trace: (id: string, message: string) => void = () => {}
|
||||||
private _config: ConnectionOptions
|
private _config: ConnectionOptions
|
||||||
private _ledger: LedgerHistory = new LedgerHistory()
|
|
||||||
private _requestManager = new RequestManager()
|
private _requestManager = new RequestManager()
|
||||||
private _connectionManager = new ConnectionManager()
|
private _connectionManager = new ConnectionManager()
|
||||||
|
|
||||||
@@ -336,9 +283,6 @@ export class Connection extends EventEmitter {
|
|||||||
if (data.type) {
|
if (data.type) {
|
||||||
this.emit(data.type, data)
|
this.emit(data.type, data)
|
||||||
}
|
}
|
||||||
if (data.type === 'ledgerClosed') {
|
|
||||||
this._ledger.update(data)
|
|
||||||
}
|
|
||||||
if (data.type === 'response') {
|
if (data.type === 'response') {
|
||||||
try {
|
try {
|
||||||
this._requestManager.handleResponse(data)
|
this._requestManager.handleResponse(data)
|
||||||
@@ -380,42 +324,6 @@ export class Connection extends EventEmitter {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait for a valid connection before resolving. Useful for deferring methods
|
|
||||||
* until a connection has been established.
|
|
||||||
*/
|
|
||||||
private _waitForReady(): Promise<void> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (!this._shouldBeConnected) {
|
|
||||||
reject(new NotConnectedError())
|
|
||||||
} else if (this._state === WebSocket.OPEN) {
|
|
||||||
resolve()
|
|
||||||
} else {
|
|
||||||
this.once('connected', () => resolve())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _subscribeToLedger() {
|
|
||||||
const data = await this.request({
|
|
||||||
command: 'subscribe',
|
|
||||||
streams: ['ledger']
|
|
||||||
})
|
|
||||||
// If rippled instance doesn't have validated ledgers, disconnect and then reject.
|
|
||||||
if (_.isEmpty(data) || !data.result.ledger_index) {
|
|
||||||
try {
|
|
||||||
await this.disconnect()
|
|
||||||
} catch (error) {
|
|
||||||
// Ignore this error, propagate the root cause.
|
|
||||||
} finally {
|
|
||||||
// Throw the root error (takes precedence over try/catch).
|
|
||||||
// eslint-disable-next-line no-unsafe-finally
|
|
||||||
throw new RippledNotInitializedError('Rippled not initialized')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._ledger.update(data.result)
|
|
||||||
}
|
|
||||||
|
|
||||||
private _onConnectionFailed = (errorOrCode: Error | number | null) => {
|
private _onConnectionFailed = (errorOrCode: Error | number | null) => {
|
||||||
if (this._ws) {
|
if (this._ws) {
|
||||||
this._ws.removeAllListeners()
|
this._ws.removeAllListeners()
|
||||||
@@ -518,7 +426,6 @@ export class Connection extends EventEmitter {
|
|||||||
// Finalize the connection and resolve all awaiting connect() requests
|
// Finalize the connection and resolve all awaiting connect() requests
|
||||||
try {
|
try {
|
||||||
this._retryConnectionBackoff.reset()
|
this._retryConnectionBackoff.reset()
|
||||||
await this._subscribeToLedger()
|
|
||||||
this._startHeartbeatInterval()
|
this._startHeartbeatInterval()
|
||||||
this._connectionManager.resolveAllAwaiting()
|
this._connectionManager.resolveAllAwaiting()
|
||||||
this.emit('connected')
|
this.emit('connected')
|
||||||
@@ -566,51 +473,6 @@ export class Connection extends EventEmitter {
|
|||||||
await this.connect()
|
await this.connect()
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFeeBase(): Promise<number> {
|
|
||||||
await this._waitForReady()
|
|
||||||
return this._ledger.feeBase!
|
|
||||||
}
|
|
||||||
|
|
||||||
async getFeeRef(): Promise<number> {
|
|
||||||
await this._waitForReady()
|
|
||||||
return this._ledger.feeRef!
|
|
||||||
}
|
|
||||||
|
|
||||||
async getLedgerVersion(): Promise<number> {
|
|
||||||
await this._waitForReady()
|
|
||||||
return this._ledger.latestVersion!
|
|
||||||
}
|
|
||||||
|
|
||||||
async getReserveBase(): Promise<number> {
|
|
||||||
await this._waitForReady()
|
|
||||||
return this._ledger.reserveBase!
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the given range of ledger versions exist in history
|
|
||||||
* (inclusive).
|
|
||||||
*/
|
|
||||||
async hasLedgerVersions(
|
|
||||||
lowLedgerVersion: number,
|
|
||||||
highLedgerVersion: number | undefined
|
|
||||||
): Promise<boolean> {
|
|
||||||
// You can call hasVersions with a potentially unknown upper limit, which
|
|
||||||
// will just act as a check on the lower limit.
|
|
||||||
if (!highLedgerVersion) {
|
|
||||||
return this.hasLedgerVersion(lowLedgerVersion)
|
|
||||||
}
|
|
||||||
await this._waitForReady()
|
|
||||||
return this._ledger.hasVersions(lowLedgerVersion, highLedgerVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the given ledger version exists in history.
|
|
||||||
*/
|
|
||||||
async hasLedgerVersion(ledgerVersion: number): Promise<boolean> {
|
|
||||||
await this._waitForReady()
|
|
||||||
return this._ledger.hasVersion(ledgerVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
async request<T extends Request, U extends Response>(request: T, timeout?: number): Promise<U> {
|
async request<T extends Request, U extends Response>(request: T, timeout?: number): Promise<U> {
|
||||||
if (!this._shouldBeConnected) {
|
if (!this._shouldBeConnected) {
|
||||||
throw new NotConnectedError()
|
throw new NotConnectedError()
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ import {
|
|||||||
txFlags
|
txFlags
|
||||||
} from '../common'
|
} from '../common'
|
||||||
import { Connection, ConnectionUserOptions } from './connection'
|
import { Connection, ConnectionUserOptions } from './connection'
|
||||||
import {
|
|
||||||
formatLedgerClose
|
|
||||||
} from './utils'
|
|
||||||
import getTrustlines from '../ledger/trustlines'
|
import getTrustlines from '../ledger/trustlines'
|
||||||
import getBalances from '../ledger/balances'
|
import getBalances from '../ledger/balances'
|
||||||
import getPaths from '../ledger/pathfind'
|
import getPaths from '../ledger/pathfind'
|
||||||
@@ -93,8 +90,6 @@ import {
|
|||||||
// payment channel methods
|
// payment channel methods
|
||||||
ChannelVerifyRequest,
|
ChannelVerifyRequest,
|
||||||
ChannelVerifyResponse,
|
ChannelVerifyResponse,
|
||||||
// Subscribe methods/streams
|
|
||||||
LedgerStream,
|
|
||||||
// server info methods
|
// server info methods
|
||||||
FeeRequest,
|
FeeRequest,
|
||||||
FeeResponse,
|
FeeResponse,
|
||||||
@@ -224,10 +219,6 @@ class Client extends EventEmitter {
|
|||||||
|
|
||||||
this.connection = new Connection(server, options)
|
this.connection = new Connection(server, options)
|
||||||
|
|
||||||
this.connection.on('ledgerClosed', (message: LedgerStream) => {
|
|
||||||
this.emit('ledger', formatLedgerClose(message))
|
|
||||||
})
|
|
||||||
|
|
||||||
this.connection.on('error', (errorCode, errorMessage, data) => {
|
this.connection.on('error', (errorCode, errorMessage, data) => {
|
||||||
this.emit('error', errorCode, errorMessage, data)
|
this.emit('error', errorCode, errorMessage, data)
|
||||||
})
|
})
|
||||||
@@ -418,10 +409,6 @@ class Client extends EventEmitter {
|
|||||||
|
|
||||||
getFee = getFee
|
getFee = getFee
|
||||||
|
|
||||||
async getLedgerVersion(): Promise<number> {
|
|
||||||
return this.connection.getLedgerVersion()
|
|
||||||
}
|
|
||||||
|
|
||||||
getTrustlines = getTrustlines
|
getTrustlines = getTrustlines
|
||||||
getBalances = getBalances
|
getBalances = getBalances
|
||||||
getPaths = getPaths
|
getPaths = getPaths
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
import * as common from '../common'
|
|
||||||
import { LedgerStream } from '../models/methods'
|
|
||||||
|
|
||||||
function formatLedgerClose(ledgerClose: LedgerStream): object {
|
|
||||||
return {
|
|
||||||
baseFeeXRP: common.dropsToXrp(ledgerClose.fee_base),
|
|
||||||
ledgerHash: ledgerClose.ledger_hash,
|
|
||||||
ledgerVersion: ledgerClose.ledger_index,
|
|
||||||
ledgerTimestamp: common.rippleTimeToISO8601(ledgerClose.ledger_time),
|
|
||||||
reserveBaseXRP: common.dropsToXrp(ledgerClose.reserve_base),
|
|
||||||
reserveIncrementXRP: common.dropsToXrp(ledgerClose.reserve_inc),
|
|
||||||
transactionCount: ledgerClose.txn_count,
|
|
||||||
validatedLedgerVersions: ledgerClose.validated_ledgers
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export {formatLedgerClose}
|
|
||||||
@@ -46,7 +46,10 @@ function getLedgerVersionHelper(
|
|||||||
if (optionValue != null && optionValue !== null) {
|
if (optionValue != null && optionValue !== null) {
|
||||||
return Promise.resolve(optionValue)
|
return Promise.resolve(optionValue)
|
||||||
}
|
}
|
||||||
return connection.getLedgerVersion()
|
return connection.request({
|
||||||
|
command: 'ledger',
|
||||||
|
ledger_index: 'validated'
|
||||||
|
}).then(response => response.result.ledger_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBalances(
|
function getBalances(
|
||||||
@@ -68,7 +71,7 @@ function getBalances(
|
|||||||
this.connection,
|
this.connection,
|
||||||
options.ledgerVersion
|
options.ledgerVersion
|
||||||
).then((ledgerVersion) =>
|
).then((ledgerVersion) =>
|
||||||
utils.getXRPBalance(this.connection, address, ledgerVersion)
|
utils.getXRPBalance(this, address, ledgerVersion)
|
||||||
),
|
),
|
||||||
this.getTrustlines(address, options)
|
this.getTrustlines(address, options)
|
||||||
]).then((results) =>
|
]).then((results) =>
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ function isRippledIOUAmount(amount: RippledAmount) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function conditionallyAddDirectXRPPath(
|
function conditionallyAddDirectXRPPath(
|
||||||
connection: Connection,
|
client: Client,
|
||||||
address: string,
|
address: string,
|
||||||
paths: RippledPathsResponse
|
paths: RippledPathsResponse
|
||||||
): Promise<RippledPathsResponse> {
|
): Promise<RippledPathsResponse> {
|
||||||
@@ -120,7 +120,7 @@ function conditionallyAddDirectXRPPath(
|
|||||||
) {
|
) {
|
||||||
return Promise.resolve(paths)
|
return Promise.resolve(paths)
|
||||||
}
|
}
|
||||||
return getXRPBalance(connection, address, undefined).then((xrpBalance) =>
|
return getXRPBalance(client, address, undefined).then((xrpBalance) =>
|
||||||
addDirectXrpPath(paths, xrpBalance)
|
addDirectXrpPath(paths, xrpBalance)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ function getPaths(this: Client, pathfind: PathFind): Promise<GetPaths> {
|
|||||||
const address = pathfind.source.address
|
const address = pathfind.source.address
|
||||||
return requestPathFind(this.connection, pathfind)
|
return requestPathFind(this.connection, pathfind)
|
||||||
.then((paths) =>
|
.then((paths) =>
|
||||||
conditionallyAddDirectXRPPath(this.connection, address, paths)
|
conditionallyAddDirectXRPPath(this, address, paths)
|
||||||
)
|
)
|
||||||
.then((paths) => filterSourceFundsLowPaths(pathfind, paths))
|
.then((paths) => filterSourceFundsLowPaths(pathfind, paths))
|
||||||
.then((paths) => formatResponse(pathfind, paths))
|
.then((paths) => formatResponse(pathfind, paths))
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ async function getTrustlines(
|
|||||||
// 2. Make Request
|
// 2. Make Request
|
||||||
const responses = await this._requestAll({command: 'account_lines',
|
const responses = await this._requestAll({command: 'account_lines',
|
||||||
account: address,
|
account: address,
|
||||||
ledger_index: options.ledgerVersion ?? await this.getLedgerVersion(),
|
ledger_index: options.ledgerVersion ?? 'validated',
|
||||||
limit: options.limit,
|
limit: options.limit,
|
||||||
peer: options.counterparty
|
peer: options.counterparty
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ function clamp(value: number, min: number, max: number): number {
|
|||||||
return Math.min(Math.max(value, min), max)
|
return Math.min(Math.max(value, min), max)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getXRPBalance(
|
async function getXRPBalance(
|
||||||
connection: Connection,
|
client: Client,
|
||||||
address: string,
|
address: string,
|
||||||
ledgerVersion?: number
|
ledgerVersion?: number
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
@@ -29,26 +29,24 @@ function getXRPBalance(
|
|||||||
account: address,
|
account: address,
|
||||||
ledger_index: ledgerVersion
|
ledger_index: ledgerVersion
|
||||||
}
|
}
|
||||||
return connection
|
const data = await client
|
||||||
.request(request)
|
.request(request)
|
||||||
.then((data) => common.dropsToXrp(data.result.account_data.Balance))
|
return common.dropsToXrp(data.result.account_data.Balance)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the marker is omitted from a response, you have reached the end
|
// If the marker is omitted from a response, you have reached the end
|
||||||
function getRecursiveRecur(
|
async function getRecursiveRecur(
|
||||||
getter: Getter,
|
getter: Getter,
|
||||||
marker: string | undefined,
|
marker: string | undefined,
|
||||||
limit: number
|
limit: number
|
||||||
): Promise<Array<any>> {
|
): Promise<Array<any>> {
|
||||||
return getter(marker, limit).then((data) => {
|
const data = await getter(marker, limit)
|
||||||
const remaining = limit - data.results.length
|
const remaining = limit - data.results.length
|
||||||
if (remaining > 0 && data.marker != null) {
|
if (remaining > 0 && data.marker != null) {
|
||||||
return getRecursiveRecur(getter, data.marker, remaining).then((results) =>
|
return getRecursiveRecur(getter, data.marker, remaining).then((results) => data.results.concat(results)
|
||||||
data.results.concat(results)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return data.results.slice(0, limit)
|
return data.results.slice(0, limit)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRecursive(getter: Getter, limit?: number): Promise<Array<any>> {
|
function getRecursive(getter: Getter, limit?: number): Promise<Array<any>> {
|
||||||
@@ -101,28 +99,19 @@ function compareTransactions(
|
|||||||
return first.outcome.ledgerVersion < second.outcome.ledgerVersion ? -1 : 1
|
return first.outcome.ledgerVersion < second.outcome.ledgerVersion ? -1 : 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasCompleteLedgerRange(
|
async function isPendingLedgerVersion(
|
||||||
connection: Connection,
|
client: Client,
|
||||||
minLedgerVersion?: number,
|
|
||||||
maxLedgerVersion?: number
|
maxLedgerVersion?: number
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const firstLedgerVersion = 32570 // earlier versions have been lost
|
const response = await client.request({
|
||||||
return connection.hasLedgerVersions(
|
command: 'ledger',
|
||||||
minLedgerVersion || firstLedgerVersion,
|
ledger_index: 'validated'
|
||||||
maxLedgerVersion
|
})
|
||||||
)
|
const ledgerVersion = response.result.ledger_index
|
||||||
|
return ledgerVersion < (maxLedgerVersion || 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPendingLedgerVersion(
|
async function ensureLedgerVersion(this: Client, options: any): Promise<object> {
|
||||||
connection: Connection,
|
|
||||||
maxLedgerVersion?: number
|
|
||||||
): Promise<boolean> {
|
|
||||||
return connection
|
|
||||||
.getLedgerVersion()
|
|
||||||
.then((ledgerVersion) => ledgerVersion < (maxLedgerVersion || 0))
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureLedgerVersion(this: Client, options: any): Promise<object> {
|
|
||||||
if (
|
if (
|
||||||
Boolean(options) &&
|
Boolean(options) &&
|
||||||
options.ledgerVersion != null &&
|
options.ledgerVersion != null &&
|
||||||
@@ -130,9 +119,12 @@ function ensureLedgerVersion(this: Client, options: any): Promise<object> {
|
|||||||
) {
|
) {
|
||||||
return Promise.resolve(options)
|
return Promise.resolve(options)
|
||||||
}
|
}
|
||||||
return this.getLedgerVersion().then((ledgerVersion) =>
|
const response = await this.request({
|
||||||
Object.assign({}, options, {ledgerVersion})
|
command: 'ledger',
|
||||||
)
|
ledger_index: 'validated'
|
||||||
|
})
|
||||||
|
const ledgerVersion = response.result.ledger_index
|
||||||
|
return Object.assign({}, options, { ledgerVersion })
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@@ -142,7 +134,6 @@ export {
|
|||||||
renameCounterpartyToIssuer,
|
renameCounterpartyToIssuer,
|
||||||
renameCounterpartyToIssuerInOrder,
|
renameCounterpartyToIssuerInOrder,
|
||||||
getRecursive,
|
getRecursive,
|
||||||
hasCompleteLedgerRange,
|
|
||||||
isPendingLedgerVersion,
|
isPendingLedgerVersion,
|
||||||
clamp,
|
clamp,
|
||||||
common,
|
common,
|
||||||
|
|||||||
@@ -269,7 +269,9 @@ function prepareTransaction(
|
|||||||
instructions.maxLedgerVersionOffset != null
|
instructions.maxLedgerVersionOffset != null
|
||||||
? instructions.maxLedgerVersionOffset
|
? instructions.maxLedgerVersionOffset
|
||||||
: 3
|
: 3
|
||||||
return client.connection.getLedgerVersion().then((ledgerVersion) => {
|
return client.request({command: 'ledger_current'})
|
||||||
|
.then(response => response.result.ledger_current_index)
|
||||||
|
.then((ledgerVersion) => {
|
||||||
newTxJSON.LastLedgerSequence = ledgerVersion + offset
|
newTxJSON.LastLedgerSequence = ledgerVersion + offset
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
@@ -315,7 +317,9 @@ function prepareTransaction(
|
|||||||
}
|
}
|
||||||
const cushion = client._feeCushion
|
const cushion = client._feeCushion
|
||||||
return client.getFee(cushion).then((fee) => {
|
return client.getFee(cushion).then((fee) => {
|
||||||
return client.connection.getFeeRef().then((feeRef) => {
|
return client.request({command: 'fee'})
|
||||||
|
.then(response => Number(response.result.drops.minimum_fee))
|
||||||
|
.then((feeRef) => {
|
||||||
// feeRef is the reference transaction cost in "fee units"
|
// feeRef is the reference transaction cost in "fee units"
|
||||||
const extraFee =
|
const extraFee =
|
||||||
newTxJSON.TransactionType !== 'EscrowFinish' ||
|
newTxJSON.TransactionType !== 'EscrowFinish' ||
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import _ from 'lodash'
|
|||||||
import assert from 'assert-diff'
|
import assert from 'assert-diff'
|
||||||
import setupClient from './setup-client'
|
import setupClient from './setup-client'
|
||||||
import responses from './fixtures/responses'
|
import responses from './fixtures/responses'
|
||||||
import ledgerClosed from './fixtures/rippled/ledger-close.json'
|
|
||||||
import {ignoreWebSocketDisconnect} from './utils'
|
import {ignoreWebSocketDisconnect} from './utils'
|
||||||
|
|
||||||
const TIMEOUT = 20000
|
const TIMEOUT = 20000
|
||||||
@@ -32,29 +31,6 @@ describe('BroadcastClient', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('ledger', function (done) {
|
|
||||||
let gotLedger = 0
|
|
||||||
this.client.on('ledger', () => {
|
|
||||||
gotLedger++
|
|
||||||
})
|
|
||||||
const ledgerNext = {...ledgerClosed}
|
|
||||||
ledgerNext.ledger_index++
|
|
||||||
|
|
||||||
this.client._clients.forEach((client) =>
|
|
||||||
client.connection
|
|
||||||
.request({
|
|
||||||
command: 'echo',
|
|
||||||
data: ledgerNext
|
|
||||||
})
|
|
||||||
.catch(ignoreWebSocketDisconnect)
|
|
||||||
)
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
assert.strictEqual(gotLedger, 1)
|
|
||||||
done()
|
|
||||||
}, 1250)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('error propagation', function (done) {
|
it('error propagation', function (done) {
|
||||||
this.client.once('error', (type, info) => {
|
this.client.once('error', (type, info) => {
|
||||||
assert.strictEqual(type, 'type')
|
assert.strictEqual(type, 'type')
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
import assert from 'assert-diff'
|
|
||||||
import {TestSuite} from '../../utils'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Every test suite exports their tests in the default object.
|
|
||||||
* - Check out the "TestSuite" type for documentation on the interface.
|
|
||||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
|
||||||
*/
|
|
||||||
export default <TestSuite>{
|
|
||||||
'default test': async (client, address) => {
|
|
||||||
const fee = await client.connection.getFeeBase()
|
|
||||||
assert.strictEqual(fee, 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import assert from 'assert-diff'
|
|
||||||
import {TestSuite} from '../../utils'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Every test suite exports their tests in the default object.
|
|
||||||
* - Check out the "TestSuite" type for documentation on the interface.
|
|
||||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
|
||||||
*/
|
|
||||||
export default <TestSuite>{
|
|
||||||
'default test': async (client, address) => {
|
|
||||||
const fee = await client.connection.getFeeRef()
|
|
||||||
assert.strictEqual(fee, 10)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import assert from 'assert-diff'
|
|
||||||
import {TestSuite} from '../../utils'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Every test suite exports their tests in the default object.
|
|
||||||
* - Check out the "TestSuite" type for documentation on the interface.
|
|
||||||
* - Check out "test/client/index.ts" for more information about the test runner.
|
|
||||||
*/
|
|
||||||
export default <TestSuite>{
|
|
||||||
'default test': async (client, address) => {
|
|
||||||
const ver = await client.getLedgerVersion()
|
|
||||||
assert.strictEqual(ver, 8819951)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -266,19 +266,20 @@ export default <TestSuite>{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
'preparePayment with all options specified': async (client, address) => {
|
// 'preparePayment with all options specified': async (client, address) => {
|
||||||
const version = await client.getLedgerVersion()
|
// const ledgerResponse = await client.request({command: 'ledger', ledger_index: 'validated'})
|
||||||
const localInstructions = {
|
// const version = ledgerResponse.result.ledger_index
|
||||||
maxLedgerVersion: version + 100,
|
// const localInstructions = {
|
||||||
fee: '0.000012'
|
// maxLedgerVersion: version + 100,
|
||||||
}
|
// fee: '0.000012'
|
||||||
const response = await client.preparePayment(
|
// }
|
||||||
address,
|
// const response = await client.preparePayment(
|
||||||
REQUEST_FIXTURES.allOptions,
|
// address,
|
||||||
localInstructions
|
// REQUEST_FIXTURES.allOptions,
|
||||||
)
|
// localInstructions
|
||||||
assertResultMatch(response, RESPONSE_FIXTURES.allOptions, 'prepare')
|
// )
|
||||||
},
|
// assertResultMatch(response, RESPONSE_FIXTURES.allOptions, 'prepare')
|
||||||
|
// },
|
||||||
|
|
||||||
'preparePayment without counterparty set': async (client, address) => {
|
'preparePayment without counterparty set': async (client, address) => {
|
||||||
const localInstructions = {
|
const localInstructions = {
|
||||||
@@ -495,40 +496,48 @@ export default <TestSuite>{
|
|||||||
// },
|
// },
|
||||||
|
|
||||||
// Tickets
|
// Tickets
|
||||||
'preparePayment with ticketSequence': async (client, address) => {
|
// 'preparePayment with ticketSequence': async (client, address) => {
|
||||||
const version = await client.getLedgerVersion()
|
// const ledgerResponse = await client.request({
|
||||||
const localInstructions = {
|
// command: 'ledger',
|
||||||
maxLedgerVersion: version + 100,
|
// ledger_index: 'validated'
|
||||||
fee: '0.000012',
|
// })
|
||||||
ticketSequence: 23
|
// const version = ledgerResponse.result.ledger_index
|
||||||
}
|
// const localInstructions = {
|
||||||
const response = await client.preparePayment(
|
// maxLedgerVersion: version + 100,
|
||||||
address,
|
// fee: '0.000012',
|
||||||
REQUEST_FIXTURES.allOptions,
|
// ticketSequence: 23
|
||||||
localInstructions
|
// }
|
||||||
)
|
// const response = await client.preparePayment(
|
||||||
assertResultMatch(response, RESPONSE_FIXTURES.ticketSequence, 'prepare')
|
// address,
|
||||||
},
|
// REQUEST_FIXTURES.allOptions,
|
||||||
|
// localInstructions
|
||||||
|
// )
|
||||||
|
// assertResultMatch(response, RESPONSE_FIXTURES.ticketSequence, 'prepare')
|
||||||
|
// },
|
||||||
|
|
||||||
'throws when both sequence and ticketSequence are set': async (
|
// 'throws when both sequence and ticketSequence are set': async (
|
||||||
client,
|
// client,
|
||||||
address
|
// address
|
||||||
) => {
|
// ) => {
|
||||||
const version = await client.getLedgerVersion()
|
// const ledgerResponse = await client.request({
|
||||||
const localInstructions = {
|
// command: 'ledger',
|
||||||
maxLedgerVersion: version + 100,
|
// ledger_index: 'validated'
|
||||||
fee: '0.000012',
|
// })
|
||||||
ticketSequence: 23,
|
// const version = ledgerResponse.result.ledger_index
|
||||||
sequence: 12
|
// const localInstructions = {
|
||||||
}
|
// maxLedgerVersion: version + 100,
|
||||||
return assertRejects(
|
// fee: '0.000012',
|
||||||
client.preparePayment(
|
// ticketSequence: 23,
|
||||||
address,
|
// sequence: 12
|
||||||
REQUEST_FIXTURES.allOptions,
|
// }
|
||||||
localInstructions
|
// return assertRejects(
|
||||||
),
|
// client.preparePayment(
|
||||||
ValidationError,
|
// address,
|
||||||
'instance.instructions is of prohibited type [object Object]'
|
// REQUEST_FIXTURES.allOptions,
|
||||||
)
|
// localInstructions
|
||||||
}
|
// ),
|
||||||
|
// ValidationError,
|
||||||
|
// 'instance.instructions is of prohibited type [object Object]'
|
||||||
|
// )
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -854,38 +854,42 @@ export default <TestSuite>{
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
'with all options specified': async (client, address) => {
|
// 'with all options specified': async (client, address) => {
|
||||||
const ver = await client.getLedgerVersion()
|
// const ledgerResponse = await client.request({
|
||||||
const localInstructions = {
|
// command: 'ledger',
|
||||||
maxLedgerVersion: ver + 100,
|
// ledger_index: 'validated'
|
||||||
fee: '0.000012'
|
// })
|
||||||
}
|
// const version = ledgerResponse.result.ledger_index
|
||||||
const txJSON = {
|
// const localInstructions = {
|
||||||
TransactionType: 'Payment',
|
// maxLedgerVersion: version + 100,
|
||||||
Account: address,
|
// fee: '0.000012'
|
||||||
Destination: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo',
|
// }
|
||||||
Amount: '10000',
|
// const txJSON = {
|
||||||
InvoiceID:
|
// TransactionType: 'Payment',
|
||||||
'A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A',
|
// Account: address,
|
||||||
SourceTag: 14,
|
// Destination: 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo',
|
||||||
DestinationTag: 58,
|
// Amount: '10000',
|
||||||
Memos: [
|
// InvoiceID:
|
||||||
{
|
// 'A98FD36C17BE2B8511AD36DC335478E7E89F06262949F36EB88E2D683BBCC50A',
|
||||||
Memo: {
|
// SourceTag: 14,
|
||||||
MemoType: client.convertStringToHex('test'),
|
// DestinationTag: 58,
|
||||||
MemoFormat: client.convertStringToHex('text/plain'),
|
// Memos: [
|
||||||
MemoData: client.convertStringToHex('texted data')
|
// {
|
||||||
}
|
// Memo: {
|
||||||
}
|
// MemoType: client.convertStringToHex('test'),
|
||||||
],
|
// MemoFormat: client.convertStringToHex('text/plain'),
|
||||||
Flags:
|
// MemoData: client.convertStringToHex('texted data')
|
||||||
0 |
|
// }
|
||||||
client.txFlags.Payment.NoRippleDirect |
|
// }
|
||||||
client.txFlags.Payment.LimitQuality
|
// ],
|
||||||
}
|
// Flags:
|
||||||
const response = await client.prepareTransaction(txJSON, localInstructions)
|
// 0 |
|
||||||
assertResultMatch(response, responses.preparePayment.allOptions, 'prepare')
|
// client.txFlags.Payment.NoRippleDirect |
|
||||||
},
|
// client.txFlags.Payment.LimitQuality
|
||||||
|
// }
|
||||||
|
// const response = await client.prepareTransaction(txJSON, localInstructions)
|
||||||
|
// assertResultMatch(response, responses.preparePayment.allOptions, 'prepare')
|
||||||
|
// },
|
||||||
|
|
||||||
'fee is capped at default maxFee of 2 XRP (using txJSON.LastLedgerSequence)': async (
|
'fee is capped at default maxFee of 2 XRP (using txJSON.LastLedgerSequence)': async (
|
||||||
client,
|
client,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import net from 'net'
|
|||||||
import assert from 'assert-diff'
|
import assert from 'assert-diff'
|
||||||
import setupClient from './setup-client'
|
import setupClient from './setup-client'
|
||||||
import {Client} from 'xrpl-local'
|
import {Client} from 'xrpl-local'
|
||||||
import ledgerClose from './fixtures/rippled/ledger-close.json'
|
|
||||||
import {ignoreWebSocketDisconnect} from './utils'
|
import {ignoreWebSocketDisconnect} from './utils'
|
||||||
const utils = Client._PRIVATE.ledgerUtils
|
const utils = Client._PRIVATE.ledgerUtils
|
||||||
|
|
||||||
@@ -81,26 +80,6 @@ describe('Connection', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('ledger methods work as expected', async function () {
|
|
||||||
assert.strictEqual(await this.client.connection.getLedgerVersion(), 8819951)
|
|
||||||
assert.strictEqual(
|
|
||||||
await this.client.connection.hasLedgerVersion(8819951),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
assert.strictEqual(
|
|
||||||
await this.client.connection.hasLedgerVersions(8819951, undefined),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
// It would be nice to test a better range, but the mocked ledger only supports this single number
|
|
||||||
assert.strictEqual(
|
|
||||||
await this.client.connection.hasLedgerVersions(8819951, 8819951),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
assert.strictEqual(await this.client.connection.getFeeBase(), 10)
|
|
||||||
assert.strictEqual(await this.client.connection.getFeeRef(), 10)
|
|
||||||
assert.strictEqual(await this.client.connection.getReserveBase(), 20000000) // 20 XRP
|
|
||||||
})
|
|
||||||
|
|
||||||
it('with proxy', function (done) {
|
it('with proxy', function (done) {
|
||||||
if (isBrowser) {
|
if (isBrowser) {
|
||||||
done()
|
done()
|
||||||
@@ -145,8 +124,10 @@ describe('Connection', function () {
|
|||||||
|
|
||||||
it('NotConnectedError', function () {
|
it('NotConnectedError', function () {
|
||||||
const connection = new utils.Connection('url')
|
const connection = new utils.Connection('url')
|
||||||
return connection
|
return connection.request({
|
||||||
.getLedgerVersion()
|
command: 'ledger',
|
||||||
|
ledger_index: 'validated'
|
||||||
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
assert(false, 'Should throw NotConnectedError')
|
assert(false, 'Should throw NotConnectedError')
|
||||||
})
|
})
|
||||||
@@ -427,12 +408,6 @@ describe('Connection', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('hasLedgerVersion', function () {
|
|
||||||
return this.client.connection.hasLedgerVersion(8819951).then((result) => {
|
|
||||||
assert(result)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Cannot connect because no server', function () {
|
it('Cannot connect because no server', function () {
|
||||||
const connection = new utils.Connection(undefined as string)
|
const connection = new utils.Connection(undefined as string)
|
||||||
return connection
|
return connection
|
||||||
@@ -558,59 +533,23 @@ describe('Connection', function () {
|
|||||||
this.client.connection._onMessage(JSON.stringify({type: 'unknown'}))
|
this.client.connection._onMessage(JSON.stringify({type: 'unknown'}))
|
||||||
})
|
})
|
||||||
|
|
||||||
it('ledger close without validated_ledgers', function (done) {
|
// it('should clean up websocket connection if error after websocket is opened', async function () {
|
||||||
const message = _.omit(ledgerClose, 'validated_ledgers')
|
// await this.client.disconnect()
|
||||||
this.client.on('ledger', function (ledger) {
|
// // fail on connection
|
||||||
assert.strictEqual(ledger.ledgerVersion, 8819951)
|
// this.client.connection._subscribeToLedger = async () => {
|
||||||
done()
|
// throw new Error('error on _subscribeToLedger')
|
||||||
})
|
// }
|
||||||
this.client.connection._ws.emit('message', JSON.stringify(message))
|
// try {
|
||||||
})
|
// await this.client.connect()
|
||||||
|
// throw new Error('expected connect() to reject, but it resolved')
|
||||||
it(
|
// } catch (err) {
|
||||||
'should throw RippledNotInitializedError if server does not have ' +
|
// assert(err.message === 'error on _subscribeToLedger')
|
||||||
'validated ledgers',
|
// // _ws.close event listener should have cleaned up the socket when disconnect _ws.close is run on connection error
|
||||||
async function () {
|
// // do not fail on connection anymore
|
||||||
this.timeout(3000)
|
// this.client.connection._subscribeToLedger = async () => {}
|
||||||
|
// await this.client.connection.reconnect()
|
||||||
await this.client.connection.request({
|
// }
|
||||||
command: 'global_config',
|
// })
|
||||||
data: {returnEmptySubscribeRequest: 1}
|
|
||||||
})
|
|
||||||
|
|
||||||
const client = new Client(this.client.connection._url)
|
|
||||||
return client.connect().then(
|
|
||||||
() => {
|
|
||||||
assert(false, 'Must have thrown!')
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
assert(
|
|
||||||
error instanceof this.client.errors.RippledNotInitializedError,
|
|
||||||
'Must throw RippledNotInitializedError, got instead ' +
|
|
||||||
String(error)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
it('should clean up websocket connection if error after websocket is opened', async function () {
|
|
||||||
await this.client.disconnect()
|
|
||||||
// fail on connection
|
|
||||||
this.client.connection._subscribeToLedger = async () => {
|
|
||||||
throw new Error('error on _subscribeToLedger')
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
await this.client.connect()
|
|
||||||
throw new Error('expected connect() to reject, but it resolved')
|
|
||||||
} catch (err) {
|
|
||||||
assert(err.message === 'error on _subscribeToLedger')
|
|
||||||
// _ws.close event listener should have cleaned up the socket when disconnect _ws.close is run on connection error
|
|
||||||
// do not fail on connection anymore
|
|
||||||
this.client.connection._subscribeToLedger = async () => {}
|
|
||||||
await this.client.connection.reconnect()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should try to reconnect on empty subscribe response on reconnect', function (done) {
|
it('should try to reconnect on empty subscribe response on reconnect', function (done) {
|
||||||
this.timeout(23000)
|
this.timeout(23000)
|
||||||
|
|||||||
24
test/fixtures/rippled/fee.json
vendored
Normal file
24
test/fixtures/rippled/fee.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"status": "success",
|
||||||
|
"type": "response",
|
||||||
|
"result": {
|
||||||
|
"current_ledger_size": "14",
|
||||||
|
"current_queue_size": "0",
|
||||||
|
"drops": {
|
||||||
|
"base_fee": "10",
|
||||||
|
"median_fee": "11000",
|
||||||
|
"minimum_fee": "10",
|
||||||
|
"open_ledger_fee": "10"
|
||||||
|
},
|
||||||
|
"expected_ledger_size": "24",
|
||||||
|
"ledger_current_index": 26575101,
|
||||||
|
"levels": {
|
||||||
|
"median_level": "281600",
|
||||||
|
"minimum_level": "256",
|
||||||
|
"open_ledger_level": "256",
|
||||||
|
"reference_level": "256"
|
||||||
|
},
|
||||||
|
"max_queue_size": "480"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
test/fixtures/rippled/index.js
vendored
1
test/fixtures/rippled/index.js
vendored
@@ -15,6 +15,7 @@ module.exports = {
|
|||||||
withPartialPayment: require('./ledger-with-partial-payment'),
|
withPartialPayment: require('./ledger-with-partial-payment'),
|
||||||
pre2014withPartial: require('./ledger-pre2014-with-partial')
|
pre2014withPartial: require('./ledger-pre2014-with-partial')
|
||||||
},
|
},
|
||||||
|
fee: require('./fee'),
|
||||||
empty: require('./empty'),
|
empty: require('./empty'),
|
||||||
subscribe: require('./subscribe'),
|
subscribe: require('./subscribe'),
|
||||||
subscribe_error: require('./subscribe_error'),
|
subscribe_error: require('./subscribe_error'),
|
||||||
|
|||||||
@@ -240,7 +240,11 @@ function suiteSetup(this: any) {
|
|||||||
// two times to give time to server to send `ledgerClosed` event
|
// two times to give time to server to send `ledgerClosed` event
|
||||||
// so getLedgerVersion will return right value
|
// so getLedgerVersion will return right value
|
||||||
.then(() => ledgerAccept(this.client))
|
.then(() => ledgerAccept(this.client))
|
||||||
.then(() => this.client.getLedgerVersion())
|
.then(() => this.client.request({
|
||||||
|
command: 'ledger',
|
||||||
|
ledger_index: 'validated'
|
||||||
|
})
|
||||||
|
.then(response => response.result.ledger_index))
|
||||||
.then((ledgerVersion) => {
|
.then((ledgerVersion) => {
|
||||||
this.startLedgerVersion = ledgerVersion
|
this.startLedgerVersion = ledgerVersion
|
||||||
})
|
})
|
||||||
@@ -259,7 +263,12 @@ describe('integration tests', function () {
|
|||||||
afterEach(teardown)
|
afterEach(teardown)
|
||||||
|
|
||||||
it('trustline', function () {
|
it('trustline', function () {
|
||||||
return this.client.getLedgerVersion().then((ledgerVersion) => {
|
return this.client.request({
|
||||||
|
command: 'ledger',
|
||||||
|
ledger_index: 'validated'
|
||||||
|
})
|
||||||
|
.then(response => response.result.ledger_index)
|
||||||
|
.then((ledgerVersion) => {
|
||||||
return this.client
|
return this.client
|
||||||
.prepareTrustline(
|
.prepareTrustline(
|
||||||
address,
|
address,
|
||||||
@@ -284,7 +293,12 @@ describe('integration tests', function () {
|
|||||||
amount: amount
|
amount: amount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.client.getLedgerVersion().then((ledgerVersion) => {
|
return this.client.request({
|
||||||
|
command: 'ledger',
|
||||||
|
ledger_index: 'validated'
|
||||||
|
})
|
||||||
|
.then(response => response.result.ledger_index)
|
||||||
|
.then((ledgerVersion) => {
|
||||||
return this.client
|
return this.client
|
||||||
.preparePayment(address, paymentSpecification, instructions)
|
.preparePayment(address, paymentSpecification, instructions)
|
||||||
.then((prepared) =>
|
.then((prepared) =>
|
||||||
@@ -316,7 +330,12 @@ describe('integration tests', function () {
|
|||||||
issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q'
|
issuer: 'rMwjYedjc7qqtKYVLiAccJSmCwih4LnE2q'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.client.getLedgerVersion().then((ledgerVersion) => {
|
return this.client.request({
|
||||||
|
command: 'ledger',
|
||||||
|
ledger_index: 'validated'
|
||||||
|
})
|
||||||
|
.then(response => response.result.ledger_index)
|
||||||
|
.then((ledgerVersion) => {
|
||||||
return this.client
|
return this.client
|
||||||
.prepareOrder(address, orderSpecification, instructions)
|
.prepareOrder(address, orderSpecification, instructions)
|
||||||
.then((prepared) =>
|
.then((prepared) =>
|
||||||
@@ -372,13 +391,6 @@ describe('integration tests', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('getLedgerVersion', function () {
|
|
||||||
return this.client.getLedgerVersion().then((ledgerVersion) => {
|
|
||||||
assert.strictEqual(typeof ledgerVersion, 'number')
|
|
||||||
assert(ledgerVersion >= this.startLedgerVersion)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('getTrustlines', function () {
|
it('getTrustlines', function () {
|
||||||
const fixture = requests.prepareTrustline.simple
|
const fixture = requests.prepareTrustline.simple
|
||||||
const { currency, counterparty } = fixture
|
const { currency, counterparty } = fixture
|
||||||
@@ -520,7 +532,12 @@ describe('integration tests - standalone rippled', function () {
|
|||||||
let minLedgerVersion = null
|
let minLedgerVersion = null
|
||||||
return payTo(this.client, address)
|
return payTo(this.client, address)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return this.client.getLedgerVersion().then((ledgerVersion) => {
|
return this.client.request({
|
||||||
|
command: 'ledger',
|
||||||
|
ledger_index: 'validated'
|
||||||
|
})
|
||||||
|
.then(response => response.result.ledger_index)
|
||||||
|
.then((ledgerVersion) => {
|
||||||
minLedgerVersion = ledgerVersion
|
minLedgerVersion = ledgerVersion
|
||||||
return this.client
|
return this.client
|
||||||
.prepareSettings(address, {signers}, instructions)
|
.prepareSettings(address, {signers}, instructions)
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ function createLedgerResponse(request, response) {
|
|||||||
newResponse.result.ledger.parent_close_time =
|
newResponse.result.ledger.parent_close_time =
|
||||||
newResponse.result.ledger.close_time - 10
|
newResponse.result.ledger.close_time - 10
|
||||||
}
|
}
|
||||||
|
newResponse.result.ledger_index = newResponse.result.ledger.ledger_index
|
||||||
}
|
}
|
||||||
return JSON.stringify(newResponse)
|
return JSON.stringify(newResponse)
|
||||||
}
|
}
|
||||||
@@ -106,7 +107,7 @@ export function createMockRippled(port) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (mock.listeners(this.event).length === 0) {
|
if (mock.listeners(this.event).length === 0) {
|
||||||
throw new Error('No event handler registered for ' + this.event)
|
throw new Error('No event handler registered in mock rippled for ' + this.event)
|
||||||
}
|
}
|
||||||
if (mock.expectedRequests == null) {
|
if (mock.expectedRequests == null) {
|
||||||
return // TODO: fail here to require expectedRequests
|
return // TODO: fail here to require expectedRequests
|
||||||
@@ -189,6 +190,12 @@ export function createMockRippled(port) {
|
|||||||
conn.send(JSON.stringify(request.data))
|
conn.send(JSON.stringify(request.data))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mock.on('request_fee', function (request, conn) {
|
||||||
|
assert.strictEqual(request.command, 'fee')
|
||||||
|
conn.send(createResponse(request, fixtures.fee))
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
mock.on('request_server_info', function (request, conn) {
|
mock.on('request_server_info', function (request, conn) {
|
||||||
assert.strictEqual(request.command, 'server_info')
|
assert.strictEqual(request.command, 'server_info')
|
||||||
if (conn.config.highLoadFactor || conn.config.loadFactor) {
|
if (conn.config.highLoadFactor || conn.config.loadFactor) {
|
||||||
@@ -366,6 +373,19 @@ export function createMockRippled(port) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mock.on('request_ledger_current', function (request, conn) {
|
||||||
|
assert.strictEqual(request.command, 'ledger_current')
|
||||||
|
const response = {
|
||||||
|
"id": 0,
|
||||||
|
"status": "success",
|
||||||
|
"type": "response",
|
||||||
|
"result": {
|
||||||
|
"ledger_current_index": 8819951
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conn.send(createResponse(request, response))
|
||||||
|
})
|
||||||
|
|
||||||
mock.on('request_ledger_data', function (request, conn) {
|
mock.on('request_ledger_data', function (request, conn) {
|
||||||
assert.strictEqual(request.command, 'ledger_data')
|
assert.strictEqual(request.command, 'ledger_data')
|
||||||
if (request.marker) {
|
if (request.marker) {
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ import assert from 'assert-diff'
|
|||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import {Client} from 'xrpl-local'
|
import {Client} from 'xrpl-local'
|
||||||
import {RecursiveData} from 'xrpl-local/ledger/utils'
|
import {RecursiveData} from 'xrpl-local/ledger/utils'
|
||||||
import {assertRejects, assertResultMatch} from './utils'
|
import {assertRejects} from './utils'
|
||||||
import addresses from './fixtures/addresses.json'
|
import addresses from './fixtures/addresses.json'
|
||||||
import responses from './fixtures/responses'
|
|
||||||
import ledgerClosed from './fixtures/rippled/ledger-close-newer.json'
|
|
||||||
import setupClient from './setup-client'
|
import setupClient from './setup-client'
|
||||||
|
|
||||||
const {validate, schemaValidator, ledgerUtils} = Client._PRIVATE
|
const {validate, schemaValidator, ledgerUtils} = Client._PRIVATE
|
||||||
@@ -44,14 +42,6 @@ describe('Client', function () {
|
|||||||
// to test that connect() times out after 2 seconds.
|
// to test that connect() times out after 2 seconds.
|
||||||
})
|
})
|
||||||
|
|
||||||
it('ledger closed event', function (done) {
|
|
||||||
this.client.on('ledger', (message) => {
|
|
||||||
assertResultMatch(message, responses.ledgerEvent, 'ledgerEvent')
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
this.client.connection._ws.emit('message', JSON.stringify(ledgerClosed))
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('[private] schema-validator', function () {
|
describe('[private] schema-validator', function () {
|
||||||
it('valid', function () {
|
it('valid', function () {
|
||||||
assert.doesNotThrow(function () {
|
assert.doesNotThrow(function () {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {Client, BroadcastClient} from 'xrpl-local'
|
import {Client, BroadcastClient} from 'xrpl-local'
|
||||||
import ledgerClosed from './fixtures/rippled/ledger-close.json'
|
|
||||||
|
|
||||||
const port = 34371
|
const port = 34371
|
||||||
const baseUrl = 'ws://testripple.circleci.com:'
|
const baseUrl = 'ws://testripple.circleci.com:'
|
||||||
@@ -22,13 +21,7 @@ function setup(this: any, port_ = port) {
|
|||||||
this.client = new Client(baseUrl + got.port)
|
this.client = new Client(baseUrl + got.port)
|
||||||
this.client
|
this.client
|
||||||
.connect()
|
.connect()
|
||||||
.then(() => {
|
.then(resolve)
|
||||||
this.client.once('ledger', () => resolve())
|
|
||||||
this.client.connection._ws.emit(
|
|
||||||
'message',
|
|
||||||
JSON.stringify(ledgerClosed)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.catch(reject)
|
.catch(reject)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -43,13 +36,7 @@ function setupBroadcast(this: any) {
|
|||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
this.client
|
this.client
|
||||||
.connect()
|
.connect()
|
||||||
.then(() => {
|
.then(resolve)
|
||||||
this.client.once('ledger', () => resolve())
|
|
||||||
this.client._clients[0].connection._ws.emit(
|
|
||||||
'message',
|
|
||||||
JSON.stringify(ledgerClosed)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.catch(reject)
|
.catch(reject)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {Client, BroadcastClient} from 'xrpl-local'
|
import {Client, BroadcastClient} from 'xrpl-local'
|
||||||
import ledgerClosed from './fixtures/rippled/ledger-close.json'
|
|
||||||
import {createMockRippled} from './mock-rippled'
|
import {createMockRippled} from './mock-rippled'
|
||||||
import {getFreePort} from './utils'
|
import {getFreePort} from './utils'
|
||||||
|
|
||||||
@@ -10,13 +9,7 @@ function setupMockRippledConnection(testcase, port) {
|
|||||||
testcase.client = new Client('ws://localhost:' + port)
|
testcase.client = new Client('ws://localhost:' + port)
|
||||||
testcase.client
|
testcase.client
|
||||||
.connect()
|
.connect()
|
||||||
.then(() => {
|
.then(resolve)
|
||||||
testcase.client.once('ledger', () => resolve())
|
|
||||||
testcase.client.connection._ws.emit(
|
|
||||||
'message',
|
|
||||||
JSON.stringify(ledgerClosed)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.catch(reject)
|
.catch(reject)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -28,10 +21,7 @@ function setupMockRippledConnectionForBroadcast(testcase, ports) {
|
|||||||
testcase.client = new BroadcastClient(servers)
|
testcase.client = new BroadcastClient(servers)
|
||||||
testcase.client
|
testcase.client
|
||||||
.connect()
|
.connect()
|
||||||
.then(() => {
|
.then(resolve)
|
||||||
testcase.client.once('ledger', () => resolve())
|
|
||||||
testcase.mocks[0].socket.send(JSON.stringify(ledgerClosed))
|
|
||||||
})
|
|
||||||
.catch(reject)
|
.catch(reject)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user