mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-12-06 17:27:59 +00:00
ci: run lint tests (#1603)
* turn on lint tests * remove tsc * fix errors in src/utils/hashes * fix linter errors in src/utils * fix lint issues in test/ * resolve lint issues in src/client * resolve dependency cycle * resolve other linting issues in src/models * resolve rest of linting issues * fix tests * fix linting errors in test/integration * fix rest of linting issues * fix test name
This commit is contained in:
32
.eslintrc.js
32
.eslintrc.js
@@ -19,8 +19,10 @@ module.exports = {
|
||||
|
||||
// Specify global variables that are predefined
|
||||
env: {
|
||||
node: true, // Enable node global variables & Node.js scoping
|
||||
es2020: true, // Add all ECMAScript 2020 globals and automatically set the ecmaVersion parser option to ES2020
|
||||
// Enable node global variables & Node.js scoping
|
||||
node: true,
|
||||
// Add all ECMAScript 2020 globals and automatically set the ecmaVersion parser option to ES2020
|
||||
es2020: true,
|
||||
},
|
||||
|
||||
plugins: [],
|
||||
@@ -39,9 +41,30 @@ module.exports = {
|
||||
{ max: 40, skipBlankLines: true, skipComments: true },
|
||||
],
|
||||
'max-statements': ['warn', 25],
|
||||
'id-length': ['error', { exceptions: ['_'] }], // exception for lodash
|
||||
// exception for lodash
|
||||
'id-length': ['error', { exceptions: ['_'] }],
|
||||
|
||||
// no-shadow has false-positives for enum, @typescript-eslint version fixes that
|
||||
'no-shadow': 'off',
|
||||
'@typescript-eslint/no-shadow': ['error'],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['.eslintrc.js'],
|
||||
rules: {
|
||||
'import/no-unused-modules': 'off',
|
||||
'@typescript-eslint/no-magic-numbers': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
// TODO: remove when snippets are written
|
||||
files: ['snippets/src/*.ts'],
|
||||
rules: {
|
||||
'max-len': 'off',
|
||||
'import/unambiguous': 'off',
|
||||
'import/no-unused-modules': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['test/**/*.ts'],
|
||||
rules: {
|
||||
@@ -79,6 +102,9 @@ module.exports = {
|
||||
|
||||
// Tests are already in 2 callbacks, so max 3 is pretty restrictive
|
||||
'max-nested-callbacks': 'off',
|
||||
|
||||
// setup/teardown client is easier to do in before/after, even if there is only one testcase
|
||||
'mocha/no-hooks-for-single-case': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
28
.github/workflows/nodejs.yml
vendored
28
.github/workflows/nodejs.yml
vendored
@@ -10,22 +10,22 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
# build-and-lint:
|
||||
# runs-on: ubuntu-latest
|
||||
build-and-lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# strategy:
|
||||
# matrix:
|
||||
# node-version: [14.x]
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: Use Node.js ${{ matrix.node-version }}
|
||||
# uses: actions/setup-node@v1
|
||||
# with:
|
||||
# node-version: ${{ matrix.node-version }}
|
||||
# - run: npm run install
|
||||
# - run: npm run lint
|
||||
# - run: npm run build
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm install
|
||||
- run: npm run lint
|
||||
- run: npm run build
|
||||
|
||||
unit:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -92,7 +92,7 @@ function getAgent(url: string, config: ConnectionOptions): Agent | undefined {
|
||||
node/global-require, global-require, -- Necessary for the `require` */
|
||||
HttpsProxyAgent = require('https-proxy-agent')
|
||||
/* eslint-enable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports,
|
||||
node/global-require, global-require */
|
||||
node/global-require, global-require, */
|
||||
} catch (_error) {
|
||||
throw new Error('"proxy" option is not supported in the browser')
|
||||
}
|
||||
@@ -239,9 +239,8 @@ export class Connection extends EventEmitter {
|
||||
const connectionTimeoutID = setTimeout(() => {
|
||||
this.onConnectionFailed(
|
||||
new ConnectionError(
|
||||
`Error: connect() timed out after ${this.config.connectionTimeout} ms. ` +
|
||||
`If your internet connection is working, the rippled server may be blocked or inaccessible. ` +
|
||||
`You can also try setting the 'connectionTimeout' option in the Client constructor.`,
|
||||
`Error: connect() timed out after ${this.config.connectionTimeout} ms. If your internet connection is working, the ` +
|
||||
`rippled server may be blocked or inaccessible. You can also try setting the 'connectionTimeout' option in the Client constructor.`,
|
||||
),
|
||||
)
|
||||
}, this.config.connectionTimeout)
|
||||
@@ -380,8 +379,11 @@ export class Connection extends EventEmitter {
|
||||
try {
|
||||
this.requestManager.handleResponse(data)
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line max-depth -- okay here
|
||||
if (error instanceof Error) {
|
||||
this.emit('error', 'badMessage', error.message, message)
|
||||
} else {
|
||||
this.emit('error', 'badMessage', error, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/member-ordering -- Okay for Client so that client methods can be near the bottom */
|
||||
/* eslint-disable max-lines -- This might not be necessary later, but this file needs to be big right now */
|
||||
import * as assert from 'assert'
|
||||
import { EventEmitter } from 'events'
|
||||
@@ -171,6 +172,7 @@ class Client extends EventEmitter {
|
||||
* @param server - URL of the server to connect to.
|
||||
* @param options - Options for client settings.
|
||||
*/
|
||||
// eslint-disable-next-line max-lines-per-function -- okay because we have to set up all the connection handlers
|
||||
public constructor(server: string, options: ClientOptions = {}) {
|
||||
super()
|
||||
if (typeof server !== 'string' || !/wss?(?:\+unix)?:\/\//u.exec(server)) {
|
||||
@@ -188,6 +190,20 @@ class Client extends EventEmitter {
|
||||
this.emit('error', errorCode, errorMessage, data)
|
||||
})
|
||||
|
||||
this.connection.on('connected', () => {
|
||||
this.emit('connected')
|
||||
})
|
||||
|
||||
this.connection.on('disconnected', (code: number) => {
|
||||
let finalCode = code
|
||||
// 4000: Connection uses a 4000 code internally to indicate a manual disconnect/close
|
||||
// Since 4000 is a normal disconnect reason, we convert this to the standard exit code 1000
|
||||
if (finalCode === INTENTIONAL_DISCONNECT_CODE) {
|
||||
finalCode = 1000
|
||||
}
|
||||
this.emit('disconnected', finalCode)
|
||||
})
|
||||
|
||||
this.connection.on('ledgerClosed', (ledger) => {
|
||||
this.emit('ledgerClosed', ledger)
|
||||
})
|
||||
@@ -215,20 +231,6 @@ class Client extends EventEmitter {
|
||||
this.connection.on('path_find', (path) => {
|
||||
this.emit('path_find', path)
|
||||
})
|
||||
|
||||
this.connection.on('connected', () => {
|
||||
this.emit('connected')
|
||||
})
|
||||
|
||||
this.connection.on('disconnected', (code: number) => {
|
||||
let finalCode = code
|
||||
// 4000: Connection uses a 4000 code internally to indicate a manual disconnect/close
|
||||
// Since 4000 is a normal disconnect reason, we convert this to the standard exit code 1000
|
||||
if (finalCode === INTENTIONAL_DISCONNECT_CODE) {
|
||||
finalCode = 1000
|
||||
}
|
||||
this.emit('disconnected', finalCode)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -379,6 +381,7 @@ class Client extends EventEmitter {
|
||||
listener: (phase: ConsensusStream) => void,
|
||||
): this
|
||||
public on(event: 'path_find', listener: (path: PathFindStream) => void): this
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- actually needs to be any here
|
||||
public on(event: 'error', listener: (...err: any[]) => void): this
|
||||
/**
|
||||
* Event handler for subscription streams.
|
||||
@@ -387,6 +390,7 @@ class Client extends EventEmitter {
|
||||
* @param listener - Function to run on event.
|
||||
* @returns This, because it inherits from EventEmitter.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- actually needs to be any here
|
||||
public on(eventName: string, listener: (...args: any[]) => void): this {
|
||||
return super.on(eventName, listener)
|
||||
}
|
||||
@@ -519,4 +523,4 @@ class Client extends EventEmitter {
|
||||
public errors = errors
|
||||
}
|
||||
|
||||
export { Client, Connection }
|
||||
export { Client }
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable import/no-unused-modules -- Used by webpack */
|
||||
/* eslint-disable max-classes-per-file -- Needs to be a wrapper for ws */
|
||||
import { EventEmitter } from 'events'
|
||||
|
||||
@@ -27,7 +28,7 @@ interface WSWrapperOptions {
|
||||
* Provides `EventEmitter` interface for native browser `WebSocket`,
|
||||
* same, as `ws` package provides.
|
||||
*/
|
||||
class WSWrapper extends EventEmitter {
|
||||
export default class WSWrapper extends EventEmitter {
|
||||
public static CONNECTING = 0
|
||||
public static OPEN = 1
|
||||
public static CLOSING = 2
|
||||
@@ -96,5 +97,3 @@ class WSWrapper extends EventEmitter {
|
||||
return this.ws.readyState
|
||||
}
|
||||
}
|
||||
|
||||
export default WSWrapper
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// eslint-disable-next-line no-shadow -- No shadow here
|
||||
enum ECDSA {
|
||||
ed25519 = 'ed25519',
|
||||
secp256k1 = 'ecdsa-secp256k1',
|
||||
|
||||
@@ -12,3 +12,5 @@ export * from './utils'
|
||||
export * from './errors'
|
||||
|
||||
export { default as Wallet } from './wallet'
|
||||
|
||||
export * from './wallet/signer'
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/* eslint-disable import/max-dependencies -- Needs to export all ledger objects */
|
||||
/* eslint-disable import/no-unused-modules -- Needs to export all ledger objects */
|
||||
import AccountRoot from './accountRoot'
|
||||
import AccountRoot, { AccountRootLedgerFlags } from './accountRoot'
|
||||
import Amendments from './amendments'
|
||||
import Check from './check'
|
||||
import DepositPreauth from './depositPreauth'
|
||||
@@ -11,14 +10,15 @@ import Ledger from './ledger'
|
||||
import LedgerEntry from './ledgerEntry'
|
||||
import LedgerHashes from './ledgerHashes'
|
||||
import NegativeUNL from './negativeUNL'
|
||||
import Offer from './offer'
|
||||
import Offer, { OfferLedgerFlags } from './offer'
|
||||
import PayChannel from './payChannel'
|
||||
import RippleState from './rippleState'
|
||||
import SignerList from './signerList'
|
||||
import RippleState, { RippleStateLedgerFlags } from './rippleState'
|
||||
import SignerList, { SignerListLedgerFlags } from './signerList'
|
||||
import Ticket from './ticket'
|
||||
|
||||
export {
|
||||
AccountRoot,
|
||||
AccountRootLedgerFlags,
|
||||
Amendments,
|
||||
Check,
|
||||
DepositPreauth,
|
||||
@@ -30,8 +30,11 @@ export {
|
||||
LedgerHashes,
|
||||
NegativeUNL,
|
||||
Offer,
|
||||
OfferLedgerFlags,
|
||||
PayChannel,
|
||||
RippleState,
|
||||
RippleStateLedgerFlags,
|
||||
SignerList,
|
||||
SignerListLedgerFlags,
|
||||
Ticket,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable import/max-dependencies -- Needed for the type */
|
||||
import AccountRoot from './accountRoot'
|
||||
import Amendments from './amendments'
|
||||
import Check from './check'
|
||||
|
||||
@@ -19,12 +19,15 @@ export default interface RippleState extends BaseLedgerEntry {
|
||||
}
|
||||
|
||||
export enum RippleStateLedgerFlags {
|
||||
lsfLowReserve = 0x00010000, // True, if entry counts toward reserve.
|
||||
// True, if entry counts toward reserve.
|
||||
lsfLowReserve = 0x00010000,
|
||||
lsfHighReserve = 0x00020000,
|
||||
lsfLowAuth = 0x00040000,
|
||||
lsfHighAuth = 0x00080000,
|
||||
lsfLowNoRipple = 0x00100000,
|
||||
lsfHighNoRipple = 0x00200000,
|
||||
lsfLowFreeze = 0x00400000, // True, low side has set freeze flag
|
||||
lsfHighFreeze = 0x00800000, // True, high side has set freeze flag
|
||||
// True, low side has set freeze flag
|
||||
lsfLowFreeze = 0x00400000,
|
||||
// True, high side has set freeze flag
|
||||
lsfHighFreeze = 0x00800000,
|
||||
}
|
||||
|
||||
@@ -19,5 +19,6 @@ export default interface SignerList extends BaseLedgerEntry {
|
||||
}
|
||||
|
||||
export enum SignerListLedgerFlags {
|
||||
lsfOneOwnerCount = 0x00010000, // True, uses only one OwnerCount
|
||||
// True, uses only one OwnerCount
|
||||
lsfOneOwnerCount = 0x00010000,
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ const MAX_TICK_SIZE = 15
|
||||
* @param tx - An AccountSet Transaction.
|
||||
* @throws When the AccountSet is Malformed.
|
||||
*/
|
||||
// eslint-disable-next-line max-lines-per-function -- okay for this method, only a little over
|
||||
export function validateAccountSet(tx: Record<string, unknown>): void {
|
||||
validateBaseTransaction(tx)
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ export function isAmount(amount: unknown): boolean {
|
||||
)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface -- no global flags right now, so this is fine
|
||||
export interface GlobalFlags {}
|
||||
|
||||
export interface BaseTransaction {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* eslint-disable import/no-unused-modules -- Needs to export all types + validate methods */
|
||||
/* eslint-disable import/max-dependencies -- Needs to export all types + validate methods */
|
||||
// TODO: replace * imports with direct imports
|
||||
export * from './transaction'
|
||||
export {
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
isAmount,
|
||||
} from './common'
|
||||
|
||||
// eslint-disable-next-line no-shadow -- variable declaration is unique
|
||||
export enum OfferCreateTransactionFlags {
|
||||
tfPassive = 0x00010000,
|
||||
tfImmediateOrCancel = 0x00020000,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable max-statements -- Necessary for validatePayment */
|
||||
/* eslint-disable complexity -- Necessary for validatePayment */
|
||||
import { ValidationError } from '../../errors'
|
||||
import { Amount, Path } from '../common'
|
||||
@@ -95,9 +94,9 @@ function checkPartialPayment(tx: Record<string, unknown>): void {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS
|
||||
const flags = tx.Flags as number | PaymentFlagsInterface
|
||||
const isTfPartialPayment =
|
||||
typeof flags !== 'number'
|
||||
? flags.tfPartialPayment ?? false
|
||||
: isFlagEnabled(flags, PaymentTransactionFlags.tfPartialPayment)
|
||||
typeof flags === 'number'
|
||||
? isFlagEnabled(flags, PaymentTransactionFlags.tfPartialPayment)
|
||||
: flags.tfPartialPayment ?? false
|
||||
|
||||
if (!isTfPartialPayment) {
|
||||
throw new ValidationError(
|
||||
|
||||
@@ -19,6 +19,7 @@ export interface PaymentChannelCreate extends BaseTransaction {
|
||||
* @param tx - An PaymentChannelCreate Transaction.
|
||||
* @throws When the PaymentChannelCreate is Malformed.
|
||||
*/
|
||||
// eslint-disable-next-line max-lines-per-function -- okay for this function, there's a lot of things to check
|
||||
export function validatePaymentChannelCreate(
|
||||
tx: Record<string, unknown>,
|
||||
): void {
|
||||
|
||||
@@ -5,7 +5,7 @@ import _ from 'lodash'
|
||||
import { encode, decode } from 'ripple-binary-codec'
|
||||
|
||||
import { ValidationError } from '../../errors'
|
||||
import { setTransactionFlagsToNumber } from '../utils'
|
||||
import setTransactionFlagsToNumber from '../utils/flags'
|
||||
|
||||
import { AccountDelete, validateAccountDelete } from './accountDelete'
|
||||
import {
|
||||
@@ -86,6 +86,13 @@ export interface TransactionAndMetadata {
|
||||
*/
|
||||
export function validate(transaction: Record<string, unknown>): void {
|
||||
const tx = { ...transaction }
|
||||
if (tx.TransactionType == null) {
|
||||
throw new ValidationError('Object does not have a `TransactionType`')
|
||||
}
|
||||
if (typeof tx.TransactionType !== 'string') {
|
||||
throw new ValidationError("Object's `TransactionType` is not a string")
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- okay here
|
||||
setTransactionFlagsToNumber(tx as unknown as Transaction)
|
||||
switch (tx.TransactionType) {
|
||||
case 'AccountDelete':
|
||||
|
||||
103
src/models/utils/flags.ts
Normal file
103
src/models/utils/flags.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
/* eslint-disable no-param-reassign -- param reassign is safe */
|
||||
/* eslint-disable no-bitwise -- flags require bitwise operations */
|
||||
|
||||
import { ValidationError } from '../../errors'
|
||||
import {
|
||||
AccountSetFlagsInterface,
|
||||
AccountSetTransactionFlags,
|
||||
} from '../transactions/accountSet'
|
||||
import { GlobalFlags } from '../transactions/common'
|
||||
import {
|
||||
OfferCreateFlagsInterface,
|
||||
OfferCreateTransactionFlags,
|
||||
} from '../transactions/offerCreate'
|
||||
import {
|
||||
PaymentFlagsInterface,
|
||||
PaymentTransactionFlags,
|
||||
} from '../transactions/payment'
|
||||
import {
|
||||
PaymentChannelClaimFlagsInterface,
|
||||
PaymentChannelClaimTransactionFlags,
|
||||
} from '../transactions/paymentChannelClaim'
|
||||
import type { Transaction } from '../transactions/transaction'
|
||||
import {
|
||||
TrustSetFlagsInterface,
|
||||
TrustSetTransactionFlags,
|
||||
} from '../transactions/trustSet'
|
||||
|
||||
/**
|
||||
* Sets a transaction's flags to its numeric representation.
|
||||
*
|
||||
* @param tx - A transaction to set its flags to its numeric representation.
|
||||
*/
|
||||
export default function setTransactionFlagsToNumber(tx: Transaction): void {
|
||||
if (tx.Flags == null) {
|
||||
tx.Flags = 0
|
||||
return
|
||||
}
|
||||
if (typeof tx.Flags === 'number') {
|
||||
return
|
||||
}
|
||||
|
||||
switch (tx.TransactionType) {
|
||||
case 'AccountSet':
|
||||
tx.Flags = convertAccountSetFlagsToNumber(tx.Flags)
|
||||
return
|
||||
case 'OfferCreate':
|
||||
tx.Flags = convertOfferCreateFlagsToNumber(tx.Flags)
|
||||
return
|
||||
case 'PaymentChannelClaim':
|
||||
tx.Flags = convertPaymentChannelClaimFlagsToNumber(tx.Flags)
|
||||
return
|
||||
case 'Payment':
|
||||
tx.Flags = convertPaymentTransactionFlagsToNumber(tx.Flags)
|
||||
return
|
||||
case 'TrustSet':
|
||||
tx.Flags = convertTrustSetFlagsToNumber(tx.Flags)
|
||||
return
|
||||
default:
|
||||
tx.Flags = 0
|
||||
}
|
||||
}
|
||||
|
||||
function convertAccountSetFlagsToNumber(
|
||||
flags: AccountSetFlagsInterface,
|
||||
): number {
|
||||
return reduceFlags(flags, AccountSetTransactionFlags)
|
||||
}
|
||||
|
||||
function convertOfferCreateFlagsToNumber(
|
||||
flags: OfferCreateFlagsInterface,
|
||||
): number {
|
||||
return reduceFlags(flags, OfferCreateTransactionFlags)
|
||||
}
|
||||
|
||||
function convertPaymentChannelClaimFlagsToNumber(
|
||||
flags: PaymentChannelClaimFlagsInterface,
|
||||
): number {
|
||||
return reduceFlags(flags, PaymentChannelClaimTransactionFlags)
|
||||
}
|
||||
|
||||
function convertPaymentTransactionFlagsToNumber(
|
||||
flags: PaymentFlagsInterface,
|
||||
): number {
|
||||
return reduceFlags(flags, PaymentTransactionFlags)
|
||||
}
|
||||
|
||||
function convertTrustSetFlagsToNumber(flags: TrustSetFlagsInterface): number {
|
||||
return reduceFlags(flags, TrustSetTransactionFlags)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- added ValidationError check for flagEnum
|
||||
function reduceFlags(flags: GlobalFlags, flagEnum: any): number {
|
||||
return Object.keys(flags).reduce((resultFlags, flag) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- safe member access
|
||||
if (flagEnum[flag] == null) {
|
||||
throw new ValidationError(
|
||||
`flag ${flag} doesn't exist in flagEnum: ${JSON.stringify(flagEnum)}`,
|
||||
)
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- safe member access
|
||||
return flags[flag] ? resultFlags | flagEnum[flag] : resultFlags
|
||||
}, 0)
|
||||
}
|
||||
@@ -1,22 +1,3 @@
|
||||
/* eslint-disable no-param-reassign -- param reassign is safe */
|
||||
/* eslint-disable no-bitwise -- flags require bitwise operations */
|
||||
import { ValidationError } from '../../errors'
|
||||
// eslint-disable-next-line import/no-cycle -- cycle is safe
|
||||
import {
|
||||
AccountSetFlagsInterface,
|
||||
AccountSetTransactionFlags,
|
||||
OfferCreateFlagsInterface,
|
||||
OfferCreateTransactionFlags,
|
||||
PaymentChannelClaimFlagsInterface,
|
||||
PaymentChannelClaimTransactionFlags,
|
||||
PaymentFlagsInterface,
|
||||
PaymentTransactionFlags,
|
||||
Transaction,
|
||||
TrustSetFlagsInterface,
|
||||
TrustSetTransactionFlags,
|
||||
} from '../transactions'
|
||||
import type { GlobalFlags } from '../transactions/common'
|
||||
|
||||
/**
|
||||
* Verify that all fields of an object are in fields.
|
||||
*
|
||||
@@ -39,82 +20,6 @@ export function onlyHasFields(
|
||||
* @returns True if checkFlag is enabled within Flags.
|
||||
*/
|
||||
export function isFlagEnabled(Flags: number, checkFlag: number): boolean {
|
||||
// eslint-disable-next-line no-bitwise -- flags needs bitwise
|
||||
return (checkFlag & Flags) === checkFlag
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a transaction's flags to its numeric representation.
|
||||
*
|
||||
* @param tx - A transaction to set its flags to its numeric representation.
|
||||
*/
|
||||
export function setTransactionFlagsToNumber(tx: Transaction): void {
|
||||
if (tx.Flags == null) {
|
||||
tx.Flags = 0
|
||||
return
|
||||
}
|
||||
if (typeof tx.Flags === 'number') {
|
||||
return
|
||||
}
|
||||
|
||||
switch (tx.TransactionType) {
|
||||
case 'AccountSet':
|
||||
tx.Flags = convertAccountSetFlagsToNumber(tx.Flags)
|
||||
return
|
||||
case 'OfferCreate':
|
||||
tx.Flags = convertOfferCreateFlagsToNumber(tx.Flags)
|
||||
return
|
||||
case 'PaymentChannelClaim':
|
||||
tx.Flags = convertPaymentChannelClaimFlagsToNumber(tx.Flags)
|
||||
return
|
||||
case 'Payment':
|
||||
tx.Flags = convertPaymentTransactionFlagsToNumber(tx.Flags)
|
||||
return
|
||||
case 'TrustSet':
|
||||
tx.Flags = convertTrustSetFlagsToNumber(tx.Flags)
|
||||
return
|
||||
default:
|
||||
tx.Flags = 0
|
||||
}
|
||||
}
|
||||
|
||||
function convertAccountSetFlagsToNumber(
|
||||
flags: AccountSetFlagsInterface,
|
||||
): number {
|
||||
return reduceFlags(flags, AccountSetTransactionFlags)
|
||||
}
|
||||
|
||||
function convertOfferCreateFlagsToNumber(
|
||||
flags: OfferCreateFlagsInterface,
|
||||
): number {
|
||||
return reduceFlags(flags, OfferCreateTransactionFlags)
|
||||
}
|
||||
|
||||
function convertPaymentChannelClaimFlagsToNumber(
|
||||
flags: PaymentChannelClaimFlagsInterface,
|
||||
): number {
|
||||
return reduceFlags(flags, PaymentChannelClaimTransactionFlags)
|
||||
}
|
||||
|
||||
function convertPaymentTransactionFlagsToNumber(
|
||||
flags: PaymentFlagsInterface,
|
||||
): number {
|
||||
return reduceFlags(flags, PaymentTransactionFlags)
|
||||
}
|
||||
|
||||
function convertTrustSetFlagsToNumber(flags: TrustSetFlagsInterface): number {
|
||||
return reduceFlags(flags, TrustSetTransactionFlags)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- added ValidationError check for flagEnum
|
||||
function reduceFlags(flags: GlobalFlags, flagEnum: any): number {
|
||||
return Object.keys(flags).reduce((resultFlags, flag) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- safe member access
|
||||
if (flagEnum[flag] == null) {
|
||||
throw new ValidationError(
|
||||
`flag ${flag} doesn't exist in flagEnum: ${JSON.stringify(flagEnum)}`,
|
||||
)
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- safe member access
|
||||
return flags[flag] ? resultFlags | flagEnum[flag] : resultFlags
|
||||
}, 0)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { Client } from '..'
|
||||
import { ValidationError } from '../errors'
|
||||
import { AccountInfoRequest, LedgerRequest } from '../models/methods'
|
||||
import { Transaction } from '../models/transactions'
|
||||
import { setTransactionFlagsToNumber } from '../models/utils'
|
||||
import setTransactionFlagsToNumber from '../models/utils/flags'
|
||||
import { xrpToDrops } from '../utils'
|
||||
|
||||
// 20 drops
|
||||
@@ -138,9 +138,9 @@ async function calculateFeePerTransactionType(
|
||||
signersCount = 0,
|
||||
): Promise<void> {
|
||||
// netFee is usually 0.00001 XRP (10 drops)
|
||||
const netFeeXRP: string = await client.getFee()
|
||||
const netFeeDrops: string = xrpToDrops(netFeeXRP)
|
||||
let baseFee: BigNumber = new BigNumber(netFeeDrops)
|
||||
const netFeeXRP = await client.getFee()
|
||||
const netFeeDrops = xrpToDrops(netFeeXRP)
|
||||
let baseFee = new BigNumber(netFeeDrops)
|
||||
|
||||
// EscrowFinish Transaction with Fulfillment
|
||||
if (tx.TransactionType === 'EscrowFinish' && tx.Fulfillment != null) {
|
||||
|
||||
@@ -30,7 +30,7 @@ interface GetBalancesOptions {
|
||||
/**
|
||||
* Get XRP/non-XRP balances for an account.
|
||||
*
|
||||
* @param client - Client.
|
||||
* @param this - Client.
|
||||
* @param account - Account address.
|
||||
* @param options - Options to include for getting balances.
|
||||
* @returns An array of XRP/non-XRP balances.
|
||||
|
||||
@@ -10,7 +10,7 @@ const BASE_10 = 10
|
||||
* Note: This is a public API that can be called directly.
|
||||
* This is not used by the `prepare*` methods. See `src/transaction/utils.ts`.
|
||||
*
|
||||
* @param client - The Client used to connect to the ledger.
|
||||
* @param this - The Client used to connect to the ledger.
|
||||
* @param cushion - The fee cushion to use.
|
||||
* @returns The transaction fee.
|
||||
*/
|
||||
|
||||
@@ -82,10 +82,11 @@ async function getOrderbook(
|
||||
const buy: BookOffer[] = []
|
||||
const sell: BookOffer[] = []
|
||||
orders.forEach((order) => {
|
||||
if ((order.Flags & OfferLedgerFlags.lsfSell) !== 0) {
|
||||
sell.push(order)
|
||||
} else {
|
||||
// eslint-disable-next-line no-bitwise -- necessary for flags check
|
||||
if ((order.Flags & OfferLedgerFlags.lsfSell) === 0) {
|
||||
buy.push(order)
|
||||
} else {
|
||||
sell.push(order)
|
||||
}
|
||||
})
|
||||
return { buy: sortOffers(buy), sell: sortOffers(sell) }
|
||||
|
||||
@@ -7,6 +7,7 @@ import { xAddressToClassicAddress, isValidXAddress } from 'ripple-address-codec'
|
||||
* @returns The account's classic address.
|
||||
* @throws Error if the X-Address has an associated tag.
|
||||
*/
|
||||
// eslint-disable-next-line import/prefer-default-export -- okay for a utils file - there could be more exports later
|
||||
export function ensureClassicAddress(account: string): string {
|
||||
if (isValidXAddress(account)) {
|
||||
const { classicAddress, tag } = xAddressToClassicAddress(account)
|
||||
|
||||
@@ -154,7 +154,7 @@ export function computeStateTreeHash(entries: LedgerEntry[]): string {
|
||||
return shamap.hash
|
||||
}
|
||||
|
||||
export function computeTransactionHash(
|
||||
function computeTransactionHash(
|
||||
ledger: Ledger,
|
||||
options: ComputeLedgerHeaderHashOptions,
|
||||
): string {
|
||||
@@ -184,7 +184,7 @@ export function computeTransactionHash(
|
||||
return transactionHash
|
||||
}
|
||||
|
||||
export function computeStateHash(
|
||||
function computeStateHash(
|
||||
ledger: Ledger,
|
||||
options: ComputeLedgerHeaderHashOptions,
|
||||
): string {
|
||||
|
||||
@@ -30,11 +30,12 @@ class Leaf extends Node {
|
||||
/**
|
||||
* Add item to Leaf.
|
||||
*
|
||||
* @param tag - Index of the Node.
|
||||
* @param node - Node to insert.
|
||||
* @param _tag - Index of the Node.
|
||||
* @param _node - Node to insert.
|
||||
* @throws When called, because LeafNodes cannot addItem.
|
||||
*/
|
||||
public addItem(tag: string, node: Node): void {
|
||||
// eslint-disable-next-line class-methods-use-this -- no `this` needed here
|
||||
public addItem(_tag: string, _node: Node): void {
|
||||
throw new Error('Cannot call addItem on a LeafNode')
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,12 @@ function removeUndefined<T extends Record<string, unknown>>(obj: T): T {
|
||||
return newObj
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to its hex equivalent. Useful for Memos.
|
||||
*
|
||||
* @param string - The string to convert to Hex.
|
||||
* @returns The Hex equivalent of the string.
|
||||
*/
|
||||
function convertStringToHex(string: string): string {
|
||||
return Buffer.from(string, 'utf8').toString('hex').toUpperCase()
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { xrpToDrops } from './xrpConversion'
|
||||
* @param publicKey - Public key that signed the paymentChannelClaim.
|
||||
* @returns True if the channel is valid.
|
||||
*/
|
||||
// eslint-disable-next-line max-params -- Needs 4 params
|
||||
function verifyPaymentChannelClaim(
|
||||
channel: string,
|
||||
amount: string,
|
||||
|
||||
@@ -68,19 +68,17 @@ export function xrpToDrops(xrpToConvert: BigNumber.Value): string {
|
||||
if (typeof xrp === 'string') {
|
||||
if (!/^-?[0-9]*\.?[0-9]*$/u.exec(xrp)) {
|
||||
throw new ValidationError(
|
||||
`xrpToDrops: invalid value '${xrp}',` +
|
||||
` should be a number matching (^-?[0-9]*\\.?[0-9]*$).`,
|
||||
`xrpToDrops: invalid value '${xrp}', should be a number matching (^-?[0-9]*\\.?[0-9]*$).`,
|
||||
)
|
||||
} else if (xrp === '.') {
|
||||
throw new ValidationError(
|
||||
`xrpToDrops: invalid value '${xrp}',` +
|
||||
` should be a BigNumber or string-encoded number.`,
|
||||
`xrpToDrops: invalid value '${xrp}', should be a BigNumber or string-encoded number.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Important: specify base 10 to avoid exponential notation, e.g. '1e-7'.
|
||||
xrp = new BigNumber(xrp).toString(10)
|
||||
xrp = new BigNumber(xrp).toString(BASE_TEN)
|
||||
// This should never happen; the value has already been
|
||||
// validated above. This just ensures BigNumber did not do
|
||||
// something unexpected.
|
||||
|
||||
@@ -15,7 +15,6 @@ interface FaucetWallet {
|
||||
balance: number
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-shadow -- Not previously declared
|
||||
enum FaucetNetwork {
|
||||
Testnet = 'faucet.altnet.rippletest.net',
|
||||
Devnet = 'faucet.devnet.rippletest.net',
|
||||
@@ -69,6 +68,17 @@ async function generateFaucetWallet(
|
||||
// Options to pass to https.request
|
||||
const options = getOptions(client, postBody)
|
||||
|
||||
return returnPromise(options, client, startingBalance, fundWallet, postBody)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line max-params -- Helper function created for organizational purposes
|
||||
async function returnPromise(
|
||||
options: RequestOptions,
|
||||
client: Client,
|
||||
startingBalance: number,
|
||||
fundWallet: Wallet,
|
||||
postBody: Uint8Array,
|
||||
): Promise<Wallet | undefined> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = httpsRequest(options, (response) => {
|
||||
const chunks: Uint8Array[] = []
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Client } from 'xrpl-local'
|
||||
|
||||
describe('client constructor', function () {
|
||||
it('Client - implicit server port', function () {
|
||||
// eslint-disable-next-line no-new -- Testing constructor
|
||||
new Client('wss://s1.ripple.com')
|
||||
})
|
||||
|
||||
|
||||
@@ -1,362 +0,0 @@
|
||||
// import BigNumber from 'bignumber.js'
|
||||
// import {assert} from 'chai'
|
||||
// import {Client} from 'xrpl-local'
|
||||
// import requests from '../fixtures/requests'
|
||||
// import responses from '../fixtures/responses'
|
||||
|
||||
// function checkSortingOfOrders(orders) {
|
||||
// let previousRate = '0'
|
||||
// for (var i = 0; i < orders.length; i++) {
|
||||
// const order = orders[i]
|
||||
// let rate
|
||||
|
||||
// // We calculate the quality of output/input here as a test.
|
||||
// // This won't hold in general because when output and input amounts get tiny,
|
||||
// // the quality can differ significantly. However, the offer stays in the
|
||||
// // order book where it was originally placed. It would be more consistent
|
||||
// // to check the quality from the offer book, but for the test data set,
|
||||
// // this calculation holds.
|
||||
|
||||
// if (order.specification.direction === 'buy') {
|
||||
// rate = new BigNumber(order.specification.quantity.value)
|
||||
// .dividedBy(order.specification.totalPrice.value)
|
||||
// .toString()
|
||||
// } else {
|
||||
// rate = new BigNumber(order.specification.totalPrice.value)
|
||||
// .dividedBy(order.specification.quantity.value)
|
||||
// .toString()
|
||||
// }
|
||||
// assert(
|
||||
// new BigNumber(rate).isGreaterThanOrEqualTo(previousRate),
|
||||
// 'Rates must be sorted from least to greatest: ' +
|
||||
// rate +
|
||||
// ' should be >= ' +
|
||||
// previousRate
|
||||
// )
|
||||
// previousRate = rate
|
||||
// }
|
||||
// return true
|
||||
// }
|
||||
|
||||
describe('client.formatBidsAndAsks', function () {
|
||||
// 'normal': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// base: {
|
||||
// currency: 'USD',
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// },
|
||||
// counter: {
|
||||
// currency: 'BTC',
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// }
|
||||
// }
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
// taker_pays: orderbookInfo.counter,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 20,
|
||||
// taker: address
|
||||
// }),
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.counter,
|
||||
// taker_pays: orderbookInfo.base,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 20,
|
||||
// taker: address
|
||||
// })
|
||||
// ]).then(([directOfferResults, reverseOfferResults]) => {
|
||||
// const directOffers = (directOfferResults
|
||||
// ? directOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const reverseOffers = (reverseOfferResults
|
||||
// ? reverseOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const orderbook = Client.formatBidsAndAsks(orderbookInfo, [
|
||||
// ...directOffers,
|
||||
// ...reverseOffers
|
||||
// ])
|
||||
// assert.deepEqual(orderbook, responses.getOrderbook.normal)
|
||||
// })
|
||||
// },
|
||||
// 'with XRP': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// base: {
|
||||
// currency: 'USD',
|
||||
// issuer: 'rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw'
|
||||
// },
|
||||
// counter: {
|
||||
// currency: 'XRP'
|
||||
// }
|
||||
// }
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
// taker_pays: orderbookInfo.counter,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 20,
|
||||
// taker: address
|
||||
// }),
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.counter,
|
||||
// taker_pays: orderbookInfo.base,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 20,
|
||||
// taker: address
|
||||
// })
|
||||
// ]).then(([directOfferResults, reverseOfferResults]) => {
|
||||
// const directOffers = (directOfferResults
|
||||
// ? directOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const reverseOffers = (reverseOfferResults
|
||||
// ? reverseOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const orderbook = Client.formatBidsAndAsks(orderbookInfo, [
|
||||
// ...directOffers,
|
||||
// ...reverseOffers
|
||||
// ])
|
||||
// assert.deepEqual(orderbook, responses.getOrderbook.withXRP)
|
||||
// })
|
||||
// },
|
||||
// 'sample XRP/JPY book has orders sorted correctly': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// base: {
|
||||
// // the first currency in pair
|
||||
// currency: 'XRP'
|
||||
// },
|
||||
// counter: {
|
||||
// currency: 'JPY',
|
||||
// issuer: 'rB3gZey7VWHYRqJHLoHDEJXJ2pEPNieKiS'
|
||||
// }
|
||||
// }
|
||||
// const myAddress = 'rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR'
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
// taker_pays: orderbookInfo.counter,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 400, // must match `test/fixtures/rippled/requests/1-taker_gets-XRP-taker_pays-JPY.json`
|
||||
// taker: myAddress
|
||||
// }),
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.counter,
|
||||
// taker_pays: orderbookInfo.base,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 400, // must match `test/fixtures/rippled/requests/2-taker_gets-JPY-taker_pays-XRP.json`
|
||||
// taker: myAddress
|
||||
// })
|
||||
// ]).then(([directOfferResults, reverseOfferResults]) => {
|
||||
// const directOffers = (directOfferResults
|
||||
// ? directOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const reverseOffers = (reverseOfferResults
|
||||
// ? reverseOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const orderbook = Client.formatBidsAndAsks(orderbookInfo, [
|
||||
// ...directOffers,
|
||||
// ...reverseOffers
|
||||
// ])
|
||||
// assert.deepStrictEqual([], orderbook.bids)
|
||||
// return checkSortingOfOrders(orderbook.asks)
|
||||
// })
|
||||
// },
|
||||
// 'sample USD/XRP book has orders sorted correctly': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// counter: {currency: 'XRP'},
|
||||
// base: {
|
||||
// currency: 'USD',
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// }
|
||||
// }
|
||||
// const myAddress = 'rE9qNjzJXpiUbVomdv7R4xhrXVeH2oVmGR'
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
// taker_pays: orderbookInfo.counter,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 400, // must match `test/fixtures/rippled/requests/1-taker_gets-XRP-taker_pays-JPY.json`
|
||||
// taker: myAddress
|
||||
// }),
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.counter,
|
||||
// taker_pays: orderbookInfo.base,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 400, // must match `test/fixtures/rippled/requests/2-taker_gets-JPY-taker_pays-XRP.json`
|
||||
// taker: myAddress
|
||||
// })
|
||||
// ]).then(([directOfferResults, reverseOfferResults]) => {
|
||||
// const directOffers = (directOfferResults
|
||||
// ? directOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const reverseOffers = (reverseOfferResults
|
||||
// ? reverseOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const orderbook = Client.formatBidsAndAsks(orderbookInfo, [
|
||||
// ...directOffers,
|
||||
// ...reverseOffers
|
||||
// ])
|
||||
// return (
|
||||
// checkSortingOfOrders(orderbook.bids) &&
|
||||
// checkSortingOfOrders(orderbook.asks)
|
||||
// )
|
||||
// })
|
||||
// },
|
||||
// 'sorted so that best deals come first': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// base: {
|
||||
// currency: 'USD',
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// },
|
||||
// counter: {
|
||||
// currency: 'BTC',
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// }
|
||||
// }
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
// taker_pays: orderbookInfo.counter,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 20,
|
||||
// taker: address
|
||||
// }),
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.counter,
|
||||
// taker_pays: orderbookInfo.base,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 20,
|
||||
// taker: address
|
||||
// })
|
||||
// ]).then(([directOfferResults, reverseOfferResults]) => {
|
||||
// const directOffers = (directOfferResults
|
||||
// ? directOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const reverseOffers = (reverseOfferResults
|
||||
// ? reverseOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const orderbook = Client.formatBidsAndAsks(orderbookInfo, [
|
||||
// ...directOffers,
|
||||
// ...reverseOffers
|
||||
// ])
|
||||
// const bidRates = orderbook.bids.map(
|
||||
// (bid) => bid.properties.makerExchangeRate
|
||||
// )
|
||||
// const askRates = orderbook.asks.map(
|
||||
// (ask) => ask.properties.makerExchangeRate
|
||||
// )
|
||||
// // makerExchangeRate = quality = takerPays.value/takerGets.value
|
||||
// // so the best deal for the taker is the lowest makerExchangeRate
|
||||
// // bids and asks should be sorted so that the best deals come first
|
||||
// assert.deepEqual(bidRates.map((x) => Number(x)).sort(), bidRates)
|
||||
// assert.deepEqual(askRates.map((x) => Number(x)).sort(), askRates)
|
||||
// })
|
||||
// },
|
||||
// 'currency & counterparty are correct': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// base: {
|
||||
// currency: 'USD',
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// },
|
||||
// counter: {
|
||||
// currency: 'BTC',
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// }
|
||||
// }
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
// taker_pays: orderbookInfo.counter,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 20,
|
||||
// taker: address
|
||||
// }),
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.counter,
|
||||
// taker_pays: orderbookInfo.base,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 20,
|
||||
// taker: address
|
||||
// })
|
||||
// ]).then(([directOfferResults, reverseOfferResults]) => {
|
||||
// const directOffers = (directOfferResults
|
||||
// ? directOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const reverseOffers = (reverseOfferResults
|
||||
// ? reverseOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const orderbook = Client.formatBidsAndAsks(orderbookInfo, [
|
||||
// ...directOffers,
|
||||
// ...reverseOffers
|
||||
// ])
|
||||
// const orders = [...orderbook.bids, ...orderbook.asks]
|
||||
// orders.forEach((order) => {
|
||||
// const quantity = order.specification.quantity
|
||||
// const totalPrice = order.specification.totalPrice
|
||||
// const {base, counter} = requests.getOrderbook.normal
|
||||
// assert.strictEqual(quantity.currency, base.currency)
|
||||
// assert.strictEqual(quantity.counterparty, base.counterparty)
|
||||
// assert.strictEqual(totalPrice.currency, counter.currency)
|
||||
// assert.strictEqual(totalPrice.counterparty, counter.counterparty)
|
||||
// })
|
||||
// })
|
||||
// },
|
||||
// 'direction is correct for bids and asks': async (client, address) => {
|
||||
// const orderbookInfo = {
|
||||
// base: {
|
||||
// currency: 'USD',
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// },
|
||||
// counter: {
|
||||
// currency: 'BTC',
|
||||
// counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
|
||||
// }
|
||||
// }
|
||||
// await Promise.all([
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.base,
|
||||
// taker_pays: orderbookInfo.counter,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 20,
|
||||
// taker: address
|
||||
// }),
|
||||
// client.request({command: 'book_offers',
|
||||
// taker_gets: orderbookInfo.counter,
|
||||
// taker_pays: orderbookInfo.base,
|
||||
// ledger_index: 'validated',
|
||||
// limit: 20,
|
||||
// taker: address
|
||||
// })
|
||||
// ]).then(([directOfferResults, reverseOfferResults]) => {
|
||||
// const directOffers = (directOfferResults
|
||||
// ? directOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const reverseOffers = (reverseOfferResults
|
||||
// ? reverseOfferResults.result.offers
|
||||
// : []
|
||||
// ).reduce((acc, res) => acc.concat(res), [])
|
||||
// const orderbook = Client.formatBidsAndAsks(orderbookInfo, [
|
||||
// ...directOffers,
|
||||
// ...reverseOffers
|
||||
// ])
|
||||
// assert(
|
||||
// orderbook.bids.every((bid) => bid.specification.direction === 'buy')
|
||||
// )
|
||||
// assert(
|
||||
// orderbook.asks.every((ask) => ask.specification.direction === 'sell')
|
||||
// )
|
||||
// })
|
||||
// }
|
||||
})
|
||||
@@ -2,6 +2,7 @@
|
||||
// import { assert } from "chai";
|
||||
|
||||
import { assert } from 'chai'
|
||||
|
||||
import { BookOffersRequest } from '../../src'
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable mocha/no-hooks-for-single-case -- Use of hooks is restricted when there is a single test case. */
|
||||
import { assert } from 'chai'
|
||||
|
||||
import { setupClient, teardownClient } from '../setupClient'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable mocha/no-hooks-for-single-case -- expected for setupClient & teardownClient */
|
||||
import { assert } from 'chai'
|
||||
|
||||
import { Transaction } from 'xrpl-local/models/transactions'
|
||||
|
||||
@@ -3,7 +3,7 @@ import { assert } from 'chai'
|
||||
import rippled from '../fixtures/rippled'
|
||||
import { setupClient, teardownClient } from '../setupClient'
|
||||
|
||||
describe('Subscription', function () {
|
||||
describe('Client subscription', function () {
|
||||
beforeEach(setupClient)
|
||||
afterEach(teardownClient)
|
||||
|
||||
@@ -74,15 +74,6 @@ describe('Subscription', function () {
|
||||
this.client.connection.onMessage(JSON.stringify(rippled.streams.pathFind))
|
||||
})
|
||||
|
||||
it('Emits peerStatusChange', async function (done) {
|
||||
this.client.on('peerStatusChange', (path) => {
|
||||
assert(path.type === 'peerStatusChange')
|
||||
done()
|
||||
})
|
||||
|
||||
this.client.connection.onMessage(JSON.stringify(rippled.streams.peerStatus))
|
||||
})
|
||||
|
||||
it('Emits validationReceived', async function (done) {
|
||||
this.client.on('validationReceived', (path) => {
|
||||
assert(path.type === 'validationReceived')
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
XrplError,
|
||||
TimeoutError,
|
||||
} from 'xrpl-local'
|
||||
import { Connection } from 'xrpl-local/client'
|
||||
import { Connection } from 'xrpl-local/client/connection'
|
||||
|
||||
import rippled from './fixtures/rippled'
|
||||
import { setupClient, teardownClient } from './setupClient'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable max-params -- helper test functions */
|
||||
import { assert } from 'chai'
|
||||
import _ from 'lodash'
|
||||
import { decode } from 'ripple-binary-codec'
|
||||
|
||||
@@ -2,4 +2,6 @@ import { Wallet } from 'xrpl-local'
|
||||
|
||||
const walletSecret = 'shK6YXzwYfnFVn3YZSaMh5zuAddKx'
|
||||
|
||||
export const wallet = Wallet.fromSeed(walletSecret)
|
||||
const wallet = Wallet.fromSeed(walletSecret)
|
||||
|
||||
export default wallet
|
||||
|
||||
@@ -12,11 +12,8 @@ import {
|
||||
TrustSet,
|
||||
TrustSetTransactionFlags,
|
||||
} from 'xrpl-local'
|
||||
|
||||
import {
|
||||
isFlagEnabled,
|
||||
setTransactionFlagsToNumber,
|
||||
} from '../../src/models/utils'
|
||||
import { isFlagEnabled } from 'xrpl-local/models/utils'
|
||||
import setTransactionFlagsToNumber from 'xrpl-local/models/utils/flags'
|
||||
|
||||
/**
|
||||
* Utils Testing.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { assert } from 'chai'
|
||||
|
||||
import { ValidationError, XrplError } from 'xrpl-local'
|
||||
|
||||
import { computeLedgerHash } from '../../src/utils'
|
||||
import requests from '../fixtures/requests'
|
||||
import responses from '../fixtures/responses'
|
||||
@@ -23,7 +24,7 @@ describe('computeLedgerHash', function () {
|
||||
)
|
||||
|
||||
ledger.parent_close_time = ledger.close_time
|
||||
let hash
|
||||
let hash: string
|
||||
try {
|
||||
hash = computeLedgerHash(ledger, { computeTreeHashes: true })
|
||||
} catch (error) {
|
||||
@@ -139,6 +140,7 @@ describe('computeLedgerHash', function () {
|
||||
...REQUEST_FIXTURES.header,
|
||||
transaction_hash:
|
||||
'325EACC5271322539EEEC2D6A5292471EF1B3E72AE7180533EFC3B8F0AD435C9',
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- okay for tests
|
||||
transactions: REQUEST_FIXTURES.transactions as any,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { assert } from 'chai'
|
||||
|
||||
import ECDSA from '../../src/ecdsa'
|
||||
import { UnexpectedError } from 'xrpl-local'
|
||||
|
||||
import ECDSA from '../../src/ecdsa'
|
||||
import {
|
||||
generateXAddress,
|
||||
GenerateAddressOptions,
|
||||
|
||||
Reference in New Issue
Block a user