diff --git a/src/models/ledger/accountRoot.ts b/src/models/ledger/accountRoot.ts index f7111210..a5755384 100644 --- a/src/models/ledger/accountRoot.ts +++ b/src/models/ledger/accountRoot.ts @@ -18,3 +18,15 @@ export default interface AccountRoot extends BaseLedgerEntry { TickSize?: number TransferRate?: number } + +export enum AccountRootLedgerFlags { + lsfPasswordSpent = 0x00010000, + lsfRequireDestTag = 0x00020000, + lsfRequireAuth = 0x00040000, + lsfDisallowXRP = 0x00080000, + lsfDisableMaster = 0x00100000, + lsfNoFreeze = 0x00200000, + lsfGlobalFreeze = 0x00400000, + lsfDefaultRipple = 0x00800000, + lsfDepositAuth = 0x01000000, +} diff --git a/src/models/ledger/offer.ts b/src/models/ledger/offer.ts index 19c85b35..f9de2df7 100644 --- a/src/models/ledger/offer.ts +++ b/src/models/ledger/offer.ts @@ -16,3 +16,8 @@ export default interface Offer extends BaseLedgerEntry { PreviousTxnLgrSeq: number Expiration?: number } + +export enum OfferLedgerFlags { + lsfPassive = 0x00010000, + lsfSell = 0x00020000, +} diff --git a/src/models/ledger/rippleState.ts b/src/models/ledger/rippleState.ts index 2fd7165f..2376e3c1 100644 --- a/src/models/ledger/rippleState.ts +++ b/src/models/ledger/rippleState.ts @@ -17,3 +17,14 @@ export default interface RippleState extends BaseLedgerEntry { HighQualityIn?: number HighQualityOut?: number } + +export enum RippleStateLedgerFlags { + lsfLowReserve = 0x00010000, // True, if entry counts toward reserve. + 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 +} diff --git a/src/models/ledger/signerList.ts b/src/models/ledger/signerList.ts index 191fb3a4..d324f736 100644 --- a/src/models/ledger/signerList.ts +++ b/src/models/ledger/signerList.ts @@ -17,3 +17,7 @@ export default interface SignerList extends BaseLedgerEntry { SignerListID: number SignerQuorum: number } + +export enum SignerListLedgerFlags { + lsfOneOwnerCount = 0x00010000, // True, uses only one OwnerCount +} diff --git a/src/sugar/orderbook.ts b/src/sugar/orderbook.ts index 65498530..b8fa0014 100644 --- a/src/sugar/orderbook.ts +++ b/src/sugar/orderbook.ts @@ -3,14 +3,13 @@ import _ from 'lodash' import type { Client } from '../client' import { LedgerIndex } from '../models/common' +import { OfferLedgerFlags } from '../models/ledger/offer' import { BookOffer, BookOffersRequest, TakerAmount, } from '../models/methods/bookOffers' -import { orderFlags } from './parse/flags' - function sortOffers(offers: BookOffer[]): BookOffer[] { return offers.sort((offerA, offerB) => { const qualityA = offerA.quality ?? 0 @@ -64,6 +63,7 @@ async function getOrderbook( request.taker_gets = takerPays request.taker_pays = takerGets const reverseOfferResults = await client.requestAll(request) + // 3. Return Formatted Response const directOffers = _.flatMap( directOfferResults, @@ -73,6 +73,7 @@ async function getOrderbook( reverseOfferResults, (reverseOfferResult) => reverseOfferResult.result.offers, ) + // Sort the orders // for both buys and sells, lowest quality is closest to mid-market // we sort the orders so that earlier orders are closer to mid-market @@ -82,7 +83,7 @@ async function getOrderbook( const buy: BookOffer[] = [] const sell: BookOffer[] = [] orders.forEach((order) => { - if (order.Flags === orderFlags.Sell) { + if ((order.Flags & OfferLedgerFlags.lsfSell) !== 0) { sell.push(order) } else { buy.push(order) diff --git a/src/sugar/parse/account-delete.ts b/src/sugar/parse/account-delete.ts deleted file mode 100644 index 3f428f00..00000000 --- a/src/sugar/parse/account-delete.ts +++ /dev/null @@ -1,39 +0,0 @@ -import * as assert from 'assert' - -import { classicAddressToXAddress } from 'ripple-address-codec' - -import { removeUndefined } from '../../utils' - -import { parseMemos } from './utils' - -export interface FormattedAccountDelete { - // account (address) of an account to receive any leftover XRP after deleting the sending account. - // Must be a funded account in the ledger, and must not be the sending account. - destination: string - - // (Optional) Arbitrary destination tag that identifies a hosted recipient or other information - // for the recipient of the deleted account's leftover XRP. NB: Ensure that the hosted recipient is - // able to account for AccountDelete transactions; if not, your balance may not be properly credited. - destinationTag?: number - - // X-address of an account to receive any leftover XRP after deleting the sending account. - // Must be a funded account in the ledger, and must not be the sending account. - destinationXAddress: string -} - -function parseAccountDelete(tx: any): FormattedAccountDelete { - assert.ok(tx.TransactionType === 'AccountDelete') - - return removeUndefined({ - memos: parseMemos(tx), - destination: tx.Destination, - destinationTag: tx.DestinationTag, - destinationXAddress: classicAddressToXAddress( - tx.Destination, - tx.DestinationTag == null ? false : tx.DestinationTag, - false, - ), - }) -} - -export default parseAccountDelete diff --git a/src/sugar/parse/account-order.ts b/src/sugar/parse/account-order.ts deleted file mode 100644 index 8d18f1cf..00000000 --- a/src/sugar/parse/account-order.ts +++ /dev/null @@ -1,62 +0,0 @@ -import BigNumber from 'bignumber.js' - -import { FormattedOrderSpecification } from '../../common/types/objects' -import { removeUndefined } from '../../utils' - -import parseAmount from './amount' -import { orderFlags } from './flags' -import { parseTimestamp, adjustQualityForXRP } from './utils' - -export interface FormattedAccountOrder { - specification: FormattedOrderSpecification - properties: { - maker: string - sequence: number - makerExchangeRate: string - } -} - -// TODO: remove this function once rippled provides quality directly -function computeQuality(takerGets, takerPays) { - const quotient = new BigNumber(takerPays.value).dividedBy(takerGets.value) - return quotient.precision(16, BigNumber.ROUND_HALF_UP).toString() -} - -// rippled 'account_offers' returns a different format for orders than 'tx' -// the flags are also different -export function parseAccountOrder( - address: string, - order: any, -): FormattedAccountOrder { - const direction = (order.flags & orderFlags.Sell) === 0 ? 'buy' : 'sell' - const takerGetsAmount = parseAmount(order.taker_gets) - const takerPaysAmount = parseAmount(order.taker_pays) - const quantity = direction === 'buy' ? takerPaysAmount : takerGetsAmount - const totalPrice = direction === 'buy' ? takerGetsAmount : takerPaysAmount - - // note: immediateOrCancel and fillOrKill orders cannot enter the order book - // so we can omit those flags here - const specification = removeUndefined({ - direction, - quantity, - totalPrice, - passive: (order.flags & orderFlags.Passive) !== 0 || undefined, - // rippled currently does not provide "expiration" in account_offers - expirationTime: parseTimestamp(order.expiration), - }) - - const makerExchangeRate = order.quality - ? adjustQualityForXRP( - order.quality.toString(), - takerGetsAmount.currency, - takerPaysAmount.currency, - ) - : computeQuality(takerGetsAmount, takerPaysAmount) - const properties = { - maker: address, - sequence: order.seq, - makerExchangeRate, - } - - return { specification, properties } -} diff --git a/src/sugar/parse/account-trustline.ts b/src/sugar/parse/account-trustline.ts deleted file mode 100644 index 7534f842..00000000 --- a/src/sugar/parse/account-trustline.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - Trustline, - FormattedTrustline, -} from '../../common/types/objects/trustlines' -import { removeUndefined } from '../../utils' - -import { parseQuality } from './utils' - -// rippled 'account_lines' returns a different format for -// trustlines than 'tx' -function parseAccountTrustline(trustline: Trustline): FormattedTrustline { - const specification = removeUndefined({ - limit: trustline.limit, - currency: trustline.currency, - counterparty: trustline.account, - qualityIn: parseQuality(trustline.quality_in) || undefined, - qualityOut: parseQuality(trustline.quality_out) || undefined, - ripplingDisabled: trustline.no_ripple, - frozen: trustline.freeze, - authorized: trustline.authorized, - }) - // rippled doesn't provide the counterparty's qualities - const counterparty = removeUndefined({ - limit: trustline.limit_peer, - ripplingDisabled: trustline.no_ripple_peer, - frozen: trustline.freeze_peer, - authorized: trustline.peer_authorized, - }) - const state = { - balance: trustline.balance, - } - return { specification, counterparty, state } -} - -export default parseAccountTrustline diff --git a/src/sugar/parse/amendment.ts b/src/sugar/parse/amendment.ts deleted file mode 100644 index c9834688..00000000 --- a/src/sugar/parse/amendment.ts +++ /dev/null @@ -1,7 +0,0 @@ -function parseAmendment(tx: any) { - return { - amendment: tx.Amendment, - } -} - -export default parseAmendment diff --git a/src/sugar/parse/amount.ts b/src/sugar/parse/amount.ts deleted file mode 100644 index ed973f25..00000000 --- a/src/sugar/parse/amount.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Amount, RippledAmount } from '../../common/types/objects' -import { dropsToXrp } from '../../utils' - -function parseAmount(amount: RippledAmount): Amount { - if (typeof amount === 'string') { - return { - currency: 'XRP', - value: dropsToXrp(amount), - } - } - return { - currency: amount.currency, - value: amount.value, - counterparty: amount.issuer, - } -} - -export default parseAmount diff --git a/src/sugar/parse/cancellation.ts b/src/sugar/parse/cancellation.ts deleted file mode 100644 index 05630031..00000000 --- a/src/sugar/parse/cancellation.ts +++ /dev/null @@ -1,13 +0,0 @@ -import * as assert from 'assert' - -import { parseMemos } from './utils' - -function parseOrderCancellation(tx: any): object { - assert.ok(tx.TransactionType === 'OfferCancel') - return { - memos: parseMemos(tx), - orderSequence: tx.OfferSequence, - } -} - -export default parseOrderCancellation diff --git a/src/sugar/parse/check-cancel.ts b/src/sugar/parse/check-cancel.ts deleted file mode 100644 index c6519c14..00000000 --- a/src/sugar/parse/check-cancel.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as assert from 'assert' - -import { removeUndefined } from '../../utils' - -import { parseMemos } from './utils' - -export interface FormattedCheckCancel { - // ID of the Check ledger object to cancel. - checkID: string -} - -function parseCheckCancel(tx: any): FormattedCheckCancel { - assert.ok(tx.TransactionType === 'CheckCancel') - - return removeUndefined({ - memos: parseMemos(tx), - checkID: tx.CheckID, - }) -} - -export default parseCheckCancel diff --git a/src/sugar/parse/check-cash.ts b/src/sugar/parse/check-cash.ts deleted file mode 100644 index 27f18d4e..00000000 --- a/src/sugar/parse/check-cash.ts +++ /dev/null @@ -1,38 +0,0 @@ -import * as assert from 'assert' - -import { Amount } from '../../common/types/objects' -import { removeUndefined } from '../../utils' - -import parseAmount from './amount' -import { parseMemos } from './utils' - -export interface FormattedCheckCash { - // ID of the Check ledger object to cash. - checkID: string - - // (Optional) redeem the Check for exactly this amount, if possible. - // The currency must match that of the `SendMax` of the corresponding - // `CheckCreate` transaction. - amount: Amount - - // (Optional) redeem the Check for at least this amount and - // for as much as possible. - // The currency must match that of the `SendMax` of the corresponding - // `CheckCreate` transaction. - deliverMin: Amount - - // *must* include either Amount or DeliverMin, but not both. -} - -function parseCheckCash(tx: any): FormattedCheckCash { - assert.ok(tx.TransactionType === 'CheckCash') - - return removeUndefined({ - memos: parseMemos(tx), - checkID: tx.CheckID, - amount: tx.Amount && parseAmount(tx.Amount), - deliverMin: tx.DeliverMin && parseAmount(tx.DeliverMin), - }) -} - -export default parseCheckCash diff --git a/src/sugar/parse/check-create.ts b/src/sugar/parse/check-create.ts deleted file mode 100644 index 6fa164d6..00000000 --- a/src/sugar/parse/check-create.ts +++ /dev/null @@ -1,40 +0,0 @@ -import * as assert from 'assert' - -import { Amount } from '../../common/types/objects' -import { removeUndefined } from '../../utils' - -import parseAmount from './amount' -import { parseTimestamp, parseMemos } from './utils' - -export interface FormattedCheckCreate { - // account that can cash the check. - destination: string - - // amount the check is allowed to debit the sender, - // including transfer fees on non-XRP currencies. - sendMax: Amount - - // (Optional) identifies the reason for the check, or a hosted recipient. - destinationTag?: string - - // (Optional) time in seconds since the Ripple Epoch. - expiration?: string - - // (Optional) 256-bit hash representing a specific reason or identifier. - invoiceID?: string -} - -function parseCheckCreate(tx: any): FormattedCheckCreate { - assert.ok(tx.TransactionType === 'CheckCreate') - - return removeUndefined({ - memos: parseMemos(tx), - destination: tx.Destination, - sendMax: parseAmount(tx.SendMax), - destinationTag: tx.DestinationTag, - expiration: tx.Expiration && parseTimestamp(tx.Expiration), - invoiceID: tx.InvoiceID, - }) -} - -export default parseCheckCreate diff --git a/src/sugar/parse/deposit-preauth.ts b/src/sugar/parse/deposit-preauth.ts deleted file mode 100644 index 4a6f0408..00000000 --- a/src/sugar/parse/deposit-preauth.ts +++ /dev/null @@ -1,25 +0,0 @@ -import * as assert from 'assert' - -import { removeUndefined } from '../../utils' - -import { parseMemos } from './utils' - -export interface FormattedDepositPreauth { - // account (address) of the sender to preauthorize - authorize: string - - // account (address) of the sender whose preauthorization should be revoked - unauthorize: string -} - -function parseDepositPreauth(tx: any): FormattedDepositPreauth { - assert.ok(tx.TransactionType === 'DepositPreauth') - - return removeUndefined({ - memos: parseMemos(tx), - authorize: tx.Authorize, - unauthorize: tx.Unauthorize, - }) -} - -export default parseDepositPreauth diff --git a/src/sugar/parse/escrow-cancellation.ts b/src/sugar/parse/escrow-cancellation.ts deleted file mode 100644 index 2003898a..00000000 --- a/src/sugar/parse/escrow-cancellation.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as assert from 'assert' - -import { removeUndefined } from '../../utils' - -import { parseMemos } from './utils' - -function parseEscrowCancellation(tx: any): object { - assert.ok(tx.TransactionType === 'EscrowCancel') - - return removeUndefined({ - memos: parseMemos(tx), - owner: tx.Owner, - escrowSequence: tx.OfferSequence, - }) -} - -export default parseEscrowCancellation diff --git a/src/sugar/parse/escrow-creation.ts b/src/sugar/parse/escrow-creation.ts deleted file mode 100644 index abf7b7e3..00000000 --- a/src/sugar/parse/escrow-creation.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as assert from 'assert' - -import { removeUndefined } from '../../utils' - -import parseAmount from './amount' -import { parseTimestamp, parseMemos } from './utils' - -function parseEscrowCreation(tx: any): object { - assert.ok(tx.TransactionType === 'EscrowCreate') - - return removeUndefined({ - amount: parseAmount(tx.Amount).value, - destination: tx.Destination, - memos: parseMemos(tx), - condition: tx.Condition, - allowCancelAfter: parseTimestamp(tx.CancelAfter), - allowExecuteAfter: parseTimestamp(tx.FinishAfter), - sourceTag: tx.SourceTag, - destinationTag: tx.DestinationTag, - }) -} - -export default parseEscrowCreation diff --git a/src/sugar/parse/escrow-execution.ts b/src/sugar/parse/escrow-execution.ts deleted file mode 100644 index 33ba4c35..00000000 --- a/src/sugar/parse/escrow-execution.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as assert from 'assert' - -import { removeUndefined } from '../../utils' - -import { parseMemos } from './utils' - -function parseEscrowExecution(tx: any): object { - assert.ok(tx.TransactionType === 'EscrowFinish') - - return removeUndefined({ - memos: parseMemos(tx), - owner: tx.Owner, - escrowSequence: tx.OfferSequence, - condition: tx.Condition, - fulfillment: tx.Fulfillment, - }) -} - -export default parseEscrowExecution diff --git a/src/sugar/parse/fee-update.ts b/src/sugar/parse/fee-update.ts deleted file mode 100644 index b70853a8..00000000 --- a/src/sugar/parse/fee-update.ts +++ /dev/null @@ -1,18 +0,0 @@ -import BigNumber from 'bignumber.js' - -import { dropsToXrp } from '../../utils' - -import { parseMemos } from './utils' - -function parseFeeUpdate(tx: any) { - const baseFeeDrops = new BigNumber(tx.BaseFee, 16).toString() - return { - memos: parseMemos(tx), - baseFeeXRP: dropsToXrp(baseFeeDrops), - referenceFeeUnits: tx.ReferenceFeeUnits, - reserveBaseXRP: dropsToXrp(tx.ReserveBase), - reserveIncrementXRP: dropsToXrp(tx.ReserveIncrement), - } -} - -export default parseFeeUpdate diff --git a/src/sugar/parse/fields.ts b/src/sugar/parse/fields.ts deleted file mode 100644 index af8f93d2..00000000 --- a/src/sugar/parse/fields.ts +++ /dev/null @@ -1,54 +0,0 @@ -import BigNumber from 'bignumber.js' -import _ from 'lodash' - -import { constants } from '..' - -const AccountFields = constants.AccountFields - -function parseField(info, value) { - if (info.encoding === 'hex' && !info.length) { - // e.g. "domain" - return Buffer.from(value, 'hex').toString('ascii') - } - if (info.shift) { - return new BigNumber(value).shiftedBy(-info.shift).toNumber() - } - return value -} - -function parseFields(data: any): object { - const settings: any = {} - for (const fieldName in AccountFields) { - const fieldValue = data[fieldName] - if (fieldValue != null) { - const info = AccountFields[fieldName] - settings[info.name] = parseField(info, fieldValue) - } - } - - if (data.RegularKey) { - settings.regularKey = data.RegularKey - } - - // Since an account can own at most one SignerList, - // this array must have exactly one member if it is present. - if (data.signer_lists && data.signer_lists.length === 1) { - settings.signers = {} - if (data.signer_lists[0].SignerQuorum) { - settings.signers.threshold = data.signer_lists[0].SignerQuorum - } - if (data.signer_lists[0].SignerEntries) { - settings.signers.weights = data.signer_lists[0].SignerEntries.map( - (entry: any) => { - return { - address: entry.SignerEntry.Account, - weight: entry.SignerEntry.SignerWeight, - } - }, - ) - } - } - return settings -} - -export default parseFields diff --git a/src/sugar/parse/flags.ts b/src/sugar/parse/flags.ts deleted file mode 100644 index ba1f1634..00000000 --- a/src/sugar/parse/flags.ts +++ /dev/null @@ -1,17 +0,0 @@ -const orderFlags = { - Passive: 0x00010000, - Sell: 0x00020000, // offer was placed as a sell -} - -const trustlineFlags = { - LowReserve: 0x00010000, // entry counts toward reserve - HighReserve: 0x00020000, - LowAuth: 0x00040000, - HighAuth: 0x00080000, - LowNoRipple: 0x00100000, - HighNoRipple: 0x00200000, - LowFreeze: 0x00400000, - HighFreeze: 0x00800000, -} - -export { orderFlags, trustlineFlags } diff --git a/src/sugar/parse/ledger.ts b/src/sugar/parse/ledger.ts deleted file mode 100644 index d4e949de..00000000 --- a/src/sugar/parse/ledger.ts +++ /dev/null @@ -1,92 +0,0 @@ -import _ from 'lodash' - -import { TransactionAndMetadata } from '../../models/transactions' -import { removeUndefined, rippleTimeToISOTime } from '../../utils' - -import parseTransaction from './transaction' - -export interface FormattedLedger { - // TODO: properties in type don't match response object. Fix! - // closed: boolean, - stateHash: string - closeTime: string - closeTimeResolution: number - closeFlags: number - ledgerHash: string - ledgerVersion: number - parentLedgerHash: string - parentCloseTime: string - totalDrops: string - transactionHash: string - transactions?: object[] - transactionHashes?: string[] - rawState?: string - stateHashes?: string[] -} - -function parseTransactionWrapper( - ledgerVersion: number, - tx: TransactionAndMetadata, -) { - // renames metaData to meta and adds ledger_index - const transaction = { - ..._.omit(tx, 'metadata'), - meta: tx.metadata, - ledger_index: ledgerVersion, - } - const result = parseTransaction(transaction, true) - if (!result.outcome.ledgerVersion) { - result.outcome.ledgerVersion = ledgerVersion - } - return result -} - -function parseTransactions( - transactions: string[] | TransactionAndMetadata[], - ledgerVersion: number, -) { - if (_.isEmpty(transactions)) { - return {} - } - if (typeof transactions[0] === 'string') { - return { transactionHashes: transactions as unknown as string[] } - } - return { - transactions: (transactions as unknown as TransactionAndMetadata[]).map( - _.partial(parseTransactionWrapper, ledgerVersion), - ), - } -} - -function parseState(state) { - if (_.isEmpty(state)) { - return {} - } - if (typeof state[0] === 'string') { - return { stateHashes: state } - } - return { rawState: JSON.stringify(state) } -} - -/** - * @param ledger - Must be a *closed* ledger with valid `close_time` and `parent_close_time`. - * @returns Formatted ledger. - * @throws RangeError: Invalid time value (rippleTimeToISOTime). - */ -export function parseLedger(ledger): FormattedLedger { - const ledgerVersion = parseInt(ledger.ledger_index, 10) - return removeUndefined({ - stateHash: ledger.account_hash, - closeTime: rippleTimeToISOTime(ledger.close_time), - closeTimeResolution: ledger.close_time_resolution, - closeFlags: ledger.close_flags, - ledgerHash: ledger.ledger_hash, - ledgerVersion, - parentLedgerHash: ledger.parent_hash, - parentCloseTime: rippleTimeToISOTime(ledger.parent_close_time), - totalDrops: ledger.total_coins, - transactionHash: ledger.transaction_hash, - ...parseTransactions(ledger.transactions, ledgerVersion), - ...parseState(ledger.accountState), - }) -} diff --git a/src/sugar/parse/order.ts b/src/sugar/parse/order.ts deleted file mode 100644 index 157831a7..00000000 --- a/src/sugar/parse/order.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as assert from 'assert' - -import { txFlags } from '..' -import { - FormattedOrderSpecification, - OfferCreateTransaction, -} from '../../common/types/objects/index' -import { removeUndefined } from '../../utils' - -import parseAmount from './amount' -import { parseTimestamp, parseMemos } from './utils' - -const flags = txFlags.OfferCreate - -function parseOrder(tx: OfferCreateTransaction): FormattedOrderSpecification { - assert.ok(tx.TransactionType === 'OfferCreate') - - const direction = (tx.Flags & flags.Sell) === 0 ? 'buy' : 'sell' - const takerGetsAmount = parseAmount(tx.TakerGets) - const takerPaysAmount = parseAmount(tx.TakerPays) - const quantity = direction === 'buy' ? takerPaysAmount : takerGetsAmount - const totalPrice = direction === 'buy' ? takerGetsAmount : takerPaysAmount - - return removeUndefined({ - memos: parseMemos(tx), - direction, - quantity, - totalPrice, - passive: (tx.Flags & flags.Passive) !== 0 || undefined, - immediateOrCancel: (tx.Flags & flags.ImmediateOrCancel) !== 0 || undefined, - fillOrKill: (tx.Flags & flags.FillOrKill) !== 0 || undefined, - expirationTime: parseTimestamp(tx.Expiration), - }) -} - -export default parseOrder diff --git a/src/sugar/parse/orderbook-order.ts b/src/sugar/parse/orderbook-order.ts deleted file mode 100644 index 9a173643..00000000 --- a/src/sugar/parse/orderbook-order.ts +++ /dev/null @@ -1,74 +0,0 @@ -import _ from 'lodash' - -import { BookOffer } from '../../common/types/commands' -import { Amount, FormattedOrderSpecification } from '../../common/types/objects' -import { removeUndefined } from '../../utils' - -import parseAmount from './amount' -import { orderFlags } from './flags' -import { parseTimestamp, adjustQualityForXRP } from './utils' - -export interface FormattedOrderbookOrder { - specification: FormattedOrderSpecification - properties: { - maker: string - sequence: number - makerExchangeRate: string - } - state?: { - fundedAmount: Amount - priceOfFundedAmount: Amount - } - data: BookOffer -} - -export function parseOrderbookOrder(data: BookOffer): FormattedOrderbookOrder { - const direction = (data.Flags & orderFlags.Sell) === 0 ? 'buy' : 'sell' - const takerGetsAmount = parseAmount(data.TakerGets) - const takerPaysAmount = parseAmount(data.TakerPays) - const quantity = direction === 'buy' ? takerPaysAmount : takerGetsAmount - const totalPrice = direction === 'buy' ? takerGetsAmount : takerPaysAmount - - // note: immediateOrCancel and fillOrKill orders cannot enter the order book - // so we can omit those flags here - const specification: FormattedOrderSpecification = removeUndefined({ - direction, - quantity, - totalPrice, - passive: (data.Flags & orderFlags.Passive) !== 0 || undefined, - expirationTime: parseTimestamp(data.Expiration), - }) - - if (data.quality == null) { - throw new Error('parseOrderBookOrder: Could not find quality') - } - - const properties = { - maker: data.Account, - sequence: data.Sequence, - makerExchangeRate: adjustQualityForXRP( - data.quality, - takerGetsAmount.currency, - takerPaysAmount.currency, - ), - } - - const takerGetsFunded = data.taker_gets_funded - ? parseAmount(data.taker_gets_funded) - : undefined - const takerPaysFunded = data.taker_pays_funded - ? parseAmount(data.taker_pays_funded) - : undefined - const available = removeUndefined({ - fundedAmount: takerGetsFunded, - priceOfFundedAmount: takerPaysFunded, - }) - const state = _.isEmpty(available) ? undefined : available - - return removeUndefined({ - specification, - properties, - state, - data, - }) as FormattedOrderbookOrder -} diff --git a/src/sugar/parse/pathfind.ts b/src/sugar/parse/pathfind.ts deleted file mode 100644 index 86b511ed..00000000 --- a/src/sugar/parse/pathfind.ts +++ /dev/null @@ -1,70 +0,0 @@ -import _ from 'lodash' - -import { Amount, RippledAmount } from '../../common/types/objects' -import { Path, GetPaths, RippledPathsResponse } from '../pathfind-types' - -import parseAmount from './amount' - -function parsePaths(paths) { - return paths.map((steps) => - steps.map((step) => _.omit(step, ['type', 'type_hex'])), - ) -} - -function removeAnyCounterpartyEncoding(address: string, amount: Amount) { - return amount.counterparty === address - ? _.omit(amount, 'counterparty') - : amount -} - -function createAdjustment( - address: string, - adjustmentWithoutAddress: object, -): any { - const amountKey = Object.keys(adjustmentWithoutAddress)[0] - const amount = adjustmentWithoutAddress[amountKey] - return _.set( - { address }, - amountKey, - removeAnyCounterpartyEncoding(address, amount), - ) -} - -function parseAlternative( - sourceAddress: string, - destinationAddress: string, - destinationAmount: RippledAmount, - alternative: any, -): Path { - // we use "maxAmount"/"minAmount" here so that the result can be passed - // directly to preparePayment - const amounts = - alternative.destination_amount != null - ? { - source: { amount: parseAmount(alternative.source_amount) }, - destination: { - minAmount: parseAmount(alternative.destination_amount), - }, - } - : { - source: { maxAmount: parseAmount(alternative.source_amount) }, - destination: { amount: parseAmount(destinationAmount) }, - } - - return { - source: createAdjustment(sourceAddress, amounts.source), - destination: createAdjustment(destinationAddress, amounts.destination), - paths: JSON.stringify(parsePaths(alternative.paths_computed)), - } -} - -function parsePathfind(pathfindResult: RippledPathsResponse): GetPaths { - const sourceAddress = pathfindResult.source_account - const destinationAddress = pathfindResult.destination_account - const destinationAmount = pathfindResult.destination_amount - return pathfindResult.alternatives.map((alt) => - parseAlternative(sourceAddress, destinationAddress, destinationAmount, alt), - ) -} - -export default parsePathfind diff --git a/src/sugar/parse/payment-channel-claim.ts b/src/sugar/parse/payment-channel-claim.ts deleted file mode 100644 index 67a3949f..00000000 --- a/src/sugar/parse/payment-channel-claim.ts +++ /dev/null @@ -1,26 +0,0 @@ -import * as assert from 'assert' - -import { txFlags } from '..' -import { removeUndefined } from '../../utils' - -import parseAmount from './amount' -import { parseMemos } from './utils' - -const claimFlags = txFlags.PaymentChannelClaim - -function parsePaymentChannelClaim(tx: any): object { - assert.ok(tx.TransactionType === 'PaymentChannelClaim') - - return removeUndefined({ - memos: parseMemos(tx), - channel: tx.Channel, - balance: tx.Balance && parseAmount(tx.Balance).value, - amount: tx.Amount && parseAmount(tx.Amount).value, - signature: tx.Signature, - publicKey: tx.PublicKey, - renew: Boolean(tx.Flags & claimFlags.Renew) || undefined, - close: Boolean(tx.Flags & claimFlags.Close) || undefined, - }) -} - -export default parsePaymentChannelClaim diff --git a/src/sugar/parse/payment-channel-create.ts b/src/sugar/parse/payment-channel-create.ts deleted file mode 100644 index e6be67e9..00000000 --- a/src/sugar/parse/payment-channel-create.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as assert from 'assert' - -import { removeUndefined } from '../../utils' - -import parseAmount from './amount' -import { parseTimestamp, parseMemos } from './utils' - -function parsePaymentChannelCreate(tx: any): object { - assert.ok(tx.TransactionType === 'PaymentChannelCreate') - - return removeUndefined({ - memos: parseMemos(tx), - amount: parseAmount(tx.Amount).value, - destination: tx.Destination, - settleDelay: tx.SettleDelay, - publicKey: tx.PublicKey, - cancelAfter: tx.CancelAfter && parseTimestamp(tx.CancelAfter), - sourceTag: tx.SourceTag, - destinationTag: tx.DestinationTag, - }) -} - -export default parsePaymentChannelCreate diff --git a/src/sugar/parse/payment-channel-fund.ts b/src/sugar/parse/payment-channel-fund.ts deleted file mode 100644 index 2ea87149..00000000 --- a/src/sugar/parse/payment-channel-fund.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as assert from 'assert' - -import { removeUndefined } from '../../utils' - -import parseAmount from './amount' -import { parseTimestamp, parseMemos } from './utils' - -function parsePaymentChannelFund(tx: any): object { - assert.ok(tx.TransactionType === 'PaymentChannelFund') - - return removeUndefined({ - memos: parseMemos(tx), - channel: tx.Channel, - amount: parseAmount(tx.Amount).value, - expiration: tx.Expiration && parseTimestamp(tx.Expiration), - }) -} - -export default parsePaymentChannelFund diff --git a/src/sugar/parse/payment-channel.ts b/src/sugar/parse/payment-channel.ts deleted file mode 100644 index 56074cb7..00000000 --- a/src/sugar/parse/payment-channel.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { PayChannel } from '../../models/ledger' -import { removeUndefined, dropsToXrp } from '../../utils' - -import { parseTimestamp, parseMemos } from './utils' - -export interface FormattedPaymentChannel { - account: string - amount: string - balance: string - publicKey: string - destination: string - settleDelay: number - expiration?: string - cancelAfter?: string - sourceTag?: number - destinationTag?: number - previousAffectingTransactionID: string - previousAffectingTransactionLedgerVersion: number -} - -export function parsePaymentChannel(data: PayChannel): FormattedPaymentChannel { - return removeUndefined({ - memos: parseMemos(data), - account: data.Account, - amount: dropsToXrp(data.Amount), - balance: dropsToXrp(data.Balance), - destination: data.Destination, - publicKey: data.PublicKey, - settleDelay: data.SettleDelay, - expiration: parseTimestamp(data.Expiration), - cancelAfter: parseTimestamp(data.CancelAfter), - sourceTag: data.SourceTag, - destinationTag: data.DestinationTag, - previousAffectingTransactionID: data.PreviousTxnID, - previousAffectingTransactionLedgerVersion: data.PreviousTxnLgrSeq, - }) -} diff --git a/src/sugar/parse/payment.ts b/src/sugar/parse/payment.ts deleted file mode 100644 index 48d869e7..00000000 --- a/src/sugar/parse/payment.ts +++ /dev/null @@ -1,59 +0,0 @@ -import * as assert from 'assert' - -import _ from 'lodash' - -import { txFlags } from '..' -import { removeUndefined } from '../../utils' - -import parseAmount from './amount' -import * as utils from './utils' - -function isNoDirectRipple(tx) { - return (tx.Flags & txFlags.Payment.NoRippleDirect) !== 0 -} - -function isQualityLimited(tx) { - return (tx.Flags & txFlags.Payment.LimitQuality) !== 0 -} - -function removeGenericCounterparty(amount, address) { - return amount.counterparty === address - ? _.omit(amount, 'counterparty') - : amount -} - -// Payment specification -function parsePayment(tx: any): object { - assert.ok(tx.TransactionType === 'Payment') - - const source = { - address: tx.Account, - maxAmount: removeGenericCounterparty( - parseAmount(tx.SendMax || tx.Amount), - tx.Account, - ), - tag: tx.SourceTag, - } - - const destination: { - address: string - tag: number | undefined - } = { - address: tx.Destination, - tag: tx.DestinationTag, - // Notice that `amount` is omitted to prevent misinterpretation - } - - return removeUndefined({ - source: removeUndefined(source), - destination: removeUndefined(destination), - memos: utils.parseMemos(tx), - invoiceID: tx.InvoiceID, - paths: tx.Paths ? JSON.stringify(tx.Paths) : undefined, - allowPartialPayment: utils.isPartialPayment(tx) || undefined, - noDirectRipple: isNoDirectRipple(tx) || undefined, - limitQuality: isQualityLimited(tx) || undefined, - }) -} - -export default parsePayment diff --git a/src/sugar/parse/settings.ts b/src/sugar/parse/settings.ts deleted file mode 100644 index 28bf8644..00000000 --- a/src/sugar/parse/settings.ts +++ /dev/null @@ -1,69 +0,0 @@ -import * as assert from 'assert' - -import _ from 'lodash' - -import { constants } from '..' - -import parseFields from './fields' - -const AccountFlags = constants.AccountFlags - -function getAccountRootModifiedNode(tx: any) { - const modifiedNodes = tx.meta.AffectedNodes.filter( - (node) => node.ModifiedNode.LedgerEntryType === 'AccountRoot', - ) - assert.ok(modifiedNodes.length === 1) - return modifiedNodes[0].ModifiedNode -} - -function parseFlags(tx: any): any { - const settings: any = {} - if (tx.TransactionType !== 'AccountSet') { - return settings - } - - const node = getAccountRootModifiedNode(tx) - const oldFlags = _.get(node.PreviousFields, 'Flags') - const newFlags = _.get(node.FinalFields, 'Flags') - - if (oldFlags != null && newFlags != null) { - const changedFlags = oldFlags ^ newFlags - const setFlags = newFlags & changedFlags - const clearedFlags = oldFlags & changedFlags - Object.entries(AccountFlags).forEach((entry) => { - const [flagName, flagValue] = entry - if (setFlags & flagValue) { - settings[flagName] = true - } else if (clearedFlags & flagValue) { - settings[flagName] = false - } - }) - } - - // enableTransactionIDTracking requires a special case because it - // does not affect the Flags field; instead it adds/removes a field called - // "AccountTxnID" to/from the account root. - - const oldField = _.get(node.PreviousFields, 'AccountTxnID') - const newField = _.get(node.FinalFields, 'AccountTxnID') - if (newField && !oldField) { - settings.enableTransactionIDTracking = true - } else if (oldField && !newField) { - settings.enableTransactionIDTracking = false - } - - return settings -} - -function parseSettings(tx: any) { - const txType = tx.TransactionType - assert.ok( - txType === 'AccountSet' || - txType === 'SetRegularKey' || - txType === 'SignerListSet', - ) - - return { ...parseFlags(tx), ...parseFields(tx) } -} - -export default parseSettings diff --git a/src/sugar/parse/ticket-create.ts b/src/sugar/parse/ticket-create.ts deleted file mode 100644 index c9e695d6..00000000 --- a/src/sugar/parse/ticket-create.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as assert from 'assert' - -import { removeUndefined } from '../../utils' - -import { parseMemos } from './utils' - -function parseTicketCreate(tx: any): object { - assert.ok(tx.TransactionType === 'TicketCreate') - return removeUndefined({ - memos: parseMemos(tx), - ticketCount: tx.TicketCount, - }) -} - -export default parseTicketCreate diff --git a/src/sugar/parse/transaction.ts b/src/sugar/parse/transaction.ts deleted file mode 100644 index 37a161a8..00000000 --- a/src/sugar/parse/transaction.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { removeUndefined } from '../../utils' - -import parseAccountDelete from './account-delete' -import parseAmendment from './amendment' // pseudo-transaction -import parseOrderCancellation from './cancellation' -import parseCheckCancel from './check-cancel' -import parseCheckCash from './check-cash' -import parseCheckCreate from './check-create' -import parseDepositPreauth from './deposit-preauth' -import parseEscrowCancellation from './escrow-cancellation' -import parseEscrowCreation from './escrow-creation' -import parseEscrowExecution from './escrow-execution' -import parseFeeUpdate from './fee-update' // pseudo-transaction -import parseOrder from './order' -import parsePayment from './payment' -import parsePaymentChannelClaim from './payment-channel-claim' -import parsePaymentChannelCreate from './payment-channel-create' -import parsePaymentChannelFund from './payment-channel-fund' -import parseSettings from './settings' -import parseTicketCreate from './ticket-create' -import parseTrustline from './trustline' -import { parseOutcome } from './utils' - -function parseTransactionType(type) { - // Ordering matches https://developers.ripple.com/transaction-types.html - const mapping = { - AccountSet: 'settings', - AccountDelete: 'accountDelete', - CheckCancel: 'checkCancel', - CheckCash: 'checkCash', - CheckCreate: 'checkCreate', - DepositPreauth: 'depositPreauth', - EscrowCancel: 'escrowCancellation', - EscrowCreate: 'escrowCreation', - EscrowFinish: 'escrowExecution', - OfferCancel: 'orderCancellation', - OfferCreate: 'order', - Payment: 'payment', - PaymentChannelClaim: 'paymentChannelClaim', - PaymentChannelCreate: 'paymentChannelCreate', - PaymentChannelFund: 'paymentChannelFund', - SetRegularKey: 'settings', - SignerListSet: 'settings', - TicketCreate: 'ticketCreate', - TrustSet: 'trustline', - - EnableAmendment: 'amendment', // pseudo-transaction - SetFee: 'feeUpdate', // pseudo-transaction - } - return mapping[type] || null -} - -// includeRawTransaction: undefined by default (getTransaction) -function parseTransaction(tx: any, includeRawTransaction: boolean): any { - const type = parseTransactionType(tx.TransactionType) - const mapping = { - settings: parseSettings, - accountDelete: parseAccountDelete, - checkCancel: parseCheckCancel, - checkCash: parseCheckCash, - checkCreate: parseCheckCreate, - depositPreauth: parseDepositPreauth, - escrowCancellation: parseEscrowCancellation, - escrowCreation: parseEscrowCreation, - escrowExecution: parseEscrowExecution, - orderCancellation: parseOrderCancellation, - order: parseOrder, - payment: parsePayment, - paymentChannelClaim: parsePaymentChannelClaim, - paymentChannelCreate: parsePaymentChannelCreate, - paymentChannelFund: parsePaymentChannelFund, - ticketCreate: parseTicketCreate, - trustline: parseTrustline, - - amendment: parseAmendment, // pseudo-transaction - feeUpdate: parseFeeUpdate, // pseudo-transaction - } - const parser: Function = mapping[type] - - const specification = parser - ? parser(tx) - : { - UNAVAILABLE: 'Unrecognized transaction type.', - SEE_RAW_TRANSACTION: - 'Since this type is unrecognized, `rawTransaction` is included in this response.', - } - if (!parser) { - includeRawTransaction = true - } - - const outcome = parseOutcome(tx) - return removeUndefined({ - type, - address: tx.Account, - sequence: tx.Sequence, - id: tx.hash, - specification: removeUndefined(specification), - outcome: outcome ? removeUndefined(outcome) : undefined, - rawTransaction: includeRawTransaction ? JSON.stringify(tx) : undefined, - }) -} - -export default parseTransaction diff --git a/src/sugar/parse/trustline.ts b/src/sugar/parse/trustline.ts deleted file mode 100644 index e37fbc73..00000000 --- a/src/sugar/parse/trustline.ts +++ /dev/null @@ -1,40 +0,0 @@ -import * as assert from 'assert' - -import { txFlags } from '..' -import { removeUndefined } from '../../utils' - -import { parseQuality, parseMemos } from './utils' - -const flags = txFlags.TrustSet - -function parseFlag(flagsValue, trueValue, falseValue) { - if (flagsValue & trueValue) { - return true - } - if (flagsValue & falseValue) { - return false - } - return undefined -} - -function parseTrustline(tx: any): object { - assert.ok(tx.TransactionType === 'TrustSet') - - return removeUndefined({ - limit: tx.LimitAmount.value, - currency: tx.LimitAmount.currency, - counterparty: tx.LimitAmount.issuer, - memos: parseMemos(tx), - qualityIn: parseQuality(tx.QualityIn), - qualityOut: parseQuality(tx.QualityOut), - ripplingDisabled: parseFlag( - tx.Flags, - flags.SetNoRipple, - flags.ClearNoRipple, - ), - frozen: parseFlag(tx.Flags, flags.SetFreeze, flags.ClearFreeze), - authorized: parseFlag(tx.Flags, flags.SetAuth, 0), - }) -} - -export default parseTrustline diff --git a/src/sugar/parse/utils.ts b/src/sugar/parse/utils.ts deleted file mode 100644 index 13942458..00000000 --- a/src/sugar/parse/utils.ts +++ /dev/null @@ -1,178 +0,0 @@ -import BigNumber from 'bignumber.js' -import transactionParser from 'ripple-lib-transactionparser' - -import { txFlags } from '..' -import { Amount, Memo } from '../../common/types/objects' -import { removeUndefined, dropsToXrp, rippleTimeToISOTime } from '../../utils' - -import parseAmount from './amount' - -interface OfferDescription { - direction: string - quantity: any - totalPrice: any - sequence: number - status: string - makerExchangeRate: string -} - -interface Orderbook { - [key: string]: OfferDescription[] -} - -interface BalanceSheetItem { - counterparty: string - currency: string - value: string -} - -interface BalanceSheet { - [key: string]: BalanceSheetItem[] -} - -function adjustQualityForXRP( - quality: string, - takerGetsCurrency: string, - takerPaysCurrency: string, -) { - // quality = takerPays.value/takerGets.value - // using drops (1e-6 XRP) for XRP values - const numeratorShift = takerPaysCurrency === 'XRP' ? -6 : 0 - const denominatorShift = takerGetsCurrency === 'XRP' ? -6 : 0 - const shift = numeratorShift - denominatorShift - return shift === 0 - ? quality - : new BigNumber(quality).shiftedBy(shift).toString() -} - -function parseQuality(quality?: number | null): number | undefined { - if (typeof quality !== 'number') { - return undefined - } - return new BigNumber(quality).shiftedBy(-9).toNumber() -} - -function parseTimestamp(rippleTime?: number | null): string | undefined { - if (typeof rippleTime !== 'number') { - return undefined - } - return rippleTimeToISOTime(rippleTime) -} - -function removeEmptyCounterparty(amount) { - if (amount.counterparty === '') { - delete amount.counterparty - } -} - -function removeEmptyCounterpartyInBalanceChanges(balanceChanges: BalanceSheet) { - Object.entries(balanceChanges).forEach(([_, changes]) => { - changes.forEach(removeEmptyCounterparty) - }) -} - -function removeEmptyCounterpartyInOrderbookChanges( - orderbookChanges: Orderbook, -) { - Object.entries(orderbookChanges).forEach(([_, changes]) => { - changes.forEach((change) => { - Object.entries(change).forEach(removeEmptyCounterparty) - }) - }) -} - -function isPartialPayment(tx: any) { - return (tx.Flags & txFlags.Payment.PartialPayment) !== 0 -} - -function parseDeliveredAmount(tx: any): Amount | void { - if ( - tx.TransactionType !== 'Payment' || - tx.meta.TransactionResult !== 'tesSUCCESS' - ) { - return undefined - } - - if (tx.meta.delivered_amount && tx.meta.delivered_amount === 'unavailable') { - return undefined - } - - // parsable delivered_amount - if (tx.meta.delivered_amount) { - return parseAmount(tx.meta.delivered_amount) - } - - // DeliveredAmount only present on partial payments - if (tx.meta.DeliveredAmount) { - return parseAmount(tx.meta.DeliveredAmount) - } - - // no partial payment flag, use tx.Amount - if (tx.Amount && !isPartialPayment(tx)) { - return parseAmount(tx.Amount) - } - - // DeliveredAmount field was introduced at - // ledger 4594095 - after that point its absence - // on a tx flagged as partial payment indicates - // the full amount was transferred. The amount - // transferred with a partial payment before - // that date must be derived from metadata. - if (tx.Amount && tx.ledger_index > 4594094) { - return parseAmount(tx.Amount) - } - - return undefined -} - -function parseOutcome(tx: any): any | undefined { - const metadata = tx.meta || tx.metaData - if (!metadata) { - return undefined - } - const balanceChanges = transactionParser.parseBalanceChanges(metadata) - const orderbookChanges = transactionParser.parseOrderbookChanges(metadata) - const channelChanges = transactionParser.parseChannelChanges(metadata) - - removeEmptyCounterpartyInBalanceChanges(balanceChanges) - removeEmptyCounterpartyInOrderbookChanges(orderbookChanges) - - return removeUndefined({ - result: tx.meta.TransactionResult, - timestamp: parseTimestamp(tx.date), - fee: dropsToXrp(tx.Fee), - balanceChanges, - orderbookChanges, - channelChanges, - ledgerVersion: tx.ledger_index, - indexInLedger: tx.meta.TransactionIndex, - deliveredAmount: parseDeliveredAmount(tx), - }) -} - -function hexToString(hex: string): string | undefined { - return hex ? Buffer.from(hex, 'hex').toString('utf-8') : undefined -} - -function parseMemos(tx: any): Memo[] | undefined { - if (!Array.isArray(tx.Memos) || tx.Memos.length === 0) { - return undefined - } - return tx.Memos.map((m) => { - return removeUndefined({ - type: m.Memo.parsed_memo_type || hexToString(m.Memo.MemoType), - format: m.Memo.parsed_memo_format || hexToString(m.Memo.MemoFormat), - data: m.Memo.parsed_memo_data || hexToString(m.Memo.MemoData), - }) - }) -} - -export { - parseQuality, - parseOutcome, - parseMemos, - hexToString, - parseTimestamp, - adjustQualityForXRP, - isPartialPayment, -} diff --git a/test/client/getOrderbook.ts b/test/client/getOrderbook.ts index 4c0547e3..7b9ed3ba 100644 --- a/test/client/getOrderbook.ts +++ b/test/client/getOrderbook.ts @@ -1,12 +1,13 @@ // import BigNumber from "bignumber.js"; // import { assert } from "chai"; +import { assert } from 'chai' import { BookOffersRequest } from '../../src' import requests from '../fixtures/requests' import responses from '../fixtures/responses' import rippled from '../fixtures/rippled' import { setupClient, teardownClient } from '../setupClient' -import { addressTests, assertResultMatch } from '../testUtils' +import { addressTests } from '../testUtils' // function checkSortingOfOrders(orders) { // let previousRate = "0"; @@ -94,11 +95,7 @@ describe('client.getOrderbook', function () { limit: 1, }, ) - assertResultMatch( - response, - responses.getOrderbook.normal, - 'getOrderbook', - ) + assert.deepEqual(response, responses.getOrderbook.normal) }) // it("invalid options", async function () {