From 69cbf97f76d736a20e099f0c384f60bdd74fc8f9 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 5 Feb 2025 17:00:55 -0800 Subject: [PATCH 01/46] round 1 --- .../xrpl/src/models/transactions/AMMCreate.ts | 24 ++++------- .../xrpl/src/models/transactions/AMMDelete.ts | 25 ++++------- .../src/models/transactions/AMMDeposit.ts | 41 ++++--------------- .../xrpl/src/models/transactions/AMMVote.ts | 24 ++++------- .../src/models/transactions/AMMWithdraw.ts | 35 ++++------------ .../src/models/transactions/accountSet.ts | 21 +++------- .../src/models/transactions/checkCancel.ts | 13 +++--- .../xrpl/src/models/transactions/checkCash.ts | 31 ++++++-------- .../src/models/transactions/checkCreate.ts | 27 +++--------- .../xrpl/src/models/transactions/clawback.ts | 40 +++++++++--------- .../xrpl/src/models/transactions/index.ts | 6 +-- .../src/models/transactions/transaction.ts | 6 +-- .../transactions/credentialDelete.test.ts | 2 +- .../xrpl/test/models/CredentialAccept.test.ts | 2 +- .../xrpl/test/models/CredentialCreate.test.ts | 2 +- .../xrpl/test/models/CredentialDelete.test.ts | 2 +- 16 files changed, 100 insertions(+), 201 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMCreate.ts b/packages/xrpl/src/models/transactions/AMMCreate.ts index 8924fa75ff..ecc91cdd08 100644 --- a/packages/xrpl/src/models/transactions/AMMCreate.ts +++ b/packages/xrpl/src/models/transactions/AMMCreate.ts @@ -1,7 +1,12 @@ import { ValidationError } from '../../errors' import { Amount } from '../common' -import { BaseTransaction, isAmount, validateBaseTransaction } from './common' +import { + BaseTransaction, + isAmount, + validateBaseTransaction, + validateRequiredField, +} from './common' export const AMM_MAX_TRADING_FEE = 1000 @@ -48,21 +53,8 @@ export interface AMMCreate extends BaseTransaction { export function validateAMMCreate(tx: Record): void { validateBaseTransaction(tx) - if (tx.Amount == null) { - throw new ValidationError('AMMCreate: missing field Amount') - } - - if (!isAmount(tx.Amount)) { - throw new ValidationError('AMMCreate: Amount must be an Amount') - } - - if (tx.Amount2 == null) { - throw new ValidationError('AMMCreate: missing field Amount2') - } - - if (!isAmount(tx.Amount2)) { - throw new ValidationError('AMMCreate: Amount2 must be an Amount') - } + validateRequiredField(tx, 'Amount', isAmount) + validateRequiredField(tx, 'Amount2', isAmount) if (tx.TradingFee == null) { throw new ValidationError('AMMCreate: missing field TradingFee') diff --git a/packages/xrpl/src/models/transactions/AMMDelete.ts b/packages/xrpl/src/models/transactions/AMMDelete.ts index 6e64f8c58b..d6bf2ebc23 100644 --- a/packages/xrpl/src/models/transactions/AMMDelete.ts +++ b/packages/xrpl/src/models/transactions/AMMDelete.ts @@ -1,7 +1,11 @@ -import { ValidationError } from '../../errors' import { Currency } from '../common' -import { BaseTransaction, isCurrency, validateBaseTransaction } from './common' +import { + BaseTransaction, + isCurrency, + validateBaseTransaction, + validateRequiredField, +} from './common' /** * Delete an empty Automated Market Maker (AMM) instance that could not be fully deleted automatically. @@ -37,19 +41,6 @@ export interface AMMDelete extends BaseTransaction { export function validateAMMDelete(tx: Record): void { validateBaseTransaction(tx) - if (tx.Asset == null) { - throw new ValidationError('AMMDelete: missing field Asset') - } - - if (!isCurrency(tx.Asset)) { - throw new ValidationError('AMMDelete: Asset must be a Currency') - } - - if (tx.Asset2 == null) { - throw new ValidationError('AMMDelete: missing field Asset2') - } - - if (!isCurrency(tx.Asset2)) { - throw new ValidationError('AMMDelete: Asset2 must be a Currency') - } + validateRequiredField(tx, 'Asset', isCurrency) + validateRequiredField(tx, 'Asset2', isCurrency) } diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts index 2dd8d27e39..9fac35539d 100644 --- a/packages/xrpl/src/models/transactions/AMMDeposit.ts +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -8,6 +8,8 @@ import { isCurrency, isIssuedCurrency, validateBaseTransaction, + validateOptionalField, + validateRequiredField, } from './common' /** @@ -85,21 +87,12 @@ export interface AMMDeposit extends BaseTransaction { export function validateAMMDeposit(tx: Record): void { validateBaseTransaction(tx) - if (tx.Asset == null) { - throw new ValidationError('AMMDeposit: missing field Asset') - } - - if (!isCurrency(tx.Asset)) { - throw new ValidationError('AMMDeposit: Asset must be a Currency') - } - - if (tx.Asset2 == null) { - throw new ValidationError('AMMDeposit: missing field Asset2') - } - - if (!isCurrency(tx.Asset2)) { - throw new ValidationError('AMMDeposit: Asset2 must be a Currency') - } + validateRequiredField(tx, 'Asset', isCurrency) + validateRequiredField(tx, 'Asset2', isCurrency) + validateOptionalField(tx, 'LPTokenOut', isIssuedCurrency) + validateOptionalField(tx, 'Amount', isAmount) + validateOptionalField(tx, 'Amount2', isAmount) + validateOptionalField(tx, 'EPrice', isAmount) if (tx.Amount2 != null && tx.Amount == null) { throw new ValidationError('AMMDeposit: must set Amount with Amount2') @@ -110,22 +103,4 @@ export function validateAMMDeposit(tx: Record): void { 'AMMDeposit: must set at least LPTokenOut or Amount', ) } - - if (tx.LPTokenOut != null && !isIssuedCurrency(tx.LPTokenOut)) { - throw new ValidationError( - 'AMMDeposit: LPTokenOut must be an IssuedCurrencyAmount', - ) - } - - if (tx.Amount != null && !isAmount(tx.Amount)) { - throw new ValidationError('AMMDeposit: Amount must be an Amount') - } - - if (tx.Amount2 != null && !isAmount(tx.Amount2)) { - throw new ValidationError('AMMDeposit: Amount2 must be an Amount') - } - - if (tx.EPrice != null && !isAmount(tx.EPrice)) { - throw new ValidationError('AMMDeposit: EPrice must be an Amount') - } } diff --git a/packages/xrpl/src/models/transactions/AMMVote.ts b/packages/xrpl/src/models/transactions/AMMVote.ts index 0d469fa0a8..0f7cfa6c6f 100644 --- a/packages/xrpl/src/models/transactions/AMMVote.ts +++ b/packages/xrpl/src/models/transactions/AMMVote.ts @@ -2,7 +2,12 @@ import { ValidationError } from '../../errors' import { Currency } from '../common' import { AMM_MAX_TRADING_FEE } from './AMMCreate' -import { BaseTransaction, isCurrency, validateBaseTransaction } from './common' +import { + BaseTransaction, + isCurrency, + validateBaseTransaction, + validateRequiredField, +} from './common' /** * Vote on the trading fee for an Automated Market Maker (AMM) instance. @@ -39,21 +44,8 @@ export interface AMMVote extends BaseTransaction { export function validateAMMVote(tx: Record): void { validateBaseTransaction(tx) - if (tx.Asset == null) { - throw new ValidationError('AMMVote: missing field Asset') - } - - if (!isCurrency(tx.Asset)) { - throw new ValidationError('AMMVote: Asset must be a Currency') - } - - if (tx.Asset2 == null) { - throw new ValidationError('AMMVote: missing field Asset2') - } - - if (!isCurrency(tx.Asset2)) { - throw new ValidationError('AMMVote: Asset2 must be a Currency') - } + validateRequiredField(tx, 'Asset', isCurrency) + validateRequiredField(tx, 'Asset2', isCurrency) if (tx.TradingFee == null) { throw new ValidationError('AMMVote: missing field TradingFee') diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts index fcce5912b3..19dade25eb 100644 --- a/packages/xrpl/src/models/transactions/AMMWithdraw.ts +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -8,6 +8,8 @@ import { isCurrency, isIssuedCurrency, validateBaseTransaction, + validateOptionalField, + validateRequiredField, } from './common' /** @@ -83,21 +85,12 @@ export interface AMMWithdraw extends BaseTransaction { export function validateAMMWithdraw(tx: Record): void { validateBaseTransaction(tx) - if (tx.Asset == null) { - throw new ValidationError('AMMWithdraw: missing field Asset') - } - - if (!isCurrency(tx.Asset)) { - throw new ValidationError('AMMWithdraw: Asset must be a Currency') - } - - if (tx.Asset2 == null) { - throw new ValidationError('AMMWithdraw: missing field Asset2') - } - - if (!isCurrency(tx.Asset2)) { - throw new ValidationError('AMMWithdraw: Asset2 must be a Currency') - } + validateRequiredField(tx, 'Asset', isCurrency) + validateRequiredField(tx, 'Asset2', isCurrency) + validateOptionalField(tx, 'Amount', isAmount) + validateOptionalField(tx, 'Amount2', isAmount) + validateOptionalField(tx, 'LPTokenIn', isIssuedCurrency) + validateOptionalField(tx, 'EPrice', isAmount) if (tx.Amount2 != null && tx.Amount == null) { throw new ValidationError('AMMWithdraw: must set Amount with Amount2') @@ -110,16 +103,4 @@ export function validateAMMWithdraw(tx: Record): void { 'AMMWithdraw: LPTokenIn must be an IssuedCurrencyAmount', ) } - - if (tx.Amount != null && !isAmount(tx.Amount)) { - throw new ValidationError('AMMWithdraw: Amount must be an Amount') - } - - if (tx.Amount2 != null && !isAmount(tx.Amount2)) { - throw new ValidationError('AMMWithdraw: Amount2 must be an Amount') - } - - if (tx.EPrice != null && !isAmount(tx.EPrice)) { - throw new ValidationError('AMMWithdraw: EPrice must be an Amount') - } } diff --git a/packages/xrpl/src/models/transactions/accountSet.ts b/packages/xrpl/src/models/transactions/accountSet.ts index 1d4c9078a5..199b7c3279 100644 --- a/packages/xrpl/src/models/transactions/accountSet.ts +++ b/packages/xrpl/src/models/transactions/accountSet.ts @@ -4,6 +4,8 @@ import { Account, BaseTransaction, isAccount, + isNumber, + isString, validateBaseTransaction, validateOptionalField, } from './common' @@ -171,7 +173,6 @@ 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): void { validateBaseTransaction(tx) @@ -186,17 +187,9 @@ export function validateAccountSet(tx: Record): void { } } - if (tx.Domain !== undefined && typeof tx.Domain !== 'string') { - throw new ValidationError('AccountSet: invalid Domain') - } - - if (tx.EmailHash !== undefined && typeof tx.EmailHash !== 'string') { - throw new ValidationError('AccountSet: invalid EmailHash') - } - - if (tx.MessageKey !== undefined && typeof tx.MessageKey !== 'string') { - throw new ValidationError('AccountSet: invalid MessageKey') - } + validateOptionalField(tx, 'Domain', isString) + validateOptionalField(tx, 'EmailHash', isString) + validateOptionalField(tx, 'MessageKey', isString) if (tx.SetFlag !== undefined) { if (typeof tx.SetFlag !== 'number') { @@ -207,9 +200,7 @@ export function validateAccountSet(tx: Record): void { } } - if (tx.TransferRate !== undefined && typeof tx.TransferRate !== 'number') { - throw new ValidationError('AccountSet: invalid TransferRate') - } + validateOptionalField(tx, 'TransferRate', isNumber) if (tx.TickSize !== undefined) { if (typeof tx.TickSize !== 'number') { diff --git a/packages/xrpl/src/models/transactions/checkCancel.ts b/packages/xrpl/src/models/transactions/checkCancel.ts index 6d129a7d20..7d8aaad0f3 100644 --- a/packages/xrpl/src/models/transactions/checkCancel.ts +++ b/packages/xrpl/src/models/transactions/checkCancel.ts @@ -1,6 +1,9 @@ -import { ValidationError } from '../../errors' - -import { BaseTransaction, validateBaseTransaction } from './common' +import { + BaseTransaction, + isString, + validateBaseTransaction, + validateRequiredField, +} from './common' /** * Cancels an unredeemed Check, removing it from the ledger without sending any @@ -28,7 +31,5 @@ export interface CheckCancel extends BaseTransaction { export function validateCheckCancel(tx: Record): void { validateBaseTransaction(tx) - if (tx.CheckID !== undefined && typeof tx.CheckID !== 'string') { - throw new ValidationError('CheckCancel: invalid CheckID') - } + validateRequiredField(tx, 'CheckID', isString) } diff --git a/packages/xrpl/src/models/transactions/checkCash.ts b/packages/xrpl/src/models/transactions/checkCash.ts index 462f1944c6..4d867a6679 100644 --- a/packages/xrpl/src/models/transactions/checkCash.ts +++ b/packages/xrpl/src/models/transactions/checkCash.ts @@ -1,7 +1,14 @@ import { ValidationError } from '../../errors' import { Amount } from '../common' -import { BaseTransaction, validateBaseTransaction, isAmount } from './common' +import { + BaseTransaction, + validateBaseTransaction, + isAmount, + validateRequiredField, + isString, + validateOptionalField, +} from './common' /** * Attempts to redeem a Check object in the ledger to receive up to the amount @@ -40,6 +47,10 @@ export interface CheckCash extends BaseTransaction { export function validateCheckCash(tx: Record): void { validateBaseTransaction(tx) + validateRequiredField(tx, 'CheckID', isString) + validateOptionalField(tx, 'Amount', isAmount) + validateOptionalField(tx, 'DeliverMin', isAmount) + if (tx.Amount == null && tx.DeliverMin == null) { throw new ValidationError( 'CheckCash: must have either Amount or DeliverMin', @@ -51,22 +62,4 @@ export function validateCheckCash(tx: Record): void { 'CheckCash: cannot have both Amount and DeliverMin', ) } - - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Necessary check - if (tx.Amount != null && tx.Amount !== undefined && !isAmount(tx.Amount)) { - throw new ValidationError('CheckCash: invalid Amount') - } - - if ( - tx.DeliverMin != null && - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Necessary check - tx.DeliverMin !== undefined && - !isAmount(tx.DeliverMin) - ) { - throw new ValidationError('CheckCash: invalid DeliverMin') - } - - if (tx.CheckID !== undefined && typeof tx.CheckID !== 'string') { - throw new ValidationError('CheckCash: invalid CheckID') - } } diff --git a/packages/xrpl/src/models/transactions/checkCreate.ts b/packages/xrpl/src/models/transactions/checkCreate.ts index c8a84430f4..b17a56a521 100644 --- a/packages/xrpl/src/models/transactions/checkCreate.ts +++ b/packages/xrpl/src/models/transactions/checkCreate.ts @@ -1,15 +1,15 @@ -import { ValidationError } from '../../errors' import { Amount } from '../common' import { BaseTransaction, validateBaseTransaction, - isIssuedCurrency, isAccount, validateRequiredField, validateOptionalField, isNumber, Account, + isAmount, + isString, } from './common' /** @@ -57,26 +57,9 @@ export interface CheckCreate extends BaseTransaction { export function validateCheckCreate(tx: Record): void { validateBaseTransaction(tx) - if (tx.SendMax === undefined) { - throw new ValidationError('CheckCreate: missing field SendMax') - } - + validateRequiredField(tx, 'SendMax', isAmount) validateRequiredField(tx, 'Destination', isAccount) validateOptionalField(tx, 'DestinationTag', isNumber) - - if ( - typeof tx.SendMax !== 'string' && - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS - !isIssuedCurrency(tx.SendMax as Record) - ) { - throw new ValidationError('CheckCreate: invalid SendMax') - } - - if (tx.Expiration !== undefined && typeof tx.Expiration !== 'number') { - throw new ValidationError('CheckCreate: invalid Expiration') - } - - if (tx.InvoiceID !== undefined && typeof tx.InvoiceID !== 'string') { - throw new ValidationError('CheckCreate: invalid InvoiceID') - } + validateOptionalField(tx, 'Expiration', isNumber) + validateOptionalField(tx, 'InvoiceID', isString) } diff --git a/packages/xrpl/src/models/transactions/clawback.ts b/packages/xrpl/src/models/transactions/clawback.ts index 759701118b..e5a661ab97 100644 --- a/packages/xrpl/src/models/transactions/clawback.ts +++ b/packages/xrpl/src/models/transactions/clawback.ts @@ -8,6 +8,7 @@ import { isMPTAmount, isAccount, validateOptionalField, + validateRequiredField, } from './common' /** @@ -43,28 +44,27 @@ export interface Clawback extends BaseTransaction { export function validateClawback(tx: Record): void { validateBaseTransaction(tx) validateOptionalField(tx, 'Holder', isAccount) + validateRequiredField( + tx, + 'Amount', + (inp) => isIssuedCurrency(inp) || isMPTAmount(inp), + ) - if (tx.Amount == null) { - throw new ValidationError('Clawback: missing field Amount') - } - - if (!isIssuedCurrency(tx.Amount) && !isMPTAmount(tx.Amount)) { - throw new ValidationError('Clawback: invalid Amount') - } - - if (isIssuedCurrency(tx.Amount) && tx.Account === tx.Amount.issuer) { - throw new ValidationError('Clawback: invalid holder Account') - } - - if (isMPTAmount(tx.Amount) && tx.Account === tx.Holder) { - throw new ValidationError('Clawback: invalid holder Account') - } + if (isIssuedCurrency(tx.Amount)) { + if (tx.Account === tx.Amount.issuer) { + throw new ValidationError('Clawback: invalid holder Account') + } - if (isIssuedCurrency(tx.Amount) && tx.Holder) { - throw new ValidationError('Clawback: cannot have Holder for currency') - } + if (tx.Holder) { + throw new ValidationError('Clawback: cannot have Holder for currency') + } + } else if (isMPTAmount(tx.Amount)) { + if (tx.Account === tx.Holder) { + throw new ValidationError('Clawback: invalid holder Account') + } - if (isMPTAmount(tx.Amount) && !tx.Holder) { - throw new ValidationError('Clawback: missing Holder') + if (!tx.Holder) { + throw new ValidationError('Clawback: missing Holder') + } } } diff --git a/packages/xrpl/src/models/transactions/index.ts b/packages/xrpl/src/models/transactions/index.ts index 956f61a344..f3426dab62 100644 --- a/packages/xrpl/src/models/transactions/index.ts +++ b/packages/xrpl/src/models/transactions/index.ts @@ -32,9 +32,9 @@ export { CheckCancel } from './checkCancel' export { CheckCash } from './checkCash' export { CheckCreate } from './checkCreate' export { Clawback } from './clawback' -export { CredentialAccept } from './CredentialAccept' -export { CredentialCreate } from './CredentialCreate' -export { CredentialDelete } from './CredentialDelete' +export { CredentialAccept } from './credentialAccept' +export { CredentialCreate } from './credentialCreate' +export { CredentialDelete } from './credentialDelete' export { DIDDelete } from './DIDDelete' export { DIDSet } from './DIDSet' export { DepositPreauth } from './depositPreauth' diff --git a/packages/xrpl/src/models/transactions/transaction.ts b/packages/xrpl/src/models/transactions/transaction.ts index e774b2c41a..be6ea3eda4 100644 --- a/packages/xrpl/src/models/transactions/transaction.ts +++ b/packages/xrpl/src/models/transactions/transaction.ts @@ -19,9 +19,9 @@ import { CheckCash, validateCheckCash } from './checkCash' import { CheckCreate, validateCheckCreate } from './checkCreate' import { Clawback, validateClawback } from './clawback' import { BaseTransaction, isIssuedCurrency } from './common' -import { CredentialAccept, validateCredentialAccept } from './CredentialAccept' -import { CredentialCreate, validateCredentialCreate } from './CredentialCreate' -import { CredentialDelete, validateCredentialDelete } from './CredentialDelete' +import { CredentialAccept, validateCredentialAccept } from './credentialAccept' +import { CredentialCreate, validateCredentialCreate } from './credentialCreate' +import { CredentialDelete, validateCredentialDelete } from './credentialDelete' import { DepositPreauth, validateDepositPreauth } from './depositPreauth' import { DIDDelete, validateDIDDelete } from './DIDDelete' import { DIDSet, validateDIDSet } from './DIDSet' diff --git a/packages/xrpl/test/integration/transactions/credentialDelete.test.ts b/packages/xrpl/test/integration/transactions/credentialDelete.test.ts index 246397c66f..1e58b731d7 100644 --- a/packages/xrpl/test/integration/transactions/credentialDelete.test.ts +++ b/packages/xrpl/test/integration/transactions/credentialDelete.test.ts @@ -6,7 +6,7 @@ import { CredentialAccept, CredentialCreate, } from '../../../src' -import { CredentialDelete } from '../../../src/models/transactions/CredentialDelete' +import { CredentialDelete } from '../../../src/models/transactions/credentialDelete' import serverUrl from '../serverUrl' import { setupClient, diff --git a/packages/xrpl/test/models/CredentialAccept.test.ts b/packages/xrpl/test/models/CredentialAccept.test.ts index 042101bd1f..2c8a1890ed 100644 --- a/packages/xrpl/test/models/CredentialAccept.test.ts +++ b/packages/xrpl/test/models/CredentialAccept.test.ts @@ -2,7 +2,7 @@ import { stringToHex } from '@xrplf/isomorphic/dist/utils' import { assert } from 'chai' import { validate, ValidationError } from '../../src' -import { validateCredentialAccept } from '../../src/models/transactions/CredentialAccept' +import { validateCredentialAccept } from '../../src/models/transactions/credentialAccept' /** * CredentialAccept Transaction Verification Testing. diff --git a/packages/xrpl/test/models/CredentialCreate.test.ts b/packages/xrpl/test/models/CredentialCreate.test.ts index 96a530c538..25c9c58ca3 100644 --- a/packages/xrpl/test/models/CredentialCreate.test.ts +++ b/packages/xrpl/test/models/CredentialCreate.test.ts @@ -2,7 +2,7 @@ import { stringToHex } from '@xrplf/isomorphic/dist/utils' import { assert } from 'chai' import { validate, ValidationError } from '../../src' -import { validateCredentialCreate } from '../../src/models/transactions/CredentialCreate' +import { validateCredentialCreate } from '../../src/models/transactions/credentialCreate' /** * CredentialCreate Transaction Verification Testing. diff --git a/packages/xrpl/test/models/CredentialDelete.test.ts b/packages/xrpl/test/models/CredentialDelete.test.ts index bb1ebc12c3..bb188687a1 100644 --- a/packages/xrpl/test/models/CredentialDelete.test.ts +++ b/packages/xrpl/test/models/CredentialDelete.test.ts @@ -2,7 +2,7 @@ import { stringToHex } from '@xrplf/isomorphic/dist/utils' import { assert } from 'chai' import { validate, ValidationError } from '../../src' -import { validateCredentialDelete } from '../../src/models/transactions/CredentialDelete' +import { validateCredentialDelete } from '../../src/models/transactions/credentialDelete' /** * CredentialDelete Transaction Verification Testing. From acfddeea50643137051cdd2ffb19b03451274ecb Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 5 Feb 2025 17:15:02 -0800 Subject: [PATCH 02/46] round 2 --- .../models/transactions/NFTokenAcceptOffer.ts | 7 ++++ .../models/transactions/NFTokenCreateOffer.ts | 16 ++++----- .../src/models/transactions/NFTokenMint.ts | 14 ++++---- .../xrpl/src/models/transactions/common.ts | 2 +- .../src/models/transactions/escrowCancel.ts | 16 ++------- .../src/models/transactions/escrowCreate.ts | 18 ++++------ .../src/models/transactions/escrowFinish.ts | 27 ++++----------- .../src/models/transactions/offerCancel.ts | 15 ++++---- .../src/models/transactions/offerCreate.ts | 30 ++++------------ .../xrpl/src/models/transactions/payment.ts | 34 +++++++------------ 10 files changed, 63 insertions(+), 116 deletions(-) diff --git a/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts b/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts index 1a33f46e5f..40dea89497 100644 --- a/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts +++ b/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts @@ -3,8 +3,11 @@ import { Amount } from '../common' import { BaseTransaction, + isAmount, + isString, parseAmountValue, validateBaseTransaction, + validateOptionalField, } from './common' import type { TransactionMetadataBase } from './metadata' @@ -98,6 +101,10 @@ function validateNFTokenBrokerFee(tx: Record): void { export function validateNFTokenAcceptOffer(tx: Record): void { validateBaseTransaction(tx) + validateOptionalField(tx, 'NFTokenSellOffer', isString) + validateOptionalField(tx, 'NFTokenBuyOffer', isString) + validateOptionalField(tx, 'NFTokenBrokerFee', isAmount) + if (tx.NFTokenBrokerFee != null) { validateNFTokenBrokerFee(tx) } diff --git a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts index 9575d1b6be..040a1675c2 100644 --- a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts +++ b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts @@ -11,6 +11,9 @@ import { isAccount, validateOptionalField, Account, + validateRequiredField, + isString, + isNumber, } from './common' import type { TransactionMetadataBase } from './metadata' @@ -135,16 +138,11 @@ export function validateNFTokenCreateOffer(tx: Record): void { ) } - validateOptionalField(tx, 'Destination', isAccount) + validateRequiredField(tx, 'NFTokenID', isString) + validateRequiredField(tx, 'Amount', isAmount) validateOptionalField(tx, 'Owner', isAccount) - - if (tx.NFTokenID == null) { - throw new ValidationError('NFTokenCreateOffer: missing field NFTokenID') - } - - if (!isAmount(tx.Amount)) { - throw new ValidationError('NFTokenCreateOffer: invalid Amount') - } + validateOptionalField(tx, 'Expiration', isNumber) + validateOptionalField(tx, 'Destination', isAccount) if ( typeof tx.Flags === 'number' && diff --git a/packages/xrpl/src/models/transactions/NFTokenMint.ts b/packages/xrpl/src/models/transactions/NFTokenMint.ts index 1bd7947929..4463bf3140 100644 --- a/packages/xrpl/src/models/transactions/NFTokenMint.ts +++ b/packages/xrpl/src/models/transactions/NFTokenMint.ts @@ -6,8 +6,11 @@ import { BaseTransaction, GlobalFlags, isAccount, + isNumber, + isString, validateBaseTransaction, validateOptionalField, + validateRequiredField, } from './common' import type { TransactionMetadataBase } from './metadata' @@ -121,14 +124,17 @@ export interface NFTokenMintMetadata extends TransactionMetadataBase { export function validateNFTokenMint(tx: Record): void { validateBaseTransaction(tx) + validateRequiredField(tx, 'NFTokenTaxon', isNumber) + validateOptionalField(tx, 'Issuer', isAccount) + validateOptionalField(tx, 'TransferFee', isNumber) + validateOptionalField(tx, 'URI', isString) + if (tx.Account === tx.Issuer) { throw new ValidationError( 'NFTokenMint: Issuer must not be equal to Account', ) } - validateOptionalField(tx, 'Issuer', isAccount) - if (typeof tx.URI === 'string' && tx.URI === '') { throw new ValidationError('NFTokenMint: URI must not be empty string') } @@ -136,8 +142,4 @@ export function validateNFTokenMint(tx: Record): void { if (typeof tx.URI === 'string' && !isHex(tx.URI)) { throw new ValidationError('NFTokenMint: URI must be in hex format') } - - if (tx.NFTokenTaxon == null) { - throw new ValidationError('NFTokenMint: missing field NFTokenTaxon') - } } diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index d82625355f..3ee36288ec 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -90,7 +90,7 @@ export function isString(str: unknown): str is string { * @returns Whether the number is properly formed. */ export function isNumber(num: unknown): num is number { - return typeof num === 'number' + return typeof num === 'number' || Number.isNaN(Number(num)) } /** diff --git a/packages/xrpl/src/models/transactions/escrowCancel.ts b/packages/xrpl/src/models/transactions/escrowCancel.ts index f06676c730..49afec9e7c 100644 --- a/packages/xrpl/src/models/transactions/escrowCancel.ts +++ b/packages/xrpl/src/models/transactions/escrowCancel.ts @@ -1,9 +1,8 @@ -import { ValidationError } from '../../errors' - import { Account, BaseTransaction, isAccount, + isNumber, validateBaseTransaction, validateRequiredField, } from './common' @@ -34,16 +33,5 @@ export function validateEscrowCancel(tx: Record): void { validateBaseTransaction(tx) validateRequiredField(tx, 'Owner', isAccount) - - if (tx.OfferSequence == null) { - throw new ValidationError('EscrowCancel: missing OfferSequence') - } - - if ( - (typeof tx.OfferSequence !== 'number' && - typeof tx.OfferSequence !== 'string') || - Number.isNaN(Number(tx.OfferSequence)) - ) { - throw new ValidationError('EscrowCancel: OfferSequence must be a number') - } + validateRequiredField(tx, 'OfferSequence', isNumber) } diff --git a/packages/xrpl/src/models/transactions/escrowCreate.ts b/packages/xrpl/src/models/transactions/escrowCreate.ts index 4f15d77dd8..e9a3e1889b 100644 --- a/packages/xrpl/src/models/transactions/escrowCreate.ts +++ b/packages/xrpl/src/models/transactions/escrowCreate.ts @@ -4,7 +4,9 @@ import { Account, BaseTransaction, isAccount, + isAmount, isNumber, + isString, validateBaseTransaction, validateOptionalField, validateRequiredField, @@ -66,8 +68,12 @@ export function validateEscrowCreate(tx: Record): void { throw new ValidationError('EscrowCreate: Amount must be a string') } + validateRequiredField(tx, 'Amount', isAmount) validateRequiredField(tx, 'Destination', isAccount) validateOptionalField(tx, 'DestinationTag', isNumber) + validateOptionalField(tx, 'CancelAfter', isNumber) + validateOptionalField(tx, 'FinishAfter', isNumber) + validateOptionalField(tx, 'Condition', isString) if (tx.CancelAfter === undefined && tx.FinishAfter === undefined) { throw new ValidationError( @@ -80,16 +86,4 @@ export function validateEscrowCreate(tx: Record): void { 'EscrowCreate: Either Condition or FinishAfter must be specified', ) } - - if (tx.CancelAfter !== undefined && typeof tx.CancelAfter !== 'number') { - throw new ValidationError('EscrowCreate: CancelAfter must be a number') - } - - if (tx.FinishAfter !== undefined && typeof tx.FinishAfter !== 'number') { - throw new ValidationError('EscrowCreate: FinishAfter must be a number') - } - - if (tx.Condition !== undefined && typeof tx.Condition !== 'string') { - throw new ValidationError('EscrowCreate: Condition must be a string') - } } diff --git a/packages/xrpl/src/models/transactions/escrowFinish.ts b/packages/xrpl/src/models/transactions/escrowFinish.ts index cba8fff202..fd8cb1549d 100644 --- a/packages/xrpl/src/models/transactions/escrowFinish.ts +++ b/packages/xrpl/src/models/transactions/escrowFinish.ts @@ -1,11 +1,12 @@ -import { ValidationError } from '../../errors' - import { Account, BaseTransaction, isAccount, + isNumber, + isString, validateBaseTransaction, validateCredentialsList, + validateOptionalField, validateRequiredField, } from './common' @@ -57,23 +58,7 @@ export function validateEscrowFinish(tx: Record): void { true, ) - if (tx.OfferSequence == null) { - throw new ValidationError('EscrowFinish: missing field OfferSequence') - } - - if ( - (typeof tx.OfferSequence !== 'number' && - typeof tx.OfferSequence !== 'string') || - Number.isNaN(Number(tx.OfferSequence)) - ) { - throw new ValidationError('EscrowFinish: OfferSequence must be a number') - } - - if (tx.Condition !== undefined && typeof tx.Condition !== 'string') { - throw new ValidationError('EscrowFinish: Condition must be a string') - } - - if (tx.Fulfillment !== undefined && typeof tx.Fulfillment !== 'string') { - throw new ValidationError('EscrowFinish: Fulfillment must be a string') - } + validateRequiredField(tx, 'OfferSequence', isNumber) + validateOptionalField(tx, 'Condition', isString) + validateOptionalField(tx, 'Fulfillment', isString) } diff --git a/packages/xrpl/src/models/transactions/offerCancel.ts b/packages/xrpl/src/models/transactions/offerCancel.ts index 4989d18883..546b8d5216 100644 --- a/packages/xrpl/src/models/transactions/offerCancel.ts +++ b/packages/xrpl/src/models/transactions/offerCancel.ts @@ -1,6 +1,11 @@ import { ValidationError } from '../../errors' -import { BaseTransaction, validateBaseTransaction } from './common' +import { + BaseTransaction, + isNumber, + validateBaseTransaction, + validateRequiredField, +} from './common' /** * An OfferCancel transaction removes an Offer object from the XRP Ledger. @@ -27,11 +32,5 @@ export interface OfferCancel extends BaseTransaction { export function validateOfferCancel(tx: Record): void { validateBaseTransaction(tx) - if (tx.OfferSequence === undefined) { - throw new ValidationError('OfferCancel: missing field OfferSequence') - } - - if (typeof tx.OfferSequence !== 'number') { - throw new ValidationError('OfferCancel: OfferSequence must be a number') - } + validateRequiredField(tx, 'OfferSequence', isNumber) } diff --git a/packages/xrpl/src/models/transactions/offerCreate.ts b/packages/xrpl/src/models/transactions/offerCreate.ts index 782e635499..6aef05e018 100644 --- a/packages/xrpl/src/models/transactions/offerCreate.ts +++ b/packages/xrpl/src/models/transactions/offerCreate.ts @@ -6,6 +6,9 @@ import { GlobalFlags, validateBaseTransaction, isAmount, + validateRequiredField, + validateOptionalField, + isNumber, } from './common' /** @@ -117,27 +120,8 @@ export interface OfferCreate extends BaseTransaction { export function validateOfferCreate(tx: Record): void { validateBaseTransaction(tx) - if (tx.TakerGets === undefined) { - throw new ValidationError('OfferCreate: missing field TakerGets') - } - - if (tx.TakerPays === undefined) { - throw new ValidationError('OfferCreate: missing field TakerPays') - } - - if (typeof tx.TakerGets !== 'string' && !isAmount(tx.TakerGets)) { - throw new ValidationError('OfferCreate: invalid TakerGets') - } - - if (typeof tx.TakerPays !== 'string' && !isAmount(tx.TakerPays)) { - throw new ValidationError('OfferCreate: invalid TakerPays') - } - - if (tx.Expiration !== undefined && typeof tx.Expiration !== 'number') { - throw new ValidationError('OfferCreate: invalid Expiration') - } - - if (tx.OfferSequence !== undefined && typeof tx.OfferSequence !== 'number') { - throw new ValidationError('OfferCreate: invalid OfferSequence') - } + validateOptionalField(tx, 'Expiration', isNumber) + validateOptionalField(tx, 'OfferSequence', isNumber) + validateRequiredField(tx, 'TakerGets', isAmount) + validateRequiredField(tx, 'TakerPays', isAmount) } diff --git a/packages/xrpl/src/models/transactions/payment.ts b/packages/xrpl/src/models/transactions/payment.ts index 25f3dc8974..b3ae3c9b60 100644 --- a/packages/xrpl/src/models/transactions/payment.ts +++ b/packages/xrpl/src/models/transactions/payment.ts @@ -13,6 +13,7 @@ import { isNumber, Account, validateCredentialsList, + isString, } from './common' import type { TransactionMetadataBase } from './metadata' @@ -172,27 +173,10 @@ export interface PaymentMetadata extends TransactionMetadataBase { export function validatePayment(tx: Record): void { validateBaseTransaction(tx) - if (tx.Amount === undefined) { - throw new ValidationError('PaymentTransaction: missing field Amount') - } - - if (!isAmount(tx.Amount)) { - throw new ValidationError('PaymentTransaction: invalid Amount') - } - + validateRequiredField(tx, 'Amount', isAmount) validateRequiredField(tx, 'Destination', isAccount) validateOptionalField(tx, 'DestinationTag', isNumber) - - validateCredentialsList( - tx.CredentialIDs, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- known from base check - tx.TransactionType as string, - true, - ) - - if (tx.InvoiceID !== undefined && typeof tx.InvoiceID !== 'string') { - throw new ValidationError('PaymentTransaction: InvoiceID must be a string') - } + validateOptionalField(tx, 'InvoiceID', isString) if ( tx.Paths !== undefined && @@ -202,9 +186,15 @@ export function validatePayment(tx: Record): void { throw new ValidationError('PaymentTransaction: invalid Paths') } - if (tx.SendMax !== undefined && !isAmount(tx.SendMax)) { - throw new ValidationError('PaymentTransaction: invalid SendMax') - } + validateOptionalField(tx, 'SendMax', isAmount) + validateOptionalField(tx, 'DeliverMin', isAmount) + + validateCredentialsList( + tx.CredentialIDs, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- known from base check + tx.TransactionType as string, + true, + ) checkPartialPayment(tx) } From 284e51bb28be4aa1f2e9c89025f69b762030da97 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 12 Feb 2025 12:57:53 -0500 Subject: [PATCH 03/46] round 3 --- .../models/transactions/NFTokenCancelOffer.ts | 14 +++-- .../transactions/paymentChannelClaim.ts | 35 ++++--------- .../transactions/paymentChannelCreate.ts | 51 ++++--------------- .../models/transactions/paymentChannelFund.ts | 33 ++++-------- .../src/models/transactions/setRegularKey.ts | 13 ++--- .../src/models/transactions/signerListSet.ts | 31 +++++------ .../src/models/transactions/ticketCreate.ts | 25 +++++---- .../xrpl/src/models/transactions/trustSet.ts | 22 +++----- 8 files changed, 78 insertions(+), 146 deletions(-) diff --git a/packages/xrpl/src/models/transactions/NFTokenCancelOffer.ts b/packages/xrpl/src/models/transactions/NFTokenCancelOffer.ts index b0b8bcd228..5b4be4cf79 100644 --- a/packages/xrpl/src/models/transactions/NFTokenCancelOffer.ts +++ b/packages/xrpl/src/models/transactions/NFTokenCancelOffer.ts @@ -1,6 +1,10 @@ import { ValidationError } from '../../errors' -import { BaseTransaction, validateBaseTransaction } from './common' +import { + BaseTransaction, + validateBaseTransaction, + validateRequiredField, +} from './common' import type { TransactionMetadataBase } from './metadata' /** @@ -41,11 +45,11 @@ export interface NFTokenCancelOfferMetadata extends TransactionMetadataBase { export function validateNFTokenCancelOffer(tx: Record): void { validateBaseTransaction(tx) - if (!Array.isArray(tx.NFTokenOffers)) { - throw new ValidationError('NFTokenCancelOffer: missing field NFTokenOffers') - } + validateRequiredField(tx, 'NFTokenOffers', Array.isArray) - if (tx.NFTokenOffers.length < 1) { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- checked above + const offers = tx.NFTokenOffers as unknown[] + if (offers.length < 1) { throw new ValidationError('NFTokenCancelOffer: empty field NFTokenOffers') } } diff --git a/packages/xrpl/src/models/transactions/paymentChannelClaim.ts b/packages/xrpl/src/models/transactions/paymentChannelClaim.ts index f99368b388..ef28985d03 100644 --- a/packages/xrpl/src/models/transactions/paymentChannelClaim.ts +++ b/packages/xrpl/src/models/transactions/paymentChannelClaim.ts @@ -1,10 +1,11 @@ -import { ValidationError } from '../../errors' - import { BaseTransaction, GlobalFlags, + isString, validateBaseTransaction, validateCredentialsList, + validateOptionalField, + validateRequiredField, } from './common' /** @@ -148,34 +149,16 @@ export interface PaymentChannelClaim extends BaseTransaction { export function validatePaymentChannelClaim(tx: Record): void { validateBaseTransaction(tx) + validateRequiredField(tx, 'Channel', isString) + validateOptionalField(tx, 'Balance', isString) + validateOptionalField(tx, 'Amount', isString) + validateOptionalField(tx, 'Signature', isString) + validateOptionalField(tx, 'PublicKey', isString) + validateCredentialsList( tx.CredentialIDs, // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- known from base check tx.TransactionType as string, true, ) - - if (tx.Channel === undefined) { - throw new ValidationError('PaymentChannelClaim: missing Channel') - } - - if (typeof tx.Channel !== 'string') { - throw new ValidationError('PaymentChannelClaim: Channel must be a string') - } - - if (tx.Balance !== undefined && typeof tx.Balance !== 'string') { - throw new ValidationError('PaymentChannelClaim: Balance must be a string') - } - - if (tx.Amount !== undefined && typeof tx.Amount !== 'string') { - throw new ValidationError('PaymentChannelClaim: Amount must be a string') - } - - if (tx.Signature !== undefined && typeof tx.Signature !== 'string') { - throw new ValidationError('PaymentChannelClaim: Signature must be a string') - } - - if (tx.PublicKey !== undefined && typeof tx.PublicKey !== 'string') { - throw new ValidationError('PaymentChannelClaim: PublicKey must be a string') - } } diff --git a/packages/xrpl/src/models/transactions/paymentChannelCreate.ts b/packages/xrpl/src/models/transactions/paymentChannelCreate.ts index 1a7ca3eadc..b6308cfff0 100644 --- a/packages/xrpl/src/models/transactions/paymentChannelCreate.ts +++ b/packages/xrpl/src/models/transactions/paymentChannelCreate.ts @@ -1,10 +1,9 @@ -import { ValidationError } from '../../errors' - import { Account, BaseTransaction, isAccount, isNumber, + isString, validateBaseTransaction, validateOptionalField, validateRequiredField, @@ -30,6 +29,11 @@ export interface PaymentChannelCreate extends BaseTransaction { * the "destination address" for the channel. */ Destination: Account + /** + * Arbitrary tag to further specify the destination for this payment channel, + * such as a hosted recipient at the destination address. + */ + DestinationTag?: number /** * Amount of time the source address must wait before closing the channel if * it has unclaimed XRP. @@ -49,11 +53,6 @@ export interface PaymentChannelCreate extends BaseTransaction { * this time. */ CancelAfter?: number - /** - * Arbitrary tag to further specify the destination for this payment channel, - * such as a hosted recipient at the destination address. - */ - DestinationTag?: number } /** @@ -67,40 +66,10 @@ export function validatePaymentChannelCreate( ): void { validateBaseTransaction(tx) - if (tx.Amount === undefined) { - throw new ValidationError('PaymentChannelCreate: missing Amount') - } - - if (typeof tx.Amount !== 'string') { - throw new ValidationError('PaymentChannelCreate: Amount must be a string') - } - + validateRequiredField(tx, 'Amount', isString) validateRequiredField(tx, 'Destination', isAccount) validateOptionalField(tx, 'DestinationTag', isNumber) - - if (tx.SettleDelay === undefined) { - throw new ValidationError('PaymentChannelCreate: missing SettleDelay') - } - - if (typeof tx.SettleDelay !== 'number') { - throw new ValidationError( - 'PaymentChannelCreate: SettleDelay must be a number', - ) - } - - if (tx.PublicKey === undefined) { - throw new ValidationError('PaymentChannelCreate: missing PublicKey') - } - - if (typeof tx.PublicKey !== 'string') { - throw new ValidationError( - 'PaymentChannelCreate: PublicKey must be a string', - ) - } - - if (tx.CancelAfter !== undefined && typeof tx.CancelAfter !== 'number') { - throw new ValidationError( - 'PaymentChannelCreate: CancelAfter must be a number', - ) - } + validateRequiredField(tx, 'SettleDelay', isNumber) + validateRequiredField(tx, 'PublicKey', isString) + validateOptionalField(tx, 'CancelAfter', isNumber) } diff --git a/packages/xrpl/src/models/transactions/paymentChannelFund.ts b/packages/xrpl/src/models/transactions/paymentChannelFund.ts index 8c46687afa..33dba39d83 100644 --- a/packages/xrpl/src/models/transactions/paymentChannelFund.ts +++ b/packages/xrpl/src/models/transactions/paymentChannelFund.ts @@ -1,6 +1,11 @@ -import { ValidationError } from '../../errors' - -import { BaseTransaction, validateBaseTransaction } from './common' +import { + BaseTransaction, + isNumber, + isString, + validateBaseTransaction, + validateOptionalField, + validateRequiredField, +} from './common' /** * Add additional XRP to an open payment channel, and optionally update the @@ -43,23 +48,7 @@ export interface PaymentChannelFund extends BaseTransaction { export function validatePaymentChannelFund(tx: Record): void { validateBaseTransaction(tx) - if (tx.Channel === undefined) { - throw new ValidationError('PaymentChannelFund: missing Channel') - } - - if (typeof tx.Channel !== 'string') { - throw new ValidationError('PaymentChannelFund: Channel must be a string') - } - - if (tx.Amount === undefined) { - throw new ValidationError('PaymentChannelFund: missing Amount') - } - - if (typeof tx.Amount !== 'string') { - throw new ValidationError('PaymentChannelFund: Amount must be a string') - } - - if (tx.Expiration !== undefined && typeof tx.Expiration !== 'number') { - throw new ValidationError('PaymentChannelFund: Expiration must be a number') - } + validateRequiredField(tx, 'Channel', isString) + validateRequiredField(tx, 'Amount', isString) + validateOptionalField(tx, 'Expiration', isNumber) } diff --git a/packages/xrpl/src/models/transactions/setRegularKey.ts b/packages/xrpl/src/models/transactions/setRegularKey.ts index deeee77025..452d593d9a 100644 --- a/packages/xrpl/src/models/transactions/setRegularKey.ts +++ b/packages/xrpl/src/models/transactions/setRegularKey.ts @@ -1,6 +1,9 @@ -import { ValidationError } from '../../errors' - -import { BaseTransaction, validateBaseTransaction } from './common' +import { + BaseTransaction, + isString, + validateBaseTransaction, + validateOptionalField, +} from './common' /** * A SetRegularKey transaction assigns, changes, or removes the regular key @@ -27,7 +30,5 @@ export interface SetRegularKey extends BaseTransaction { export function validateSetRegularKey(tx: Record): void { validateBaseTransaction(tx) - if (tx.RegularKey !== undefined && typeof tx.RegularKey !== 'string') { - throw new ValidationError('SetRegularKey: RegularKey must be a string') - } + validateOptionalField(tx, 'RegularKey', isString) } diff --git a/packages/xrpl/src/models/transactions/signerListSet.ts b/packages/xrpl/src/models/transactions/signerListSet.ts index f264d55b2f..201efafa2d 100644 --- a/packages/xrpl/src/models/transactions/signerListSet.ts +++ b/packages/xrpl/src/models/transactions/signerListSet.ts @@ -1,7 +1,12 @@ import { ValidationError } from '../../errors' import { SignerEntry } from '../common' -import { BaseTransaction, validateBaseTransaction } from './common' +import { + BaseTransaction, + isNumber, + validateBaseTransaction, + validateRequiredField, +} from './common' /** * The SignerListSet transaction creates, replaces, or removes a list of @@ -39,40 +44,30 @@ const HEX_WALLET_LOCATOR_REGEX = /^[0-9A-Fa-f]{64}$/u export function validateSignerListSet(tx: Record): void { validateBaseTransaction(tx) - if (tx.SignerQuorum === undefined) { - throw new ValidationError('SignerListSet: missing field SignerQuorum') - } - - if (typeof tx.SignerQuorum !== 'number') { - throw new ValidationError('SignerListSet: invalid SignerQuorum') - } + validateRequiredField(tx, 'SignerQuorum', isNumber) // All other checks are for if SignerQuorum is greater than 0 if (tx.SignerQuorum === 0) { return } - if (tx.SignerEntries === undefined) { - throw new ValidationError('SignerListSet: missing field SignerEntries') - } - - if (!Array.isArray(tx.SignerEntries)) { - throw new ValidationError('SignerListSet: invalid SignerEntries') - } + validateRequiredField(tx, 'SignerEntries', Array.isArray) - if (tx.SignerEntries.length === 0) { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- checked above + const signerEntries = tx.SignerEntries as unknown[] + if (signerEntries.length === 0) { throw new ValidationError( 'SignerListSet: need at least 1 member in SignerEntries', ) } - if (tx.SignerEntries.length > MAX_SIGNERS) { + if (signerEntries.length > MAX_SIGNERS) { throw new ValidationError( `SignerListSet: maximum of ${MAX_SIGNERS} members allowed in SignerEntries`, ) } - for (const entry of tx.SignerEntries) { + for (const entry of signerEntries) { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Should be a SignerEntry const signerEntry = entry as SignerEntry const { WalletLocator } = signerEntry.SignerEntry diff --git a/packages/xrpl/src/models/transactions/ticketCreate.ts b/packages/xrpl/src/models/transactions/ticketCreate.ts index 3206ffe54e..8a17ce7b30 100644 --- a/packages/xrpl/src/models/transactions/ticketCreate.ts +++ b/packages/xrpl/src/models/transactions/ticketCreate.ts @@ -1,6 +1,11 @@ import { ValidationError } from '../../errors' -import { BaseTransaction, validateBaseTransaction } from './common' +import { + BaseTransaction, + isNumber, + validateBaseTransaction, + validateRequiredField, +} from './common' /** * A TicketCreate transaction sets aside one or more sequence numbers as @@ -28,20 +33,14 @@ const MAX_TICKETS = 250 */ export function validateTicketCreate(tx: Record): void { validateBaseTransaction(tx) - const { TicketCount } = tx - - if (TicketCount === undefined) { - throw new ValidationError('TicketCreate: missing field TicketCount') - } - - if (typeof TicketCount !== 'number') { - throw new ValidationError('TicketCreate: TicketCount must be a number') - } + validateRequiredField(tx, 'TicketCount', isNumber) + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- checked above + const ticketCount = tx.TicketCount as number if ( - !Number.isInteger(TicketCount) || - TicketCount < 1 || - TicketCount > MAX_TICKETS + !Number.isInteger(ticketCount) || + ticketCount < 1 || + ticketCount > MAX_TICKETS ) { throw new ValidationError( 'TicketCreate: TicketCount must be an integer from 1 to 250', diff --git a/packages/xrpl/src/models/transactions/trustSet.ts b/packages/xrpl/src/models/transactions/trustSet.ts index f584261af3..2367ab9bc9 100644 --- a/packages/xrpl/src/models/transactions/trustSet.ts +++ b/packages/xrpl/src/models/transactions/trustSet.ts @@ -5,7 +5,11 @@ import { BaseTransaction, GlobalFlags, isAmount, + isIssuedCurrency, + isNumber, validateBaseTransaction, + validateOptionalField, + validateRequiredField, } from './common' /** @@ -126,21 +130,9 @@ export interface TrustSet extends BaseTransaction { */ export function validateTrustSet(tx: Record): void { validateBaseTransaction(tx) - const { LimitAmount, QualityIn, QualityOut } = tx - if (LimitAmount === undefined) { - throw new ValidationError('TrustSet: missing field LimitAmount') - } + validateRequiredField(tx, 'LimitAmount', isIssuedCurrency) - if (!isAmount(LimitAmount)) { - throw new ValidationError('TrustSet: invalid LimitAmount') - } - - if (QualityIn !== undefined && typeof QualityIn !== 'number') { - throw new ValidationError('TrustSet: QualityIn must be a number') - } - - if (QualityOut !== undefined && typeof QualityOut !== 'number') { - throw new ValidationError('TrustSet: QualityOut must be a number') - } + validateOptionalField(tx, 'QualityIn', isNumber) + validateOptionalField(tx, 'QualityOut', isNumber) } From cf40d2ab253a7bf1f6e25bd5665b8e727b0d5dbc Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 12 Feb 2025 13:28:27 -0500 Subject: [PATCH 04/46] fixing tests round 1 --- .../xrpl/src/models/transactions/AMMCreate.ts | 12 +-- .../xrpl/src/models/transactions/common.ts | 7 +- .../src/models/transactions/escrowFinish.ts | 6 +- .../src/models/transactions/offerCancel.ts | 2 - .../src/models/transactions/offerCreate.ts | 1 - .../src/models/transactions/ticketCreate.ts | 3 +- .../xrpl/src/models/transactions/trustSet.ts | 2 - packages/xrpl/test/models/AMMCreate.test.ts | 6 +- packages/xrpl/test/models/AMMDelete.test.ts | 4 +- packages/xrpl/test/models/AMMDeposit.test.ts | 13 ++- packages/xrpl/test/models/AMMVote.test.ts | 6 +- packages/xrpl/test/models/AMMWithdraw.test.ts | 13 ++- .../test/models/NFTokenCreateOffer.test.ts | 4 +- packages/xrpl/test/models/checkCreate.test.ts | 16 +-- packages/xrpl/test/models/clawback.test.ts | 6 +- .../xrpl/test/models/escrowCancel.test.ts | 8 +- .../xrpl/test/models/escrowFinish.test.ts | 14 +-- packages/xrpl/test/models/offerCancel.test.ts | 2 +- packages/xrpl/test/models/offerCreate.test.ts | 101 ++++-------------- .../xrpl/test/models/oracleDelete.test.ts | 2 +- packages/xrpl/test/models/oracleSet.test.ts | 8 +- .../test/models/paymentChannelFund.test.ts | 20 ++-- .../xrpl/test/models/setRegularKey.test.ts | 4 +- .../xrpl/test/models/ticketCreate.test.ts | 4 +- 24 files changed, 94 insertions(+), 170 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMCreate.ts b/packages/xrpl/src/models/transactions/AMMCreate.ts index ecc91cdd08..4849bb464a 100644 --- a/packages/xrpl/src/models/transactions/AMMCreate.ts +++ b/packages/xrpl/src/models/transactions/AMMCreate.ts @@ -4,6 +4,7 @@ import { Amount } from '../common' import { BaseTransaction, isAmount, + isNumber, validateBaseTransaction, validateRequiredField, } from './common' @@ -55,16 +56,11 @@ export function validateAMMCreate(tx: Record): void { validateRequiredField(tx, 'Amount', isAmount) validateRequiredField(tx, 'Amount2', isAmount) + validateRequiredField(tx, 'TradingFee', isNumber) - if (tx.TradingFee == null) { - throw new ValidationError('AMMCreate: missing field TradingFee') - } - - if (typeof tx.TradingFee !== 'number') { - throw new ValidationError('AMMCreate: TradingFee must be a number') - } + const tradingFee = Number(tx.TradingFee) - if (tx.TradingFee < 0 || tx.TradingFee > AMM_MAX_TRADING_FEE) { + if (tradingFee < 0 || tradingFee > AMM_MAX_TRADING_FEE) { throw new ValidationError( `AMMCreate: TradingFee must be between 0 and ${AMM_MAX_TRADING_FEE}`, ) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 3ee36288ec..6b60e8a180 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -90,7 +90,7 @@ export function isString(str: unknown): str is string { * @returns Whether the number is properly formed. */ export function isNumber(num: unknown): num is number { - return typeof num === 'number' || Number.isNaN(Number(num)) + return typeof num === 'number' || !Number.isNaN(Number(num)) } /** @@ -457,7 +457,6 @@ export function validateCredentialType(tx: Record): void { * @param isStringID Toggle for if array contains IDs instead of AuthorizeCredential objects * @throws Validation Error if the formatting is incorrect */ -// eslint-disable-next-line max-lines-per-function -- separating logic further will add unnecessary complexity export function validateCredentialsList( credentials: unknown, transactionType: string, @@ -467,9 +466,7 @@ export function validateCredentialsList( return } if (!Array.isArray(credentials)) { - throw new ValidationError( - `${transactionType}: Credentials must be an array`, - ) + throw new ValidationError(`${transactionType}: invalid field Credentials`) } if (credentials.length > MAX_CREDENTIALS_LIST_LENGTH) { throw new ValidationError( diff --git a/packages/xrpl/src/models/transactions/escrowFinish.ts b/packages/xrpl/src/models/transactions/escrowFinish.ts index fd8cb1549d..e580b5c3b5 100644 --- a/packages/xrpl/src/models/transactions/escrowFinish.ts +++ b/packages/xrpl/src/models/transactions/escrowFinish.ts @@ -58,7 +58,11 @@ export function validateEscrowFinish(tx: Record): void { true, ) - validateRequiredField(tx, 'OfferSequence', isNumber) + validateRequiredField( + tx, + 'OfferSequence', + (inp) => isNumber(inp) || isString(inp), + ) validateOptionalField(tx, 'Condition', isString) validateOptionalField(tx, 'Fulfillment', isString) } diff --git a/packages/xrpl/src/models/transactions/offerCancel.ts b/packages/xrpl/src/models/transactions/offerCancel.ts index 546b8d5216..29e4d48779 100644 --- a/packages/xrpl/src/models/transactions/offerCancel.ts +++ b/packages/xrpl/src/models/transactions/offerCancel.ts @@ -1,5 +1,3 @@ -import { ValidationError } from '../../errors' - import { BaseTransaction, isNumber, diff --git a/packages/xrpl/src/models/transactions/offerCreate.ts b/packages/xrpl/src/models/transactions/offerCreate.ts index 6aef05e018..15c18ef06b 100644 --- a/packages/xrpl/src/models/transactions/offerCreate.ts +++ b/packages/xrpl/src/models/transactions/offerCreate.ts @@ -1,4 +1,3 @@ -import { ValidationError } from '../../errors' import { Amount } from '../common' import { diff --git a/packages/xrpl/src/models/transactions/ticketCreate.ts b/packages/xrpl/src/models/transactions/ticketCreate.ts index 8a17ce7b30..b25d8258e7 100644 --- a/packages/xrpl/src/models/transactions/ticketCreate.ts +++ b/packages/xrpl/src/models/transactions/ticketCreate.ts @@ -35,8 +35,7 @@ export function validateTicketCreate(tx: Record): void { validateBaseTransaction(tx) validateRequiredField(tx, 'TicketCount', isNumber) - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- checked above - const ticketCount = tx.TicketCount as number + const ticketCount = Number(tx.TicketCount) if ( !Number.isInteger(ticketCount) || ticketCount < 1 || diff --git a/packages/xrpl/src/models/transactions/trustSet.ts b/packages/xrpl/src/models/transactions/trustSet.ts index 2367ab9bc9..364ceddda0 100644 --- a/packages/xrpl/src/models/transactions/trustSet.ts +++ b/packages/xrpl/src/models/transactions/trustSet.ts @@ -1,10 +1,8 @@ -import { ValidationError } from '../../errors' import { IssuedCurrencyAmount } from '../common' import { BaseTransaction, GlobalFlags, - isAmount, isIssuedCurrency, isNumber, validateBaseTransaction, diff --git a/packages/xrpl/test/models/AMMCreate.test.ts b/packages/xrpl/test/models/AMMCreate.test.ts index 56242140ab..d763acfec8 100644 --- a/packages/xrpl/test/models/AMMCreate.test.ts +++ b/packages/xrpl/test/models/AMMCreate.test.ts @@ -44,7 +44,7 @@ describe('AMMCreate', function () { it(`throws w/ Amount must be an Amount`, function () { ammCreate.Amount = 1000 - const errorMessage = 'AMMCreate: Amount must be an Amount' + const errorMessage = 'AMMCreate: invalid field Amount' assert.throws( () => validateAMMCreate(ammCreate), ValidationError, @@ -66,7 +66,7 @@ describe('AMMCreate', function () { it(`throws w/ Amount2 must be an Amount`, function () { ammCreate.Amount2 = 1000 - const errorMessage = 'AMMCreate: Amount2 must be an Amount' + const errorMessage = 'AMMCreate: invalid field Amount2' assert.throws( () => validateAMMCreate(ammCreate), ValidationError, @@ -88,7 +88,7 @@ describe('AMMCreate', function () { it(`throws w/ TradingFee must be a number`, function () { ammCreate.TradingFee = '12' - const errorMessage = 'AMMCreate: TradingFee must be a number' + const errorMessage = 'AMMCreate: invalid TradingFee' assert.throws( () => validateAMMCreate(ammCreate), ValidationError, diff --git a/packages/xrpl/test/models/AMMDelete.test.ts b/packages/xrpl/test/models/AMMDelete.test.ts index 8c4c9936c8..0da6db8511 100644 --- a/packages/xrpl/test/models/AMMDelete.test.ts +++ b/packages/xrpl/test/models/AMMDelete.test.ts @@ -45,7 +45,7 @@ describe('AMMDelete', function () { it(`throws w/ Asset must be a Currency`, function () { ammDelete.Asset = 1234 - const errorMessage = 'AMMDelete: Asset must be a Currency' + const errorMessage = 'AMMDelete: invalid field Asset' assert.throws( () => validateAMMDelete(ammDelete), ValidationError, @@ -67,7 +67,7 @@ describe('AMMDelete', function () { it(`throws w/ Asset2 must be a Currency`, function () { ammDelete.Asset2 = 1234 - const errorMessage = 'AMMDelete: Asset2 must be a Currency' + const errorMessage = 'AMMDelete: invalid field Asset2' assert.throws( () => validateAMMDelete(ammDelete), ValidationError, diff --git a/packages/xrpl/test/models/AMMDeposit.test.ts b/packages/xrpl/test/models/AMMDeposit.test.ts index 0f041d86f4..2e98371727 100644 --- a/packages/xrpl/test/models/AMMDeposit.test.ts +++ b/packages/xrpl/test/models/AMMDeposit.test.ts @@ -88,7 +88,7 @@ describe('AMMDeposit', function () { it(`throws w/ Asset must be a Currency`, function () { deposit.Asset = 1234 - const errorMessage = 'AMMDeposit: Asset must be a Currency' + const errorMessage = 'AMMDeposit: invalid field Asset' assert.throws( () => validateAMMDeposit(deposit), ValidationError, @@ -110,7 +110,7 @@ describe('AMMDeposit', function () { it(`throws w/ Asset2 must be a Currency`, function () { deposit.Asset2 = 1234 - const errorMessage = 'AMMDeposit: Asset2 must be a Currency' + const errorMessage = 'AMMDeposit: invalid field Asset2' assert.throws( () => validateAMMDeposit(deposit), ValidationError, @@ -157,8 +157,7 @@ describe('AMMDeposit', function () { it(`throws w/ LPTokenOut must be an IssuedCurrencyAmount`, function () { deposit.LPTokenOut = 1234 - const errorMessage = - 'AMMDeposit: LPTokenOut must be an IssuedCurrencyAmount' + const errorMessage = 'AMMDeposit: invalid field LPTokenOut' assert.throws( () => validateAMMDeposit(deposit), ValidationError, @@ -169,7 +168,7 @@ describe('AMMDeposit', function () { it(`throws w/ Amount must be an Amount`, function () { deposit.Amount = 1234 - const errorMessage = 'AMMDeposit: Amount must be an Amount' + const errorMessage = 'AMMDeposit: invalid field Amount' assert.throws( () => validateAMMDeposit(deposit), ValidationError, @@ -181,7 +180,7 @@ describe('AMMDeposit', function () { it(`throws w/ Amount2 must be an Amount`, function () { deposit.Amount = '1000' deposit.Amount2 = 1234 - const errorMessage = 'AMMDeposit: Amount2 must be an Amount' + const errorMessage = 'AMMDeposit: invalid field Amount2' assert.throws( () => validateAMMDeposit(deposit), ValidationError, @@ -193,7 +192,7 @@ describe('AMMDeposit', function () { it(`throws w/ EPrice must be an Amount`, function () { deposit.Amount = '1000' deposit.EPrice = 1234 - const errorMessage = 'AMMDeposit: EPrice must be an Amount' + const errorMessage = 'AMMDeposit: invalid field EPrice' assert.throws( () => validateAMMDeposit(deposit), ValidationError, diff --git a/packages/xrpl/test/models/AMMVote.test.ts b/packages/xrpl/test/models/AMMVote.test.ts index 25f6cdeffe..be3b8c50b3 100644 --- a/packages/xrpl/test/models/AMMVote.test.ts +++ b/packages/xrpl/test/models/AMMVote.test.ts @@ -41,7 +41,7 @@ describe('AMMVote', function () { it(`throws w/ Asset must be a Currency`, function () { vote.Asset = 1234 - const errorMessage = 'AMMVote: Asset must be a Currency' + const errorMessage = 'AMMVote: invalid field Asset' assert.throws(() => validateAMMVote(vote), ValidationError, errorMessage) assert.throws(() => validate(vote), ValidationError, errorMessage) }) @@ -55,7 +55,7 @@ describe('AMMVote', function () { it(`throws w/ Asset2 must be a Currency`, function () { vote.Asset2 = 1234 - const errorMessage = 'AMMVote: Asset2 must be a Currency' + const errorMessage = 'AMMVote: invalid field Asset2' assert.throws(() => validateAMMVote(vote), ValidationError, errorMessage) assert.throws(() => validate(vote), ValidationError, errorMessage) }) @@ -69,7 +69,7 @@ describe('AMMVote', function () { it(`throws w/ TradingFee must be a number`, function () { vote.TradingFee = '25' - const errorMessage = 'AMMVote: TradingFee must be a number' + const errorMessage = 'AMMVote: invalid field TradingFee' assert.throws(() => validateAMMVote(vote), ValidationError, errorMessage) assert.throws(() => validate(vote), ValidationError, errorMessage) }) diff --git a/packages/xrpl/test/models/AMMWithdraw.test.ts b/packages/xrpl/test/models/AMMWithdraw.test.ts index 47092ef724..abeabee70b 100644 --- a/packages/xrpl/test/models/AMMWithdraw.test.ts +++ b/packages/xrpl/test/models/AMMWithdraw.test.ts @@ -101,7 +101,7 @@ describe('AMMWithdraw', function () { it(`throws w/ Asset must be a Currency`, function () { withdraw.Asset = 1234 - const errorMessage = 'AMMWithdraw: Asset must be a Currency' + const errorMessage = 'AMMWithdraw: invalid field Asset' assert.throws( () => validateAMMWithdraw(withdraw), ValidationError, @@ -123,7 +123,7 @@ describe('AMMWithdraw', function () { it(`throws w/ Asset2 must be a Currency`, function () { withdraw.Asset2 = 1234 - const errorMessage = 'AMMWithdraw: Asset2 must be a Currency' + const errorMessage = 'AMMWithdraw: invalid field Asset2' assert.throws( () => validateAMMWithdraw(withdraw), ValidationError, @@ -160,8 +160,7 @@ describe('AMMWithdraw', function () { it(`throws w/ LPTokenIn must be an IssuedCurrencyAmount`, function () { withdraw.LPTokenIn = 1234 - const errorMessage = - 'AMMWithdraw: LPTokenIn must be an IssuedCurrencyAmount' + const errorMessage = 'AMMWithdraw: invalid field LPTokenIn' assert.throws( () => validateAMMWithdraw(withdraw), ValidationError, @@ -172,7 +171,7 @@ describe('AMMWithdraw', function () { it(`throws w/ Amount must be an Amount`, function () { withdraw.Amount = 1234 - const errorMessage = 'AMMWithdraw: Amount must be an Amount' + const errorMessage = 'AMMWithdraw: invalid field Amount' assert.throws( () => validateAMMWithdraw(withdraw), ValidationError, @@ -184,7 +183,7 @@ describe('AMMWithdraw', function () { it(`throws w/ Amount2 must be an Amount`, function () { withdraw.Amount = '1000' withdraw.Amount2 = 1234 - const errorMessage = 'AMMWithdraw: Amount2 must be an Amount' + const errorMessage = 'AMMWithdraw: invalid field Amount2' assert.throws( () => validateAMMWithdraw(withdraw), ValidationError, @@ -196,7 +195,7 @@ describe('AMMWithdraw', function () { it(`throws w/ EPrice must be an Amount`, function () { withdraw.Amount = '1000' withdraw.EPrice = 1234 - const errorMessage = 'AMMWithdraw: EPrice must be an Amount' + const errorMessage = 'AMMWithdraw: invalid field EPrice' assert.throws( () => validateAMMWithdraw(withdraw), ValidationError, diff --git a/packages/xrpl/test/models/NFTokenCreateOffer.test.ts b/packages/xrpl/test/models/NFTokenCreateOffer.test.ts index 6260861608..d498732885 100644 --- a/packages/xrpl/test/models/NFTokenCreateOffer.test.ts +++ b/packages/xrpl/test/models/NFTokenCreateOffer.test.ts @@ -135,7 +135,7 @@ describe('NFTokenCreateOffer', function () { assert.throws( () => validate(invalid), ValidationError, - 'NFTokenCreateOffer: invalid Amount', + 'NFTokenCreateOffer: invalid field Amount', ) }) @@ -154,7 +154,7 @@ describe('NFTokenCreateOffer', function () { assert.throws( () => validate(invalid), ValidationError, - 'NFTokenCreateOffer: invalid Amount', + 'NFTokenCreateOffer: missing field Amount', ) }) diff --git a/packages/xrpl/test/models/checkCreate.test.ts b/packages/xrpl/test/models/checkCreate.test.ts index a97be25184..4c97f6f8b3 100644 --- a/packages/xrpl/test/models/checkCreate.test.ts +++ b/packages/xrpl/test/models/checkCreate.test.ts @@ -67,12 +67,12 @@ describe('CheckCreate', function () { assert.throws( () => validateCheckCreate(invalidSendMax), ValidationError, - 'CheckCreate: invalid SendMax', + 'CheckCreate: invalid field SendMax', ) assert.throws( () => validate(invalidSendMax), ValidationError, - 'CheckCreate: invalid SendMax', + 'CheckCreate: invalid field SendMax', ) }) @@ -85,7 +85,7 @@ describe('CheckCreate', function () { Expiration: 570113521, InvoiceID: '6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B', - DestinationTag: '1', + DestinationTag: 'abcd', Fee: '12', } as any @@ -107,7 +107,7 @@ describe('CheckCreate', function () { Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo', Destination: 'rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy', SendMax: '100000000', - Expiration: '570113521', + Expiration: 'abcd', InvoiceID: '6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B', DestinationTag: 1, @@ -117,12 +117,12 @@ describe('CheckCreate', function () { assert.throws( () => validateCheckCreate(invalidExpiration), ValidationError, - 'CheckCreate: invalid Expiration', + 'CheckCreate: invalid field Expiration', ) assert.throws( () => validate(invalidExpiration), ValidationError, - 'CheckCreate: invalid Expiration', + 'CheckCreate: invalid field Expiration', ) }) @@ -141,12 +141,12 @@ describe('CheckCreate', function () { assert.throws( () => validateCheckCreate(invalidInvoiceID), ValidationError, - 'CheckCreate: invalid InvoiceID', + 'CheckCreate: invalid field InvoiceID', ) assert.throws( () => validate(invalidInvoiceID), ValidationError, - 'CheckCreate: invalid InvoiceID', + 'CheckCreate: invalid field InvoiceID', ) }) }) diff --git a/packages/xrpl/test/models/clawback.test.ts b/packages/xrpl/test/models/clawback.test.ts index 30abcdfcb9..e2ce8158a9 100644 --- a/packages/xrpl/test/models/clawback.test.ts +++ b/packages/xrpl/test/models/clawback.test.ts @@ -45,7 +45,7 @@ describe('Clawback', function () { assert.throws( () => validate(invalidAmount), ValidationError, - 'Clawback: invalid Amount', + 'Clawback: invalid field Amount', ) const invalidStrAmount = { @@ -57,7 +57,7 @@ describe('Clawback', function () { assert.throws( () => validate(invalidStrAmount), ValidationError, - 'Clawback: invalid Amount', + 'Clawback: invalid field Amount', ) }) @@ -124,7 +124,7 @@ describe('Clawback', function () { assert.throws( () => validate(invalidAccount), ValidationError, - 'Clawback: missing Holder', + 'Clawback: missing field Holder', ) }) diff --git a/packages/xrpl/test/models/escrowCancel.test.ts b/packages/xrpl/test/models/escrowCancel.test.ts index 8ec73fe45f..fd833b3f22 100644 --- a/packages/xrpl/test/models/escrowCancel.test.ts +++ b/packages/xrpl/test/models/escrowCancel.test.ts @@ -53,12 +53,12 @@ describe('EscrowCancel', function () { assert.throws( () => validateEscrowCancel(cancel), ValidationError, - 'EscrowCancel: missing OfferSequence', + 'EscrowCancel: missing field OfferSequence', ) assert.throws( () => validate(cancel), ValidationError, - 'EscrowCancel: missing OfferSequence', + 'EscrowCancel: missing field OfferSequence', ) }) @@ -83,12 +83,12 @@ describe('EscrowCancel', function () { assert.throws( () => validateEscrowCancel(cancel), ValidationError, - 'EscrowCancel: OfferSequence must be a number', + 'EscrowCancel: invalid field OfferSequence', ) assert.throws( () => validate(cancel), ValidationError, - 'EscrowCancel: OfferSequence must be a number', + 'EscrowCancel: invalid field OfferSequence', ) }) }) diff --git a/packages/xrpl/test/models/escrowFinish.test.ts b/packages/xrpl/test/models/escrowFinish.test.ts index cac92d1e15..4e98b97417 100644 --- a/packages/xrpl/test/models/escrowFinish.test.ts +++ b/packages/xrpl/test/models/escrowFinish.test.ts @@ -67,12 +67,12 @@ describe('EscrowFinish', function () { assert.throws( () => validateEscrowFinish(escrow), ValidationError, - 'EscrowFinish: OfferSequence must be a number', + 'EscrowFinish: invalid field OfferSequence', ) assert.throws( () => validate(escrow), ValidationError, - 'EscrowFinish: OfferSequence must be a number', + 'EscrowFinish: invalid field OfferSequence', ) }) @@ -82,12 +82,12 @@ describe('EscrowFinish', function () { assert.throws( () => validateEscrowFinish(escrow), ValidationError, - 'EscrowFinish: Condition must be a string', + 'EscrowFinish: invalid field Condition', ) assert.throws( () => validate(escrow), ValidationError, - 'EscrowFinish: Condition must be a string', + 'EscrowFinish: invalid field Condition', ) }) @@ -97,12 +97,12 @@ describe('EscrowFinish', function () { assert.throws( () => validateEscrowFinish(escrow), ValidationError, - 'EscrowFinish: Fulfillment must be a string', + 'EscrowFinish: invalid field Fulfillment', ) assert.throws( () => validate(escrow), ValidationError, - 'EscrowFinish: Fulfillment must be a string', + 'EscrowFinish: invalid field Fulfillment', ) }) @@ -110,7 +110,7 @@ describe('EscrowFinish', function () { escrow.CredentialIDs = 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66A' - const errorMessage = 'EscrowFinish: Credentials must be an array' + const errorMessage = 'EscrowFinish: invalid field Credentials' assert.throws( () => validateEscrowFinish(escrow), diff --git a/packages/xrpl/test/models/offerCancel.test.ts b/packages/xrpl/test/models/offerCancel.test.ts index 2aea40c3cc..0e8df7167e 100644 --- a/packages/xrpl/test/models/offerCancel.test.ts +++ b/packages/xrpl/test/models/offerCancel.test.ts @@ -39,7 +39,7 @@ describe('OfferCancel', function () { }) it(`throws w/ OfferSequence must be a number`, function () { - offer.OfferSequence = '99' + offer.OfferSequence = 'abcd' assert.throws( () => validateOfferCancel(offer), ValidationError, diff --git a/packages/xrpl/test/models/offerCreate.test.ts b/packages/xrpl/test/models/offerCreate.test.ts index d3fa1c9d11..10b4dfb42e 100644 --- a/packages/xrpl/test/models/offerCreate.test.ts +++ b/packages/xrpl/test/models/offerCreate.test.ts @@ -9,8 +9,10 @@ import { validateOfferCreate } from '../../src/models/transactions/offerCreate' * Providing runtime verification testing for each specific transaction type. */ describe('OfferCreate', function () { - it(`verifies valid OfferCreate`, function () { - const offer = { + let offer + + beforeEach(function () { + offer = { Account: 'r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W', Fee: '10', Flags: 0, @@ -30,7 +32,8 @@ describe('OfferCreate', function () { TxnSignature: '3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91', } as any - + }) + it(`verifies valid OfferCreate`, function () { assert.doesNotThrow(() => validateOfferCreate(offer)) assert.doesNotThrow(() => validate(offer)) @@ -84,130 +87,62 @@ describe('OfferCreate', function () { }) it(`throws w/ invalid Expiration`, function () { - const offer = { - Account: 'r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W', - Fee: '10', - Flags: 0, - LastLedgerSequence: 65453019, - Sequence: 40949322, - SigningPubKey: - '03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22', - Expiration: '11', - TakerGets: '12928290425', - TakerPays: { - currency: 'DSH', - issuer: 'rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX', - value: '43.11584856965009', - }, - TransactionType: 'OfferCreate', - TxnSignature: - '3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91', - } as any + offer.Expiration = 'abcd' assert.throws( () => validateOfferCreate(offer), ValidationError, - 'OfferCreate: invalid Expiration', + 'OfferCreate: invalid field Expiration', ) assert.throws( () => validate(offer), ValidationError, - 'OfferCreate: invalid Expiration', + 'OfferCreate: invalid field Expiration', ) }) it(`throws w/ invalid OfferSequence`, function () { - const offer = { - Account: 'r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W', - Fee: '10', - Flags: 0, - LastLedgerSequence: 65453019, - Sequence: 40949322, - SigningPubKey: - '03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22', - OfferSequence: '11', - TakerGets: '12928290425', - TakerPays: { - currency: 'DSH', - issuer: 'rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX', - value: '43.11584856965009', - }, - TransactionType: 'OfferCreate', - TxnSignature: - '3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91', - } as any + offer.OfferSequence = 'abcd' assert.throws( () => validateOfferCreate(offer), ValidationError, - 'OfferCreate: invalid OfferSequence', + 'OfferCreate: invalid field OfferSequence', ) assert.throws( () => validate(offer), ValidationError, - 'OfferCreate: invalid OfferSequence', + 'OfferCreate: invalid field OfferSequence', ) }) it(`throws w/ invalid TakerPays`, function () { - const offer = { - Account: 'r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W', - Fee: '10', - Flags: 0, - LastLedgerSequence: 65453019, - Sequence: 40949322, - SigningPubKey: - '03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22', - OfferSequence: '11', - TakerGets: '12928290425', - TakerPays: 10, - TransactionType: 'OfferCreate', - TxnSignature: - '3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91', - } as any + offer.TakerPays = 10 assert.throws( () => validateOfferCreate(offer), ValidationError, - 'OfferCreate: invalid TakerPays', + 'OfferCreate: invalid field TakerPays', ) assert.throws( () => validate(offer), ValidationError, - 'OfferCreate: invalid TakerPays', + 'OfferCreate: invalid field TakerPays', ) }) it(`throws w/ invalid TakerGets`, function () { - const offer = { - Account: 'r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W', - Fee: '10', - Flags: 0, - LastLedgerSequence: 65453019, - Sequence: 40949322, - SigningPubKey: - '03C48299E57F5AE7C2BE1391B581D313F1967EA2301628C07AC412092FDC15BA22', - OfferSequence: '11', - TakerGets: 11, - TakerPays: { - currency: 'DSH', - issuer: 'rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX', - value: '43.11584856965009', - }, - TransactionType: 'OfferCreate', - TxnSignature: - '3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91', - } as any + offer.TakerGets = 11 assert.throws( () => validateOfferCreate(offer), ValidationError, - 'OfferCreate: invalid TakerGets', + 'OfferCreate: invalid field TakerGets', ) assert.throws( () => validate(offer), ValidationError, - 'OfferCreate: invalid TakerGets', + 'OfferCreate: invalid field TakerGets', ) }) }) diff --git a/packages/xrpl/test/models/oracleDelete.test.ts b/packages/xrpl/test/models/oracleDelete.test.ts index 78188638bc..734caef230 100644 --- a/packages/xrpl/test/models/oracleDelete.test.ts +++ b/packages/xrpl/test/models/oracleDelete.test.ts @@ -32,7 +32,7 @@ describe('OracleDelete', function () { }) it(`throws w/ invalid OracleDocumentID`, function () { - tx.OracleDocumentID = '1234' + tx.OracleDocumentID = 'abcd' const errorMessage = 'OracleDelete: invalid field OracleDocumentID' assert.throws(() => validateOracleDelete(tx), ValidationError, errorMessage) assert.throws(() => validate(tx), ValidationError, errorMessage) diff --git a/packages/xrpl/test/models/oracleSet.test.ts b/packages/xrpl/test/models/oracleSet.test.ts index 18ce5d87e8..d7ec991250 100644 --- a/packages/xrpl/test/models/oracleSet.test.ts +++ b/packages/xrpl/test/models/oracleSet.test.ts @@ -47,7 +47,7 @@ describe('OracleSet', function () { }) it(`throws w/ invalid OracleDocumentID`, function () { - tx.OracleDocumentID = '1234' + tx.OracleDocumentID = 'abcd' const errorMessage = 'OracleSet: invalid field OracleDocumentID' assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) assert.throws(() => validate(tx), ValidationError, errorMessage) @@ -61,7 +61,7 @@ describe('OracleSet', function () { }) it(`throws w/ invalid LastUpdateTime`, function () { - tx.LastUpdateTime = '768062172' + tx.LastUpdateTime = 'abcd' const errorMessage = 'OracleSet: invalid field LastUpdateTime' assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) assert.throws(() => validate(tx), ValidationError, errorMessage) @@ -167,14 +167,14 @@ describe('OracleSet', function () { }) it(`throws w/ invalid AssetPrice of PriceDataSeries`, function () { - tx.PriceDataSeries[0].PriceData.AssetPrice = '1234' + tx.PriceDataSeries[0].PriceData.AssetPrice = 'abcd' const errorMessage = 'OracleSet: invalid field AssetPrice' assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) assert.throws(() => validate(tx), ValidationError, errorMessage) }) it(`throws w/ invalid Scale of PriceDataSeries`, function () { - tx.PriceDataSeries[0].PriceData.Scale = '1234' + tx.PriceDataSeries[0].PriceData.Scale = 'abcd' const errorMessage = 'OracleSet: invalid field Scale' assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) assert.throws(() => validate(tx), ValidationError, errorMessage) diff --git a/packages/xrpl/test/models/paymentChannelFund.test.ts b/packages/xrpl/test/models/paymentChannelFund.test.ts index 65c39c9878..6fd3f83e34 100644 --- a/packages/xrpl/test/models/paymentChannelFund.test.ts +++ b/packages/xrpl/test/models/paymentChannelFund.test.ts @@ -40,12 +40,12 @@ describe('PaymentChannelFund', function () { assert.throws( () => validatePaymentChannelFund(channel), ValidationError, - 'PaymentChannelFund: missing Amount', + 'PaymentChannelFund: missing field Amount', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelFund: missing Amount', + 'PaymentChannelFund: missing field Amount', ) }) @@ -55,12 +55,12 @@ describe('PaymentChannelFund', function () { assert.throws( () => validatePaymentChannelFund(channel), ValidationError, - 'PaymentChannelFund: missing Channel', + 'PaymentChannelFund: missing field Channel', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelFund: missing Channel', + 'PaymentChannelFund: missing field Channel', ) }) @@ -70,12 +70,12 @@ describe('PaymentChannelFund', function () { assert.throws( () => validatePaymentChannelFund(channel), ValidationError, - 'PaymentChannelFund: Amount must be a string', + 'PaymentChannelFund: invalid field Amount', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelFund: Amount must be a string', + 'PaymentChannelFund: invalid field Amount', ) }) @@ -85,12 +85,12 @@ describe('PaymentChannelFund', function () { assert.throws( () => validatePaymentChannelFund(channel), ValidationError, - 'PaymentChannelFund: Channel must be a string', + 'PaymentChannelFund: invalid field Channel', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelFund: Channel must be a string', + 'PaymentChannelFund: Channel', ) }) @@ -100,12 +100,12 @@ describe('PaymentChannelFund', function () { assert.throws( () => validatePaymentChannelFund(channel), ValidationError, - 'PaymentChannelFund: Expiration must be a number', + 'PaymentChannelFund: invalid field Expiration', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelFund: Expiration must be a number', + 'PaymentChannelFund: invalid field Expiration', ) }) }) diff --git a/packages/xrpl/test/models/setRegularKey.test.ts b/packages/xrpl/test/models/setRegularKey.test.ts index 1dcb859891..a410dd7bc1 100644 --- a/packages/xrpl/test/models/setRegularKey.test.ts +++ b/packages/xrpl/test/models/setRegularKey.test.ts @@ -38,12 +38,12 @@ describe('SetRegularKey', function () { assert.throws( () => validateSetRegularKey(account), ValidationError, - 'SetRegularKey: RegularKey must be a string', + 'SetRegularKey: invalid field RegularKey', ) assert.throws( () => validate(account), ValidationError, - 'SetRegularKey: RegularKey must be a string', + 'SetRegularKey: invalid field RegularKey', ) }) }) diff --git a/packages/xrpl/test/models/ticketCreate.test.ts b/packages/xrpl/test/models/ticketCreate.test.ts index 4ec21a8bf4..a45f333779 100644 --- a/packages/xrpl/test/models/ticketCreate.test.ts +++ b/packages/xrpl/test/models/ticketCreate.test.ts @@ -43,12 +43,12 @@ describe('TicketCreate', function () { assert.throws( () => validateTicketCreate(ticketCreate), ValidationError, - 'TicketCreate: TicketCount must be a number', + 'TicketCreate: invalid field TicketCount', ) assert.throws( () => validate(ticketCreate), ValidationError, - 'TicketCreate: TicketCount must be a number', + 'TicketCreate: invalid field TicketCount', ) }) From 2e1ff66885f548db72593634d7d319ddf02bb359 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 12 Feb 2025 14:00:07 -0500 Subject: [PATCH 05/46] fix all tests --- .../xrpl/src/models/transactions/AMMBid.ts | 35 +-- .../xrpl/src/models/transactions/AMMVote.ts | 13 +- .../models/transactions/NFTokenAcceptOffer.ts | 4 +- .../src/models/transactions/accountSet.ts | 12 +- .../xrpl/src/models/transactions/clawback.ts | 2 +- .../xrpl/src/models/transactions/common.ts | 4 +- .../src/models/transactions/depositPreauth.ts | 4 +- .../src/models/transactions/escrowCreate.ts | 8 - .../src/models/transactions/escrowFinish.ts | 6 +- .../xrpl/src/models/transactions/payment.ts | 8 +- packages/xrpl/test/models/AMMBid.test.ts | 16 +- packages/xrpl/test/models/AMMCreate.test.ts | 4 +- packages/xrpl/test/models/AMMVote.test.ts | 2 +- .../test/models/NFTokenAcceptOffer.test.ts | 2 +- .../xrpl/test/models/accountDelete.test.ts | 2 +- packages/xrpl/test/models/accountSet.test.ts | 34 +-- .../xrpl/test/models/baseTransaction.test.ts | 14 +- packages/xrpl/test/models/checkCancel.test.ts | 4 +- packages/xrpl/test/models/checkCash.test.ts | 14 +- packages/xrpl/test/models/clawback.test.ts | 32 +++ .../xrpl/test/models/depositPreauth.test.ts | 12 +- .../xrpl/test/models/escrowCreate.test.ts | 20 +- packages/xrpl/test/models/offerCancel.test.ts | 4 +- packages/xrpl/test/models/payment.test.ts | 227 +++++++----------- .../test/models/paymentChannelClaim.test.ts | 24 +- .../test/models/paymentChannelCreate.test.ts | 34 +-- .../test/models/paymentChannelFund.test.ts | 4 +- .../xrpl/test/models/signerListSet.test.ts | 4 +- .../xrpl/test/models/ticketCreate.test.ts | 2 +- packages/xrpl/test/models/trustSet.test.ts | 16 +- 30 files changed, 263 insertions(+), 304 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMBid.ts b/packages/xrpl/src/models/transactions/AMMBid.ts index 046aeacceb..3468f7116d 100644 --- a/packages/xrpl/src/models/transactions/AMMBid.ts +++ b/packages/xrpl/src/models/transactions/AMMBid.ts @@ -6,6 +6,8 @@ import { isAmount, isCurrency, validateBaseTransaction, + validateOptionalField, + validateRequiredField, } from './common' const MAX_AUTH_ACCOUNTS = 4 @@ -61,29 +63,10 @@ export interface AMMBid extends BaseTransaction { export function validateAMMBid(tx: Record): void { validateBaseTransaction(tx) - if (tx.Asset == null) { - throw new ValidationError('AMMBid: missing field Asset') - } - - if (!isCurrency(tx.Asset)) { - throw new ValidationError('AMMBid: Asset must be a Currency') - } - - if (tx.Asset2 == null) { - throw new ValidationError('AMMBid: missing field Asset2') - } - - if (!isCurrency(tx.Asset2)) { - throw new ValidationError('AMMBid: Asset2 must be a Currency') - } - - if (tx.BidMin != null && !isAmount(tx.BidMin)) { - throw new ValidationError('AMMBid: BidMin must be an Amount') - } - - if (tx.BidMax != null && !isAmount(tx.BidMax)) { - throw new ValidationError('AMMBid: BidMax must be an Amount') - } + validateRequiredField(tx, 'Asset', isCurrency) + validateRequiredField(tx, 'Asset2', isCurrency) + validateOptionalField(tx, 'BidMin', isAmount) + validateOptionalField(tx, 'BidMax', isAmount) if (tx.AuthAccounts != null) { if (!Array.isArray(tx.AuthAccounts)) { @@ -114,17 +97,17 @@ function validateAuthAccounts( authAccount.AuthAccount == null || typeof authAccount.AuthAccount !== 'object' ) { - throw new ValidationError(`AMMBid: invalid AuthAccounts`) + throw new ValidationError(`AMMBid: invalid field AuthAccounts`) } // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- used for null check // @ts-expect-error -- used for null check if (authAccount.AuthAccount.Account == null) { - throw new ValidationError(`AMMBid: invalid AuthAccounts`) + throw new ValidationError(`AMMBid: invalid field AuthAccounts`) } // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- used for null check // @ts-expect-error -- used for null check if (typeof authAccount.AuthAccount.Account !== 'string') { - throw new ValidationError(`AMMBid: invalid AuthAccounts`) + throw new ValidationError(`AMMBid: invalid field AuthAccounts`) } // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- used for null check // @ts-expect-error -- used for null check diff --git a/packages/xrpl/src/models/transactions/AMMVote.ts b/packages/xrpl/src/models/transactions/AMMVote.ts index 0f7cfa6c6f..c900cbcf8a 100644 --- a/packages/xrpl/src/models/transactions/AMMVote.ts +++ b/packages/xrpl/src/models/transactions/AMMVote.ts @@ -5,6 +5,7 @@ import { AMM_MAX_TRADING_FEE } from './AMMCreate' import { BaseTransaction, isCurrency, + isNumber, validateBaseTransaction, validateRequiredField, } from './common' @@ -46,16 +47,10 @@ export function validateAMMVote(tx: Record): void { validateRequiredField(tx, 'Asset', isCurrency) validateRequiredField(tx, 'Asset2', isCurrency) + validateRequiredField(tx, 'TradingFee', isNumber) - if (tx.TradingFee == null) { - throw new ValidationError('AMMVote: missing field TradingFee') - } - - if (typeof tx.TradingFee !== 'number') { - throw new ValidationError('AMMVote: TradingFee must be a number') - } - - if (tx.TradingFee < 0 || tx.TradingFee > AMM_MAX_TRADING_FEE) { + const tradingFee = Number(tx.TradingFee) + if (tradingFee < 0 || tradingFee > AMM_MAX_TRADING_FEE) { throw new ValidationError( `AMMVote: TradingFee must be between 0 and ${AMM_MAX_TRADING_FEE}`, ) diff --git a/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts b/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts index 40dea89497..950b0387b6 100644 --- a/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts +++ b/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts @@ -76,7 +76,9 @@ export interface NFTokenAcceptOfferMetadata extends TransactionMetadataBase { function validateNFTokenBrokerFee(tx: Record): void { const value = parseAmountValue(tx.NFTokenBrokerFee) if (Number.isNaN(value)) { - throw new ValidationError('NFTokenAcceptOffer: invalid NFTokenBrokerFee') + throw new ValidationError( + 'NFTokenAcceptOffer: invalid field NFTokenBrokerFee', + ) } if (value <= 0) { diff --git a/packages/xrpl/src/models/transactions/accountSet.ts b/packages/xrpl/src/models/transactions/accountSet.ts index 199b7c3279..47933652a0 100644 --- a/packages/xrpl/src/models/transactions/accountSet.ts +++ b/packages/xrpl/src/models/transactions/accountSet.ts @@ -180,10 +180,10 @@ export function validateAccountSet(tx: Record): void { if (tx.ClearFlag !== undefined) { if (typeof tx.ClearFlag !== 'number') { - throw new ValidationError('AccountSet: invalid ClearFlag') + throw new ValidationError('AccountSet: invalid field ClearFlag') } if (!Object.values(AccountSetAsfFlags).includes(tx.ClearFlag)) { - throw new ValidationError('AccountSet: invalid ClearFlag') + throw new ValidationError('AccountSet: invalid field ClearFlag') } } @@ -193,10 +193,10 @@ export function validateAccountSet(tx: Record): void { if (tx.SetFlag !== undefined) { if (typeof tx.SetFlag !== 'number') { - throw new ValidationError('AccountSet: invalid SetFlag') + throw new ValidationError('AccountSet: invalid field SetFlag') } if (!Object.values(AccountSetAsfFlags).includes(tx.SetFlag)) { - throw new ValidationError('AccountSet: invalid SetFlag') + throw new ValidationError('AccountSet: invalid field SetFlag') } } @@ -204,13 +204,13 @@ export function validateAccountSet(tx: Record): void { if (tx.TickSize !== undefined) { if (typeof tx.TickSize !== 'number') { - throw new ValidationError('AccountSet: invalid TickSize') + throw new ValidationError('AccountSet: invalid field TickSize') } if ( tx.TickSize !== 0 && (tx.TickSize < MIN_TICK_SIZE || tx.TickSize > MAX_TICK_SIZE) ) { - throw new ValidationError('AccountSet: invalid TickSize') + throw new ValidationError('AccountSet: invalid field TickSize') } } } diff --git a/packages/xrpl/src/models/transactions/clawback.ts b/packages/xrpl/src/models/transactions/clawback.ts index e5a661ab97..6699953f4a 100644 --- a/packages/xrpl/src/models/transactions/clawback.ts +++ b/packages/xrpl/src/models/transactions/clawback.ts @@ -64,7 +64,7 @@ export function validateClawback(tx: Record): void { } if (!tx.Holder) { - throw new ValidationError('Clawback: missing Holder') + throw new ValidationError('Clawback: missing field Holder') } } } diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 6b60e8a180..511695139e 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -371,7 +371,7 @@ export function validateBaseTransaction(common: Record): void { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS const memos = common.Memos as Array<{ Memo?: unknown }> | undefined if (memos !== undefined && !memos.every(isMemo)) { - throw new ValidationError('BaseTransaction: invalid Memos') + throw new ValidationError('BaseTransaction: invalid field Memos') } // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS @@ -381,7 +381,7 @@ export function validateBaseTransaction(common: Record): void { signers !== undefined && (signers.length === 0 || !signers.every(isSigner)) ) { - throw new ValidationError('BaseTransaction: invalid Signers') + throw new ValidationError('BaseTransaction: invalid field Signers') } validateOptionalField(common, 'SourceTag', isNumber) diff --git a/packages/xrpl/src/models/transactions/depositPreauth.ts b/packages/xrpl/src/models/transactions/depositPreauth.ts index 71476d42d4..0ee23d715e 100644 --- a/packages/xrpl/src/models/transactions/depositPreauth.ts +++ b/packages/xrpl/src/models/transactions/depositPreauth.ts @@ -48,7 +48,7 @@ export function validateDepositPreauth(tx: Record): void { if (tx.Authorize !== undefined) { if (typeof tx.Authorize !== 'string') { - throw new ValidationError('DepositPreauth: Authorize must be a string') + throw new ValidationError('DepositPreauth: invalid field Authorize') } if (tx.Account === tx.Authorize) { @@ -58,7 +58,7 @@ export function validateDepositPreauth(tx: Record): void { } } else if (tx.Unauthorize !== undefined) { if (typeof tx.Unauthorize !== 'string') { - throw new ValidationError('DepositPreauth: Unauthorize must be a string') + throw new ValidationError('DepositPreauth: invalid field Unauthorize') } if (tx.Account === tx.Unauthorize) { diff --git a/packages/xrpl/src/models/transactions/escrowCreate.ts b/packages/xrpl/src/models/transactions/escrowCreate.ts index e9a3e1889b..1e3fddcbb3 100644 --- a/packages/xrpl/src/models/transactions/escrowCreate.ts +++ b/packages/xrpl/src/models/transactions/escrowCreate.ts @@ -60,14 +60,6 @@ export interface EscrowCreate extends BaseTransaction { export function validateEscrowCreate(tx: Record): void { validateBaseTransaction(tx) - if (tx.Amount === undefined) { - throw new ValidationError('EscrowCreate: missing field Amount') - } - - if (typeof tx.Amount !== 'string') { - throw new ValidationError('EscrowCreate: Amount must be a string') - } - validateRequiredField(tx, 'Amount', isAmount) validateRequiredField(tx, 'Destination', isAccount) validateOptionalField(tx, 'DestinationTag', isNumber) diff --git a/packages/xrpl/src/models/transactions/escrowFinish.ts b/packages/xrpl/src/models/transactions/escrowFinish.ts index e580b5c3b5..fd8cb1549d 100644 --- a/packages/xrpl/src/models/transactions/escrowFinish.ts +++ b/packages/xrpl/src/models/transactions/escrowFinish.ts @@ -58,11 +58,7 @@ export function validateEscrowFinish(tx: Record): void { true, ) - validateRequiredField( - tx, - 'OfferSequence', - (inp) => isNumber(inp) || isString(inp), - ) + validateRequiredField(tx, 'OfferSequence', isNumber) validateOptionalField(tx, 'Condition', isString) validateOptionalField(tx, 'Fulfillment', isString) } diff --git a/packages/xrpl/src/models/transactions/payment.ts b/packages/xrpl/src/models/transactions/payment.ts index b3ae3c9b60..6695b19e90 100644 --- a/packages/xrpl/src/models/transactions/payment.ts +++ b/packages/xrpl/src/models/transactions/payment.ts @@ -183,7 +183,7 @@ export function validatePayment(tx: Record): void { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS !isPaths(tx.Paths as Array>>) ) { - throw new ValidationError('PaymentTransaction: invalid Paths') + throw new ValidationError('Payment: invalid field Paths') } validateOptionalField(tx, 'SendMax', isAmount) @@ -203,7 +203,7 @@ function checkPartialPayment(tx: Record): void { if (tx.DeliverMin != null) { if (tx.Flags == null) { throw new ValidationError( - 'PaymentTransaction: tfPartialPayment flag required with DeliverMin', + 'Payment: tfPartialPayment flag required with DeliverMin', ) } @@ -216,12 +216,12 @@ function checkPartialPayment(tx: Record): void { if (!isTfPartialPayment) { throw new ValidationError( - 'PaymentTransaction: tfPartialPayment flag required with DeliverMin', + 'Payment: tfPartialPayment flag required with DeliverMin', ) } if (!isAmount(tx.DeliverMin)) { - throw new ValidationError('PaymentTransaction: invalid DeliverMin') + throw new ValidationError('Payment: invalid field DeliverMin') } } } diff --git a/packages/xrpl/test/models/AMMBid.test.ts b/packages/xrpl/test/models/AMMBid.test.ts index d7f0ea7385..68b1a53662 100644 --- a/packages/xrpl/test/models/AMMBid.test.ts +++ b/packages/xrpl/test/models/AMMBid.test.ts @@ -72,7 +72,7 @@ describe('AMMBid', function () { it(`throws w/ Asset must be a Currency`, function () { bid.Asset = 1234 - const errorMessage = 'AMMBid: Asset must be a Currency' + const errorMessage = 'AMMBid: invalid field Asset' assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) assert.throws(() => validate(bid), ValidationError, errorMessage) }) @@ -86,21 +86,21 @@ describe('AMMBid', function () { it(`throws w/ Asset2 must be a Currency`, function () { bid.Asset2 = 1234 - const errorMessage = 'AMMBid: Asset2 must be a Currency' + const errorMessage = 'AMMBid: invalid field Asset2' assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) assert.throws(() => validate(bid), ValidationError, errorMessage) }) it(`throws w/ BidMin must be an Amount`, function () { bid.BidMin = 5 - const errorMessage = 'AMMBid: BidMin must be an Amount' + const errorMessage = 'AMMBid: invalid field BidMin' assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) assert.throws(() => validate(bid), ValidationError, errorMessage) }) it(`throws w/ BidMax must be an Amount`, function () { bid.BidMax = 10 - const errorMessage = 'AMMBid: BidMax must be an Amount' + const errorMessage = 'AMMBid: invalid field BidMax' assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) assert.throws(() => validate(bid), ValidationError, errorMessage) }) @@ -128,7 +128,7 @@ describe('AMMBid', function () { bid.AuthAccounts[0] = { AuthAccount: null, } - const errorMessage = 'AMMBid: invalid AuthAccounts' + const errorMessage = 'AMMBid: invalid field AuthAccounts' assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) assert.throws(() => validate(bid), ValidationError, errorMessage) }) @@ -137,7 +137,7 @@ describe('AMMBid', function () { bid.AuthAccounts[0] = { AuthAccount: undefined, } - const errorMessage = 'AMMBid: invalid AuthAccounts' + const errorMessage = 'AMMBid: invalid field AuthAccounts' assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) assert.throws(() => validate(bid), ValidationError, errorMessage) }) @@ -146,7 +146,7 @@ describe('AMMBid', function () { bid.AuthAccounts[0] = { AuthAccount: 1234, } - const errorMessage = 'AMMBid: invalid AuthAccounts' + const errorMessage = 'AMMBid: invalid field AuthAccounts' assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) assert.throws(() => validate(bid), ValidationError, errorMessage) }) @@ -157,7 +157,7 @@ describe('AMMBid', function () { Account: 1234, }, } - const errorMessage = 'AMMBid: invalid AuthAccounts' + const errorMessage = 'AMMBid: invalid field AuthAccounts' assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) assert.throws(() => validate(bid), ValidationError, errorMessage) }) diff --git a/packages/xrpl/test/models/AMMCreate.test.ts b/packages/xrpl/test/models/AMMCreate.test.ts index d763acfec8..620f63ed82 100644 --- a/packages/xrpl/test/models/AMMCreate.test.ts +++ b/packages/xrpl/test/models/AMMCreate.test.ts @@ -87,8 +87,8 @@ describe('AMMCreate', function () { }) it(`throws w/ TradingFee must be a number`, function () { - ammCreate.TradingFee = '12' - const errorMessage = 'AMMCreate: invalid TradingFee' + ammCreate.TradingFee = 'abcd' + const errorMessage = 'AMMCreate: invalid field TradingFee' assert.throws( () => validateAMMCreate(ammCreate), ValidationError, diff --git a/packages/xrpl/test/models/AMMVote.test.ts b/packages/xrpl/test/models/AMMVote.test.ts index be3b8c50b3..b5c7bd45c6 100644 --- a/packages/xrpl/test/models/AMMVote.test.ts +++ b/packages/xrpl/test/models/AMMVote.test.ts @@ -68,7 +68,7 @@ describe('AMMVote', function () { }) it(`throws w/ TradingFee must be a number`, function () { - vote.TradingFee = '25' + vote.TradingFee = 'abcd' const errorMessage = 'AMMVote: invalid field TradingFee' assert.throws(() => validateAMMVote(vote), ValidationError, errorMessage) assert.throws(() => validate(vote), ValidationError, errorMessage) diff --git a/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts b/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts index f53b14c340..57af203c54 100644 --- a/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts +++ b/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts @@ -173,7 +173,7 @@ describe('NFTokenAcceptOffer', function () { assert.throws( () => validate(invalid), ValidationError, - 'NFTokenAcceptOffer: invalid NFTokenBrokerFee', + 'NFTokenAcceptOffer: invalid field NFTokenBrokerFee', ) }) }) diff --git a/packages/xrpl/test/models/accountDelete.test.ts b/packages/xrpl/test/models/accountDelete.test.ts index 34b0cfa0f0..19c02070b6 100644 --- a/packages/xrpl/test/models/accountDelete.test.ts +++ b/packages/xrpl/test/models/accountDelete.test.ts @@ -83,7 +83,7 @@ describe('AccountDelete', function () { validAccountDelete.CredentialIDs = 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66A' - const errorMessage = 'AccountDelete: Credentials must be an array' + const errorMessage = 'AccountDelete: invalid field Credentials' assert.throws( () => validateAccountDelete(validAccountDelete), diff --git a/packages/xrpl/test/models/accountSet.test.ts b/packages/xrpl/test/models/accountSet.test.ts index b3ce24eadd..19655ccac0 100644 --- a/packages/xrpl/test/models/accountSet.test.ts +++ b/packages/xrpl/test/models/accountSet.test.ts @@ -35,12 +35,12 @@ describe('AccountSet', function () { assert.throws( () => validateAccountSet(account), ValidationError, - 'AccountSet: invalid SetFlag', + 'AccountSet: invalid field SetFlag', ) assert.throws( () => validate(account), ValidationError, - 'AccountSet: invalid SetFlag', + 'AccountSet: invalid field SetFlag', ) }) @@ -50,12 +50,12 @@ describe('AccountSet', function () { assert.throws( () => validateAccountSet(account), ValidationError, - 'AccountSet: invalid SetFlag', + 'AccountSet: invalid field SetFlag', ) assert.throws( () => validate(account), ValidationError, - 'AccountSet: invalid SetFlag', + 'AccountSet: invalid field SetFlag', ) }) @@ -65,12 +65,12 @@ describe('AccountSet', function () { assert.throws( () => validateAccountSet(account), ValidationError, - 'AccountSet: invalid ClearFlag', + 'AccountSet: invalid field ClearFlag', ) assert.throws( () => validate(account), ValidationError, - 'AccountSet: invalid ClearFlag', + 'AccountSet: invalid field ClearFlag', ) }) @@ -80,12 +80,12 @@ describe('AccountSet', function () { assert.throws( () => validateAccountSet(account), ValidationError, - 'AccountSet: invalid Domain', + 'AccountSet: invalid field Domain', ) assert.throws( () => validate(account), ValidationError, - 'AccountSet: invalid Domain', + 'AccountSet: invalid field Domain', ) }) @@ -95,12 +95,12 @@ describe('AccountSet', function () { assert.throws( () => validateAccountSet(account), ValidationError, - 'AccountSet: invalid EmailHash', + 'AccountSet: invalid field EmailHash', ) assert.throws( () => validate(account), ValidationError, - 'AccountSet: invalid EmailHash', + 'AccountSet: invalid field EmailHash', ) }) @@ -110,27 +110,27 @@ describe('AccountSet', function () { assert.throws( () => validateAccountSet(account), ValidationError, - 'AccountSet: invalid MessageKey', + 'AccountSet: invalid field MessageKey', ) assert.throws( () => validate(account), ValidationError, - 'AccountSet: invalid MessageKey', + 'AccountSet: invalid field MessageKey', ) }) it(`throws w/ invalid TransferRate`, function () { - account.TransferRate = '1000000001' + account.TransferRate = 'abcd' assert.throws( () => validateAccountSet(account), ValidationError, - 'AccountSet: invalid TransferRate', + 'AccountSet: invalid field TransferRate', ) assert.throws( () => validate(account), ValidationError, - 'AccountSet: invalid TransferRate', + 'AccountSet: invalid field TransferRate', ) }) @@ -140,12 +140,12 @@ describe('AccountSet', function () { assert.throws( () => validateAccountSet(account), ValidationError, - 'AccountSet: invalid TickSize', + 'AccountSet: invalid field TickSize', ) assert.throws( () => validate(account), ValidationError, - 'AccountSet: invalid TickSize', + 'AccountSet: invalid field TickSize', ) }) diff --git a/packages/xrpl/test/models/baseTransaction.test.ts b/packages/xrpl/test/models/baseTransaction.test.ts index 10e272f7f2..a1c7718177 100644 --- a/packages/xrpl/test/models/baseTransaction.test.ts +++ b/packages/xrpl/test/models/baseTransaction.test.ts @@ -86,7 +86,7 @@ describe('BaseTransaction', function () { const invalidSeq = { Account: 'r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe', TransactionType: 'Payment', - Sequence: '145', + Sequence: 'abcd', } as any assert.throws( @@ -114,7 +114,7 @@ describe('BaseTransaction', function () { const invalidLastLedgerSequence = { Account: 'r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe', TransactionType: 'Payment', - LastLedgerSequence: '1000', + LastLedgerSequence: 'abcd', } as any assert.throws( @@ -156,7 +156,7 @@ describe('BaseTransaction', function () { const invalidTicketSequence = { Account: 'r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe', TransactionType: 'Payment', - TicketSequence: '1000', + TicketSequence: 'abcd', } as any assert.throws( @@ -190,7 +190,7 @@ describe('BaseTransaction', function () { assert.throws( () => validateBaseTransaction(invalidSigners), ValidationError, - 'BaseTransaction: invalid Signers', + 'BaseTransaction: invalid field Signers', ) const invalidSigners2 = { @@ -208,7 +208,7 @@ describe('BaseTransaction', function () { assert.throws( () => validateBaseTransaction(invalidSigners2), ValidationError, - 'BaseTransaction: invalid Signers', + 'BaseTransaction: invalid field Signers', ) }) @@ -229,7 +229,7 @@ describe('BaseTransaction', function () { assert.throws( () => validateBaseTransaction(invalidMemo), ValidationError, - 'BaseTransaction: invalid Memos', + 'BaseTransaction: invalid field Memos', ) }) @@ -237,7 +237,7 @@ describe('BaseTransaction', function () { const invalidNetworkID = { Account: 'r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe', TransactionType: 'Payment', - NetworkID: '1024', + NetworkID: 'abcd', } assert.throws( () => validateBaseTransaction(invalidNetworkID), diff --git a/packages/xrpl/test/models/checkCancel.test.ts b/packages/xrpl/test/models/checkCancel.test.ts index 1cf87834a7..00dd1583d8 100644 --- a/packages/xrpl/test/models/checkCancel.test.ts +++ b/packages/xrpl/test/models/checkCancel.test.ts @@ -31,12 +31,12 @@ describe('CheckCancel', function () { assert.throws( () => validateCheckCancel(invalidCheckID), ValidationError, - 'CheckCancel: invalid CheckID', + 'CheckCancel: invalid field CheckID', ) assert.throws( () => validate(invalidCheckID), ValidationError, - 'CheckCancel: invalid CheckID', + 'CheckCancel: invalid field CheckID', ) }) }) diff --git a/packages/xrpl/test/models/checkCash.test.ts b/packages/xrpl/test/models/checkCash.test.ts index 918bdeb300..8539341255 100644 --- a/packages/xrpl/test/models/checkCash.test.ts +++ b/packages/xrpl/test/models/checkCash.test.ts @@ -34,12 +34,12 @@ describe('CheckCash', function () { assert.throws( () => validateCheckCash(invalidCheckID), ValidationError, - 'CheckCash: invalid CheckID', + 'CheckCash: invalid field CheckID', ) assert.throws( () => validate(invalidCheckID), ValidationError, - 'CheckCash: invalid CheckID', + 'CheckCash: invalid field CheckID', ) }) @@ -55,12 +55,12 @@ describe('CheckCash', function () { assert.throws( () => validateCheckCash(invalidAmount), ValidationError, - 'CheckCash: invalid Amount', + 'CheckCash: invalid field Amount', ) assert.throws( () => validate(invalidAmount), ValidationError, - 'CheckCash: invalid Amount', + 'CheckCash: invalid field Amount', ) }) @@ -69,7 +69,7 @@ describe('CheckCash', function () { Account: 'rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy', TransactionType: 'CheckCash', Amount: '100000000', - DeliverMin: 852156963, + DeliverMin: '852156963', CheckID: '838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334', } as any @@ -98,12 +98,12 @@ describe('CheckCash', function () { assert.throws( () => validateCheckCash(invalidDeliverMin), ValidationError, - 'CheckCash: invalid DeliverMin', + 'CheckCash: invalid field DeliverMin', ) assert.throws( () => validate(invalidDeliverMin), ValidationError, - 'CheckCash: invalid DeliverMin', + 'CheckCash: invalid field DeliverMin', ) }) }) diff --git a/packages/xrpl/test/models/clawback.test.ts b/packages/xrpl/test/models/clawback.test.ts index e2ce8158a9..7fdae32778 100644 --- a/packages/xrpl/test/models/clawback.test.ts +++ b/packages/xrpl/test/models/clawback.test.ts @@ -1,6 +1,7 @@ import { assert } from 'chai' import { validate, ValidationError } from '../../src' +import { validateClawback } from '../../src/models/transactions/clawback' /** * Clawback Transaction Verification Testing. @@ -20,6 +21,7 @@ describe('Clawback', function () { } as any assert.doesNotThrow(() => validate(validClawback)) + assert.doesNotThrow(() => validateClawback(validClawback)) }) it(`throws w/ missing Amount`, function () { @@ -47,6 +49,11 @@ describe('Clawback', function () { ValidationError, 'Clawback: invalid field Amount', ) + assert.throws( + () => validateClawback(invalidAmount), + ValidationError, + 'Clawback: invalid field Amount', + ) const invalidStrAmount = { TransactionType: 'Clawback', @@ -59,6 +66,11 @@ describe('Clawback', function () { ValidationError, 'Clawback: invalid field Amount', ) + assert.throws( + () => validateClawback(invalidStrAmount), + ValidationError, + 'Clawback: invalid field Amount', + ) }) it(`throws w/ invalid holder Account`, function () { @@ -77,6 +89,11 @@ describe('Clawback', function () { ValidationError, 'Clawback: invalid holder Account', ) + assert.throws( + () => validateClawback(invalidAccount), + ValidationError, + 'Clawback: invalid holder Account', + ) }) it(`verifies valid MPT Clawback`, function () { @@ -109,6 +126,11 @@ describe('Clawback', function () { ValidationError, 'Clawback: invalid holder Account', ) + assert.throws( + () => validateClawback(invalidAccount), + ValidationError, + 'Clawback: invalid holder Account', + ) }) it(`throws w/ invalid Holder`, function () { @@ -126,6 +148,11 @@ describe('Clawback', function () { ValidationError, 'Clawback: missing field Holder', ) + assert.throws( + () => validateClawback(invalidAccount), + ValidationError, + 'Clawback: missing field Holder', + ) }) it(`throws w/ invalid currency Holder`, function () { @@ -145,5 +172,10 @@ describe('Clawback', function () { ValidationError, 'Clawback: cannot have Holder for currency', ) + assert.throws( + () => validateClawback(invalidAccount), + ValidationError, + 'Clawback: cannot have Holder for currency', + ) }) }) diff --git a/packages/xrpl/test/models/depositPreauth.test.ts b/packages/xrpl/test/models/depositPreauth.test.ts index d2598ba452..1d0ca2aea4 100644 --- a/packages/xrpl/test/models/depositPreauth.test.ts +++ b/packages/xrpl/test/models/depositPreauth.test.ts @@ -112,12 +112,12 @@ describe('DepositPreauth', function () { assert.throws( () => validateDepositPreauth(depositPreauth), ValidationError, - 'DepositPreauth: Authorize must be a string', + 'DepositPreauth: invalid field Authorize', ) assert.throws( () => validate(depositPreauth), ValidationError, - 'DepositPreauth: Authorize must be a string', + 'DepositPreauth: invalid field Authorize', ) }) @@ -135,12 +135,12 @@ describe('DepositPreauth', function () { assert.throws( () => validateDepositPreauth(depositPreauth), ValidationError, - 'DepositPreauth: Unauthorize must be a string', + 'DepositPreauth: invalid field Unauthorize', ) assert.throws( () => validate(depositPreauth), ValidationError, - 'DepositPreauth: Unauthorize must be a string', + 'DepositPreauth: invalid field Unauthorize', ) }) @@ -159,7 +159,7 @@ describe('DepositPreauth', function () { }) it('throws when AuthorizeCredentials is not an array', function () { - const errorMessage = 'DepositPreauth: Credentials must be an array' + const errorMessage = 'DepositPreauth: invalid field Credentials' depositPreauth.AuthorizeCredentials = validCredential assert.throws( @@ -171,7 +171,7 @@ describe('DepositPreauth', function () { }) it('throws when UnauthorizeCredentials is not an array', function () { - const errorMessage = 'DepositPreauth: Credentials must be an array' + const errorMessage = 'DepositPreauth: invalid field Credentials' depositPreauth.UnauthorizeCredentials = validCredential assert.throws( diff --git a/packages/xrpl/test/models/escrowCreate.test.ts b/packages/xrpl/test/models/escrowCreate.test.ts index 4458fdd128..235943db70 100644 --- a/packages/xrpl/test/models/escrowCreate.test.ts +++ b/packages/xrpl/test/models/escrowCreate.test.ts @@ -82,37 +82,37 @@ describe('EscrowCreate', function () { assert.throws( () => validateEscrowCreate(escrow), ValidationError, - 'EscrowCreate: Amount must be a string', + 'EscrowCreate: invalid field Amount', ) assert.throws( () => validate(escrow), ValidationError, - 'EscrowCreate: Amount must be a string', + 'EscrowCreate: invalid field Amount', ) }) it(`invalid CancelAfter`, function () { - escrow.CancelAfter = '100' + escrow.CancelAfter = 'abcd' assert.throws( () => validateEscrowCreate(escrow), ValidationError, - 'EscrowCreate: CancelAfter must be a number', + 'EscrowCreate: invalid field CancelAfter', ) assert.throws( () => validate(escrow), ValidationError, - 'EscrowCreate: CancelAfter must be a number', + 'EscrowCreate: invalid field CancelAfter', ) }) it(`invalid FinishAfter`, function () { - escrow.FinishAfter = '1000' + escrow.FinishAfter = 'abcd' assert.throws( () => validateEscrowCreate(escrow), ValidationError, - 'EscrowCreate: FinishAfter must be a number', + 'EscrowCreate: invalid field FinishAfter', ) }) @@ -122,17 +122,17 @@ describe('EscrowCreate', function () { assert.throws( () => validateEscrowCreate(escrow), ValidationError, - 'EscrowCreate: Condition must be a string', + 'EscrowCreate: invalid field Condition', ) assert.throws( () => validate(escrow), ValidationError, - 'EscrowCreate: Condition must be a string', + 'EscrowCreate: invalid field Condition', ) }) it(`invalid DestinationTag`, function () { - escrow.DestinationTag = '100' + escrow.DestinationTag = 'abcd' assert.throws( () => validateEscrowCreate(escrow), diff --git a/packages/xrpl/test/models/offerCancel.test.ts b/packages/xrpl/test/models/offerCancel.test.ts index 0e8df7167e..eb4e2dfc89 100644 --- a/packages/xrpl/test/models/offerCancel.test.ts +++ b/packages/xrpl/test/models/offerCancel.test.ts @@ -43,12 +43,12 @@ describe('OfferCancel', function () { assert.throws( () => validateOfferCancel(offer), ValidationError, - 'OfferCancel: OfferSequence must be a number', + 'OfferCancel: invalid field OfferSequence', ) assert.throws( () => validate(offer), ValidationError, - 'OfferCancel: OfferSequence must be a number', + 'OfferCancel: invalid field OfferSequence', ) }) diff --git a/packages/xrpl/test/models/payment.test.ts b/packages/xrpl/test/models/payment.test.ts index 1af633e0a1..cb76a49121 100644 --- a/packages/xrpl/test/models/payment.test.ts +++ b/packages/xrpl/test/models/payment.test.ts @@ -5,15 +5,15 @@ import { validate, PaymentFlags, ValidationError } from '../../src' import { validatePayment } from '../../src/models/transactions/payment' /** - * PaymentTransaction Verification Testing. + * Payment Verification Testing. * * Providing runtime verification testing for each specific transaction type. */ describe('Payment', function () { - let paymentTransaction + let payment beforeEach(function () { - paymentTransaction = { + payment = { TransactionType: 'Payment', Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo', Amount: '1234', @@ -36,13 +36,13 @@ describe('Payment', function () { } as any }) - it(`verifies valid PaymentTransaction`, function () { - assert.doesNotThrow(() => validatePayment(paymentTransaction)) - assert.doesNotThrow(() => validate(paymentTransaction)) + it(`verifies valid Payment`, function () { + assert.doesNotThrow(() => validatePayment(payment)) + assert.doesNotThrow(() => validate(payment)) }) it(`Verifies memos correctly`, function () { - paymentTransaction.Memos = [ + payment.Memos = [ { Memo: { MemoData: '32324324', @@ -50,11 +50,11 @@ describe('Payment', function () { }, ] - assert.doesNotThrow(() => validate(paymentTransaction)) + assert.doesNotThrow(() => validate(payment)) }) it(`Verifies memos correctly`, function () { - paymentTransaction.Memos = [ + payment.Memos = [ { Memo: { MemoData: '32324324', @@ -64,204 +64,203 @@ describe('Payment', function () { ] assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, - 'BaseTransaction: invalid Memos', + 'BaseTransaction: invalid field Memos', ) }) it(`throws when Amount is missing`, function () { - delete paymentTransaction.Amount + delete payment.Amount assert.throws( - () => validatePayment(paymentTransaction), + () => validatePayment(payment), ValidationError, - 'PaymentTransaction: missing field Amount', + 'Payment: missing field Amount', ) assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, - 'PaymentTransaction: missing field Amount', + 'Payment: missing field Amount', ) }) it(`throws when Amount is invalid`, function () { - paymentTransaction.Amount = 1234 + payment.Amount = 1234 assert.throws( - () => validatePayment(paymentTransaction), + () => validatePayment(payment), ValidationError, - 'PaymentTransaction: invalid Amount', + 'Payment: invalid field Amount', ) assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, - 'PaymentTransaction: invalid Amount', + 'Payment: invalid field Amount', ) }) it(`throws when Destination is missing`, function () { - delete paymentTransaction.Destination + delete payment.Destination assert.throws( - () => validatePayment(paymentTransaction), + () => validatePayment(payment), ValidationError, 'Payment: missing field Destination', ) assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, 'Payment: missing field Destination', ) }) it(`throws when Destination is invalid`, function () { - paymentTransaction.Destination = 7896214 + payment.Destination = 7896214 assert.throws( - () => validatePayment(paymentTransaction), + () => validatePayment(payment), ValidationError, 'Payment: invalid field Destination', ) assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, 'Payment: invalid field Destination', ) }) it(`throws when Destination is invalid classic address`, function () { - paymentTransaction.Destination = 'rABCD' + payment.Destination = 'rABCD' assert.throws( - () => validatePayment(paymentTransaction), + () => validatePayment(payment), ValidationError, 'Payment: invalid field Destination', ) assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, 'Payment: invalid field Destination', ) }) it(`does not throw when Destination is a valid x-address`, function () { - paymentTransaction.Destination = - 'X7WZKEeNVS2p9Tire9DtNFkzWBZbFtSiS2eDBib7svZXuc2' - assert.doesNotThrow(() => validatePayment(paymentTransaction)) - assert.doesNotThrow(() => validate(paymentTransaction)) + payment.Destination = 'X7WZKEeNVS2p9Tire9DtNFkzWBZbFtSiS2eDBib7svZXuc2' + assert.doesNotThrow(() => validatePayment(payment)) + assert.doesNotThrow(() => validate(payment)) }) it(`throws when Destination is an empty string`, function () { - paymentTransaction.Destination = '' + payment.Destination = '' assert.throws( - () => validatePayment(paymentTransaction), + () => validatePayment(payment), ValidationError, 'Payment: invalid field Destination', ) assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, 'Payment: invalid field Destination', ) }) it(`throws when DestinationTag is not a number`, function () { - paymentTransaction.DestinationTag = '1' + payment.DestinationTag = 'abcd' assert.throws( - () => validatePayment(paymentTransaction), + () => validatePayment(payment), ValidationError, 'Payment: invalid field DestinationTag', ) assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, 'Payment: invalid field DestinationTag', ) }) it(`throws when InvoiceID is not a string`, function () { - paymentTransaction.InvoiceID = 19832 + payment.InvoiceID = 19832 assert.throws( - () => validatePayment(paymentTransaction), + () => validatePayment(payment), ValidationError, - 'PaymentTransaction: InvoiceID must be a string', + 'Payment: invalid field InvoiceID', ) assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, - 'PaymentTransaction: InvoiceID must be a string', + 'Payment: invalid field InvoiceID', ) }) it(`throws when Paths is invalid`, function () { - paymentTransaction.Paths = [[{ account: 123 }]] + payment.Paths = [[{ account: 123 }]] assert.throws( - () => validatePayment(paymentTransaction), + () => validatePayment(payment), ValidationError, - 'PaymentTransaction: invalid Paths', + 'Payment: invalid field Paths', ) assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, - 'PaymentTransaction: invalid Paths', + 'Payment: invalid field Paths', ) }) it(`throws when SendMax is invalid`, function () { - paymentTransaction.SendMax = 100000000 + payment.SendMax = 100000000 assert.throws( - () => validatePayment(paymentTransaction), + () => validatePayment(payment), ValidationError, - 'PaymentTransaction: invalid SendMax', + 'Payment: invalid field SendMax', ) assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, - 'PaymentTransaction: invalid SendMax', + 'Payment: invalid field SendMax', ) }) it(`verifies valid DeliverMin with tfPartialPayment flag set as a number`, function () { - paymentTransaction.DeliverMin = '10000' - paymentTransaction.Flags = PaymentFlags.tfPartialPayment - assert.doesNotThrow(() => validatePayment(paymentTransaction)) - assert.doesNotThrow(() => validate(paymentTransaction)) + payment.DeliverMin = '10000' + payment.Flags = PaymentFlags.tfPartialPayment + assert.doesNotThrow(() => validatePayment(payment)) + assert.doesNotThrow(() => validate(payment)) }) it(`verifies valid DeliverMin with tfPartialPayment flag set as a boolean`, function () { - paymentTransaction.DeliverMin = '10000' - paymentTransaction.Flags = { tfPartialPayment: true } - assert.doesNotThrow(() => validatePayment(paymentTransaction)) - assert.doesNotThrow(() => validate(paymentTransaction)) + payment.DeliverMin = '10000' + payment.Flags = { tfPartialPayment: true } + assert.doesNotThrow(() => validatePayment(payment)) + assert.doesNotThrow(() => validate(payment)) }) it(`throws when DeliverMin is invalid`, function () { - paymentTransaction.DeliverMin = 10000 - paymentTransaction.Flags = { tfPartialPayment: true } + payment.DeliverMin = 10000 + payment.Flags = { tfPartialPayment: true } assert.throws( - () => validatePayment(paymentTransaction), + () => validatePayment(payment), ValidationError, - 'PaymentTransaction: invalid DeliverMin', + 'Payment: invalid field DeliverMin', ) assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, - 'PaymentTransaction: invalid DeliverMin', + 'Payment: invalid field DeliverMin', ) }) it(`throws when tfPartialPayment flag is missing with valid DeliverMin`, function () { - paymentTransaction.DeliverMin = '10000' + payment.DeliverMin = '10000' assert.throws( - () => validatePayment(paymentTransaction), + () => validatePayment(payment), ValidationError, - 'PaymentTransaction: tfPartialPayment flag required with DeliverMin', + 'Payment: tfPartialPayment flag required with DeliverMin', ) assert.throws( - () => validate(paymentTransaction), + () => validate(payment), ValidationError, - 'PaymentTransaction: tfPartialPayment flag required with DeliverMin', + 'Payment: tfPartialPayment flag required with DeliverMin', ) }) - it(`verifies valid MPT PaymentTransaction`, function () { - const mptPaymentTransaction = { + it(`verifies valid MPT Payment`, function () { + const mptPayment = { TransactionType: 'Payment', Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo', Amount: { @@ -270,30 +269,22 @@ describe('Payment', function () { }, Destination: 'rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy', } as any - assert.doesNotThrow(() => validatePayment(mptPaymentTransaction)) - assert.doesNotThrow(() => validate(mptPaymentTransaction)) + assert.doesNotThrow(() => validatePayment(mptPayment)) + assert.doesNotThrow(() => validate(mptPayment)) }) it(`throws w/ non-array CredentialIDs`, function () { - paymentTransaction.CredentialIDs = + payment.CredentialIDs = 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66A' - const errorMessage = 'Payment: Credentials must be an array' + const errorMessage = 'Payment: invalid field Credentials' - assert.throws( - () => validatePayment(paymentTransaction), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(paymentTransaction), - ValidationError, - errorMessage, - ) + assert.throws(() => validatePayment(payment), ValidationError, errorMessage) + assert.throws(() => validate(payment), ValidationError, errorMessage) }) it(`throws CredentialIDs length exceeds max length`, function () { - paymentTransaction.CredentialIDs = [ + payment.CredentialIDs = [ 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66A', 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66B', 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66C', @@ -307,57 +298,33 @@ describe('Payment', function () { const errorMessage = 'Payment: Credentials length cannot exceed 8 elements' - assert.throws( - () => validatePayment(paymentTransaction), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(paymentTransaction), - ValidationError, - errorMessage, - ) + assert.throws(() => validatePayment(payment), ValidationError, errorMessage) + assert.throws(() => validate(payment), ValidationError, errorMessage) }) it(`throws w/ empty CredentialIDs`, function () { - paymentTransaction.CredentialIDs = [] + payment.CredentialIDs = [] const errorMessage = 'Payment: Credentials cannot be an empty array' - assert.throws( - () => validatePayment(paymentTransaction), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(paymentTransaction), - ValidationError, - errorMessage, - ) + assert.throws(() => validatePayment(payment), ValidationError, errorMessage) + assert.throws(() => validate(payment), ValidationError, errorMessage) }) it(`throws w/ non-string CredentialIDs`, function () { - paymentTransaction.CredentialIDs = [ + payment.CredentialIDs = [ 123123, 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F662', ] const errorMessage = 'Payment: Invalid Credentials ID list format' - assert.throws( - () => validatePayment(paymentTransaction), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(paymentTransaction), - ValidationError, - errorMessage, - ) + assert.throws(() => validatePayment(payment), ValidationError, errorMessage) + assert.throws(() => validate(payment), ValidationError, errorMessage) }) it(`throws w/ duplicate CredentialIDs`, function () { - paymentTransaction.CredentialIDs = [ + payment.CredentialIDs = [ 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F662', 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F662', ] @@ -365,15 +332,7 @@ describe('Payment', function () { const errorMessage = 'Payment: Credentials cannot contain duplicate elements' - assert.throws( - () => validatePayment(paymentTransaction), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(paymentTransaction), - ValidationError, - errorMessage, - ) + assert.throws(() => validatePayment(payment), ValidationError, errorMessage) + assert.throws(() => validate(payment), ValidationError, errorMessage) }) }) diff --git a/packages/xrpl/test/models/paymentChannelClaim.test.ts b/packages/xrpl/test/models/paymentChannelClaim.test.ts index af9c973556..9d6c37b9c6 100644 --- a/packages/xrpl/test/models/paymentChannelClaim.test.ts +++ b/packages/xrpl/test/models/paymentChannelClaim.test.ts @@ -47,12 +47,12 @@ describe('PaymentChannelClaim', function () { assert.throws( () => validatePaymentChannelClaim(channel), ValidationError, - 'PaymentChannelClaim: missing Channel', + 'PaymentChannelClaim: missing field Channel', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelClaim: missing Channel', + 'PaymentChannelClaim: missing field Channel', ) }) @@ -62,12 +62,12 @@ describe('PaymentChannelClaim', function () { assert.throws( () => validatePaymentChannelClaim(channel), ValidationError, - 'PaymentChannelClaim: Channel must be a string', + 'PaymentChannelClaim: invalid field Channel', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelClaim: Channel must be a string', + 'PaymentChannelClaim: invalid field Channel', ) }) @@ -77,12 +77,12 @@ describe('PaymentChannelClaim', function () { assert.throws( () => validatePaymentChannelClaim(channel), ValidationError, - 'PaymentChannelClaim: Balance must be a string', + 'PaymentChannelClaim: invalid field Balance', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelClaim: Balance must be a string', + 'PaymentChannelClaim: invalid field Balance', ) }) @@ -92,12 +92,12 @@ describe('PaymentChannelClaim', function () { assert.throws( () => validatePaymentChannelClaim(channel), ValidationError, - 'PaymentChannelClaim: Amount must be a string', + 'PaymentChannelClaim: invalid field Amount', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelClaim: Amount must be a string', + 'PaymentChannelClaim: invalid field Amount', ) }) @@ -107,12 +107,12 @@ describe('PaymentChannelClaim', function () { assert.throws( () => validatePaymentChannelClaim(channel), ValidationError, - 'PaymentChannelClaim: Signature must be a string', + 'PaymentChannelClaim: invalid field Signature', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelClaim: Signature must be a string', + 'PaymentChannelClaim: invalid field Signature', ) }) @@ -122,12 +122,12 @@ describe('PaymentChannelClaim', function () { assert.throws( () => validatePaymentChannelClaim(channel), ValidationError, - 'PaymentChannelClaim: PublicKey must be a string', + 'PaymentChannelClaim: invalid field PublicKey', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelClaim: PublicKey must be a string', + 'PaymentChannelClaim: invalid field PublicKey', ) }) }) diff --git a/packages/xrpl/test/models/paymentChannelCreate.test.ts b/packages/xrpl/test/models/paymentChannelCreate.test.ts index b3947cb9d4..6439c8b5e1 100644 --- a/packages/xrpl/test/models/paymentChannelCreate.test.ts +++ b/packages/xrpl/test/models/paymentChannelCreate.test.ts @@ -46,12 +46,12 @@ describe('PaymentChannelCreate', function () { assert.throws( () => validatePaymentChannelCreate(channel), ValidationError, - 'PaymentChannelCreate: missing Amount', + 'PaymentChannelCreate: missing field Amount', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelCreate: missing Amount', + 'PaymentChannelCreate: missing field Amount', ) }) @@ -76,12 +76,12 @@ describe('PaymentChannelCreate', function () { assert.throws( () => validatePaymentChannelCreate(channel), ValidationError, - 'PaymentChannelCreate: missing SettleDelay', + 'PaymentChannelCreate: missing field SettleDelay', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelCreate: missing SettleDelay', + 'PaymentChannelCreate: missing field SettleDelay', ) }) @@ -91,12 +91,12 @@ describe('PaymentChannelCreate', function () { assert.throws( () => validatePaymentChannelCreate(channel), ValidationError, - 'PaymentChannelCreate: missing PublicKey', + 'PaymentChannelCreate: missing field PublicKey', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelCreate: missing PublicKey', + 'PaymentChannelCreate: missing field PublicKey', ) }) @@ -106,12 +106,12 @@ describe('PaymentChannelCreate', function () { assert.throws( () => validatePaymentChannelCreate(channel), ValidationError, - 'PaymentChannelCreate: Amount must be a string', + 'PaymentChannelCreate: invalid field Amount', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelCreate: Amount must be a string', + 'PaymentChannelCreate: invalid field Amount', ) }) @@ -131,17 +131,17 @@ describe('PaymentChannelCreate', function () { }) it(`invalid SettleDelay`, function () { - channel.SettleDelay = '10' + channel.SettleDelay = 'abcd' assert.throws( () => validatePaymentChannelCreate(channel), ValidationError, - 'PaymentChannelCreate: SettleDelay must be a number', + 'PaymentChannelCreate: invalid field SettleDelay', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelCreate: SettleDelay must be a number', + 'PaymentChannelCreate: invalid field SettleDelay', ) }) @@ -151,17 +151,17 @@ describe('PaymentChannelCreate', function () { assert.throws( () => validatePaymentChannelCreate(channel), ValidationError, - 'PaymentChannelCreate: PublicKey must be a string', + 'PaymentChannelCreate: invalid field PublicKey', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelCreate: PublicKey must be a string', + 'PaymentChannelCreate: invalid field PublicKey', ) }) it(`invalid DestinationTag`, function () { - channel.DestinationTag = '10' + channel.DestinationTag = 'abcd' assert.throws( () => validatePaymentChannelCreate(channel), @@ -176,17 +176,17 @@ describe('PaymentChannelCreate', function () { }) it(`invalid CancelAfter`, function () { - channel.CancelAfter = '100' + channel.CancelAfter = 'abcd' assert.throws( () => validatePaymentChannelCreate(channel), ValidationError, - 'PaymentChannelCreate: CancelAfter must be a number', + 'PaymentChannelCreate: invalid field CancelAfter', ) assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelCreate: CancelAfter must be a number', + 'PaymentChannelCreate: invalid field CancelAfter', ) }) }) diff --git a/packages/xrpl/test/models/paymentChannelFund.test.ts b/packages/xrpl/test/models/paymentChannelFund.test.ts index 6fd3f83e34..5ac0c47bb8 100644 --- a/packages/xrpl/test/models/paymentChannelFund.test.ts +++ b/packages/xrpl/test/models/paymentChannelFund.test.ts @@ -90,12 +90,12 @@ describe('PaymentChannelFund', function () { assert.throws( () => validate(channel), ValidationError, - 'PaymentChannelFund: Channel', + 'PaymentChannelFund: invalid field Channel', ) }) it(`throws w/ invalid Expiration`, function () { - channel.Expiration = '1000' + channel.Expiration = 'abcd' assert.throws( () => validatePaymentChannelFund(channel), diff --git a/packages/xrpl/test/models/signerListSet.test.ts b/packages/xrpl/test/models/signerListSet.test.ts index d99062c586..7fad927628 100644 --- a/packages/xrpl/test/models/signerListSet.test.ts +++ b/packages/xrpl/test/models/signerListSet.test.ts @@ -82,12 +82,12 @@ describe('SignerListSet', function () { assert.throws( () => validateSignerListSet(signerListSetTx), ValidationError, - 'SignerListSet: invalid SignerEntries', + 'SignerListSet: invalid field SignerEntries', ) assert.throws( () => validate(signerListSetTx), ValidationError, - 'SignerListSet: invalid SignerEntries', + 'SignerListSet: invalid field SignerEntries', ) }) diff --git a/packages/xrpl/test/models/ticketCreate.test.ts b/packages/xrpl/test/models/ticketCreate.test.ts index a45f333779..d462a3a0c6 100644 --- a/packages/xrpl/test/models/ticketCreate.test.ts +++ b/packages/xrpl/test/models/ticketCreate.test.ts @@ -39,7 +39,7 @@ describe('TicketCreate', function () { }) it('throws when TicketCount is not a number', function () { - ticketCreate.TicketCount = '150' + ticketCreate.TicketCount = 'abcd' assert.throws( () => validateTicketCreate(ticketCreate), ValidationError, diff --git a/packages/xrpl/test/models/trustSet.test.ts b/packages/xrpl/test/models/trustSet.test.ts index ce1b05ebcd..f191c0cbb3 100644 --- a/packages/xrpl/test/models/trustSet.test.ts +++ b/packages/xrpl/test/models/trustSet.test.ts @@ -49,40 +49,40 @@ describe('TrustSet', function () { assert.throws( () => validateTrustSet(trustSet), ValidationError, - 'TrustSet: invalid LimitAmount', + 'TrustSet: invalid field LimitAmount', ) assert.throws( () => validate(trustSet), ValidationError, - 'TrustSet: invalid LimitAmount', + 'TrustSet: invalid field LimitAmount', ) }) it('throws when QualityIn is not a number', function () { - trustSet.QualityIn = '1234' + trustSet.QualityIn = 'abcd' assert.throws( () => validateTrustSet(trustSet), ValidationError, - 'TrustSet: QualityIn must be a number', + 'TrustSet: invalid field QualityIn', ) assert.throws( () => validate(trustSet), ValidationError, - 'TrustSet: QualityIn must be a number', + 'TrustSet: invalid field QualityIn', ) }) it('throws when QualityOut is not a number', function () { - trustSet.QualityOut = '4321' + trustSet.QualityOut = 'dcba' assert.throws( () => validateTrustSet(trustSet), ValidationError, - 'TrustSet: QualityOut must be a number', + 'TrustSet: invalid field QualityOut', ) assert.throws( () => validate(trustSet), ValidationError, - 'TrustSet: QualityOut must be a number', + 'TrustSet: invalid field QualityOut', ) }) }) From 30fe6e02b67cd800fff2cfdb17d6d7a9e97365ec Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 12 Feb 2025 14:02:11 -0500 Subject: [PATCH 06/46] update history --- packages/xrpl/HISTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/xrpl/HISTORY.md b/packages/xrpl/HISTORY.md index 0f995f47a7..eb0ddd39d5 100644 --- a/packages/xrpl/HISTORY.md +++ b/packages/xrpl/HISTORY.md @@ -7,6 +7,9 @@ Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xr ### Added * Adds utility function `convertTxFlagsToNumber` +### Fixed +* Better error handling for model validation + ### Changed * Deprecated `setTransactionFlagsToNumber`. Start using convertTxFlagsToNumber instead From 607342767ef76073ff87b3f2c597e66769788f5d Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 12 Feb 2025 16:52:42 -0500 Subject: [PATCH 07/46] fix build issues --- .../transactions/{CredentialAccept.ts => credentialAccept.ts} | 0 .../transactions/{CredentialCreate.ts => credentialCreate.ts} | 0 .../transactions/{CredentialDelete.ts => credentialDelete.ts} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename packages/xrpl/src/models/transactions/{CredentialAccept.ts => credentialAccept.ts} (100%) rename packages/xrpl/src/models/transactions/{CredentialCreate.ts => credentialCreate.ts} (100%) rename packages/xrpl/src/models/transactions/{CredentialDelete.ts => credentialDelete.ts} (100%) diff --git a/packages/xrpl/src/models/transactions/CredentialAccept.ts b/packages/xrpl/src/models/transactions/credentialAccept.ts similarity index 100% rename from packages/xrpl/src/models/transactions/CredentialAccept.ts rename to packages/xrpl/src/models/transactions/credentialAccept.ts diff --git a/packages/xrpl/src/models/transactions/CredentialCreate.ts b/packages/xrpl/src/models/transactions/credentialCreate.ts similarity index 100% rename from packages/xrpl/src/models/transactions/CredentialCreate.ts rename to packages/xrpl/src/models/transactions/credentialCreate.ts diff --git a/packages/xrpl/src/models/transactions/CredentialDelete.ts b/packages/xrpl/src/models/transactions/credentialDelete.ts similarity index 100% rename from packages/xrpl/src/models/transactions/CredentialDelete.ts rename to packages/xrpl/src/models/transactions/credentialDelete.ts From 6dd9b2c3588e69f8723d5d157dd30a71f798c770 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 12 Feb 2025 17:55:30 -0500 Subject: [PATCH 08/46] refactor tests to use a helper function --- .vscode/settings.json | 1 + packages/xrpl/test/models/AMMBid.test.ts | 54 ++-- packages/xrpl/test/models/AMMClawback.test.ts | 98 ++----- packages/xrpl/test/models/AMMCreate.test.ts | 71 ++---- packages/xrpl/test/models/AMMDelete.test.ts | 41 +-- packages/xrpl/test/models/AMMDeposit.test.ts | 102 ++------ packages/xrpl/test/models/AMMVote.test.ts | 37 ++- packages/xrpl/test/models/AMMWithdraw.test.ts | 101 ++------ .../xrpl/test/models/CredentialAccept.test.ts | 13 +- .../xrpl/test/models/CredentialCreate.test.ts | 13 +- .../xrpl/test/models/CredentialDelete.test.ts | 13 +- packages/xrpl/test/models/DIDDelete.test.ts | 14 +- packages/xrpl/test/models/DIDSet.test.ts | 56 +--- .../xrpl/test/models/MPTokenAuthorize.test.ts | 23 +- .../test/models/MPTokenIssuanceCreate.test.ts | 67 ++--- .../models/MPTokenIssuanceDestroy.test.ts | 9 +- .../test/models/MPTokenIssuanceSet.test.ts | 21 +- .../test/models/NFTokenAcceptOffer.test.ts | 35 +-- packages/xrpl/test/models/NFTokenBurn.test.ts | 10 +- .../test/models/NFTokenCancelOffer.test.ts | 16 +- .../test/models/NFTokenCreateOffer.test.ts | 47 +--- packages/xrpl/test/models/NFTokenMint.test.ts | 47 ++-- .../xrpl/test/models/NFTokenModify.test.ts | 24 +- .../models/XChainAccountCreateCommit.test.ts | 100 ++------ .../XChainAddAccountCreateAttestation.test.ts | 240 ++++-------------- .../models/XChainAddClaimAttestation.test.ts | 215 +++------------- packages/xrpl/test/models/XChainClaim.test.ts | 112 ++------ .../xrpl/test/models/XChainCommit.test.ts | 90 +------ .../test/models/XChainCreateBridge.test.ts | 68 +---- .../test/models/XChainCreateClaimID.test.ts | 80 +----- .../test/models/XChainModifyBridge.test.ts | 57 +---- .../xrpl/test/models/accountDelete.test.ts | 113 ++------- packages/xrpl/test/models/accountSet.test.ts | 143 ++--------- .../xrpl/test/models/baseTransaction.test.ts | 4 +- packages/xrpl/test/models/checkCancel.test.ts | 22 +- packages/xrpl/test/models/checkCash.test.ts | 54 +--- packages/xrpl/test/models/checkCreate.test.ts | 65 +---- packages/xrpl/test/models/clawback.test.ts | 80 +----- .../xrpl/test/models/depositPreauth.test.ts | 172 +++---------- .../xrpl/test/models/escrowCancel.test.ts | 60 +---- .../xrpl/test/models/escrowCreate.test.ts | 116 ++------- .../xrpl/test/models/escrowFinish.test.ts | 98 ++----- packages/xrpl/test/models/offerCancel.test.ts | 40 +-- packages/xrpl/test/models/offerCreate.test.ts | 57 +---- .../xrpl/test/models/oracleDelete.test.ts | 19 +- packages/xrpl/test/models/oracleSet.test.ts | 72 ++---- packages/xrpl/test/models/payment.test.ts | 179 +++---------- .../test/models/paymentChannelClaim.test.ts | 83 ++---- .../test/models/paymentChannelCreate.test.ts | 127 ++------- .../test/models/paymentChannelFund.test.ts | 72 +----- .../models/permissionedDomainDelete.test.ts | 28 +- .../test/models/permissionedDomainSet.test.ts | 47 ++-- .../xrpl/test/models/setRegularKey.test.ts | 28 +- .../xrpl/test/models/signerListSet.test.ts | 49 +--- .../xrpl/test/models/ticketCreate.test.ts | 67 ++--- packages/xrpl/test/models/trustSet.test.ts | 59 +---- packages/xrpl/test/testUtils.ts | 34 ++- 57 files changed, 873 insertions(+), 2890 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index ef2c734c23..60d9371aad 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,6 +10,7 @@ "multisign", "multisigned", "multisigning", + "Permissioned", "preauthorization", "rippletest", "secp256k1", diff --git a/packages/xrpl/test/models/AMMBid.test.ts b/packages/xrpl/test/models/AMMBid.test.ts index 68b1a53662..1e372cc4f7 100644 --- a/packages/xrpl/test/models/AMMBid.test.ts +++ b/packages/xrpl/test/models/AMMBid.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateAMMBid } from '../../src/models/transactions/AMMBid' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateAMMBid) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateAMMBid, message) /** * AMMBid Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateAMMBid } from '../../src/models/transactions/AMMBid' * Providing runtime verification testing for each specific transaction type. */ describe('AMMBid', function () { - let bid + let bid: any beforeEach(function () { bid = { @@ -55,54 +57,47 @@ describe('AMMBid', function () { }, ], Sequence: 1337, - } as any + } }) it(`verifies valid AMMBid`, function () { - assert.doesNotThrow(() => validateAMMBid(bid)) - assert.doesNotThrow(() => validate(bid)) + assertValid(bid) }) it(`throws w/ missing field Asset`, function () { delete bid.Asset const errorMessage = 'AMMBid: missing field Asset' - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) it(`throws w/ Asset must be a Currency`, function () { bid.Asset = 1234 const errorMessage = 'AMMBid: invalid field Asset' - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) it(`throws w/ missing field Asset2`, function () { delete bid.Asset2 const errorMessage = 'AMMBid: missing field Asset2' - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) it(`throws w/ Asset2 must be a Currency`, function () { bid.Asset2 = 1234 const errorMessage = 'AMMBid: invalid field Asset2' - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) it(`throws w/ BidMin must be an Amount`, function () { bid.BidMin = 5 const errorMessage = 'AMMBid: invalid field BidMin' - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) it(`throws w/ BidMax must be an Amount`, function () { bid.BidMax = 10 const errorMessage = 'AMMBid: invalid field BidMax' - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) it(`throws w/ AuthAccounts length must not be greater than 4`, function () { @@ -113,15 +108,13 @@ describe('AMMBid', function () { }) const errorMessage = 'AMMBid: AuthAccounts length must not be greater than 4' - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) it(`throws w/ AuthAccounts must be an AuthAccount array`, function () { bid.AuthAccounts = 1234 const errorMessage = 'AMMBid: AuthAccounts must be an AuthAccount array' - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) it(`throws w/ invalid AuthAccounts when AuthAccount is null`, function () { @@ -129,8 +122,7 @@ describe('AMMBid', function () { AuthAccount: null, } const errorMessage = 'AMMBid: invalid field AuthAccounts' - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) it(`throws w/ invalid AuthAccounts when AuthAccount is undefined`, function () { @@ -138,8 +130,7 @@ describe('AMMBid', function () { AuthAccount: undefined, } const errorMessage = 'AMMBid: invalid field AuthAccounts' - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) it(`throws w/ invalid AuthAccounts when AuthAccount is not an object`, function () { @@ -147,8 +138,7 @@ describe('AMMBid', function () { AuthAccount: 1234, } const errorMessage = 'AMMBid: invalid field AuthAccounts' - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) it(`throws w/ invalid AuthAccounts when AuthAccount.Account is not a string`, function () { @@ -158,8 +148,7 @@ describe('AMMBid', function () { }, } const errorMessage = 'AMMBid: invalid field AuthAccounts' - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) it(`throws w/ AuthAccounts must not include sender's address`, function () { @@ -170,7 +159,6 @@ describe('AMMBid', function () { } const errorMessage = "AMMBid: AuthAccounts must not include sender's address" - assert.throws(() => validateAMMBid(bid), ValidationError, errorMessage) - assert.throws(() => validate(bid), ValidationError, errorMessage) + assertInvalid(bid, errorMessage) }) }) diff --git a/packages/xrpl/test/models/AMMClawback.test.ts b/packages/xrpl/test/models/AMMClawback.test.ts index a64623fbe2..065839ee8f 100644 --- a/packages/xrpl/test/models/AMMClawback.test.ts +++ b/packages/xrpl/test/models/AMMClawback.test.ts @@ -1,10 +1,12 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { AMMClawbackFlags, validateAMMClawback, } from '../../src/models/transactions/AMMClawback' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateAMMClawback) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateAMMClawback, message) /** * AMMClawback Transaction Verification Testing. @@ -12,7 +14,7 @@ import { * Providing runtime verification testing for each specific transaction type. */ describe('AMMClawback', function () { - let ammClawback + let ammClawback: any beforeEach(function () { ammClawback = { @@ -32,145 +34,87 @@ describe('AMMClawback', function () { value: '1000', }, Sequence: 1337, - } as any + } }) it(`verifies valid AMMClawback`, function () { - assert.doesNotThrow(() => validateAMMClawback(ammClawback)) - assert.doesNotThrow(() => validate(ammClawback)) + assertValid(ammClawback) }) it(`verifies valid AMMClawback without Amount`, function () { delete ammClawback.Amount - assert.doesNotThrow(() => validateAMMClawback(ammClawback)) - assert.doesNotThrow(() => validate(ammClawback)) + assertValid(ammClawback) }) it(`verifies valid AMMClawback with tfClawTwoAssets`, function () { ammClawback.flags = AMMClawbackFlags.tfClawTwoAssets - assert.doesNotThrow(() => validateAMMClawback(ammClawback)) - assert.doesNotThrow(() => validate(ammClawback)) + assertValid(ammClawback) }) it(`throws w/ missing Holder`, function () { delete ammClawback.Holder const errorMessage = 'AMMClawback: missing field Holder' - assert.throws( - () => validateAMMClawback(ammClawback), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammClawback), ValidationError, errorMessage) + assertInvalid(ammClawback, errorMessage) }) it(`throws w/ invalid field Holder`, function () { ammClawback.Holder = 1234 const errorMessage = 'AMMClawback: invalid field Holder' - assert.throws( - () => validateAMMClawback(ammClawback), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammClawback), ValidationError, errorMessage) + assertInvalid(ammClawback, errorMessage) }) it(`throws w/ Holder and Asset.issuer must be distinct`, function () { ammClawback.Holder = ammClawback.Asset.issuer const errorMessage = 'AMMClawback: Holder and Asset.issuer must be distinct' - assert.throws( - () => validateAMMClawback(ammClawback), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammClawback), ValidationError, errorMessage) + assertInvalid(ammClawback, errorMessage) }) it(`throws w/ missing Asset`, function () { delete ammClawback.Asset const errorMessage = 'AMMClawback: missing field Asset' - assert.throws( - () => validateAMMClawback(ammClawback), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammClawback), ValidationError, errorMessage) + assertInvalid(ammClawback, errorMessage) }) it(`throws w/ invalid field Asset`, function () { ammClawback.Asset = '1000' const errorMessage = 'AMMClawback: invalid field Asset' - assert.throws( - () => validateAMMClawback(ammClawback), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammClawback), ValidationError, errorMessage) + assertInvalid(ammClawback, errorMessage) }) it(`throws w/ Account must be the same as Asset.issuer`, function () { ammClawback.Account = 'rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn' const errorMessage = 'AMMClawback: Account must be the same as Asset.issuer' - assert.throws( - () => validateAMMClawback(ammClawback), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammClawback), ValidationError, errorMessage) + assertInvalid(ammClawback, errorMessage) }) it(`throws w/ missing Asset2`, function () { delete ammClawback.Asset2 const errorMessage = 'AMMClawback: missing field Asset2' - assert.throws( - () => validateAMMClawback(ammClawback), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammClawback), ValidationError, errorMessage) + assertInvalid(ammClawback, errorMessage) }) it(`throws w/ invalid field Asset2`, function () { ammClawback.Asset2 = '1000' const errorMessage = 'AMMClawback: invalid field Asset2' - assert.throws( - () => validateAMMClawback(ammClawback), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammClawback), ValidationError, errorMessage) + assertInvalid(ammClawback, errorMessage) }) it(`throws w/ invalid field Amount`, function () { ammClawback.Amount = 1000 const errorMessage = 'AMMClawback: invalid field Amount' - assert.throws( - () => validateAMMClawback(ammClawback), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammClawback), ValidationError, errorMessage) + assertInvalid(ammClawback, errorMessage) }) it(`throws w/ Amount.currency must match Asset.currency`, function () { ammClawback.Amount.currency = 'ETH' const errorMessage = 'AMMClawback: Amount.currency must match Asset.currency' - assert.throws( - () => validateAMMClawback(ammClawback), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammClawback), ValidationError, errorMessage) + assertInvalid(ammClawback, errorMessage) }) it(`throws w/ Amount.issuer must match Amount.issuer`, function () { ammClawback.Amount.issuer = 'rnYgaEtpqpNRt3wxE39demVpDAA817rQEY' const errorMessage = 'AMMClawback: Amount.issuer must match Amount.issuer' - assert.throws( - () => validateAMMClawback(ammClawback), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammClawback), ValidationError, errorMessage) + assertInvalid(ammClawback, errorMessage) }) }) diff --git a/packages/xrpl/test/models/AMMCreate.test.ts b/packages/xrpl/test/models/AMMCreate.test.ts index 620f63ed82..10805b31f7 100644 --- a/packages/xrpl/test/models/AMMCreate.test.ts +++ b/packages/xrpl/test/models/AMMCreate.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateAMMCreate } from '../../src/models/transactions/AMMCreate' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateAMMCreate) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateAMMCreate, message) /** * AMMCreate Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateAMMCreate } from '../../src/models/transactions/AMMCreate' * Providing runtime verification testing for each specific transaction type. */ describe('AMMCreate', function () { - let ammCreate + let ammCreate: any beforeEach(function () { ammCreate = { @@ -23,99 +25,58 @@ describe('AMMCreate', function () { }, TradingFee: 12, Sequence: 1337, - } as any + } }) it(`verifies valid AMMCreate`, function () { - assert.doesNotThrow(() => validateAMMCreate(ammCreate)) - assert.doesNotThrow(() => validate(ammCreate)) + assertValid(ammCreate) }) it(`throws w/ missing Amount`, function () { delete ammCreate.Amount const errorMessage = 'AMMCreate: missing field Amount' - assert.throws( - () => validateAMMCreate(ammCreate), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammCreate), ValidationError, errorMessage) + assertInvalid(ammCreate, errorMessage) }) it(`throws w/ Amount must be an Amount`, function () { ammCreate.Amount = 1000 const errorMessage = 'AMMCreate: invalid field Amount' - assert.throws( - () => validateAMMCreate(ammCreate), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammCreate), ValidationError, errorMessage) + assertInvalid(ammCreate, errorMessage) }) it(`throws w/ missing Amount2`, function () { delete ammCreate.Amount2 const errorMessage = 'AMMCreate: missing field Amount2' - assert.throws( - () => validateAMMCreate(ammCreate), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammCreate), ValidationError, errorMessage) + assertInvalid(ammCreate, errorMessage) }) it(`throws w/ Amount2 must be an Amount`, function () { ammCreate.Amount2 = 1000 const errorMessage = 'AMMCreate: invalid field Amount2' - assert.throws( - () => validateAMMCreate(ammCreate), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammCreate), ValidationError, errorMessage) + assertInvalid(ammCreate, errorMessage) }) it(`throws w/ missing TradingFee`, function () { delete ammCreate.TradingFee const errorMessage = 'AMMCreate: missing field TradingFee' - assert.throws( - () => validateAMMCreate(ammCreate), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammCreate), ValidationError, errorMessage) + assertInvalid(ammCreate, errorMessage) }) it(`throws w/ TradingFee must be a number`, function () { ammCreate.TradingFee = 'abcd' const errorMessage = 'AMMCreate: invalid field TradingFee' - assert.throws( - () => validateAMMCreate(ammCreate), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammCreate), ValidationError, errorMessage) + assertInvalid(ammCreate, errorMessage) }) it(`throws when TradingFee is greater than 1000`, function () { ammCreate.TradingFee = 1001 const errorMessage = 'AMMCreate: TradingFee must be between 0 and 1000' - assert.throws( - () => validateAMMCreate(ammCreate), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammCreate), ValidationError, errorMessage) + assertInvalid(ammCreate, errorMessage) }) it(`throws when TradingFee is a negative number`, function () { ammCreate.TradingFee = -1 const errorMessage = 'AMMCreate: TradingFee must be between 0 and 1000' - assert.throws( - () => validateAMMCreate(ammCreate), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammCreate), ValidationError, errorMessage) + assertInvalid(ammCreate, errorMessage) }) }) diff --git a/packages/xrpl/test/models/AMMDelete.test.ts b/packages/xrpl/test/models/AMMDelete.test.ts index 0da6db8511..d669341f7f 100644 --- a/packages/xrpl/test/models/AMMDelete.test.ts +++ b/packages/xrpl/test/models/AMMDelete.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateAMMDelete } from '../../src/models/transactions/AMMDelete' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateAMMDelete) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateAMMDelete, message) /** * AMMDelete Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateAMMDelete } from '../../src/models/transactions/AMMDelete' * Providing runtime verification testing for each specific transaction type. */ describe('AMMDelete', function () { - let ammDelete + let ammDelete: any beforeEach(function () { ammDelete = { @@ -28,51 +30,30 @@ describe('AMMDelete', function () { }) it(`verifies valid AMMDelete`, function () { - assert.doesNotThrow(() => validateAMMDelete(ammDelete)) - assert.doesNotThrow(() => validate(ammDelete)) + assertValid(ammDelete) }) it(`throws w/ missing field Asset`, function () { delete ammDelete.Asset const errorMessage = 'AMMDelete: missing field Asset' - assert.throws( - () => validateAMMDelete(ammDelete), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammDelete), ValidationError, errorMessage) + assertInvalid(ammDelete, errorMessage) }) it(`throws w/ Asset must be a Currency`, function () { ammDelete.Asset = 1234 const errorMessage = 'AMMDelete: invalid field Asset' - assert.throws( - () => validateAMMDelete(ammDelete), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammDelete), ValidationError, errorMessage) + assertInvalid(ammDelete, errorMessage) }) it(`throws w/ missing field Asset2`, function () { delete ammDelete.Asset2 const errorMessage = 'AMMDelete: missing field Asset2' - assert.throws( - () => validateAMMDelete(ammDelete), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammDelete), ValidationError, errorMessage) + assertInvalid(ammDelete, errorMessage) }) it(`throws w/ Asset2 must be a Currency`, function () { ammDelete.Asset2 = 1234 const errorMessage = 'AMMDelete: invalid field Asset2' - assert.throws( - () => validateAMMDelete(ammDelete), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(ammDelete), ValidationError, errorMessage) + assertInvalid(ammDelete, errorMessage) }) }) diff --git a/packages/xrpl/test/models/AMMDeposit.test.ts b/packages/xrpl/test/models/AMMDeposit.test.ts index 2e98371727..f5e7fdbb18 100644 --- a/packages/xrpl/test/models/AMMDeposit.test.ts +++ b/packages/xrpl/test/models/AMMDeposit.test.ts @@ -1,8 +1,12 @@ /* eslint-disable no-bitwise -- bitwise necessary for enabling flags */ -import { assert } from 'chai' -import { AMMDepositFlags, validate, ValidationError } from '../../src' +import { AMMDepositFlags } from '../../src' import { validateAMMDeposit } from '../../src/models/transactions/AMMDeposit' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateAMMDeposit) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateAMMDeposit, message) /** * AMMDeposit Transaction Verification Testing. @@ -15,7 +19,7 @@ describe('AMMDeposit', function () { issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', value: '1000', } - let deposit + let deposit: any beforeEach(function () { deposit = { @@ -36,15 +40,13 @@ describe('AMMDeposit', function () { it(`verifies valid AMMDeposit with LPTokenOut`, function () { deposit.LPTokenOut = LPTokenOut deposit.Flags |= AMMDepositFlags.tfLPToken - assert.doesNotThrow(() => validateAMMDeposit(deposit)) - assert.doesNotThrow(() => validate(deposit)) + assertValid(deposit) }) it(`verifies valid AMMDeposit with Amount`, function () { deposit.Amount = '1000' deposit.Flags |= AMMDepositFlags.tfSingleAsset - assert.doesNotThrow(() => validateAMMDeposit(deposit)) - assert.doesNotThrow(() => validate(deposit)) + assertValid(deposit) }) it(`verifies valid AMMDeposit with Amount and Amount2`, function () { @@ -55,78 +57,50 @@ describe('AMMDeposit', function () { value: '2.5', } deposit.Flags |= AMMDepositFlags.tfTwoAsset - assert.doesNotThrow(() => validateAMMDeposit(deposit)) - assert.doesNotThrow(() => validate(deposit)) + assertValid(deposit) }) it(`verifies valid AMMDeposit with Amount and LPTokenOut`, function () { deposit.Amount = '1000' deposit.LPTokenOut = LPTokenOut deposit.Flags |= AMMDepositFlags.tfOneAssetLPToken - assert.doesNotThrow(() => validateAMMDeposit(deposit)) - assert.doesNotThrow(() => validate(deposit)) + assertValid(deposit) }) it(`verifies valid AMMDeposit with Amount and EPrice`, function () { deposit.Amount = '1000' deposit.EPrice = '25' deposit.Flags |= AMMDepositFlags.tfLimitLPToken - assert.doesNotThrow(() => validateAMMDeposit(deposit)) - assert.doesNotThrow(() => validate(deposit)) + assertValid(deposit) }) it(`throws w/ missing field Asset`, function () { delete deposit.Asset const errorMessage = 'AMMDeposit: missing field Asset' - assert.throws( - () => validateAMMDeposit(deposit), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(deposit), ValidationError, errorMessage) + assertInvalid(deposit, errorMessage) }) it(`throws w/ Asset must be a Currency`, function () { deposit.Asset = 1234 const errorMessage = 'AMMDeposit: invalid field Asset' - assert.throws( - () => validateAMMDeposit(deposit), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(deposit), ValidationError, errorMessage) + assertInvalid(deposit, errorMessage) }) it(`throws w/ missing field Asset2`, function () { delete deposit.Asset2 const errorMessage = 'AMMDeposit: missing field Asset2' - assert.throws( - () => validateAMMDeposit(deposit), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(deposit), ValidationError, errorMessage) + assertInvalid(deposit, errorMessage) }) it(`throws w/ Asset2 must be a Currency`, function () { deposit.Asset2 = 1234 const errorMessage = 'AMMDeposit: invalid field Asset2' - assert.throws( - () => validateAMMDeposit(deposit), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(deposit), ValidationError, errorMessage) + assertInvalid(deposit, errorMessage) }) it(`throws w/ must set at least LPTokenOut or Amount`, function () { const errorMessage = 'AMMDeposit: must set at least LPTokenOut or Amount' - assert.throws( - () => validateAMMDeposit(deposit), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(deposit), ValidationError, errorMessage) + assertInvalid(deposit, errorMessage) }) it(`throws w/ must set Amount with Amount2`, function () { @@ -136,68 +110,38 @@ describe('AMMDeposit', function () { value: '2.5', } const errorMessage = 'AMMDeposit: must set Amount with Amount2' - assert.throws( - () => validateAMMDeposit(deposit), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(deposit), ValidationError, errorMessage) + assertInvalid(deposit, errorMessage) }) it(`throws w/ must set Amount with EPrice`, function () { deposit.EPrice = '25' const errorMessage = 'AMMDeposit: must set Amount with EPrice' - assert.throws( - () => validateAMMDeposit(deposit), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(deposit), ValidationError, errorMessage) + assertInvalid(deposit, errorMessage) }) it(`throws w/ LPTokenOut must be an IssuedCurrencyAmount`, function () { deposit.LPTokenOut = 1234 const errorMessage = 'AMMDeposit: invalid field LPTokenOut' - assert.throws( - () => validateAMMDeposit(deposit), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(deposit), ValidationError, errorMessage) + assertInvalid(deposit, errorMessage) }) it(`throws w/ Amount must be an Amount`, function () { deposit.Amount = 1234 const errorMessage = 'AMMDeposit: invalid field Amount' - assert.throws( - () => validateAMMDeposit(deposit), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(deposit), ValidationError, errorMessage) + assertInvalid(deposit, errorMessage) }) it(`throws w/ Amount2 must be an Amount`, function () { deposit.Amount = '1000' deposit.Amount2 = 1234 const errorMessage = 'AMMDeposit: invalid field Amount2' - assert.throws( - () => validateAMMDeposit(deposit), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(deposit), ValidationError, errorMessage) + assertInvalid(deposit, errorMessage) }) it(`throws w/ EPrice must be an Amount`, function () { deposit.Amount = '1000' deposit.EPrice = 1234 const errorMessage = 'AMMDeposit: invalid field EPrice' - assert.throws( - () => validateAMMDeposit(deposit), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(deposit), ValidationError, errorMessage) + assertInvalid(deposit, errorMessage) }) }) diff --git a/packages/xrpl/test/models/AMMVote.test.ts b/packages/xrpl/test/models/AMMVote.test.ts index b5c7bd45c6..08604b0c31 100644 --- a/packages/xrpl/test/models/AMMVote.test.ts +++ b/packages/xrpl/test/models/AMMVote.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateAMMVote } from '../../src/models/transactions/AMMVote' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateAMMVote) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateAMMVote, message) /** * AMMVote Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateAMMVote } from '../../src/models/transactions/AMMVote' * Providing runtime verification testing for each specific transaction type. */ describe('AMMVote', function () { - let vote + let vote: any beforeEach(function () { vote = { @@ -28,63 +30,54 @@ describe('AMMVote', function () { }) it(`verifies valid AMMVote`, function () { - assert.doesNotThrow(() => validateAMMVote(vote)) - assert.doesNotThrow(() => validate(vote)) + assertValid(vote) }) it(`throws w/ missing field Asset`, function () { delete vote.Asset const errorMessage = 'AMMVote: missing field Asset' - assert.throws(() => validateAMMVote(vote), ValidationError, errorMessage) - assert.throws(() => validate(vote), ValidationError, errorMessage) + assertInvalid(vote, errorMessage) }) it(`throws w/ Asset must be a Currency`, function () { vote.Asset = 1234 const errorMessage = 'AMMVote: invalid field Asset' - assert.throws(() => validateAMMVote(vote), ValidationError, errorMessage) - assert.throws(() => validate(vote), ValidationError, errorMessage) + assertInvalid(vote, errorMessage) }) it(`throws w/ missing field Asset2`, function () { delete vote.Asset2 const errorMessage = 'AMMVote: missing field Asset2' - assert.throws(() => validateAMMVote(vote), ValidationError, errorMessage) - assert.throws(() => validate(vote), ValidationError, errorMessage) + assertInvalid(vote, errorMessage) }) it(`throws w/ Asset2 must be a Currency`, function () { vote.Asset2 = 1234 const errorMessage = 'AMMVote: invalid field Asset2' - assert.throws(() => validateAMMVote(vote), ValidationError, errorMessage) - assert.throws(() => validate(vote), ValidationError, errorMessage) + assertInvalid(vote, errorMessage) }) it(`throws w/ missing field TradingFee`, function () { delete vote.TradingFee const errorMessage = 'AMMVote: missing field TradingFee' - assert.throws(() => validateAMMVote(vote), ValidationError, errorMessage) - assert.throws(() => validate(vote), ValidationError, errorMessage) + assertInvalid(vote, errorMessage) }) it(`throws w/ TradingFee must be a number`, function () { vote.TradingFee = 'abcd' const errorMessage = 'AMMVote: invalid field TradingFee' - assert.throws(() => validateAMMVote(vote), ValidationError, errorMessage) - assert.throws(() => validate(vote), ValidationError, errorMessage) + assertInvalid(vote, errorMessage) }) it(`throws when TradingFee is greater than AMM_MAX_TRADING_FEE`, function () { vote.TradingFee = 1001 const errorMessage = 'AMMVote: TradingFee must be between 0 and 1000' - assert.throws(() => validateAMMVote(vote), ValidationError, errorMessage) - assert.throws(() => validate(vote), ValidationError, errorMessage) + assertInvalid(vote, errorMessage) }) it(`throws when TradingFee is a negative number`, function () { vote.TradingFee = -1 const errorMessage = 'AMMVote: TradingFee must be between 0 and 1000' - assert.throws(() => validateAMMVote(vote), ValidationError, errorMessage) - assert.throws(() => validate(vote), ValidationError, errorMessage) + assertInvalid(vote, errorMessage) }) }) diff --git a/packages/xrpl/test/models/AMMWithdraw.test.ts b/packages/xrpl/test/models/AMMWithdraw.test.ts index abeabee70b..3824c9a425 100644 --- a/packages/xrpl/test/models/AMMWithdraw.test.ts +++ b/packages/xrpl/test/models/AMMWithdraw.test.ts @@ -1,8 +1,12 @@ /* eslint-disable no-bitwise -- bitwise necessary for enabling flags */ -import { assert } from 'chai' -import { AMMWithdrawFlags, validate, ValidationError } from '../../src' +import { AMMWithdrawFlags } from '../../src' import { validateAMMWithdraw } from '../../src/models/transactions/AMMWithdraw' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateAMMWithdraw) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateAMMWithdraw, message) /** * AMMWithdraw Transaction Verification Testing. @@ -15,7 +19,7 @@ describe('AMMWithdraw', function () { issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', value: '1000', } - let withdraw + let withdraw: any beforeEach(function () { withdraw = { @@ -36,15 +40,13 @@ describe('AMMWithdraw', function () { it(`verifies valid AMMWithdraw with LPTokenIn`, function () { withdraw.LPTokenIn = LPTokenIn withdraw.Flags |= AMMWithdrawFlags.tfLPToken - assert.doesNotThrow(() => validateAMMWithdraw(withdraw)) - assert.doesNotThrow(() => validate(withdraw)) + assertValid(withdraw) }) it(`verifies valid AMMWithdraw with Amount`, function () { withdraw.Amount = '1000' withdraw.Flags |= AMMWithdrawFlags.tfSingleAsset - assert.doesNotThrow(() => validateAMMWithdraw(withdraw)) - assert.doesNotThrow(() => validate(withdraw)) + assertValid(withdraw) }) it(`verifies valid AMMWithdraw with Amount and Amount2`, function () { @@ -55,81 +57,56 @@ describe('AMMWithdraw', function () { value: '2.5', } withdraw.Flags |= AMMWithdrawFlags.tfTwoAsset - assert.doesNotThrow(() => validateAMMWithdraw(withdraw)) - assert.doesNotThrow(() => validate(withdraw)) + assertValid(withdraw) }) it(`verifies valid AMMWithdraw with Amount and LPTokenIn`, function () { withdraw.Amount = '1000' withdraw.LPTokenIn = LPTokenIn withdraw.Flags |= AMMWithdrawFlags.tfOneAssetLPToken - assert.doesNotThrow(() => validateAMMWithdraw(withdraw)) - assert.doesNotThrow(() => validate(withdraw)) + assertValid(withdraw) }) it(`verifies valid AMMWithdraw with Amount and EPrice`, function () { withdraw.Amount = '1000' withdraw.EPrice = '25' withdraw.Flags |= AMMWithdrawFlags.tfLimitLPToken - assert.doesNotThrow(() => validateAMMWithdraw(withdraw)) - assert.doesNotThrow(() => validate(withdraw)) + assertValid(withdraw) }) it(`verifies valid AMMWithdraw one asset withdraw all`, function () { withdraw.Amount = '1000' withdraw.Flags |= AMMWithdrawFlags.tfOneAssetWithdrawAll - assert.doesNotThrow(() => validateAMMWithdraw(withdraw)) - assert.doesNotThrow(() => validate(withdraw)) + assertValid(withdraw) }) it(`verifies valid AMMWithdraw withdraw all`, function () { withdraw.Flags |= AMMWithdrawFlags.tfWithdrawAll - assert.doesNotThrow(() => validateAMMWithdraw(withdraw)) - assert.doesNotThrow(() => validate(withdraw)) + assertValid(withdraw) }) it(`throws w/ missing field Asset`, function () { delete withdraw.Asset const errorMessage = 'AMMWithdraw: missing field Asset' - assert.throws( - () => validateAMMWithdraw(withdraw), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(withdraw), ValidationError, errorMessage) + assertInvalid(withdraw, errorMessage) }) it(`throws w/ Asset must be a Currency`, function () { withdraw.Asset = 1234 const errorMessage = 'AMMWithdraw: invalid field Asset' - assert.throws( - () => validateAMMWithdraw(withdraw), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(withdraw), ValidationError, errorMessage) + assertInvalid(withdraw, errorMessage) }) it(`throws w/ missing field Asset2`, function () { delete withdraw.Asset2 const errorMessage = 'AMMWithdraw: missing field Asset2' - assert.throws( - () => validateAMMWithdraw(withdraw), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(withdraw), ValidationError, errorMessage) + assertInvalid(withdraw, errorMessage) }) it(`throws w/ Asset2 must be a Currency`, function () { withdraw.Asset2 = 1234 const errorMessage = 'AMMWithdraw: invalid field Asset2' - assert.throws( - () => validateAMMWithdraw(withdraw), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(withdraw), ValidationError, errorMessage) + assertInvalid(withdraw, errorMessage) }) it(`throws w/ must set Amount with Amount2`, function () { @@ -139,68 +116,38 @@ describe('AMMWithdraw', function () { value: '2.5', } const errorMessage = 'AMMWithdraw: must set Amount with Amount2' - assert.throws( - () => validateAMMWithdraw(withdraw), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(withdraw), ValidationError, errorMessage) + assertInvalid(withdraw, errorMessage) }) it(`throws w/ must set Amount with EPrice`, function () { withdraw.EPrice = '25' const errorMessage = 'AMMWithdraw: must set Amount with EPrice' - assert.throws( - () => validateAMMWithdraw(withdraw), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(withdraw), ValidationError, errorMessage) + assertInvalid(withdraw, errorMessage) }) it(`throws w/ LPTokenIn must be an IssuedCurrencyAmount`, function () { withdraw.LPTokenIn = 1234 const errorMessage = 'AMMWithdraw: invalid field LPTokenIn' - assert.throws( - () => validateAMMWithdraw(withdraw), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(withdraw), ValidationError, errorMessage) + assertInvalid(withdraw, errorMessage) }) it(`throws w/ Amount must be an Amount`, function () { withdraw.Amount = 1234 const errorMessage = 'AMMWithdraw: invalid field Amount' - assert.throws( - () => validateAMMWithdraw(withdraw), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(withdraw), ValidationError, errorMessage) + assertInvalid(withdraw, errorMessage) }) it(`throws w/ Amount2 must be an Amount`, function () { withdraw.Amount = '1000' withdraw.Amount2 = 1234 const errorMessage = 'AMMWithdraw: invalid field Amount2' - assert.throws( - () => validateAMMWithdraw(withdraw), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(withdraw), ValidationError, errorMessage) + assertInvalid(withdraw, errorMessage) }) it(`throws w/ EPrice must be an Amount`, function () { withdraw.Amount = '1000' withdraw.EPrice = 1234 const errorMessage = 'AMMWithdraw: invalid field EPrice' - assert.throws( - () => validateAMMWithdraw(withdraw), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(withdraw), ValidationError, errorMessage) + assertInvalid(withdraw, errorMessage) }) }) diff --git a/packages/xrpl/test/models/CredentialAccept.test.ts b/packages/xrpl/test/models/CredentialAccept.test.ts index 2c8a1890ed..27f8ca2859 100644 --- a/packages/xrpl/test/models/CredentialAccept.test.ts +++ b/packages/xrpl/test/models/CredentialAccept.test.ts @@ -1,8 +1,12 @@ import { stringToHex } from '@xrplf/isomorphic/dist/utils' -import { assert } from 'chai' -import { validate, ValidationError } from '../../src' import { validateCredentialAccept } from '../../src/models/transactions/credentialAccept' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateCredentialAccept) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateCredentialAccept, message) /** * CredentialAccept Transaction Verification Testing. @@ -10,7 +14,7 @@ import { validateCredentialAccept } from '../../src/models/transactions/credenti * Providing runtime verification testing for each specific transaction type. */ describe('CredentialAccept', function () { - let credentialAccept + let credentialAccept: any beforeEach(function () { credentialAccept = { @@ -24,8 +28,7 @@ describe('CredentialAccept', function () { }) it(`verifies valid CredentialAccept`, function () { - assert.doesNotThrow(() => validateCredentialAccept(credentialAccept)) - assert.doesNotThrow(() => validate(credentialAccept)) + assertValid(credentialAccept) }) it(`throws w/ missing field Account`, function () { diff --git a/packages/xrpl/test/models/CredentialCreate.test.ts b/packages/xrpl/test/models/CredentialCreate.test.ts index 25c9c58ca3..277bf717d5 100644 --- a/packages/xrpl/test/models/CredentialCreate.test.ts +++ b/packages/xrpl/test/models/CredentialCreate.test.ts @@ -1,8 +1,12 @@ import { stringToHex } from '@xrplf/isomorphic/dist/utils' -import { assert } from 'chai' -import { validate, ValidationError } from '../../src' import { validateCredentialCreate } from '../../src/models/transactions/credentialCreate' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateCredentialCreate) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateCredentialCreate, message) /** * CredentialCreate Transaction Verification Testing. @@ -10,7 +14,7 @@ import { validateCredentialCreate } from '../../src/models/transactions/credenti * Providing runtime verification testing for each specific transaction type. */ describe('credentialCreate', function () { - let credentialCreate + let credentialCreate: any beforeEach(function () { credentialCreate = { @@ -26,8 +30,7 @@ describe('credentialCreate', function () { }) it(`verifies valid credentialCreate`, function () { - assert.doesNotThrow(() => validateCredentialCreate(credentialCreate)) - assert.doesNotThrow(() => validate(credentialCreate)) + assertValid(credentialCreate) }) it(`throws w/ missing field Account`, function () { diff --git a/packages/xrpl/test/models/CredentialDelete.test.ts b/packages/xrpl/test/models/CredentialDelete.test.ts index bb188687a1..838dfa2f02 100644 --- a/packages/xrpl/test/models/CredentialDelete.test.ts +++ b/packages/xrpl/test/models/CredentialDelete.test.ts @@ -1,8 +1,12 @@ import { stringToHex } from '@xrplf/isomorphic/dist/utils' -import { assert } from 'chai' -import { validate, ValidationError } from '../../src' import { validateCredentialDelete } from '../../src/models/transactions/credentialDelete' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateCredentialDelete) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateCredentialDelete, message) /** * CredentialDelete Transaction Verification Testing. @@ -10,7 +14,7 @@ import { validateCredentialDelete } from '../../src/models/transactions/credenti * Providing runtime verification testing for each specific transaction type. */ describe('CredentialDelete', function () { - let credentialDelete + let credentialDelete: any beforeEach(function () { credentialDelete = { @@ -25,8 +29,7 @@ describe('CredentialDelete', function () { }) it(`verifies valid credentialDelete`, function () { - assert.doesNotThrow(() => validateCredentialDelete(credentialDelete)) - assert.doesNotThrow(() => validate(credentialDelete)) + assertValid(credentialDelete) }) it(`throws w/ missing field Account`, function () { diff --git a/packages/xrpl/test/models/DIDDelete.test.ts b/packages/xrpl/test/models/DIDDelete.test.ts index 7248579b43..cd35e9ec97 100644 --- a/packages/xrpl/test/models/DIDDelete.test.ts +++ b/packages/xrpl/test/models/DIDDelete.test.ts @@ -1,7 +1,7 @@ -import { assert } from 'chai' - -import { validate } from '../../src' import { validateDIDDelete } from '../../src/models/transactions/DIDDelete' +import { assertTxIsValid } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateDIDDelete) /** * DIDDelete Transaction Verification Testing. @@ -9,7 +9,7 @@ import { validateDIDDelete } from '../../src/models/transactions/DIDDelete' * Providing runtime verification testing for each specific transaction type. */ describe('DIDDelete', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -22,13 +22,11 @@ describe('DIDDelete', function () { }) it('verifies valid DIDDelete', function () { - assert.doesNotThrow(() => validateDIDDelete(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it('throws on invalid DIDDelete', function () { tx.FakeField = 'blah' - assert.doesNotThrow(() => validateDIDDelete(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) }) diff --git a/packages/xrpl/test/models/DIDSet.test.ts b/packages/xrpl/test/models/DIDSet.test.ts index 2fc16ca597..0aae8287b2 100644 --- a/packages/xrpl/test/models/DIDSet.test.ts +++ b/packages/xrpl/test/models/DIDSet.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateDIDSet } from '../../src/models/transactions/DIDSet' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateDIDSet) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateDIDSet, message) /** * DIDSet Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateDIDSet } from '../../src/models/transactions/DIDSet' * Providing runtime verification testing for each specific transaction type. */ describe('DIDSet', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -25,53 +27,25 @@ describe('DIDSet', function () { }) it('verifies valid DIDSet', function () { - assert.doesNotThrow(() => validateDIDSet(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it('throws w/ invalid Data', function () { tx.Data = 123 - assert.throws( - () => validateDIDSet(tx), - ValidationError, - 'DIDSet: invalid field Data', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'DIDSet: invalid field Data', - ) + assertInvalid(tx, 'DIDSet: invalid field Data') }) it('throws w/ invalid DIDDocument', function () { tx.DIDDocument = 123 - assert.throws( - () => validateDIDSet(tx), - ValidationError, - 'DIDSet: invalid field DIDDocument', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'DIDSet: invalid field DIDDocument', - ) + assertInvalid(tx, 'DIDSet: invalid field DIDDocument') }) it('throws w/ invalid URI', function () { tx.URI = 123 - assert.throws( - () => validateDIDSet(tx), - ValidationError, - 'DIDSet: invalid field URI', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'DIDSet: invalid field URI', - ) + assertInvalid(tx, 'DIDSet: invalid field URI') }) it('throws w/ empty DID', function () { @@ -79,14 +53,8 @@ describe('DIDSet', function () { delete tx.DIDDocument delete tx.URI - assert.throws( - () => validateDIDSet(tx), - ValidationError, - 'DIDSet: Must have at least one of `Data`, `DIDDocument`, and `URI`', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'DIDSet: Must have at least one of `Data`, `DIDDocument`, and `URI`', ) }) diff --git a/packages/xrpl/test/models/MPTokenAuthorize.test.ts b/packages/xrpl/test/models/MPTokenAuthorize.test.ts index 9e87dfa561..debe77aa75 100644 --- a/packages/xrpl/test/models/MPTokenAuthorize.test.ts +++ b/packages/xrpl/test/models/MPTokenAuthorize.test.ts @@ -1,6 +1,11 @@ -import { assert } from 'chai' +import { MPTokenAuthorizeFlags } from '../../src' +import { validateMPTokenAuthorize } from '../../src/models/transactions/mptokenAuthorize' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' -import { validate, ValidationError, MPTokenAuthorizeFlags } from '../../src' +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateMPTokenAuthorize) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateMPTokenAuthorize, message) const TOKEN_ID = '000004C463C52827307480341125DA0577DEFC38405B0E3E' @@ -17,7 +22,7 @@ describe('MPTokenAuthorize', function () { MPTokenIssuanceID: TOKEN_ID, } as any - assert.doesNotThrow(() => validate(validMPTokenAuthorize)) + assertValid(validMPTokenAuthorize) validMPTokenAuthorize = { TransactionType: 'MPTokenAuthorize', @@ -26,7 +31,7 @@ describe('MPTokenAuthorize', function () { MPTokenIssuanceID: TOKEN_ID, } as any - assert.doesNotThrow(() => validate(validMPTokenAuthorize)) + assertValid(validMPTokenAuthorize) validMPTokenAuthorize = { TransactionType: 'MPTokenAuthorize', @@ -35,7 +40,7 @@ describe('MPTokenAuthorize', function () { Flags: MPTokenAuthorizeFlags.tfMPTUnauthorize, } as any - assert.doesNotThrow(() => validate(validMPTokenAuthorize)) + assertValid(validMPTokenAuthorize) validMPTokenAuthorize = { TransactionType: 'MPTokenAuthorize', @@ -45,7 +50,7 @@ describe('MPTokenAuthorize', function () { Flags: MPTokenAuthorizeFlags.tfMPTUnauthorize, } as any - assert.doesNotThrow(() => validate(validMPTokenAuthorize)) + assertValid(validMPTokenAuthorize) }) it(`throws w/ missing MPTokenIssuanceID`, function () { @@ -54,10 +59,6 @@ describe('MPTokenAuthorize', function () { Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'MPTokenAuthorize: missing field MPTokenIssuanceID', - ) + assertInvalid(invalid, 'MPTokenAuthorize: missing field MPTokenIssuanceID') }) }) diff --git a/packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts b/packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts index 0752394382..21a1f40de3 100644 --- a/packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts +++ b/packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts @@ -1,11 +1,12 @@ -import { assert } from 'chai' +import { stringToHex } from '@xrplf/isomorphic/src/utils' -import { - convertStringToHex, - validate, - ValidationError, - MPTokenIssuanceCreateFlags, -} from '../../src' +import { MPTokenIssuanceCreateFlags } from '../../src' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validatePermissionedDomainSet) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validatePermissionedDomainSet, message) /** * MPTokenIssuanceCreate Transaction Verification Testing. @@ -22,10 +23,10 @@ describe('MPTokenIssuanceCreate', function () { AssetScale: 2, TransferFee: 1, Flags: MPTokenIssuanceCreateFlags.tfMPTCanTransfer, - MPTokenMetadata: convertStringToHex('http://xrpl.org'), + MPTokenMetadata: stringToHex('http://xrpl.org'), } as any - assert.doesNotThrow(() => validate(validMPTokenIssuanceCreate)) + assertValid(validMPTokenIssuanceCreate) }) it(`throws w/ MPTokenMetadata being an empty string`, function () { @@ -36,9 +37,8 @@ describe('MPTokenIssuanceCreate', function () { MPTokenMetadata: '', } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'MPTokenIssuanceCreate: MPTokenMetadata must not be empty string', ) }) @@ -51,9 +51,8 @@ describe('MPTokenIssuanceCreate', function () { MPTokenMetadata: 'http://xrpl.org', } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'MPTokenIssuanceCreate: MPTokenMetadata must be in hex format', ) }) @@ -65,11 +64,7 @@ describe('MPTokenIssuanceCreate', function () { MaximumAmount: '9223372036854775808', } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'MPTokenIssuanceCreate: MaximumAmount out of range', - ) + assertInvalid(invalid, 'MPTokenIssuanceCreate: MaximumAmount out of range') invalid = { TransactionType: 'MPTokenIssuanceCreate', @@ -77,11 +72,7 @@ describe('MPTokenIssuanceCreate', function () { MaximumAmount: '-1', } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'MPTokenIssuanceCreate: Invalid MaximumAmount', - ) + assertInvalid(invalid, 'MPTokenIssuanceCreate: Invalid MaximumAmount') invalid = { TransactionType: 'MPTokenIssuanceCreate', @@ -89,11 +80,7 @@ describe('MPTokenIssuanceCreate', function () { MaximumAmount: '0x12', } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'MPTokenIssuanceCreate: Invalid MaximumAmount', - ) + assertInvalid(invalid, 'MPTokenIssuanceCreate: Invalid MaximumAmount') }) it(`throws w/ Invalid TransferFee`, function () { @@ -103,9 +90,8 @@ describe('MPTokenIssuanceCreate', function () { TransferFee: -1, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'MPTokenIssuanceCreate: TransferFee must be between 0 and 50000', ) @@ -115,9 +101,8 @@ describe('MPTokenIssuanceCreate', function () { TransferFee: 50001, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'MPTokenIssuanceCreate: TransferFee must be between 0 and 50000', ) @@ -127,9 +112,8 @@ describe('MPTokenIssuanceCreate', function () { TransferFee: 100, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'MPTokenIssuanceCreate: TransferFee cannot be provided without enabling tfMPTCanTransfer flag', ) @@ -140,9 +124,8 @@ describe('MPTokenIssuanceCreate', function () { Flags: { tfMPTCanClawback: true }, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'MPTokenIssuanceCreate: TransferFee cannot be provided without enabling tfMPTCanTransfer flag', ) }) diff --git a/packages/xrpl/test/models/MPTokenIssuanceDestroy.test.ts b/packages/xrpl/test/models/MPTokenIssuanceDestroy.test.ts index 46bd53814c..a9cc03533b 100644 --- a/packages/xrpl/test/models/MPTokenIssuanceDestroy.test.ts +++ b/packages/xrpl/test/models/MPTokenIssuanceDestroy.test.ts @@ -1,7 +1,3 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' - const TOKEN_ID = '000004C463C52827307480341125DA0577DEFC38405B0E3E' /** @@ -26,9 +22,8 @@ describe('MPTokenIssuanceDestroy', function () { Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'MPTokenIssuanceDestroy: missing field MPTokenIssuanceID', ) }) diff --git a/packages/xrpl/test/models/MPTokenIssuanceSet.test.ts b/packages/xrpl/test/models/MPTokenIssuanceSet.test.ts index 0932727e54..08f2755478 100644 --- a/packages/xrpl/test/models/MPTokenIssuanceSet.test.ts +++ b/packages/xrpl/test/models/MPTokenIssuanceSet.test.ts @@ -1,6 +1,4 @@ -import { assert } from 'chai' - -import { validate, ValidationError, MPTokenIssuanceSetFlags } from '../../src' +import { MPTokenIssuanceSetFlags } from '../../src' const TOKEN_ID = '000004C463C52827307480341125DA0577DEFC38405B0E3E' @@ -47,9 +45,8 @@ describe('MPTokenIssuanceSet', function () { Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'MPTokenIssuanceSet: missing field MPTokenIssuanceID', ) }) @@ -65,18 +62,10 @@ describe('MPTokenIssuanceSet', function () { // eslint-disable-next-line no-bitwise -- not needed MPTokenIssuanceSetFlags.tfMPTLock | MPTokenIssuanceSetFlags.tfMPTUnlock - assert.throws( - () => validate(invalid), - ValidationError, - 'MPTokenIssuanceSet: flag conflict', - ) + assertInvalid(invalid, 'MPTokenIssuanceSet: flag conflict') invalid.Flags = { tfMPTLock: true, tfMPTUnlock: true } - assert.throws( - () => validate(invalid), - ValidationError, - 'MPTokenIssuanceSet: flag conflict', - ) + assertInvalid(invalid, 'MPTokenIssuanceSet: flag conflict') }) }) diff --git a/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts b/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts index 57af203c54..30f51909ad 100644 --- a/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts +++ b/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts @@ -1,7 +1,3 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' - const NFTOKEN_BUY_OFFER = 'AED08CC1F50DD5F23A1948AF86153A3F3B7593E5EC77D65A02BB1B29E05AB6AF' const NFTOKEN_SELL_OFFER = @@ -48,9 +44,8 @@ describe('NFTokenAcceptOffer', function () { Flags: 2147483648, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'NFTokenAcceptOffer: must set either NFTokenSellOffer or NFTokenBuyOffer', ) }) @@ -66,9 +61,8 @@ describe('NFTokenAcceptOffer', function () { Flags: 2147483648, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'NFTokenAcceptOffer: both NFTokenSellOffer and NFTokenBuyOffer must be set if using brokered mode', ) }) @@ -84,9 +78,8 @@ describe('NFTokenAcceptOffer', function () { Flags: 2147483648, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'NFTokenAcceptOffer: both NFTokenSellOffer and NFTokenBuyOffer must be set if using brokered mode', ) }) @@ -132,9 +125,8 @@ describe('NFTokenAcceptOffer', function () { Flags: 2147483648, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'NFTokenAcceptOffer: NFTokenBrokerFee must be greater than 0; omit if there is no fee', ) }) @@ -151,9 +143,8 @@ describe('NFTokenAcceptOffer', function () { Flags: 2147483648, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'NFTokenAcceptOffer: NFTokenBrokerFee must be greater than 0; omit if there is no fee', ) }) @@ -170,10 +161,6 @@ describe('NFTokenAcceptOffer', function () { Flags: 2147483648, } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenAcceptOffer: invalid field NFTokenBrokerFee', - ) + assertInvalid(invalid, 'NFTokenAcceptOffer: invalid field NFTokenBrokerFee') }) }) diff --git a/packages/xrpl/test/models/NFTokenBurn.test.ts b/packages/xrpl/test/models/NFTokenBurn.test.ts index 9d799a3262..c73c86999f 100644 --- a/packages/xrpl/test/models/NFTokenBurn.test.ts +++ b/packages/xrpl/test/models/NFTokenBurn.test.ts @@ -1,7 +1,3 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' - const TOKEN_ID = '00090032B5F762798A53D543A014CAF8B297CFF8F2F937E844B17C9E00000003' @@ -33,10 +29,6 @@ describe('NFTokenBurn', function () { Flags: 2147483648, } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenBurn: missing field NFTokenID', - ) + assertInvalid(invalid, 'NFTokenBurn: missing field NFTokenID') }) }) diff --git a/packages/xrpl/test/models/NFTokenCancelOffer.test.ts b/packages/xrpl/test/models/NFTokenCancelOffer.test.ts index d020299529..63c23c5fb7 100644 --- a/packages/xrpl/test/models/NFTokenCancelOffer.test.ts +++ b/packages/xrpl/test/models/NFTokenCancelOffer.test.ts @@ -1,7 +1,3 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' - const BUY_OFFER = 'AED08CC1F50DD5F23A1948AF86153A3F3B7593E5EC77D65A02BB1B29E05AB6AF' @@ -33,11 +29,7 @@ describe('NFTokenCancelOffer', function () { Flags: 2147483648, } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenCancelOffer: missing field NFTokenOffers', - ) + assertInvalid(invalid, 'NFTokenCancelOffer: missing field NFTokenOffers') }) it(`throws w/ empty NFTokenOffers`, function () { @@ -50,10 +42,6 @@ describe('NFTokenCancelOffer', function () { Flags: 2147483648, } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenCancelOffer: empty field NFTokenOffers', - ) + assertInvalid(invalid, 'NFTokenCancelOffer: empty field NFTokenOffers') }) }) diff --git a/packages/xrpl/test/models/NFTokenCreateOffer.test.ts b/packages/xrpl/test/models/NFTokenCreateOffer.test.ts index d498732885..196f9283de 100644 --- a/packages/xrpl/test/models/NFTokenCreateOffer.test.ts +++ b/packages/xrpl/test/models/NFTokenCreateOffer.test.ts @@ -1,6 +1,4 @@ -import { assert } from 'chai' - -import { validate, ValidationError, NFTokenCreateOfferFlags } from '../../src' +import { NFTokenCreateOfferFlags } from '../../src' const NFTOKEN_ID = '00090032B5F762798A53D543A014CAF8B297CFF8F2F937E844B17C9E00000003' @@ -73,9 +71,8 @@ describe('NFTokenCreateOffer', function () { Sequence: 2470665, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'NFTokenCreateOffer: Owner and Account must not be equal', ) }) @@ -93,9 +90,8 @@ describe('NFTokenCreateOffer', function () { Sequence: 2470665, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'NFTokenCreateOffer: Destination and Account must not be equal', ) }) @@ -112,11 +108,7 @@ describe('NFTokenCreateOffer', function () { Sequence: 2470665, } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenCreateOffer: missing field NFTokenID', - ) + assertInvalid(invalid, 'NFTokenCreateOffer: missing field NFTokenID') }) it(`throws w/ invalid Amount`, function () { @@ -132,11 +124,7 @@ describe('NFTokenCreateOffer', function () { Sequence: 2470665, } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenCreateOffer: invalid field Amount', - ) + assertInvalid(invalid, 'NFTokenCreateOffer: invalid field Amount') }) it(`throws w/ missing Amount`, function () { @@ -151,11 +139,7 @@ describe('NFTokenCreateOffer', function () { Sequence: 2470665, } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenCreateOffer: missing field Amount', - ) + assertInvalid(invalid, 'NFTokenCreateOffer: missing field Amount') }) it(`throws w/ Owner for sell offer`, function () { @@ -171,9 +155,8 @@ describe('NFTokenCreateOffer', function () { Sequence: 2470665, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'NFTokenCreateOffer: Owner must not be present for sell offers', ) }) @@ -189,9 +172,8 @@ describe('NFTokenCreateOffer', function () { Sequence: 2470665, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'NFTokenCreateOffer: Owner must be present for buy offers', ) }) @@ -208,9 +190,8 @@ describe('NFTokenCreateOffer', function () { Sequence: 2470665, } as any - assert.throws( - () => validate(invalid), - ValidationError, + assertInvalid( + invalid, 'NFTokenCreateOffer: Amount must be greater than 0 for buy offers', ) }) diff --git a/packages/xrpl/test/models/NFTokenMint.test.ts b/packages/xrpl/test/models/NFTokenMint.test.ts index 82dbd001f5..f508479a2f 100644 --- a/packages/xrpl/test/models/NFTokenMint.test.ts +++ b/packages/xrpl/test/models/NFTokenMint.test.ts @@ -1,11 +1,12 @@ -import { assert } from 'chai' +import { stringToHex } from '@xrplf/isomorphic/src/utils' -import { - convertStringToHex, - validate, - ValidationError, - NFTokenMintFlags, -} from '../../src' +import { NFTokenMintFlags } from '../../src' +import { validateNFTokenMint } from '../../src/models/transactions/nftokenMint' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateNFTokenMint) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateNFTokenMint, message) /** * NFTokenMint Transaction Verification Testing. @@ -25,10 +26,10 @@ describe('NFTokenMint', function () { NFTokenTaxon: 0, Issuer: 'r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ', TransferFee: 1, - URI: convertStringToHex('http://xrpl.org'), + URI: stringToHex('http://xrpl.org'), } as any - assert.doesNotThrow(() => validate(validNFTokenMint)) + assertValid(validNFTokenMint) }) it(`throws w/ missing NFTokenTaxon`, function () { @@ -40,14 +41,10 @@ describe('NFTokenMint', function () { Flags: NFTokenMintFlags.tfTransferable, Issuer: 'r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ', TransferFee: 1, - URI: convertStringToHex('http://xrpl.org'), + URI: stringToHex('http://xrpl.org'), } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenMint: missing field NFTokenTaxon', - ) + assertInvalid(invalid, 'NFTokenMint: missing field NFTokenTaxon') }) it(`throws w/ Account === Issuer`, function () { @@ -60,14 +57,10 @@ describe('NFTokenMint', function () { Issuer: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', TransferFee: 1, NFTokenTaxon: 0, - URI: convertStringToHex('http://xrpl.org'), + URI: stringToHex('http://xrpl.org'), } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenMint: Issuer must not be equal to Account', - ) + assertInvalid(invalid, 'NFTokenMint: Issuer must not be equal to Account') }) it(`throws w/ URI being an empty string`, function () { @@ -83,11 +76,7 @@ describe('NFTokenMint', function () { URI: '', } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenMint: URI must not be empty string', - ) + assertInvalid(invalid, 'NFTokenMint: URI must not be empty string') }) it(`throws w/ URI not in hex format`, function () { @@ -103,10 +92,6 @@ describe('NFTokenMint', function () { URI: 'http://xrpl.org', } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenMint: URI must be in hex format', - ) + assertInvalid(invalid, 'NFTokenMint: URI must be in hex format') }) }) diff --git a/packages/xrpl/test/models/NFTokenModify.test.ts b/packages/xrpl/test/models/NFTokenModify.test.ts index 8d1bb9b0bf..624b61fe13 100644 --- a/packages/xrpl/test/models/NFTokenModify.test.ts +++ b/packages/xrpl/test/models/NFTokenModify.test.ts @@ -1,6 +1,4 @@ -import { assert } from 'chai' - -import { convertStringToHex, validate, ValidationError } from '../../src' +import { stringToHex } from '@xrplf/isomorphic/src/utils' const TOKEN_ID = '00090032B5F762798A53D543A014CAF8B297CFF8F2F937E844B17C9E00000003' @@ -18,7 +16,7 @@ describe('NFTokenModify', function () { NFTokenID: TOKEN_ID, Fee: '5000000', Sequence: 2470665, - URI: convertStringToHex('http://xrpl.org'), + URI: stringToHex('http://xrpl.org'), } as any assert.doesNotThrow(() => validate(validNFTokenModify)) @@ -32,11 +30,7 @@ describe('NFTokenModify', function () { Sequence: 2470665, } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenModify: missing field NFTokenID', - ) + assertInvalid(invalid, 'NFTokenModify: missing field NFTokenID') }) it(`throws w/ URI being an empty string`, function () { @@ -49,11 +43,7 @@ describe('NFTokenModify', function () { URI: '', } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenModify: URI must not be empty string', - ) + assertInvalid(invalid, 'NFTokenModify: URI must not be empty string') }) it(`throws w/ URI not in hex format`, function () { @@ -66,10 +56,6 @@ describe('NFTokenModify', function () { URI: '--', } as any - assert.throws( - () => validate(invalid), - ValidationError, - 'NFTokenModify: URI must be in hex format', - ) + assertInvalid(invalid, 'NFTokenModify: URI must be in hex format') }) }) diff --git a/packages/xrpl/test/models/XChainAccountCreateCommit.test.ts b/packages/xrpl/test/models/XChainAccountCreateCommit.test.ts index 454458fdae..fa75c98e26 100644 --- a/packages/xrpl/test/models/XChainAccountCreateCommit.test.ts +++ b/packages/xrpl/test/models/XChainAccountCreateCommit.test.ts @@ -1,7 +1,10 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateXChainAccountCreateCommit } from '../../src/models/transactions/XChainAccountCreateCommit' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateXChainAccountCreateCommit) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateXChainAccountCreateCommit, message) /** * XChainAccountCreateCommit Transaction Verification Testing. @@ -9,7 +12,7 @@ import { validateXChainAccountCreateCommit } from '../../src/models/transactions * Providing runtime verification testing for each specific transaction type. */ describe('XChainAccountCreateCommit', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -35,51 +38,26 @@ describe('XChainAccountCreateCommit', function () { }) it('verifies valid XChainAccountCreateCommit', function () { - assert.doesNotThrow(() => validateXChainAccountCreateCommit(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it('throws w/ missing XChainBridge', function () { delete tx.XChainBridge - assert.throws( - () => validateXChainAccountCreateCommit(tx), - ValidationError, - 'XChainAccountCreateCommit: missing field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAccountCreateCommit: missing field XChainBridge', - ) + assertInvalid(tx, 'XChainAccountCreateCommit: missing field XChainBridge') }) it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assert.throws( - () => validateXChainAccountCreateCommit(tx), - ValidationError, - 'XChainAccountCreateCommit: invalid field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAccountCreateCommit: invalid field XChainBridge', - ) + assertInvalid(tx, 'XChainAccountCreateCommit: invalid field XChainBridge') }) it('throws w/ missing SignatureReward', function () { delete tx.SignatureReward - assert.throws( - () => validateXChainAccountCreateCommit(tx), - ValidationError, - 'XChainAccountCreateCommit: missing field SignatureReward', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAccountCreateCommit: missing field SignatureReward', ) }) @@ -87,14 +65,8 @@ describe('XChainAccountCreateCommit', function () { it('throws w/ invalid SignatureReward', function () { tx.SignatureReward = { currency: 'ETH' } - assert.throws( - () => validateXChainAccountCreateCommit(tx), - ValidationError, - 'XChainAccountCreateCommit: invalid field SignatureReward', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAccountCreateCommit: invalid field SignatureReward', ) }) @@ -102,60 +74,24 @@ describe('XChainAccountCreateCommit', function () { it('throws w/ missing Destination', function () { delete tx.Destination - assert.throws( - () => validateXChainAccountCreateCommit(tx), - ValidationError, - 'XChainAccountCreateCommit: missing field Destination', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAccountCreateCommit: missing field Destination', - ) + assertInvalid(tx, 'XChainAccountCreateCommit: missing field Destination') }) it('throws w/ invalid Destination', function () { tx.Destination = 123 - assert.throws( - () => validateXChainAccountCreateCommit(tx), - ValidationError, - 'XChainAccountCreateCommit: invalid field Destination', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAccountCreateCommit: invalid field Destination', - ) + assertInvalid(tx, 'XChainAccountCreateCommit: invalid field Destination') }) it('throws w/ missing Amount', function () { delete tx.Amount - assert.throws( - () => validateXChainAccountCreateCommit(tx), - ValidationError, - 'XChainAccountCreateCommit: missing field Amount', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAccountCreateCommit: missing field Amount', - ) + assertInvalid(tx, 'XChainAccountCreateCommit: missing field Amount') }) it('throws w/ invalid Amount', function () { tx.Amount = { currency: 'ETH' } - assert.throws( - () => validateXChainAccountCreateCommit(tx), - ValidationError, - 'XChainAccountCreateCommit: invalid field Amount', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAccountCreateCommit: invalid field Amount', - ) + assertInvalid(tx, 'XChainAccountCreateCommit: invalid field Amount') }) }) diff --git a/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts b/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts index 4fb98fd584..144a43a584 100644 --- a/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts +++ b/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts @@ -1,7 +1,14 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateXChainAddAccountCreateAttestation } from '../../src/models/transactions/XChainAddAccountCreateAttestation' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateXChainAddAccountCreateAttestation) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError( + tx, + validateXChainAddAccountCreateAttestation, + message, + ) /** * XChainAddAccountCreateAttestation Transaction Verification Testing. @@ -9,7 +16,7 @@ import { validateXChainAddAccountCreateAttestation } from '../../src/models/tran * Providing runtime verification testing for each specific transaction type. */ describe('XChainAddAccountCreateAttestation', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -45,51 +52,26 @@ describe('XChainAddAccountCreateAttestation', function () { }) it('verifies valid XChainAddAccountCreateAttestation', function () { - assert.doesNotThrow(() => validateXChainAddAccountCreateAttestation(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it('throws w/ missing Amount', function () { delete tx.Amount - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: missing field Amount', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: missing field Amount', - ) + assertInvalid(tx, 'XChainAddAccountCreateAttestation: missing field Amount') }) it('throws w/ invalid Amount', function () { tx.Amount = { currency: 'ETH' } - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: invalid field Amount', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: invalid field Amount', - ) + assertInvalid(tx, 'XChainAddAccountCreateAttestation: invalid field Amount') }) it('throws w/ missing AttestationRewardAccount', function () { delete tx.AttestationRewardAccount - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: missing field AttestationRewardAccount', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: missing field AttestationRewardAccount', ) }) @@ -97,14 +79,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ invalid AttestationRewardAccount', function () { tx.AttestationRewardAccount = 123 - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: invalid field AttestationRewardAccount', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: invalid field AttestationRewardAccount', ) }) @@ -112,14 +88,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ missing AttestationSignerAccount', function () { delete tx.AttestationSignerAccount - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: missing field AttestationSignerAccount', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: missing field AttestationSignerAccount', ) }) @@ -127,14 +97,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ invalid AttestationSignerAccount', function () { tx.AttestationSignerAccount = 123 - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: invalid field AttestationSignerAccount', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: invalid field AttestationSignerAccount', ) }) @@ -142,14 +106,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ missing Destination', function () { delete tx.Destination - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: missing field Destination', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: missing field Destination', ) }) @@ -157,14 +115,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ invalid Destination', function () { tx.Destination = 123 - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: invalid field Destination', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: invalid field Destination', ) }) @@ -172,14 +124,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ missing OtherChainSource', function () { delete tx.OtherChainSource - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: missing field OtherChainSource', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: missing field OtherChainSource', ) }) @@ -187,14 +133,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ invalid OtherChainSource', function () { tx.OtherChainSource = 123 - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: invalid field OtherChainSource', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: invalid field OtherChainSource', ) }) @@ -202,14 +142,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ missing PublicKey', function () { delete tx.PublicKey - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: missing field PublicKey', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: missing field PublicKey', ) }) @@ -217,14 +151,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ invalid PublicKey', function () { tx.PublicKey = 123 - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: invalid field PublicKey', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: invalid field PublicKey', ) }) @@ -232,14 +160,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ missing Signature', function () { delete tx.Signature - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: missing field Signature', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: missing field Signature', ) }) @@ -247,14 +169,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ invalid Signature', function () { tx.Signature = 123 - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: invalid field Signature', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: invalid field Signature', ) }) @@ -262,14 +178,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ missing SignatureReward', function () { delete tx.SignatureReward - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: missing field SignatureReward', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: missing field SignatureReward', ) }) @@ -277,14 +187,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ invalid SignatureReward', function () { tx.SignatureReward = { currency: 'ETH' } - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: invalid field SignatureReward', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: invalid field SignatureReward', ) }) @@ -292,14 +196,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ missing WasLockingChainSend', function () { delete tx.WasLockingChainSend - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: missing field WasLockingChainSend', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: missing field WasLockingChainSend', ) }) @@ -307,14 +205,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ invalid WasLockingChainSend', function () { tx.WasLockingChainSend = 2 - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: invalid field WasLockingChainSend', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: invalid field WasLockingChainSend', ) }) @@ -322,14 +214,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ missing XChainAccountCreateCount', function () { delete tx.XChainAccountCreateCount - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: missing field XChainAccountCreateCount', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: missing field XChainAccountCreateCount', ) }) @@ -337,14 +223,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ invalid XChainAccountCreateCount', function () { tx.XChainAccountCreateCount = { currency: 'ETH' } - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: invalid field XChainAccountCreateCount', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: invalid field XChainAccountCreateCount', ) }) @@ -352,14 +232,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ missing XChainBridge', function () { delete tx.XChainBridge - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: missing field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: missing field XChainBridge', ) }) @@ -367,14 +241,8 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assert.throws( - () => validateXChainAddAccountCreateAttestation(tx), - ValidationError, - 'XChainAddAccountCreateAttestation: invalid field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddAccountCreateAttestation: invalid field XChainBridge', ) }) diff --git a/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts b/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts index 4e7d1aeb7a..92783d9219 100644 --- a/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts +++ b/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts @@ -1,7 +1,10 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateXChainAddClaimAttestation } from '../../src/models/transactions/XChainAddClaimAttestation' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateXChainAddClaimAttestation) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateXChainAddClaimAttestation, message) /** * XChainAddClaimAttestation Transaction Verification Testing. @@ -9,7 +12,7 @@ import { validateXChainAddClaimAttestation } from '../../src/models/transactions * Providing runtime verification testing for each specific transaction type. */ describe('XChainAddClaimAttestation', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -43,51 +46,26 @@ describe('XChainAddClaimAttestation', function () { }) it('verifies valid XChainAddClaimAttestation', function () { - assert.doesNotThrow(() => validateXChainAddClaimAttestation(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it('throws w/ missing Amount', function () { delete tx.Amount - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field Amount', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field Amount', - ) + assertInvalid(tx, 'XChainAddClaimAttestation: missing field Amount') }) it('throws w/ invalid Amount', function () { tx.Amount = { currency: 'ETH' } - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field Amount', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field Amount', - ) + assertInvalid(tx, 'XChainAddClaimAttestation: invalid field Amount') }) it('throws w/ missing AttestationRewardAccount', function () { delete tx.AttestationRewardAccount - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field AttestationRewardAccount', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddClaimAttestation: missing field AttestationRewardAccount', ) }) @@ -95,14 +73,8 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ invalid AttestationRewardAccount', function () { tx.AttestationRewardAccount = 123 - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field AttestationRewardAccount', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddClaimAttestation: invalid field AttestationRewardAccount', ) }) @@ -110,14 +82,8 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ missing AttestationSignerAccount', function () { delete tx.AttestationSignerAccount - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field AttestationSignerAccount', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddClaimAttestation: missing field AttestationSignerAccount', ) }) @@ -125,14 +91,8 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ invalid AttestationSignerAccount', function () { tx.AttestationSignerAccount = 123 - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field AttestationSignerAccount', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddClaimAttestation: invalid field AttestationSignerAccount', ) }) @@ -140,29 +100,14 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ invalid Destination', function () { tx.Destination = 123 - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field Destination', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field Destination', - ) + assertInvalid(tx, 'XChainAddClaimAttestation: invalid field Destination') }) it('throws w/ missing OtherChainSource', function () { delete tx.OtherChainSource - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field OtherChainSource', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddClaimAttestation: missing field OtherChainSource', ) }) @@ -170,14 +115,8 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ invalid OtherChainSource', function () { tx.OtherChainSource = 123 - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field OtherChainSource', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddClaimAttestation: invalid field OtherChainSource', ) }) @@ -185,74 +124,32 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ missing PublicKey', function () { delete tx.PublicKey - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field PublicKey', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field PublicKey', - ) + assertInvalid(tx, 'XChainAddClaimAttestation: missing field PublicKey') }) it('throws w/ invalid PublicKey', function () { tx.PublicKey = 123 - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field PublicKey', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field PublicKey', - ) + assertInvalid(tx, 'XChainAddClaimAttestation: invalid field PublicKey') }) it('throws w/ missing Signature', function () { delete tx.Signature - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field Signature', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field Signature', - ) + assertInvalid(tx, 'XChainAddClaimAttestation: missing field Signature') }) it('throws w/ invalid Signature', function () { tx.Signature = 123 - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field Signature', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field Signature', - ) + assertInvalid(tx, 'XChainAddClaimAttestation: invalid field Signature') }) it('throws w/ missing WasLockingChainSend', function () { delete tx.WasLockingChainSend - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field WasLockingChainSend', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddClaimAttestation: missing field WasLockingChainSend', ) }) @@ -260,14 +157,8 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ invalid WasLockingChainSend', function () { tx.WasLockingChainSend = 2 - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field WasLockingChainSend', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainAddClaimAttestation: invalid field WasLockingChainSend', ) }) @@ -275,60 +166,24 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ missing XChainBridge', function () { delete tx.XChainBridge - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field XChainBridge', - ) + assertInvalid(tx, 'XChainAddClaimAttestation: missing field XChainBridge') }) it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field XChainBridge', - ) + assertInvalid(tx, 'XChainAddClaimAttestation: invalid field XChainBridge') }) it('throws w/ missing XChainClaimID', function () { delete tx.XChainClaimID - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field XChainClaimID', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddClaimAttestation: missing field XChainClaimID', - ) + assertInvalid(tx, 'XChainAddClaimAttestation: missing field XChainClaimID') }) it('throws w/ invalid XChainClaimID', function () { tx.XChainClaimID = { currency: 'ETH' } - assert.throws( - () => validateXChainAddClaimAttestation(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field XChainClaimID', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainAddClaimAttestation: invalid field XChainClaimID', - ) + assertInvalid(tx, 'XChainAddClaimAttestation: invalid field XChainClaimID') }) }) diff --git a/packages/xrpl/test/models/XChainClaim.test.ts b/packages/xrpl/test/models/XChainClaim.test.ts index 7b854ea786..8ec461224d 100644 --- a/packages/xrpl/test/models/XChainClaim.test.ts +++ b/packages/xrpl/test/models/XChainClaim.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateXChainClaim } from '../../src/models/transactions/XChainClaim' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateXChainClaim) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateXChainClaim, message) /** * XChainClaim Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateXChainClaim } from '../../src/models/transactions/XChainClaim' * Providing runtime verification testing for each specific transaction type. */ describe('XChainClaim', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -35,142 +37,60 @@ describe('XChainClaim', function () { }) it('verifies valid XChainClaim', function () { - assert.doesNotThrow(() => validateXChainClaim(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it('throws w/ missing XChainBridge', function () { delete tx.XChainBridge - assert.throws( - () => validateXChainClaim(tx), - ValidationError, - 'XChainClaim: missing field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainClaim: missing field XChainBridge', - ) + assertInvalid(tx, 'XChainClaim: missing field XChainBridge') }) it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assert.throws( - () => validateXChainClaim(tx), - ValidationError, - 'XChainClaim: invalid field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainClaim: invalid field XChainBridge', - ) + assertInvalid(tx, 'XChainClaim: invalid field XChainBridge') }) it('throws w/ missing XChainClaimID', function () { delete tx.XChainClaimID - assert.throws( - () => validateXChainClaim(tx), - ValidationError, - 'XChainClaim: missing field XChainClaimID', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainClaim: missing field XChainClaimID', - ) + assertInvalid(tx, 'XChainClaim: missing field XChainClaimID') }) it('throws w/ invalid XChainClaimID', function () { tx.XChainClaimID = { currency: 'ETH' } - assert.throws( - () => validateXChainClaim(tx), - ValidationError, - 'XChainClaim: invalid field XChainClaimID', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainClaim: invalid field XChainClaimID', - ) + assertInvalid(tx, 'XChainClaim: invalid field XChainClaimID') }) it('throws w/ missing Destination', function () { delete tx.Destination - assert.throws( - () => validateXChainClaim(tx), - ValidationError, - 'XChainClaim: missing field Destination', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainClaim: missing field Destination', - ) + assertInvalid(tx, 'XChainClaim: missing field Destination') }) it('throws w/ invalid Destination', function () { tx.Destination = 123 - assert.throws( - () => validateXChainClaim(tx), - ValidationError, - 'XChainClaim: invalid field Destination', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainClaim: invalid field Destination', - ) + assertInvalid(tx, 'XChainClaim: invalid field Destination') }) it('throws w/ invalid DestinationTag', function () { tx.DestinationTag = 'number' - assert.throws( - () => validateXChainClaim(tx), - ValidationError, - 'XChainClaim: invalid field DestinationTag', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainClaim: invalid field DestinationTag', - ) + assertInvalid(tx, 'XChainClaim: invalid field DestinationTag') }) it('throws w/ missing Amount', function () { delete tx.Amount - assert.throws( - () => validateXChainClaim(tx), - ValidationError, - 'XChainClaim: missing field Amount', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainClaim: missing field Amount', - ) + assertInvalid(tx, 'XChainClaim: missing field Amount') }) it('throws w/ invalid Amount', function () { tx.Amount = { currency: 'ETH' } - assert.throws( - () => validateXChainClaim(tx), - ValidationError, - 'XChainClaim: invalid field Amount', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainClaim: invalid field Amount', - ) + assertInvalid(tx, 'XChainClaim: invalid field Amount') }) }) diff --git a/packages/xrpl/test/models/XChainCommit.test.ts b/packages/xrpl/test/models/XChainCommit.test.ts index 4963cf1bef..2d2952a8eb 100644 --- a/packages/xrpl/test/models/XChainCommit.test.ts +++ b/packages/xrpl/test/models/XChainCommit.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateXChainCommit } from '../../src/models/transactions/XChainCommit' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateXChainCommit) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateXChainCommit, message) /** * XChainCommit Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateXChainCommit } from '../../src/models/transactions/XChainCommit * Providing runtime verification testing for each specific transaction type. */ describe('XChainCommit', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -34,112 +36,48 @@ describe('XChainCommit', function () { }) it('verifies valid XChainCommit', function () { - assert.doesNotThrow(() => validateXChainCommit(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it('throws w/ missing XChainBridge', function () { delete tx.XChainBridge - assert.throws( - () => validateXChainCommit(tx), - ValidationError, - 'XChainCommit: missing field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCommit: missing field XChainBridge', - ) + assertInvalid(tx, 'XChainCommit: missing field XChainBridge') }) it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assert.throws( - () => validateXChainCommit(tx), - ValidationError, - 'XChainCommit: invalid field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCommit: invalid field XChainBridge', - ) + assertInvalid(tx, 'XChainCommit: invalid field XChainBridge') }) it('throws w/ missing XChainClaimID', function () { delete tx.XChainClaimID - assert.throws( - () => validateXChainCommit(tx), - ValidationError, - 'XChainCommit: missing field XChainClaimID', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCommit: missing field XChainClaimID', - ) + assertInvalid(tx, 'XChainCommit: missing field XChainClaimID') }) it('throws w/ invalid XChainClaimID', function () { tx.XChainClaimID = { currency: 'ETH' } - assert.throws( - () => validateXChainCommit(tx), - ValidationError, - 'XChainCommit: invalid field XChainClaimID', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCommit: invalid field XChainClaimID', - ) + assertInvalid(tx, 'XChainCommit: invalid field XChainClaimID') }) it('throws w/ invalid OtherChainDestination', function () { tx.OtherChainDestination = 123 - assert.throws( - () => validateXChainCommit(tx), - ValidationError, - 'XChainCommit: invalid field OtherChainDestination', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCommit: invalid field OtherChainDestination', - ) + assertInvalid(tx, 'XChainCommit: invalid field OtherChainDestination') }) it('throws w/ missing Amount', function () { delete tx.Amount - assert.throws( - () => validateXChainCommit(tx), - ValidationError, - 'XChainCommit: missing field Amount', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCommit: missing field Amount', - ) + assertInvalid(tx, 'XChainCommit: missing field Amount') }) it('throws w/ invalid Amount', function () { tx.Amount = { currency: 'ETH' } - assert.throws( - () => validateXChainCommit(tx), - ValidationError, - 'XChainCommit: invalid field Amount', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCommit: invalid field Amount', - ) + assertInvalid(tx, 'XChainCommit: invalid field Amount') }) }) diff --git a/packages/xrpl/test/models/XChainCreateBridge.test.ts b/packages/xrpl/test/models/XChainCreateBridge.test.ts index dfd174058e..740c92030d 100644 --- a/packages/xrpl/test/models/XChainCreateBridge.test.ts +++ b/packages/xrpl/test/models/XChainCreateBridge.test.ts @@ -1,7 +1,10 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateXChainCreateBridge } from '../../src/models/transactions/XChainCreateBridge' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateXChainCreateBridge) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateXChainCreateBridge, message) /** * XChainCreateBridge Transaction Verification Testing. @@ -9,7 +12,7 @@ import { validateXChainCreateBridge } from '../../src/models/transactions/XChain * Providing runtime verification testing for each specific transaction type. */ describe('XChainCreateBridge', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -34,81 +37,38 @@ describe('XChainCreateBridge', function () { }) it('verifies valid XChainCreateBridge', function () { - assert.doesNotThrow(() => validateXChainCreateBridge(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it('throws w/ missing XChainBridge', function () { delete tx.XChainBridge - assert.throws( - () => validateXChainCreateBridge(tx), - ValidationError, - 'XChainCreateBridge: missing field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCreateBridge: missing field XChainBridge', - ) + assertInvalid(tx, 'XChainCreateBridge: missing field XChainBridge') }) it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assert.throws( - () => validateXChainCreateBridge(tx), - ValidationError, - 'XChainCreateBridge: invalid field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCreateBridge: invalid field XChainBridge', - ) + assertInvalid(tx, 'XChainCreateBridge: invalid field XChainBridge') }) it('throws w/ missing SignatureReward', function () { delete tx.SignatureReward - assert.throws( - () => validateXChainCreateBridge(tx), - ValidationError, - 'XChainCreateBridge: missing field SignatureReward', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCreateBridge: missing field SignatureReward', - ) + assertInvalid(tx, 'XChainCreateBridge: missing field SignatureReward') }) it('throws w/ invalid SignatureReward', function () { tx.SignatureReward = { currency: 'ETH' } - assert.throws( - () => validateXChainCreateBridge(tx), - ValidationError, - 'XChainCreateBridge: invalid field SignatureReward', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCreateBridge: invalid field SignatureReward', - ) + assertInvalid(tx, 'XChainCreateBridge: invalid field SignatureReward') }) it('throws w/ invalid MinAccountCreateAmount', function () { tx.MinAccountCreateAmount = { currency: 'ETH' } - assert.throws( - () => validateXChainCreateBridge(tx), - ValidationError, - 'XChainCreateBridge: invalid field MinAccountCreateAmount', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainCreateBridge: invalid field MinAccountCreateAmount', ) }) diff --git a/packages/xrpl/test/models/XChainCreateClaimID.test.ts b/packages/xrpl/test/models/XChainCreateClaimID.test.ts index 503fae0130..620e830954 100644 --- a/packages/xrpl/test/models/XChainCreateClaimID.test.ts +++ b/packages/xrpl/test/models/XChainCreateClaimID.test.ts @@ -1,7 +1,10 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateXChainCreateClaimID } from '../../src/models/transactions/XChainCreateClaimID' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateXChainCreateClaimID) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateXChainCreateClaimID, message) /** * XChainCreateClaimID Transaction Verification Testing. @@ -9,7 +12,7 @@ import { validateXChainCreateClaimID } from '../../src/models/transactions/XChai * Providing runtime verification testing for each specific transaction type. */ describe('XChainCreateClaimID', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -34,97 +37,42 @@ describe('XChainCreateClaimID', function () { }) it('verifies valid XChainCreateClaimID', function () { - assert.doesNotThrow(() => validateXChainCreateClaimID(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it('throws w/ missing XChainBridge', function () { delete tx.XChainBridge - assert.throws( - () => validateXChainCreateClaimID(tx), - ValidationError, - 'XChainCreateClaimID: missing field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCreateClaimID: missing field XChainBridge', - ) + assertInvalid(tx, 'XChainCreateClaimID: missing field XChainBridge') }) it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assert.throws( - () => validateXChainCreateClaimID(tx), - ValidationError, - 'XChainCreateClaimID: invalid field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCreateClaimID: invalid field XChainBridge', - ) + assertInvalid(tx, 'XChainCreateClaimID: invalid field XChainBridge') }) it('throws w/ missing SignatureReward', function () { delete tx.SignatureReward - assert.throws( - () => validateXChainCreateClaimID(tx), - ValidationError, - 'XChainCreateClaimID: missing field SignatureReward', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCreateClaimID: missing field SignatureReward', - ) + assertInvalid(tx, 'XChainCreateClaimID: missing field SignatureReward') }) it('throws w/ invalid SignatureReward', function () { tx.SignatureReward = { currency: 'ETH' } - assert.throws( - () => validateXChainCreateClaimID(tx), - ValidationError, - 'XChainCreateClaimID: invalid field SignatureReward', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCreateClaimID: invalid field SignatureReward', - ) + assertInvalid(tx, 'XChainCreateClaimID: invalid field SignatureReward') }) it('throws w/ missing OtherChainSource', function () { delete tx.OtherChainSource - assert.throws( - () => validateXChainCreateClaimID(tx), - ValidationError, - 'XChainCreateClaimID: missing field OtherChainSource', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCreateClaimID: missing field OtherChainSource', - ) + assertInvalid(tx, 'XChainCreateClaimID: missing field OtherChainSource') }) it('throws w/ invalid OtherChainSource', function () { tx.OtherChainSource = 123 - assert.throws( - () => validateXChainCreateClaimID(tx), - ValidationError, - 'XChainCreateClaimID: invalid field OtherChainSource', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainCreateClaimID: invalid field OtherChainSource', - ) + assertInvalid(tx, 'XChainCreateClaimID: invalid field OtherChainSource') }) }) diff --git a/packages/xrpl/test/models/XChainModifyBridge.test.ts b/packages/xrpl/test/models/XChainModifyBridge.test.ts index 57eeb50823..4ad095c999 100644 --- a/packages/xrpl/test/models/XChainModifyBridge.test.ts +++ b/packages/xrpl/test/models/XChainModifyBridge.test.ts @@ -1,7 +1,10 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateXChainModifyBridge } from '../../src/models/transactions/XChainModifyBridge' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateXChainModifyBridge) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateXChainModifyBridge, message) /** * XChainModifyBridge Transaction Verification Testing. @@ -9,7 +12,7 @@ import { validateXChainModifyBridge } from '../../src/models/transactions/XChain * Providing runtime verification testing for each specific transaction type. */ describe('XChainModifyBridge', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -34,66 +37,32 @@ describe('XChainModifyBridge', function () { }) it('verifies valid XChainModifyBridge', function () { - assert.doesNotThrow(() => validateXChainModifyBridge(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it('throws w/ missing XChainBridge', function () { delete tx.XChainBridge - assert.throws( - () => validateXChainModifyBridge(tx), - ValidationError, - 'XChainModifyBridge: missing field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainModifyBridge: missing field XChainBridge', - ) + assertInvalid(tx, 'XChainModifyBridge: missing field XChainBridge') }) it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assert.throws( - () => validateXChainModifyBridge(tx), - ValidationError, - 'XChainModifyBridge: invalid field XChainBridge', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainModifyBridge: invalid field XChainBridge', - ) + assertInvalid(tx, 'XChainModifyBridge: invalid field XChainBridge') }) it('throws w/ invalid SignatureReward', function () { tx.SignatureReward = { currency: 'ETH' } - assert.throws( - () => validateXChainModifyBridge(tx), - ValidationError, - 'XChainModifyBridge: invalid field SignatureReward', - ) - assert.throws( - () => validate(tx), - ValidationError, - 'XChainModifyBridge: invalid field SignatureReward', - ) + assertInvalid(tx, 'XChainModifyBridge: invalid field SignatureReward') }) it('throws w/ invalid MinAccountCreateAmount', function () { tx.MinAccountCreateAmount = { currency: 'ETH' } - assert.throws( - () => validateXChainModifyBridge(tx), - ValidationError, - 'XChainModifyBridge: invalid field MinAccountCreateAmount', - ) - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'XChainModifyBridge: invalid field MinAccountCreateAmount', ) }) diff --git a/packages/xrpl/test/models/accountDelete.test.ts b/packages/xrpl/test/models/accountDelete.test.ts index 19c02070b6..6316b7a904 100644 --- a/packages/xrpl/test/models/accountDelete.test.ts +++ b/packages/xrpl/test/models/accountDelete.test.ts @@ -1,7 +1,10 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateAccountDelete } from '../../src/models/transactions/accountDelete' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateAccountDelete) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateAccountDelete, message) /** * AccountDelete Transaction Verification Testing. @@ -9,7 +12,7 @@ import { validateAccountDelete } from '../../src/models/transactions/accountDele * Providing runtime verification testing for each specific transaction type. */ describe('AccountDelete', function () { - let validAccountDelete + let validAccountDelete: any beforeEach(() => { validAccountDelete = { @@ -23,60 +26,28 @@ describe('AccountDelete', function () { CredentialIDs: [ 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66A', ], - } as any + } }) it(`verifies valid AccountDelete`, function () { - assert.doesNotThrow(() => validateAccountDelete(validAccountDelete)) + assertValid(validAccountDelete) }) it(`throws w/ missing Destination`, function () { validAccountDelete.Destination = undefined const errorMessage = 'AccountDelete: missing field Destination' - - assert.throws( - () => validateAccountDelete(validAccountDelete), - ValidationError, - errorMessage, - ) - - assert.throws( - () => validate(validAccountDelete), - ValidationError, - errorMessage, - ) + assertInvalid(validAccountDelete, errorMessage) }) it(`throws w/ invalid Destination`, function () { validAccountDelete.Destination = 65478965 const errorMessage = 'AccountDelete: invalid field Destination' - - assert.throws( - () => validateAccountDelete(validAccountDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(validAccountDelete), - ValidationError, - errorMessage, - ) + assertInvalid(validAccountDelete, errorMessage) }) it(`throws w/ invalid DestinationTag`, function () { validAccountDelete.DestinationTag = 'gvftyujnbv' const errorMessage = 'AccountDelete: invalid field DestinationTag' - - assert.throws( - () => validateAccountDelete(validAccountDelete), - ValidationError, - errorMessage, - ) - - assert.throws( - () => validate(validAccountDelete), - ValidationError, - errorMessage, - ) + assertInvalid(validAccountDelete, errorMessage) }) it(`throws w/ non-array CredentialIDs`, function () { @@ -84,17 +55,7 @@ describe('AccountDelete', function () { 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66A' const errorMessage = 'AccountDelete: invalid field Credentials' - - assert.throws( - () => validateAccountDelete(validAccountDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(validAccountDelete), - ValidationError, - errorMessage, - ) + assertInvalid(validAccountDelete, errorMessage) }) it(`throws CredentialIDs length exceeds max length`, function () { @@ -112,34 +73,14 @@ describe('AccountDelete', function () { const errorMessage = 'AccountDelete: Credentials length cannot exceed 8 elements' - - assert.throws( - () => validateAccountDelete(validAccountDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(validAccountDelete), - ValidationError, - errorMessage, - ) + assertInvalid(validAccountDelete, errorMessage) }) it(`throws w/ empty CredentialIDs`, function () { validAccountDelete.CredentialIDs = [] const errorMessage = 'AccountDelete: Credentials cannot be an empty array' - - assert.throws( - () => validateAccountDelete(validAccountDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(validAccountDelete), - ValidationError, - errorMessage, - ) + assertInvalid(validAccountDelete, errorMessage) }) it(`throws w/ non-string CredentialIDs`, function () { @@ -149,17 +90,7 @@ describe('AccountDelete', function () { ] const errorMessage = 'AccountDelete: Invalid Credentials ID list format' - - assert.throws( - () => validateAccountDelete(validAccountDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(validAccountDelete), - ValidationError, - errorMessage, - ) + assertInvalid(validAccountDelete, errorMessage) }) it(`throws w/ duplicate CredentialIDs`, function () { @@ -170,16 +101,6 @@ describe('AccountDelete', function () { const errorMessage = 'AccountDelete: Credentials cannot contain duplicate elements' - - assert.throws( - () => validateAccountDelete(validAccountDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(validAccountDelete), - ValidationError, - errorMessage, - ) + assertInvalid(validAccountDelete, errorMessage) }) }) diff --git a/packages/xrpl/test/models/accountSet.test.ts b/packages/xrpl/test/models/accountSet.test.ts index 19655ccac0..2679177382 100644 --- a/packages/xrpl/test/models/accountSet.test.ts +++ b/packages/xrpl/test/models/accountSet.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateAccountSet } from '../../src/models/transactions/accountSet' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateAccountSet) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateAccountSet, message) /** * AccountSet Transaction Verification Testing. @@ -9,10 +11,10 @@ import { validateAccountSet } from '../../src/models/transactions/accountSet' * Providing runtime verification testing for each specific transaction type. */ describe('AccountSet', function () { - let account + let tx: any beforeEach(function () { - account = { + tx = { TransactionType: 'AccountSet', Account: 'rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn', Fee: '12', @@ -21,146 +23,55 @@ describe('AccountSet', function () { SetFlag: 5, MessageKey: '03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB', - } as any + } }) it(`verifies valid AccountSet`, function () { - assert.doesNotThrow(() => validateAccountSet(account)) - assert.doesNotThrow(() => validate(account)) + assertValid(tx) }) it(`throws w/ invalid SetFlag (out of range)`, function () { - account.SetFlag = 20 - - assert.throws( - () => validateAccountSet(account), - ValidationError, - 'AccountSet: invalid field SetFlag', - ) - assert.throws( - () => validate(account), - ValidationError, - 'AccountSet: invalid field SetFlag', - ) + tx.SetFlag = 20 + assertInvalid(tx, 'AccountSet: invalid field SetFlag') }) it(`throws w/ invalid SetFlag (incorrect type)`, function () { - account.SetFlag = 'abc' - - assert.throws( - () => validateAccountSet(account), - ValidationError, - 'AccountSet: invalid field SetFlag', - ) - assert.throws( - () => validate(account), - ValidationError, - 'AccountSet: invalid field SetFlag', - ) + tx.SetFlag = 'abc' + assertInvalid(tx, 'AccountSet: invalid field SetFlag') }) it(`throws w/ invalid ClearFlag`, function () { - account.ClearFlag = 20 - - assert.throws( - () => validateAccountSet(account), - ValidationError, - 'AccountSet: invalid field ClearFlag', - ) - assert.throws( - () => validate(account), - ValidationError, - 'AccountSet: invalid field ClearFlag', - ) + tx.ClearFlag = 20 + assertInvalid(tx, 'AccountSet: invalid field ClearFlag') }) it(`throws w/ invalid Domain`, function () { - account.Domain = 6578616 - - assert.throws( - () => validateAccountSet(account), - ValidationError, - 'AccountSet: invalid field Domain', - ) - assert.throws( - () => validate(account), - ValidationError, - 'AccountSet: invalid field Domain', - ) + tx.Domain = 6578616 + assertInvalid(tx, 'AccountSet: invalid field Domain') }) it(`throws w/ invalid EmailHash`, function () { - account.EmailHash = 6578656789876543 - - assert.throws( - () => validateAccountSet(account), - ValidationError, - 'AccountSet: invalid field EmailHash', - ) - assert.throws( - () => validate(account), - ValidationError, - 'AccountSet: invalid field EmailHash', - ) + tx.EmailHash = 6578656789876543 + assertInvalid(tx, 'AccountSet: invalid field EmailHash') }) it(`throws w/ invalid MessageKey`, function () { - account.MessageKey = 6578656789876543 - - assert.throws( - () => validateAccountSet(account), - ValidationError, - 'AccountSet: invalid field MessageKey', - ) - assert.throws( - () => validate(account), - ValidationError, - 'AccountSet: invalid field MessageKey', - ) + tx.MessageKey = 6578656789876543 + assertInvalid(tx, 'AccountSet: invalid field MessageKey') }) it(`throws w/ invalid TransferRate`, function () { - account.TransferRate = 'abcd' - - assert.throws( - () => validateAccountSet(account), - ValidationError, - 'AccountSet: invalid field TransferRate', - ) - assert.throws( - () => validate(account), - ValidationError, - 'AccountSet: invalid field TransferRate', - ) + tx.TransferRate = 'abcd' + assertInvalid(tx, 'AccountSet: invalid field TransferRate') }) it(`throws w/ invalid TickSize`, function () { - account.TickSize = 20 - - assert.throws( - () => validateAccountSet(account), - ValidationError, - 'AccountSet: invalid field TickSize', - ) - assert.throws( - () => validate(account), - ValidationError, - 'AccountSet: invalid field TickSize', - ) + tx.TickSize = 20 + assertInvalid(tx, 'AccountSet: invalid field TickSize') }) it(`throws w/ invalid NFTokenMinter`, function () { - account.NFTokenMinter = '' - - assert.throws( - () => validateAccountSet(account), - ValidationError, - 'AccountSet: invalid field NFTokenMinter', - ) - assert.throws( - () => validate(account), - ValidationError, - 'AccountSet: invalid field NFTokenMinter', - ) + tx.NFTokenMinter = '' + assertInvalid(tx, 'AccountSet: invalid field NFTokenMinter') }) }) diff --git a/packages/xrpl/test/models/baseTransaction.test.ts b/packages/xrpl/test/models/baseTransaction.test.ts index a1c7718177..d99c1942c3 100644 --- a/packages/xrpl/test/models/baseTransaction.test.ts +++ b/packages/xrpl/test/models/baseTransaction.test.ts @@ -1,7 +1,7 @@ import { assert } from 'chai' import { ValidationError } from '../../src' -import { validateBaseTransaction } from '../../src/models/transactions/common' +import { validateBaseTransaction } from '../../src/models/transactions/BaseTransaction' /** * Transaction Verification Testing. @@ -10,7 +10,7 @@ import { validateBaseTransaction } from '../../src/models/transactions/common' */ describe('BaseTransaction', function () { it(`Verifies all optional BaseTransaction`, function () { - const txJson = { + const txJson: any = { Account: 'r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe', TransactionType: 'Payment', Fee: '12', diff --git a/packages/xrpl/test/models/checkCancel.test.ts b/packages/xrpl/test/models/checkCancel.test.ts index 00dd1583d8..7a890a5406 100644 --- a/packages/xrpl/test/models/checkCancel.test.ts +++ b/packages/xrpl/test/models/checkCancel.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateCheckCancel } from '../../src/models/transactions/checkCancel' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateCheckCancel) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateCheckCancel, message) /** * CheckCancel Transaction Verification Testing. @@ -17,8 +19,7 @@ describe('CheckCancel', function () { '49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0', } as any - assert.doesNotThrow(() => validateCheckCancel(validCheckCancel)) - assert.doesNotThrow(() => validate(validCheckCancel)) + assertValid(validCheckCancel) }) it(`throws w/ invalid CheckCancel`, function () { @@ -28,15 +29,6 @@ describe('CheckCancel', function () { CheckID: 4964734566545678, } as any - assert.throws( - () => validateCheckCancel(invalidCheckID), - ValidationError, - 'CheckCancel: invalid field CheckID', - ) - assert.throws( - () => validate(invalidCheckID), - ValidationError, - 'CheckCancel: invalid field CheckID', - ) + assertInvalid(invalidCheckID, 'CheckCancel: invalid field CheckID') }) }) diff --git a/packages/xrpl/test/models/checkCash.test.ts b/packages/xrpl/test/models/checkCash.test.ts index 8539341255..ddab5bfc63 100644 --- a/packages/xrpl/test/models/checkCash.test.ts +++ b/packages/xrpl/test/models/checkCash.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateCheckCash } from '../../src/models/transactions/checkCash' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateCheckCash) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateCheckCash, message) /** * CheckCash Transaction Verification Testing. @@ -19,8 +21,7 @@ describe('CheckCash', function () { Fee: '12', } as any - assert.doesNotThrow(() => validateCheckCash(validCheckCash)) - assert.doesNotThrow(() => validate(validCheckCash)) + assertValid(validCheckCash) }) it(`throws w/ invalid CheckID`, function () { @@ -31,16 +32,7 @@ describe('CheckCash', function () { CheckID: 83876645678567890, } as any - assert.throws( - () => validateCheckCash(invalidCheckID), - ValidationError, - 'CheckCash: invalid field CheckID', - ) - assert.throws( - () => validate(invalidCheckID), - ValidationError, - 'CheckCash: invalid field CheckID', - ) + assertInvalid(invalidCheckID, 'CheckCash: invalid field CheckID') }) it(`throws w/ invalid Amount`, function () { @@ -52,16 +44,7 @@ describe('CheckCash', function () { '838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334', } as any - assert.throws( - () => validateCheckCash(invalidAmount), - ValidationError, - 'CheckCash: invalid field Amount', - ) - assert.throws( - () => validate(invalidAmount), - ValidationError, - 'CheckCash: invalid field Amount', - ) + assertInvalid(invalidAmount, 'CheckCash: invalid field Amount') }) it(`throws w/ having both Amount and DeliverMin`, function () { @@ -74,14 +57,8 @@ describe('CheckCash', function () { '838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334', } as any - assert.throws( - () => validateCheckCash(invalidDeliverMin), - ValidationError, - 'CheckCash: cannot have both Amount and DeliverMin', - ) - assert.throws( - () => validate(invalidDeliverMin), - ValidationError, + assertInvalid( + invalidDeliverMin, 'CheckCash: cannot have both Amount and DeliverMin', ) }) @@ -95,15 +72,6 @@ describe('CheckCash', function () { '838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334', } as any - assert.throws( - () => validateCheckCash(invalidDeliverMin), - ValidationError, - 'CheckCash: invalid field DeliverMin', - ) - assert.throws( - () => validate(invalidDeliverMin), - ValidationError, - 'CheckCash: invalid field DeliverMin', - ) + assertInvalid(invalidDeliverMin, 'CheckCash: invalid field DeliverMin') }) }) diff --git a/packages/xrpl/test/models/checkCreate.test.ts b/packages/xrpl/test/models/checkCreate.test.ts index 4c97f6f8b3..de1d86d5e6 100644 --- a/packages/xrpl/test/models/checkCreate.test.ts +++ b/packages/xrpl/test/models/checkCreate.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateCheckCreate } from '../../src/models/transactions/checkCreate' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateCheckCreate) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateCheckCreate, message) /** * CheckCreate Transaction Verification Testing. @@ -22,8 +24,7 @@ describe('CheckCreate', function () { Fee: '12', } as any - assert.doesNotThrow(() => validateCheckCreate(validCheck)) - assert.doesNotThrow(() => validate(validCheck)) + assertValid(validCheck) }) it(`throws w/ invalid Destination`, function () { @@ -39,16 +40,7 @@ describe('CheckCreate', function () { Fee: '12', } as any - assert.throws( - () => validateCheckCreate(invalidDestination), - ValidationError, - 'CheckCreate: invalid field Destination', - ) - assert.throws( - () => validate(invalidDestination), - ValidationError, - 'CheckCreate: invalid field Destination', - ) + assertInvalid(invalidDestination, 'CheckCreate: invalid field Destination') }) it(`throws w/ invalid SendMax`, function () { @@ -64,16 +56,7 @@ describe('CheckCreate', function () { Fee: '12', } as any - assert.throws( - () => validateCheckCreate(invalidSendMax), - ValidationError, - 'CheckCreate: invalid field SendMax', - ) - assert.throws( - () => validate(invalidSendMax), - ValidationError, - 'CheckCreate: invalid field SendMax', - ) + assertInvalid(invalidSendMax, 'CheckCreate: invalid field SendMax') }) it(`throws w/ invalid DestinationTag`, function () { @@ -89,14 +72,8 @@ describe('CheckCreate', function () { Fee: '12', } as any - assert.throws( - () => validateCheckCreate(invalidDestinationTag), - ValidationError, - 'CheckCreate: invalid field DestinationTag', - ) - assert.throws( - () => validate(invalidDestinationTag), - ValidationError, + assertInvalid( + invalidDestinationTag, 'CheckCreate: invalid field DestinationTag', ) }) @@ -114,16 +91,7 @@ describe('CheckCreate', function () { Fee: '12', } as any - assert.throws( - () => validateCheckCreate(invalidExpiration), - ValidationError, - 'CheckCreate: invalid field Expiration', - ) - assert.throws( - () => validate(invalidExpiration), - ValidationError, - 'CheckCreate: invalid field Expiration', - ) + assertInvalid(invalidExpiration, 'CheckCreate: invalid field Expiration') }) it(`throws w/ invalid InvoiceID`, function () { @@ -138,15 +106,6 @@ describe('CheckCreate', function () { Fee: '12', } as any - assert.throws( - () => validateCheckCreate(invalidInvoiceID), - ValidationError, - 'CheckCreate: invalid field InvoiceID', - ) - assert.throws( - () => validate(invalidInvoiceID), - ValidationError, - 'CheckCreate: invalid field InvoiceID', - ) + assertInvalid(invalidInvoiceID, 'CheckCreate: invalid field InvoiceID') }) }) diff --git a/packages/xrpl/test/models/clawback.test.ts b/packages/xrpl/test/models/clawback.test.ts index 7fdae32778..d6393c22de 100644 --- a/packages/xrpl/test/models/clawback.test.ts +++ b/packages/xrpl/test/models/clawback.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateClawback } from '../../src/models/transactions/clawback' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateClawback) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateClawback, message) /** * Clawback Transaction Verification Testing. @@ -30,11 +32,7 @@ describe('Clawback', function () { Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assert.throws( - () => validate(missingAmount), - ValidationError, - 'Clawback: missing field Amount', - ) + assertInvalid(missingAmount, 'Clawback: missing field Amount') }) it(`throws w/ invalid Amount`, function () { @@ -44,16 +42,7 @@ describe('Clawback', function () { Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assert.throws( - () => validate(invalidAmount), - ValidationError, - 'Clawback: invalid field Amount', - ) - assert.throws( - () => validateClawback(invalidAmount), - ValidationError, - 'Clawback: invalid field Amount', - ) + assertInvalid(invalidAmount, 'Clawback: invalid field Amount') const invalidStrAmount = { TransactionType: 'Clawback', @@ -61,16 +50,7 @@ describe('Clawback', function () { Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assert.throws( - () => validate(invalidStrAmount), - ValidationError, - 'Clawback: invalid field Amount', - ) - assert.throws( - () => validateClawback(invalidStrAmount), - ValidationError, - 'Clawback: invalid field Amount', - ) + assertInvalid(invalidStrAmount, 'Clawback: invalid field Amount') }) it(`throws w/ invalid holder Account`, function () { @@ -84,16 +64,7 @@ describe('Clawback', function () { Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assert.throws( - () => validate(invalidAccount), - ValidationError, - 'Clawback: invalid holder Account', - ) - assert.throws( - () => validateClawback(invalidAccount), - ValidationError, - 'Clawback: invalid holder Account', - ) + assertInvalid(invalidAccount, 'Clawback: invalid holder Account') }) it(`verifies valid MPT Clawback`, function () { @@ -121,16 +92,7 @@ describe('Clawback', function () { Holder: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assert.throws( - () => validate(invalidAccount), - ValidationError, - 'Clawback: invalid holder Account', - ) - assert.throws( - () => validateClawback(invalidAccount), - ValidationError, - 'Clawback: invalid holder Account', - ) + assertInvalid(invalidAccount, 'Clawback: invalid holder Account') }) it(`throws w/ invalid Holder`, function () { @@ -143,16 +105,7 @@ describe('Clawback', function () { Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assert.throws( - () => validate(invalidAccount), - ValidationError, - 'Clawback: missing field Holder', - ) - assert.throws( - () => validateClawback(invalidAccount), - ValidationError, - 'Clawback: missing field Holder', - ) + assertInvalid(invalidAccount, 'Clawback: missing field Holder') }) it(`throws w/ invalid currency Holder`, function () { @@ -167,15 +120,6 @@ describe('Clawback', function () { Holder: 'rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy', } as any - assert.throws( - () => validate(invalidAccount), - ValidationError, - 'Clawback: cannot have Holder for currency', - ) - assert.throws( - () => validateClawback(invalidAccount), - ValidationError, - 'Clawback: cannot have Holder for currency', - ) + assertInvalid(invalidAccount, 'Clawback: cannot have Holder for currency') }) }) diff --git a/packages/xrpl/test/models/depositPreauth.test.ts b/packages/xrpl/test/models/depositPreauth.test.ts index 1d0ca2aea4..3662ad29d5 100644 --- a/packages/xrpl/test/models/depositPreauth.test.ts +++ b/packages/xrpl/test/models/depositPreauth.test.ts @@ -1,8 +1,13 @@ import { stringToHex } from '@xrplf/isomorphic/dist/utils' -import { assert } from 'chai' -import { AuthorizeCredential, validate, ValidationError } from '../../src' +import { AuthorizeCredential } from '../../src' import { validateDepositPreauth } from '../../src/models/transactions/depositPreauth' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateDepositPreauth) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateDepositPreauth, message) /** * DepositPreauth Transaction Verification Testing. @@ -10,7 +15,7 @@ import { validateDepositPreauth } from '../../src/models/transactions/depositPre * Providing runtime verification testing for each specific transaction type. */ describe('DepositPreauth', function () { - let depositPreauth + let depositPreauth: any const validCredential = { Credential: { @@ -28,26 +33,22 @@ describe('DepositPreauth', function () { it('verifies valid DepositPreauth when only Authorize is provided', function () { depositPreauth.Authorize = 'rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW' - assert.doesNotThrow(() => validateDepositPreauth(depositPreauth)) - assert.doesNotThrow(() => validate(depositPreauth)) + assertValid(depositPreauth) }) it('verifies valid DepositPreauth when only Unauthorize is provided', function () { depositPreauth.Unauthorize = 'raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n' - assert.doesNotThrow(() => validateDepositPreauth(depositPreauth)) - assert.doesNotThrow(() => validate(depositPreauth)) + assertValid(depositPreauth) }) it('verifies valid DepositPreauth when only AuthorizeCredentials is provided', function () { depositPreauth.AuthorizeCredentials = [validCredential] - assert.doesNotThrow(() => validateDepositPreauth(depositPreauth)) - assert.doesNotThrow(() => validate(depositPreauth)) + assertValid(depositPreauth) }) it('verifies valid DepositPreauth when only UnauthorizeCredentials is provided', function () { depositPreauth.UnauthorizeCredentials = [validCredential] - assert.doesNotThrow(() => validateDepositPreauth(depositPreauth)) - assert.doesNotThrow(() => validate(depositPreauth)) + assertValid(depositPreauth) }) it('throws when multiple of Authorize, Unauthorize, AuthorizeCredentials, UnauthorizeCredentials are provided', function () { @@ -56,104 +57,53 @@ describe('DepositPreauth', function () { depositPreauth.Authorize = 'rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW' depositPreauth.UnauthorizeCredentials = [validCredential] - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) depositPreauth.Unauthorize = 'raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n' - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) depositPreauth.AuthorizeCredentials = [validCredential] - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) depositPreauth.Authorize = undefined - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) depositPreauth.UnauthorizeCredentials = undefined - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) }) it('throws when none of Authorize, Unauthorize, AuthorizeCredentials, UnauthorizeCredentials are provided', function () { const errorMessage = 'DepositPreauth: Requires exactly one field of the following: Authorize, Unauthorize, AuthorizeCredentials, UnauthorizeCredentials.' - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) }) it('throws when Authorize is not a string', function () { depositPreauth.Authorize = 1234 - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - 'DepositPreauth: invalid field Authorize', - ) - assert.throws( - () => validate(depositPreauth), - ValidationError, - 'DepositPreauth: invalid field Authorize', - ) + assertInvalid(depositPreauth, 'DepositPreauth: invalid field Authorize') }) it('throws when an Account attempts to preauthorize its own address', function () { depositPreauth.Authorize = depositPreauth.Account - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, + assertInvalid( + depositPreauth, "DepositPreauth: Account can't preauthorize its own address", ) }) it('throws when Unauthorize is not a string', function () { depositPreauth.Unauthorize = 1234 - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - 'DepositPreauth: invalid field Unauthorize', - ) - assert.throws( - () => validate(depositPreauth), - ValidationError, - 'DepositPreauth: invalid field Unauthorize', - ) + assertInvalid(depositPreauth, 'DepositPreauth: invalid field Unauthorize') }) it('throws when an Account attempts to unauthorize its own address', function () { depositPreauth.Unauthorize = depositPreauth.Account - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, + assertInvalid( + depositPreauth, "DepositPreauth: Account can't unauthorize its own address", ) - assert.throws( - () => validate(depositPreauth), - ValidationError, + assertInvalid( + depositPreauth, "DepositPreauth: Account can't unauthorize its own address", ) }) @@ -162,48 +112,28 @@ describe('DepositPreauth', function () { const errorMessage = 'DepositPreauth: invalid field Credentials' depositPreauth.AuthorizeCredentials = validCredential - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) }) it('throws when UnauthorizeCredentials is not an array', function () { const errorMessage = 'DepositPreauth: invalid field Credentials' depositPreauth.UnauthorizeCredentials = validCredential - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) }) it('throws when AuthorizeCredentials is empty array', function () { const errorMessage = 'DepositPreauth: Credentials cannot be an empty array' depositPreauth.AuthorizeCredentials = [] - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) }) it('throws when UnauthorizeCredentials is empty array', function () { const errorMessage = 'DepositPreauth: Credentials cannot be an empty array' depositPreauth.UnauthorizeCredentials = [] - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) }) it('throws when AuthorizeCredentials is too long', function () { @@ -219,12 +149,7 @@ describe('DepositPreauth', function () { }) } depositPreauth.AuthorizeCredentials = sampleCredentials - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) }) it('throws when UnauthorizeCredentials is too long', function () { @@ -240,12 +165,7 @@ describe('DepositPreauth', function () { }) } depositPreauth.UnauthorizeCredentials = sampleCredentials - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) }) it('throws when AuthorizeCredentials is invalid shape', function () { @@ -256,12 +176,7 @@ describe('DepositPreauth', function () { const errorMessage = 'DepositPreauth: Invalid Credentials format' depositPreauth.AuthorizeCredentials = invalidCredentials - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) }) it('throws when UnauthorizeCredentials is invalid shape', function () { @@ -272,12 +187,7 @@ describe('DepositPreauth', function () { const errorMessage = 'DepositPreauth: Invalid Credentials format' depositPreauth.UnauthorizeCredentials = invalidCredentials - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) }) it('throws when AuthorizeCredentials has duplicates', function () { @@ -286,12 +196,7 @@ describe('DepositPreauth', function () { 'DepositPreauth: Credentials cannot contain duplicate elements' depositPreauth.AuthorizeCredentials = invalidCredentials - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) }) it('throws when UnauthorizeCredentials has duplicates', function () { @@ -300,11 +205,6 @@ describe('DepositPreauth', function () { 'DepositPreauth: Credentials cannot contain duplicate elements' depositPreauth.UnauthorizeCredentials = invalidCredentials - assert.throws( - () => validateDepositPreauth(depositPreauth), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(depositPreauth), ValidationError, errorMessage) + assertInvalid(depositPreauth, errorMessage) }) }) diff --git a/packages/xrpl/test/models/escrowCancel.test.ts b/packages/xrpl/test/models/escrowCancel.test.ts index fd833b3f22..3a69cf7eb0 100644 --- a/packages/xrpl/test/models/escrowCancel.test.ts +++ b/packages/xrpl/test/models/escrowCancel.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateEscrowCancel } from '../../src/models/transactions/escrowCancel' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateEscrowCancel) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateEscrowCancel, message) /** * Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateEscrowCancel } from '../../src/models/transactions/escrowCancel * Providing runtime verification testing for each specific transaction type. */ describe('EscrowCancel', function () { - let cancel + let cancel: any beforeEach(function () { cancel = { @@ -21,74 +23,36 @@ describe('EscrowCancel', function () { }) it(`Valid EscrowCancel`, function () { - assert.doesNotThrow(() => validateEscrowCancel(cancel)) - assert.doesNotThrow(() => validate(cancel)) + assertValid(cancel) }) it(`Valid EscrowCancel with string OfferSequence`, function () { cancel.OfferSequence = '7' - assert.doesNotThrow(() => validateEscrowCancel(cancel)) - assert.doesNotThrow(() => validate(cancel)) + assertValid(cancel) }) it(`Invalid EscrowCancel missing owner`, function () { delete cancel.Owner - assert.throws( - () => validateEscrowCancel(cancel), - ValidationError, - 'EscrowCancel: missing field Owner', - ) - assert.throws( - () => validate(cancel), - ValidationError, - 'EscrowCancel: missing field Owner', - ) + assertInvalid(cancel, 'EscrowCancel: missing field Owner') }) it(`Invalid EscrowCancel missing offerSequence`, function () { delete cancel.OfferSequence - assert.throws( - () => validateEscrowCancel(cancel), - ValidationError, - 'EscrowCancel: missing field OfferSequence', - ) - assert.throws( - () => validate(cancel), - ValidationError, - 'EscrowCancel: missing field OfferSequence', - ) + assertInvalid(cancel, 'EscrowCancel: missing field OfferSequence') }) it(`Invalid Owner`, function () { cancel.Owner = 10 - assert.throws( - () => validateEscrowCancel(cancel), - ValidationError, - 'EscrowCancel: invalid field Owner', - ) - assert.throws( - () => validate(cancel), - ValidationError, - 'EscrowCancel: invalid field Owner', - ) + assertInvalid(cancel, 'EscrowCancel: invalid field Owner') }) it(`Invalid OfferSequence`, function () { cancel.OfferSequence = 'random' - assert.throws( - () => validateEscrowCancel(cancel), - ValidationError, - 'EscrowCancel: invalid field OfferSequence', - ) - assert.throws( - () => validate(cancel), - ValidationError, - 'EscrowCancel: invalid field OfferSequence', - ) + assertInvalid(cancel, 'EscrowCancel: invalid field OfferSequence') }) }) diff --git a/packages/xrpl/test/models/escrowCreate.test.ts b/packages/xrpl/test/models/escrowCreate.test.ts index 235943db70..6c4f148fca 100644 --- a/packages/xrpl/test/models/escrowCreate.test.ts +++ b/packages/xrpl/test/models/escrowCreate.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateEscrowCreate } from '../../src/models/transactions/escrowCreate' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateEscrowCreate) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateEscrowCreate, message) /** * EscrowCreate Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateEscrowCreate } from '../../src/models/transactions/escrowCreate * Providing runtime verification testing for each specific transaction type. */ describe('EscrowCreate', function () { - let escrow + let escrow: any beforeEach(function () { escrow = { @@ -27,137 +29,63 @@ describe('EscrowCreate', function () { }) it(`verifies valid EscrowCreate`, function () { - assert.doesNotThrow(() => validateEscrowCreate(escrow)) - assert.doesNotThrow(() => validate(escrow)) + assertValid(escrow) }) it(`Missing amount`, function () { delete escrow.Amount - assert.throws( - () => validateEscrowCreate(escrow), - ValidationError, - 'EscrowCreate: missing field Amount', - ) - assert.throws( - () => validate(escrow), - ValidationError, - 'EscrowCreate: missing field Amount', - ) + assertInvalid(escrow, 'EscrowCreate: missing field Amount') }) it(`Missing destination`, function () { delete escrow.Destination - assert.throws( - () => validateEscrowCreate(escrow), - ValidationError, - 'EscrowCreate: missing field Destination', - ) - assert.throws( - () => validate(escrow), - ValidationError, - 'EscrowCreate: missing field Destination', - ) + assertInvalid(escrow, 'EscrowCreate: missing field Destination') }) it(`throws w/ invalid Destination`, function () { escrow.Destination = 10 - assert.throws( - () => validateEscrowCreate(escrow), - ValidationError, - 'EscrowCreate: invalid field Destination', - ) - assert.throws( - () => validate(escrow), - ValidationError, - 'EscrowCreate: invalid field Destination', - ) + assertInvalid(escrow, 'EscrowCreate: invalid field Destination') }) it(`throws w/ invalid Amount`, function () { escrow.Amount = 1000 - assert.throws( - () => validateEscrowCreate(escrow), - ValidationError, - 'EscrowCreate: invalid field Amount', - ) - assert.throws( - () => validate(escrow), - ValidationError, - 'EscrowCreate: invalid field Amount', - ) + assertInvalid(escrow, 'EscrowCreate: invalid field Amount') }) it(`invalid CancelAfter`, function () { escrow.CancelAfter = 'abcd' - assert.throws( - () => validateEscrowCreate(escrow), - ValidationError, - 'EscrowCreate: invalid field CancelAfter', - ) - assert.throws( - () => validate(escrow), - ValidationError, - 'EscrowCreate: invalid field CancelAfter', - ) + assertInvalid(escrow, 'EscrowCreate: invalid field CancelAfter') }) it(`invalid FinishAfter`, function () { escrow.FinishAfter = 'abcd' - assert.throws( - () => validateEscrowCreate(escrow), - ValidationError, - 'EscrowCreate: invalid field FinishAfter', - ) + assertInvalid(escrow, 'EscrowCreate: invalid field FinishAfter') }) it(`invalid Condition`, function () { escrow.Condition = 0x141243 - assert.throws( - () => validateEscrowCreate(escrow), - ValidationError, - 'EscrowCreate: invalid field Condition', - ) - assert.throws( - () => validate(escrow), - ValidationError, - 'EscrowCreate: invalid field Condition', - ) + assertInvalid(escrow, 'EscrowCreate: invalid field Condition') }) it(`invalid DestinationTag`, function () { escrow.DestinationTag = 'abcd' - assert.throws( - () => validateEscrowCreate(escrow), - ValidationError, - 'EscrowCreate: invalid field DestinationTag', - ) - assert.throws( - () => validate(escrow), - ValidationError, - 'EscrowCreate: invalid field DestinationTag', - ) + assertInvalid(escrow, 'EscrowCreate: invalid field DestinationTag') }) it(`Missing both CancelAfter and FinishAfter`, function () { delete escrow.CancelAfter delete escrow.FinishAfter - assert.throws( - () => validateEscrowCreate(escrow), - ValidationError, - 'EscrowCreate: Either CancelAfter or FinishAfter must be specified', - ) - assert.throws( - () => validate(escrow), - ValidationError, + assertInvalid( + escrow, 'EscrowCreate: Either CancelAfter or FinishAfter must be specified', ) }) @@ -166,14 +94,8 @@ describe('EscrowCreate', function () { delete escrow.Condition delete escrow.FinishAfter - assert.throws( - () => validateEscrowCreate(escrow), - ValidationError, - 'EscrowCreate: Either Condition or FinishAfter must be specified', - ) - assert.throws( - () => validate(escrow), - ValidationError, + assertInvalid( + escrow, 'EscrowCreate: Either Condition or FinishAfter must be specified', ) }) diff --git a/packages/xrpl/test/models/escrowFinish.test.ts b/packages/xrpl/test/models/escrowFinish.test.ts index 4e98b97417..f7077e3307 100644 --- a/packages/xrpl/test/models/escrowFinish.test.ts +++ b/packages/xrpl/test/models/escrowFinish.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateEscrowFinish } from '../../src/models/transactions/escrowFinish' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateEscrowFinish) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateEscrowFinish, message) /** * EscrowFinish Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateEscrowFinish } from '../../src/models/transactions/escrowFinish * Providing runtime verification testing for each specific transaction type. */ describe('EscrowFinish', function () { - let escrow + let escrow: any beforeEach(function () { escrow = { @@ -26,8 +28,7 @@ describe('EscrowFinish', function () { } }) it(`verifies valid EscrowFinish`, function () { - assert.doesNotThrow(() => validateEscrowFinish(escrow)) - assert.doesNotThrow(() => validate(escrow)) + assertValid(escrow) }) it(`verifies valid EscrowFinish w/o optional`, function () { @@ -35,75 +36,37 @@ describe('EscrowFinish', function () { escrow.Fulfillment = undefined escrow.CredentialIDs = undefined - assert.doesNotThrow(() => validateEscrowFinish(escrow)) - assert.doesNotThrow(() => validate(escrow)) + assertValid(escrow) }) it(`verifies valid EscrowFinish w/string OfferSequence`, function () { escrow.OfferSequence = '7' - assert.doesNotThrow(() => validateEscrowFinish(escrow)) - assert.doesNotThrow(() => validate(escrow)) + assertValid(escrow) }) it(`throws w/ invalid Owner`, function () { escrow.Owner = 0x15415253 - assert.throws( - () => validateEscrowFinish(escrow), - ValidationError, - 'EscrowFinish: invalid field Owner', - ) - assert.throws( - () => validate(escrow), - ValidationError, - 'EscrowFinish: invalid field Owner', - ) + assertInvalid(escrow, 'EscrowFinish: invalid field Owner') }) it(`throws w/ invalid OfferSequence`, function () { escrow.OfferSequence = 'random' - assert.throws( - () => validateEscrowFinish(escrow), - ValidationError, - 'EscrowFinish: invalid field OfferSequence', - ) - assert.throws( - () => validate(escrow), - ValidationError, - 'EscrowFinish: invalid field OfferSequence', - ) + assertInvalid(escrow, 'EscrowFinish: invalid field OfferSequence') }) it(`throws w/ invalid Condition`, function () { escrow.Condition = 10 - assert.throws( - () => validateEscrowFinish(escrow), - ValidationError, - 'EscrowFinish: invalid field Condition', - ) - assert.throws( - () => validate(escrow), - ValidationError, - 'EscrowFinish: invalid field Condition', - ) + assertInvalid(escrow, 'EscrowFinish: invalid field Condition') }) it(`throws w/ invalid Fulfillment`, function () { escrow.Fulfillment = 0x142341 - assert.throws( - () => validateEscrowFinish(escrow), - ValidationError, - 'EscrowFinish: invalid field Fulfillment', - ) - assert.throws( - () => validate(escrow), - ValidationError, - 'EscrowFinish: invalid field Fulfillment', - ) + assertInvalid(escrow, 'EscrowFinish: invalid field Fulfillment') }) it(`throws w/ non-array CredentialIDs`, function () { @@ -112,12 +75,7 @@ describe('EscrowFinish', function () { const errorMessage = 'EscrowFinish: invalid field Credentials' - assert.throws( - () => validateEscrowFinish(escrow), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(escrow), ValidationError, errorMessage) + assertInvalid(escrow, errorMessage) }) it(`throws CredentialIDs length exceeds max length`, function () { @@ -136,12 +94,7 @@ describe('EscrowFinish', function () { const errorMessage = 'EscrowFinish: Credentials length cannot exceed 8 elements' - assert.throws( - () => validateEscrowFinish(escrow), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(escrow), ValidationError, errorMessage) + assertInvalid(escrow, errorMessage) }) it(`throws w/ empty CredentialIDs`, function () { @@ -149,12 +102,7 @@ describe('EscrowFinish', function () { const errorMessage = 'EscrowFinish: Credentials cannot be an empty array' - assert.throws( - () => validateEscrowFinish(escrow), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(escrow), ValidationError, errorMessage) + assertInvalid(escrow, errorMessage) }) it(`throws w/ non-string CredentialIDs`, function () { @@ -165,12 +113,7 @@ describe('EscrowFinish', function () { const errorMessage = 'EscrowFinish: Invalid Credentials ID list format' - assert.throws( - () => validateEscrowFinish(escrow), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(escrow), ValidationError, errorMessage) + assertInvalid(escrow, errorMessage) }) it(`throws w/ duplicate CredentialIDs`, function () { @@ -182,11 +125,6 @@ describe('EscrowFinish', function () { const errorMessage = 'EscrowFinish: Credentials cannot contain duplicate elements' - assert.throws( - () => validateEscrowFinish(escrow), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(escrow), ValidationError, errorMessage) + assertInvalid(escrow, errorMessage) }) }) diff --git a/packages/xrpl/test/models/offerCancel.test.ts b/packages/xrpl/test/models/offerCancel.test.ts index eb4e2dfc89..53edc1931c 100644 --- a/packages/xrpl/test/models/offerCancel.test.ts +++ b/packages/xrpl/test/models/offerCancel.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateOfferCancel } from '../../src/models/transactions/offerCancel' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateOfferCancel) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateOfferCancel, message) /** * OfferCancel Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateOfferCancel } from '../../src/models/transactions/offerCancel' * Providing runtime verification testing for each specific transaction type. */ describe('OfferCancel', function () { - let offer + let offer: any beforeEach(function () { offer = { @@ -24,45 +26,25 @@ describe('OfferCancel', function () { TransactionType: 'OfferCancel', TxnSignature: '304402203EC848BD6AB42DC8509285245804B15E1652092CC0B189D369E12E563771D049022046DF40C16EA05DC99D01E553EA2E218FCA1C5B38927889A2BDF064D1F44D60F0', - } as any + } }) it(`verifies valid OfferCancel`, function () { - assert.doesNotThrow(() => validateOfferCancel(offer)) - assert.doesNotThrow(() => validate(offer)) + assertValid(offer) }) it(`verifies valid OfferCancel with flags`, function () { offer.Flags = 2147483648 - assert.doesNotThrow(() => validateOfferCancel(offer)) - assert.doesNotThrow(() => validate(offer)) + assertValid(offer) }) it(`throws w/ OfferSequence must be a number`, function () { offer.OfferSequence = 'abcd' - assert.throws( - () => validateOfferCancel(offer), - ValidationError, - 'OfferCancel: invalid field OfferSequence', - ) - assert.throws( - () => validate(offer), - ValidationError, - 'OfferCancel: invalid field OfferSequence', - ) + assertInvalid(offer, 'OfferCancel: invalid field OfferSequence') }) it(`throws w/ missing OfferSequence`, function () { delete offer.OfferSequence - assert.throws( - () => validateOfferCancel(offer), - ValidationError, - 'OfferCancel: missing field OfferSequence', - ) - assert.throws( - () => validate(offer), - ValidationError, - 'OfferCancel: missing field OfferSequence', - ) + assertInvalid(offer, 'OfferCancel: missing field OfferSequence') }) }) diff --git a/packages/xrpl/test/models/offerCreate.test.ts b/packages/xrpl/test/models/offerCreate.test.ts index 10b4dfb42e..66c6ff81e4 100644 --- a/packages/xrpl/test/models/offerCreate.test.ts +++ b/packages/xrpl/test/models/offerCreate.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateOfferCreate } from '../../src/models/transactions/offerCreate' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateOfferCreate) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateOfferCreate, message) /** * OfferCreate Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateOfferCreate } from '../../src/models/transactions/offerCreate' * Providing runtime verification testing for each specific transaction type. */ describe('OfferCreate', function () { - let offer + let offer: any beforeEach(function () { offer = { @@ -34,8 +36,7 @@ describe('OfferCreate', function () { } as any }) it(`verifies valid OfferCreate`, function () { - assert.doesNotThrow(() => validateOfferCreate(offer)) - assert.doesNotThrow(() => validate(offer)) + assertValid(offer) const offer2 = { Account: 'r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W', @@ -89,60 +90,24 @@ describe('OfferCreate', function () { it(`throws w/ invalid Expiration`, function () { offer.Expiration = 'abcd' - assert.throws( - () => validateOfferCreate(offer), - ValidationError, - 'OfferCreate: invalid field Expiration', - ) - assert.throws( - () => validate(offer), - ValidationError, - 'OfferCreate: invalid field Expiration', - ) + assertInvalid(offer, 'OfferCreate: invalid field Expiration') }) it(`throws w/ invalid OfferSequence`, function () { offer.OfferSequence = 'abcd' - assert.throws( - () => validateOfferCreate(offer), - ValidationError, - 'OfferCreate: invalid field OfferSequence', - ) - assert.throws( - () => validate(offer), - ValidationError, - 'OfferCreate: invalid field OfferSequence', - ) + assertInvalid(offer, 'OfferCreate: invalid field OfferSequence') }) it(`throws w/ invalid TakerPays`, function () { offer.TakerPays = 10 - assert.throws( - () => validateOfferCreate(offer), - ValidationError, - 'OfferCreate: invalid field TakerPays', - ) - assert.throws( - () => validate(offer), - ValidationError, - 'OfferCreate: invalid field TakerPays', - ) + assertInvalid(offer, 'OfferCreate: invalid field TakerPays') }) it(`throws w/ invalid TakerGets`, function () { offer.TakerGets = 11 - assert.throws( - () => validateOfferCreate(offer), - ValidationError, - 'OfferCreate: invalid field TakerGets', - ) - assert.throws( - () => validate(offer), - ValidationError, - 'OfferCreate: invalid field TakerGets', - ) + assertInvalid(offer, 'OfferCreate: invalid field TakerGets') }) }) diff --git a/packages/xrpl/test/models/oracleDelete.test.ts b/packages/xrpl/test/models/oracleDelete.test.ts index 734caef230..684b0dc3fe 100644 --- a/packages/xrpl/test/models/oracleDelete.test.ts +++ b/packages/xrpl/test/models/oracleDelete.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateOracleDelete } from '../../src/models/transactions/oracleDelete' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateOracleDelete) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateOracleDelete, message) /** * OracleDelete Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateOracleDelete } from '../../src/models/transactions/oracleDelete * Providing runtime verification testing for each specific transaction type. */ describe('OracleDelete', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -20,21 +22,18 @@ describe('OracleDelete', function () { }) it('verifies valid OracleDelete', function () { - assert.doesNotThrow(() => validateOracleDelete(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it(`throws w/ missing field OracleDocumentID`, function () { delete tx.OracleDocumentID const errorMessage = 'OracleDelete: missing field OracleDocumentID' - assert.throws(() => validateOracleDelete(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ invalid OracleDocumentID`, function () { tx.OracleDocumentID = 'abcd' const errorMessage = 'OracleDelete: invalid field OracleDocumentID' - assert.throws(() => validateOracleDelete(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) }) diff --git a/packages/xrpl/test/models/oracleSet.test.ts b/packages/xrpl/test/models/oracleSet.test.ts index d7ec991250..5dc5a1652f 100644 --- a/packages/xrpl/test/models/oracleSet.test.ts +++ b/packages/xrpl/test/models/oracleSet.test.ts @@ -1,8 +1,11 @@ import { stringToHex } from '@xrplf/isomorphic/dist/utils' -import { assert } from 'chai' -import { validate, ValidationError } from '../../src' import { validateOracleSet } from '../../src/models/transactions/oracleSet' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateOracleSet) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateOracleSet, message) /** * OracleSet Transaction Verification Testing. @@ -10,7 +13,7 @@ import { validateOracleSet } from '../../src/models/transactions/oracleSet' * Providing runtime verification testing for each specific transaction type. */ describe('OracleSet', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -35,72 +38,62 @@ describe('OracleSet', function () { }) it('verifies valid OracleSet', function () { - assert.doesNotThrow(() => validateOracleSet(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it(`throws w/ missing field OracleDocumentID`, function () { delete tx.OracleDocumentID const errorMessage = 'OracleSet: missing field OracleDocumentID' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ invalid OracleDocumentID`, function () { tx.OracleDocumentID = 'abcd' const errorMessage = 'OracleSet: invalid field OracleDocumentID' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ missing field LastUpdateTime`, function () { delete tx.LastUpdateTime const errorMessage = 'OracleSet: missing field LastUpdateTime' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ invalid LastUpdateTime`, function () { tx.LastUpdateTime = 'abcd' const errorMessage = 'OracleSet: invalid field LastUpdateTime' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ missing invalid Provider`, function () { tx.Provider = 1234 const errorMessage = 'OracleSet: invalid field Provider' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ missing invalid URI`, function () { tx.URI = 1234 const errorMessage = 'OracleSet: invalid field URI' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ missing invalid AssetClass`, function () { tx.AssetClass = 1234 const errorMessage = 'OracleSet: invalid field AssetClass' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ invalid PriceDataSeries must be an array`, function () { tx.PriceDataSeries = 1234 const errorMessage = 'OracleSet: PriceDataSeries must be an array' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ invalid PriceDataSeries must be an array of objects`, function () { tx.PriceDataSeries = [1234] const errorMessage = 'OracleSet: PriceDataSeries must be an array of objects' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ PriceDataSeries must have at most 10 PriceData objects`, function () { @@ -114,83 +107,72 @@ describe('OracleSet', function () { }) const errorMessage = 'OracleSet: PriceDataSeries must have at most 10 PriceData objects' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ PriceDataSeries must have a PriceData object`, function () { delete tx.PriceDataSeries[0].PriceData const errorMessage = 'OracleSet: PriceDataSeries must have a `PriceData` object' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ PriceDataSeries must only have a single PriceData object`, function () { tx.PriceDataSeries[0].ExtraProp = 'extraprop' const errorMessage = 'OracleSet: PriceDataSeries must only have a single PriceData object' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ missing BaseAsset of PriceDataSeries`, function () { delete tx.PriceDataSeries[0].PriceData.BaseAsset const errorMessage = 'OracleSet: PriceDataSeries must have a `BaseAsset` string' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ missing QuoteAsset of PriceDataSeries`, function () { delete tx.PriceDataSeries[0].PriceData.QuoteAsset const errorMessage = 'OracleSet: PriceDataSeries must have a `QuoteAsset` string' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ missing AssetPrice with Scale present of PriceDataSeries`, function () { delete tx.PriceDataSeries[0].PriceData.AssetPrice const errorMessage = 'OracleSet: PriceDataSeries must have both `AssetPrice` and `Scale` if any are present' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ missing Scale with AssetPrice present of PriceDataSeries`, function () { delete tx.PriceDataSeries[0].PriceData.Scale const errorMessage = 'OracleSet: PriceDataSeries must have both `AssetPrice` and `Scale` if any are present' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ invalid AssetPrice of PriceDataSeries`, function () { tx.PriceDataSeries[0].PriceData.AssetPrice = 'abcd' const errorMessage = 'OracleSet: invalid field AssetPrice' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ invalid Scale of PriceDataSeries`, function () { tx.PriceDataSeries[0].PriceData.Scale = 'abcd' const errorMessage = 'OracleSet: invalid field Scale' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ Scale must be in range 0-10 when above max`, function () { tx.PriceDataSeries[0].PriceData.Scale = 11 const errorMessage = 'OracleSet: Scale must be in range 0-10' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ Scale must be in range 0-10 when below min`, function () { tx.PriceDataSeries[0].PriceData.Scale = -1 const errorMessage = 'OracleSet: Scale must be in range 0-10' - assert.throws(() => validateOracleSet(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) }) diff --git a/packages/xrpl/test/models/payment.test.ts b/packages/xrpl/test/models/payment.test.ts index cb76a49121..6a75acd976 100644 --- a/packages/xrpl/test/models/payment.test.ts +++ b/packages/xrpl/test/models/payment.test.ts @@ -1,8 +1,12 @@ /* eslint-disable max-statements -- need additional tests for optional fields */ -import { assert } from 'chai' -import { validate, PaymentFlags, ValidationError } from '../../src' +import { PaymentFlags } from '../../src' import { validatePayment } from '../../src/models/transactions/payment' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validatePayment) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validatePayment, message) /** * Payment Verification Testing. @@ -10,7 +14,7 @@ import { validatePayment } from '../../src/models/transactions/payment' * Providing runtime verification testing for each specific transaction type. */ describe('Payment', function () { - let payment + let payment: any beforeEach(function () { payment = { @@ -37,8 +41,7 @@ describe('Payment', function () { }) it(`verifies valid Payment`, function () { - assert.doesNotThrow(() => validatePayment(payment)) - assert.doesNotThrow(() => validate(payment)) + assertValid(payment) }) it(`Verifies memos correctly`, function () { @@ -50,7 +53,7 @@ describe('Payment', function () { }, ] - assert.doesNotThrow(() => validate(payment)) + assertValid(payment) }) it(`Verifies memos correctly`, function () { @@ -63,198 +66,86 @@ describe('Payment', function () { }, ] - assert.throws( - () => validate(payment), - ValidationError, - 'BaseTransaction: invalid field Memos', - ) + assertInvalid(payment, 'BaseTransaction: invalid field Memos') }) it(`throws when Amount is missing`, function () { delete payment.Amount - assert.throws( - () => validatePayment(payment), - ValidationError, - 'Payment: missing field Amount', - ) - assert.throws( - () => validate(payment), - ValidationError, - 'Payment: missing field Amount', - ) + assertInvalid(payment, 'Payment: missing field Amount') }) it(`throws when Amount is invalid`, function () { payment.Amount = 1234 - assert.throws( - () => validatePayment(payment), - ValidationError, - 'Payment: invalid field Amount', - ) - assert.throws( - () => validate(payment), - ValidationError, - 'Payment: invalid field Amount', - ) + assertInvalid(payment, 'Payment: invalid field Amount') }) it(`throws when Destination is missing`, function () { delete payment.Destination - assert.throws( - () => validatePayment(payment), - ValidationError, - 'Payment: missing field Destination', - ) - assert.throws( - () => validate(payment), - ValidationError, - 'Payment: missing field Destination', - ) + assertInvalid(payment, 'Payment: missing field Destination') }) it(`throws when Destination is invalid`, function () { payment.Destination = 7896214 - assert.throws( - () => validatePayment(payment), - ValidationError, - 'Payment: invalid field Destination', - ) - assert.throws( - () => validate(payment), - ValidationError, - 'Payment: invalid field Destination', - ) + assertInvalid(payment, 'Payment: invalid field Destination') }) it(`throws when Destination is invalid classic address`, function () { payment.Destination = 'rABCD' - assert.throws( - () => validatePayment(payment), - ValidationError, - 'Payment: invalid field Destination', - ) - assert.throws( - () => validate(payment), - ValidationError, - 'Payment: invalid field Destination', - ) + assertInvalid(payment, 'Payment: invalid field Destination') }) it(`does not throw when Destination is a valid x-address`, function () { payment.Destination = 'X7WZKEeNVS2p9Tire9DtNFkzWBZbFtSiS2eDBib7svZXuc2' - assert.doesNotThrow(() => validatePayment(payment)) - assert.doesNotThrow(() => validate(payment)) + assertValid(payment) }) it(`throws when Destination is an empty string`, function () { payment.Destination = '' - assert.throws( - () => validatePayment(payment), - ValidationError, - 'Payment: invalid field Destination', - ) - assert.throws( - () => validate(payment), - ValidationError, - 'Payment: invalid field Destination', - ) + assertInvalid(payment, 'Payment: invalid field Destination') }) it(`throws when DestinationTag is not a number`, function () { payment.DestinationTag = 'abcd' - assert.throws( - () => validatePayment(payment), - ValidationError, - 'Payment: invalid field DestinationTag', - ) - assert.throws( - () => validate(payment), - ValidationError, - 'Payment: invalid field DestinationTag', - ) + assertInvalid(payment, 'Payment: invalid field DestinationTag') }) it(`throws when InvoiceID is not a string`, function () { payment.InvoiceID = 19832 - assert.throws( - () => validatePayment(payment), - ValidationError, - 'Payment: invalid field InvoiceID', - ) - assert.throws( - () => validate(payment), - ValidationError, - 'Payment: invalid field InvoiceID', - ) + assertInvalid(payment, 'Payment: invalid field InvoiceID') }) it(`throws when Paths is invalid`, function () { payment.Paths = [[{ account: 123 }]] - assert.throws( - () => validatePayment(payment), - ValidationError, - 'Payment: invalid field Paths', - ) - assert.throws( - () => validate(payment), - ValidationError, - 'Payment: invalid field Paths', - ) + assertInvalid(payment, 'Payment: invalid field Paths') }) it(`throws when SendMax is invalid`, function () { payment.SendMax = 100000000 - assert.throws( - () => validatePayment(payment), - ValidationError, - 'Payment: invalid field SendMax', - ) - assert.throws( - () => validate(payment), - ValidationError, - 'Payment: invalid field SendMax', - ) + assertInvalid(payment, 'Payment: invalid field SendMax') }) it(`verifies valid DeliverMin with tfPartialPayment flag set as a number`, function () { payment.DeliverMin = '10000' payment.Flags = PaymentFlags.tfPartialPayment - assert.doesNotThrow(() => validatePayment(payment)) - assert.doesNotThrow(() => validate(payment)) + assertValid(payment) }) it(`verifies valid DeliverMin with tfPartialPayment flag set as a boolean`, function () { payment.DeliverMin = '10000' payment.Flags = { tfPartialPayment: true } - assert.doesNotThrow(() => validatePayment(payment)) - assert.doesNotThrow(() => validate(payment)) + assertValid(payment) }) it(`throws when DeliverMin is invalid`, function () { payment.DeliverMin = 10000 payment.Flags = { tfPartialPayment: true } - assert.throws( - () => validatePayment(payment), - ValidationError, - 'Payment: invalid field DeliverMin', - ) - assert.throws( - () => validate(payment), - ValidationError, - 'Payment: invalid field DeliverMin', - ) + assertInvalid(payment, 'Payment: invalid field DeliverMin') }) it(`throws when tfPartialPayment flag is missing with valid DeliverMin`, function () { payment.DeliverMin = '10000' - assert.throws( - () => validatePayment(payment), - ValidationError, - 'Payment: tfPartialPayment flag required with DeliverMin', - ) - assert.throws( - () => validate(payment), - ValidationError, + assertInvalid( + payment, 'Payment: tfPartialPayment flag required with DeliverMin', ) }) @@ -269,8 +160,7 @@ describe('Payment', function () { }, Destination: 'rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy', } as any - assert.doesNotThrow(() => validatePayment(mptPayment)) - assert.doesNotThrow(() => validate(mptPayment)) + assertValid(mptPayment) }) it(`throws w/ non-array CredentialIDs`, function () { @@ -279,8 +169,7 @@ describe('Payment', function () { const errorMessage = 'Payment: invalid field Credentials' - assert.throws(() => validatePayment(payment), ValidationError, errorMessage) - assert.throws(() => validate(payment), ValidationError, errorMessage) + assertInvalid(payment, errorMessage) }) it(`throws CredentialIDs length exceeds max length`, function () { @@ -298,8 +187,7 @@ describe('Payment', function () { const errorMessage = 'Payment: Credentials length cannot exceed 8 elements' - assert.throws(() => validatePayment(payment), ValidationError, errorMessage) - assert.throws(() => validate(payment), ValidationError, errorMessage) + assertInvalid(payment, errorMessage) }) it(`throws w/ empty CredentialIDs`, function () { @@ -307,8 +195,7 @@ describe('Payment', function () { const errorMessage = 'Payment: Credentials cannot be an empty array' - assert.throws(() => validatePayment(payment), ValidationError, errorMessage) - assert.throws(() => validate(payment), ValidationError, errorMessage) + assertInvalid(payment, errorMessage) }) it(`throws w/ non-string CredentialIDs`, function () { @@ -319,8 +206,7 @@ describe('Payment', function () { const errorMessage = 'Payment: Invalid Credentials ID list format' - assert.throws(() => validatePayment(payment), ValidationError, errorMessage) - assert.throws(() => validate(payment), ValidationError, errorMessage) + assertInvalid(payment, errorMessage) }) it(`throws w/ duplicate CredentialIDs`, function () { @@ -332,7 +218,6 @@ describe('Payment', function () { const errorMessage = 'Payment: Credentials cannot contain duplicate elements' - assert.throws(() => validatePayment(payment), ValidationError, errorMessage) - assert.throws(() => validate(payment), ValidationError, errorMessage) + assertInvalid(payment, errorMessage) }) }) diff --git a/packages/xrpl/test/models/paymentChannelClaim.test.ts b/packages/xrpl/test/models/paymentChannelClaim.test.ts index 9d6c37b9c6..225fcbff4a 100644 --- a/packages/xrpl/test/models/paymentChannelClaim.test.ts +++ b/packages/xrpl/test/models/paymentChannelClaim.test.ts @@ -1,7 +1,10 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validatePaymentChannelClaim } from '../../src/models/transactions/paymentChannelClaim' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validatePaymentChannelClaim) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validatePaymentChannelClaim, message) /** * PaymentChannelClaim Transaction Verification Testing. @@ -9,7 +12,7 @@ import { validatePaymentChannelClaim } from '../../src/models/transactions/payme * Providing runtime verification testing for each specific transaction type. */ describe('PaymentChannelClaim', function () { - let channel + let channel: any beforeEach(function () { channel = { @@ -27,8 +30,7 @@ describe('PaymentChannelClaim', function () { }) it(`verifies valid PaymentChannelClaim`, function () { - assert.doesNotThrow(() => validatePaymentChannelClaim(channel)) - assert.doesNotThrow(() => validate(channel)) + assertValid(channel) }) it(`verifies valid PaymentChannelClaim w/o optional`, function () { @@ -37,97 +39,42 @@ describe('PaymentChannelClaim', function () { delete channel.Signature delete channel.PublicKey - assert.doesNotThrow(() => validatePaymentChannelClaim(channel)) - assert.doesNotThrow(() => validate(channel)) + assertValid(channel) }) it(`throws w/ missing Channel`, function () { delete channel.Channel - assert.throws( - () => validatePaymentChannelClaim(channel), - ValidationError, - 'PaymentChannelClaim: missing field Channel', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelClaim: missing field Channel', - ) + assertInvalid(channel, 'PaymentChannelClaim: missing field Channel') }) it(`throws w/ invalid Channel`, function () { channel.Channel = 100 - assert.throws( - () => validatePaymentChannelClaim(channel), - ValidationError, - 'PaymentChannelClaim: invalid field Channel', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelClaim: invalid field Channel', - ) + assertInvalid(channel, 'PaymentChannelClaim: invalid field Channel') }) it(`throws w/ invalid Balance`, function () { channel.Balance = 100 - assert.throws( - () => validatePaymentChannelClaim(channel), - ValidationError, - 'PaymentChannelClaim: invalid field Balance', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelClaim: invalid field Balance', - ) + assertInvalid(channel, 'PaymentChannelClaim: invalid field Balance') }) it(`throws w/ invalid Amount`, function () { channel.Amount = 1000 - assert.throws( - () => validatePaymentChannelClaim(channel), - ValidationError, - 'PaymentChannelClaim: invalid field Amount', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelClaim: invalid field Amount', - ) + assertInvalid(channel, 'PaymentChannelClaim: invalid field Amount') }) it(`throws w/ invalid Signature`, function () { channel.Signature = 1000 - assert.throws( - () => validatePaymentChannelClaim(channel), - ValidationError, - 'PaymentChannelClaim: invalid field Signature', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelClaim: invalid field Signature', - ) + assertInvalid(channel, 'PaymentChannelClaim: invalid field Signature') }) it(`throws w/ invalid PublicKey`, function () { channel.PublicKey = ['100000'] - assert.throws( - () => validatePaymentChannelClaim(channel), - ValidationError, - 'PaymentChannelClaim: invalid field PublicKey', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelClaim: invalid field PublicKey', - ) + assertInvalid(channel, 'PaymentChannelClaim: invalid field PublicKey') }) }) diff --git a/packages/xrpl/test/models/paymentChannelCreate.test.ts b/packages/xrpl/test/models/paymentChannelCreate.test.ts index 6439c8b5e1..b090bbac73 100644 --- a/packages/xrpl/test/models/paymentChannelCreate.test.ts +++ b/packages/xrpl/test/models/paymentChannelCreate.test.ts @@ -1,7 +1,10 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validatePaymentChannelCreate } from '../../src/models/transactions/paymentChannelCreate' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validatePaymentChannelCreate) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validatePaymentChannelCreate, message) /** * PaymentChannelCreate Transaction Verification Testing. @@ -9,7 +12,7 @@ import { validatePaymentChannelCreate } from '../../src/models/transactions/paym * Providing runtime verification testing for each specific transaction type. */ describe('PaymentChannelCreate', function () { - let channel + let channel: any beforeEach(function () { channel = { @@ -27,8 +30,7 @@ describe('PaymentChannelCreate', function () { }) it(`verifies valid PaymentChannelCreate`, function () { - assert.doesNotThrow(() => validatePaymentChannelCreate(channel)) - assert.doesNotThrow(() => validate(channel)) + assertValid(channel) }) it(`verifies valid PaymentChannelCreate w/o optional`, function () { @@ -36,157 +38,66 @@ describe('PaymentChannelCreate', function () { delete channel.DestinationTag delete channel.SourceTag - assert.doesNotThrow(() => validatePaymentChannelCreate(channel)) - assert.doesNotThrow(() => validate(channel)) + assertValid(channel) }) it(`missing Amount`, function () { delete channel.Amount - assert.throws( - () => validatePaymentChannelCreate(channel), - ValidationError, - 'PaymentChannelCreate: missing field Amount', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelCreate: missing field Amount', - ) + assertInvalid(channel, 'PaymentChannelCreate: missing field Amount') }) it(`missing Destination`, function () { delete channel.Destination - assert.throws( - () => validatePaymentChannelCreate(channel), - ValidationError, - 'PaymentChannelCreate: missing field Destination', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelCreate: missing field Destination', - ) + assertInvalid(channel, 'PaymentChannelCreate: missing field Destination') }) it(`missing SettleDelay`, function () { delete channel.SettleDelay - assert.throws( - () => validatePaymentChannelCreate(channel), - ValidationError, - 'PaymentChannelCreate: missing field SettleDelay', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelCreate: missing field SettleDelay', - ) + assertInvalid(channel, 'PaymentChannelCreate: missing field SettleDelay') }) it(`missing PublicKey`, function () { delete channel.PublicKey - assert.throws( - () => validatePaymentChannelCreate(channel), - ValidationError, - 'PaymentChannelCreate: missing field PublicKey', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelCreate: missing field PublicKey', - ) + assertInvalid(channel, 'PaymentChannelCreate: missing field PublicKey') }) it(`invalid Amount`, function () { channel.Amount = 1000 - assert.throws( - () => validatePaymentChannelCreate(channel), - ValidationError, - 'PaymentChannelCreate: invalid field Amount', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelCreate: invalid field Amount', - ) + assertInvalid(channel, 'PaymentChannelCreate: invalid field Amount') }) it(`invalid Destination`, function () { channel.Destination = 10 - assert.throws( - () => validatePaymentChannelCreate(channel), - ValidationError, - 'PaymentChannelCreate: invalid field Destination', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelCreate: invalid field Destination', - ) + assertInvalid(channel, 'PaymentChannelCreate: invalid field Destination') }) it(`invalid SettleDelay`, function () { channel.SettleDelay = 'abcd' - assert.throws( - () => validatePaymentChannelCreate(channel), - ValidationError, - 'PaymentChannelCreate: invalid field SettleDelay', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelCreate: invalid field SettleDelay', - ) + assertInvalid(channel, 'PaymentChannelCreate: invalid field SettleDelay') }) it(`invalid PublicKey`, function () { channel.PublicKey = 10 - assert.throws( - () => validatePaymentChannelCreate(channel), - ValidationError, - 'PaymentChannelCreate: invalid field PublicKey', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelCreate: invalid field PublicKey', - ) + assertInvalid(channel, 'PaymentChannelCreate: invalid field PublicKey') }) it(`invalid DestinationTag`, function () { channel.DestinationTag = 'abcd' - assert.throws( - () => validatePaymentChannelCreate(channel), - ValidationError, - 'PaymentChannelCreate: invalid field DestinationTag', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelCreate: invalid field DestinationTag', - ) + assertInvalid(channel, 'PaymentChannelCreate: invalid field DestinationTag') }) it(`invalid CancelAfter`, function () { channel.CancelAfter = 'abcd' - assert.throws( - () => validatePaymentChannelCreate(channel), - ValidationError, - 'PaymentChannelCreate: invalid field CancelAfter', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelCreate: invalid field CancelAfter', - ) + assertInvalid(channel, 'PaymentChannelCreate: invalid field CancelAfter') }) }) diff --git a/packages/xrpl/test/models/paymentChannelFund.test.ts b/packages/xrpl/test/models/paymentChannelFund.test.ts index 5ac0c47bb8..82c795082d 100644 --- a/packages/xrpl/test/models/paymentChannelFund.test.ts +++ b/packages/xrpl/test/models/paymentChannelFund.test.ts @@ -1,7 +1,10 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validatePaymentChannelFund } from '../../src/models/transactions/paymentChannelFund' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validatePaymentChannelFund) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validatePaymentChannelFund, message) /** * PaymentChannelFund Transaction Verification Testing. @@ -9,7 +12,7 @@ import { validatePaymentChannelFund } from '../../src/models/transactions/paymen * Providing runtime verification testing for each specific transaction type. */ describe('PaymentChannelFund', function () { - let channel + let channel: any beforeEach(function () { channel = { @@ -23,89 +26,42 @@ describe('PaymentChannelFund', function () { }) it(`verifies valid PaymentChannelFund`, function () { - assert.doesNotThrow(() => validatePaymentChannelFund(channel)) - assert.doesNotThrow(() => validate(channel)) + assertValid(channel) }) it(`verifies valid PaymentChannelFund w/o optional`, function () { delete channel.Expiration - assert.doesNotThrow(() => validatePaymentChannelFund(channel)) - assert.doesNotThrow(() => validate(channel)) + assertValid(channel) }) it(`throws w/ missing Amount`, function () { delete channel.Amount - assert.throws( - () => validatePaymentChannelFund(channel), - ValidationError, - 'PaymentChannelFund: missing field Amount', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelFund: missing field Amount', - ) + assertInvalid(channel, 'PaymentChannelFund: missing field Amount') }) it(`throws w/ missing Channel`, function () { delete channel.Channel - assert.throws( - () => validatePaymentChannelFund(channel), - ValidationError, - 'PaymentChannelFund: missing field Channel', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelFund: missing field Channel', - ) + assertInvalid(channel, 'PaymentChannelFund: missing field Channel') }) it(`throws w/ invalid Amount`, function () { channel.Amount = 100 - assert.throws( - () => validatePaymentChannelFund(channel), - ValidationError, - 'PaymentChannelFund: invalid field Amount', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelFund: invalid field Amount', - ) + assertInvalid(channel, 'PaymentChannelFund: invalid field Amount') }) it(`throws w/ invalid Channel`, function () { channel.Channel = 1000 - assert.throws( - () => validatePaymentChannelFund(channel), - ValidationError, - 'PaymentChannelFund: invalid field Channel', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelFund: invalid field Channel', - ) + assertInvalid(channel, 'PaymentChannelFund: invalid field Channel') }) it(`throws w/ invalid Expiration`, function () { channel.Expiration = 'abcd' - assert.throws( - () => validatePaymentChannelFund(channel), - ValidationError, - 'PaymentChannelFund: invalid field Expiration', - ) - assert.throws( - () => validate(channel), - ValidationError, - 'PaymentChannelFund: invalid field Expiration', - ) + assertInvalid(channel, 'PaymentChannelFund: invalid field Expiration') }) }) diff --git a/packages/xrpl/test/models/permissionedDomainDelete.test.ts b/packages/xrpl/test/models/permissionedDomainDelete.test.ts index 801a8817bb..269f873dd9 100644 --- a/packages/xrpl/test/models/permissionedDomainDelete.test.ts +++ b/packages/xrpl/test/models/permissionedDomainDelete.test.ts @@ -1,7 +1,10 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validatePermissionedDomainDelete } from '../../src/models/transactions/permissionedDomainDelete' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validatePermissionedDomainDelete) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validatePermissionedDomainDelete, message) /** * PermissionedDomainDelete Transaction Verification Testing. @@ -9,7 +12,7 @@ import { validatePermissionedDomainDelete } from '../../src/models/transactions/ * Providing runtime verification testing for each specific transaction type. */ describe('PermissionedDomainDelete', function () { - let tx + let tx: any beforeEach(function () { tx = { @@ -21,29 +24,18 @@ describe('PermissionedDomainDelete', function () { }) it('verifies valid PermissionedDomainDelete', function () { - assert.doesNotThrow(() => validatePermissionedDomainDelete(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it(`throws w/ missing field DomainID`, function () { delete tx.DomainID const errorMessage = 'PermissionedDomainDelete: missing field DomainID' - assert.throws( - () => validatePermissionedDomainDelete(tx), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ invalid DomainID`, function () { tx.DomainID = 1234 const errorMessage = 'PermissionedDomainDelete: invalid field DomainID' - assert.throws( - () => validatePermissionedDomainDelete(tx), - ValidationError, - errorMessage, - ) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) }) diff --git a/packages/xrpl/test/models/permissionedDomainSet.test.ts b/packages/xrpl/test/models/permissionedDomainSet.test.ts index 7d51faa9e4..c4df71c995 100644 --- a/packages/xrpl/test/models/permissionedDomainSet.test.ts +++ b/packages/xrpl/test/models/permissionedDomainSet.test.ts @@ -1,7 +1,13 @@ import { stringToHex } from '@xrplf/isomorphic/dist/utils' -import { assert } from 'chai' -import { AuthorizeCredential, validate, ValidationError } from '../../src' +import { AuthorizeCredential } from '../../src' +import { validatePermissionedDomainSet } from '../../src/models/transactions/permissionedDomainSet' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validatePermissionedDomainSet) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validatePermissionedDomainSet, message) /** * PermissionedDomainSet Transaction Verification Testing. @@ -9,7 +15,7 @@ import { AuthorizeCredential, validate, ValidationError } from '../../src' * Providing runtime verification testing for each specific transaction type. */ describe('PermissionedDomainSet', function () { - let tx + let tx: any const sampleCredential: AuthorizeCredential = { Credential: { CredentialType: stringToHex('Passport'), @@ -24,69 +30,62 @@ describe('PermissionedDomainSet', function () { DomainID: 'D88930B33C2B6831660BFD006D91FF100011AD4E67CBB78B460AF0A215103737', AcceptedCredentials: [sampleCredential], - } as any + } }) it('verifies valid PermissionedDomainSet', function () { - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) it(`throws with invalid field DomainID`, function () { // DomainID is expected to be a string tx.DomainID = 1234 const errorMessage = 'PermissionedDomainSet: invalid field DomainID' - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it(`throws w/ missing field AcceptedCredentials`, function () { delete tx.AcceptedCredentials const errorMessage = 'PermissionedDomainSet: missing field AcceptedCredentials' - assert.throws(() => validate(tx), ValidationError, errorMessage) + assertInvalid(tx, errorMessage) }) it('throws when AcceptedCredentials exceeds maximum length', function () { tx.AcceptedCredentials = Array(11).fill(sampleCredential) - assert.throws( - () => validate(tx), - ValidationError, + + assertInvalid( + tx, 'PermissionedDomainSet: Credentials length cannot exceed 10 elements', ) }) it('throws when AcceptedCredentials is empty', function () { tx.AcceptedCredentials = [] - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'PermissionedDomainSet: Credentials cannot be an empty array', ) }) it('throws when AcceptedCredentials is not an array type', function () { tx.AcceptedCredentials = 'AcceptedCredentials is not an array' - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'PermissionedDomainSet: invalid field AcceptedCredentials', ) }) it('throws when AcceptedCredentials contains duplicates', function () { tx.AcceptedCredentials = [sampleCredential, sampleCredential] - assert.throws( - () => validate(tx), - ValidationError, + assertInvalid( + tx, 'PermissionedDomainSet: Credentials cannot contain duplicate elements', ) }) it('throws when AcceptedCredentials contains invalid format', function () { tx.AcceptedCredentials = [{ Field1: 'Value1', Field2: 'Value2' }] - assert.throws( - () => validate(tx), - ValidationError, - 'PermissionedDomainSet: Invalid Credentials format', - ) + assertInvalid(tx, 'PermissionedDomainSet: Invalid Credentials format') }) }) diff --git a/packages/xrpl/test/models/setRegularKey.test.ts b/packages/xrpl/test/models/setRegularKey.test.ts index a410dd7bc1..2d4a668ebb 100644 --- a/packages/xrpl/test/models/setRegularKey.test.ts +++ b/packages/xrpl/test/models/setRegularKey.test.ts @@ -1,7 +1,10 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateSetRegularKey } from '../../src/models/transactions/setRegularKey' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateSetRegularKey) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateSetRegularKey, message) /** * SetRegularKey Transaction Verification Testing. @@ -9,7 +12,7 @@ import { validateSetRegularKey } from '../../src/models/transactions/setRegularK * Providing runtime verification testing for each specific transaction type. */ describe('SetRegularKey', function () { - let account + let account: any beforeEach(function () { account = { @@ -22,28 +25,17 @@ describe('SetRegularKey', function () { }) it(`verifies valid SetRegularKey`, function () { - assert.doesNotThrow(() => validateSetRegularKey(account)) - assert.doesNotThrow(() => validate(account)) + assertValid(account) }) it(`verifies w/o SetRegularKey`, function () { account.RegularKey = undefined - assert.doesNotThrow(() => validateSetRegularKey(account)) - assert.doesNotThrow(() => validate(account)) + assertValid(account) }) it(`throws w/ invalid RegularKey`, function () { account.RegularKey = 12369846963 - assert.throws( - () => validateSetRegularKey(account), - ValidationError, - 'SetRegularKey: invalid field RegularKey', - ) - assert.throws( - () => validate(account), - ValidationError, - 'SetRegularKey: invalid field RegularKey', - ) + assertInvalid(account, 'SetRegularKey: invalid field RegularKey') }) }) diff --git a/packages/xrpl/test/models/signerListSet.test.ts b/packages/xrpl/test/models/signerListSet.test.ts index 7fad927628..cb159cee99 100644 --- a/packages/xrpl/test/models/signerListSet.test.ts +++ b/packages/xrpl/test/models/signerListSet.test.ts @@ -1,7 +1,10 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateSignerListSet } from '../../src/models/transactions/signerListSet' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateSignerListSet) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateSignerListSet, message) /** * SignerListSet Transaction Verification Testing. @@ -9,7 +12,7 @@ import { validateSignerListSet } from '../../src/models/transactions/signerListS * Providing runtime verification testing for each specific transaction type. */ describe('SignerListSet', function () { - let signerListSetTx + let signerListSetTx: any beforeEach(function () { signerListSetTx = { @@ -42,36 +45,20 @@ describe('SignerListSet', function () { }) it(`verifies valid SignerListSet`, function () { - assert.doesNotThrow(() => validateSignerListSet(signerListSetTx)) - assert.doesNotThrow(() => validate(signerListSetTx)) + assertValid(signerListSetTx) }) it(`throws w/ missing SignerQuorum`, function () { signerListSetTx.SignerQuorum = undefined - assert.throws( - () => validateSignerListSet(signerListSetTx), - ValidationError, - 'SignerListSet: missing field SignerQuorum', - ) - assert.throws( - () => validate(signerListSetTx), - ValidationError, - 'SignerListSet: missing field SignerQuorum', - ) + assertInvalid(signerListSetTx, 'SignerListSet: missing field SignerQuorum') }) it(`throws w/ empty SignerEntries`, function () { signerListSetTx.SignerEntries = [] - assert.throws( - () => validateSignerListSet(signerListSetTx), - ValidationError, - 'SignerListSet: need at least 1 member in SignerEntries', - ) - assert.throws( - () => validate(signerListSetTx), - ValidationError, + assertInvalid( + signerListSetTx, 'SignerListSet: need at least 1 member in SignerEntries', ) }) @@ -79,16 +66,7 @@ describe('SignerListSet', function () { it(`throws w/ invalid SignerEntries`, function () { signerListSetTx.SignerEntries = 'khgfgyhujk' - assert.throws( - () => validateSignerListSet(signerListSetTx), - ValidationError, - 'SignerListSet: invalid field SignerEntries', - ) - assert.throws( - () => validate(signerListSetTx), - ValidationError, - 'SignerListSet: invalid field SignerEntries', - ) + assertInvalid(signerListSetTx, 'SignerListSet: invalid field SignerEntries') }) it(`throws w/ maximum of 32 members allowed in SignerEntries`, function () { @@ -179,8 +157,7 @@ describe('SignerListSet', function () { }, ] - assert.doesNotThrow(() => validateSignerListSet(signerListSetTx)) - assert.doesNotThrow(() => validate(signerListSetTx)) + assertValid(signerListSetTx) }) it(`throws w/ invalid WalletLocator in SignerEntries`, function () { diff --git a/packages/xrpl/test/models/ticketCreate.test.ts b/packages/xrpl/test/models/ticketCreate.test.ts index d462a3a0c6..d0e92302dd 100644 --- a/packages/xrpl/test/models/ticketCreate.test.ts +++ b/packages/xrpl/test/models/ticketCreate.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateTicketCreate } from '../../src/models/transactions/ticketCreate' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateTicketCreate) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateTicketCreate, message) /** * TicketCreate Transaction Verification Testing. @@ -9,87 +11,50 @@ import { validateTicketCreate } from '../../src/models/transactions/ticketCreate * Providing runtime verification testing for each specific transaction type. */ describe('TicketCreate', function () { - let ticketCreate + let ticketCreate: any beforeEach(function () { ticketCreate = { TransactionType: 'TicketCreate', Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo', TicketCount: 150, - } as any + } }) it('verifies valid TicketCreate', function () { - assert.doesNotThrow(() => validateTicketCreate(ticketCreate)) - assert.doesNotThrow(() => validate(ticketCreate)) + assertValid(ticketCreate) }) it('throws when TicketCount is missing', function () { delete ticketCreate.TicketCount - assert.throws( - () => validateTicketCreate(ticketCreate), - ValidationError, - 'TicketCreate: missing field TicketCount', - ) - assert.throws( - () => validate(ticketCreate), - ValidationError, - 'TicketCreate: missing field TicketCount', - ) + assertInvalid(ticketCreate, 'TicketCreate: missing field TicketCount') }) it('throws when TicketCount is not a number', function () { ticketCreate.TicketCount = 'abcd' - assert.throws( - () => validateTicketCreate(ticketCreate), - ValidationError, - 'TicketCreate: invalid field TicketCount', - ) - assert.throws( - () => validate(ticketCreate), - ValidationError, - 'TicketCreate: invalid field TicketCount', - ) + assertInvalid(ticketCreate, 'TicketCreate: invalid field TicketCount') }) it('throws when TicketCount is not an integer', function () { ticketCreate.TicketCount = 12.5 - assert.throws( - () => validateTicketCreate(ticketCreate), - ValidationError, - 'TicketCreate: TicketCount must be an integer from 1 to 250', - ) - assert.throws( - () => validate(ticketCreate), - ValidationError, + assertInvalid( + ticketCreate, 'TicketCreate: TicketCount must be an integer from 1 to 250', ) }) it('throws when TicketCount is < 1', function () { ticketCreate.TicketCount = 0 - assert.throws( - () => validateTicketCreate(ticketCreate), - ValidationError, - 'TicketCreate: TicketCount must be an integer from 1 to 250', - ) - assert.throws( - () => validate(ticketCreate), - ValidationError, + assertInvalid( + ticketCreate, 'TicketCreate: TicketCount must be an integer from 1 to 250', ) }) it('throws when TicketCount is > 250', function () { ticketCreate.TicketCount = 251 - assert.throws( - () => validateTicketCreate(ticketCreate), - ValidationError, - 'TicketCreate: TicketCount must be an integer from 1 to 250', - ) - assert.throws( - () => validate(ticketCreate), - ValidationError, + assertInvalid( + ticketCreate, 'TicketCreate: TicketCount must be an integer from 1 to 250', ) }) diff --git a/packages/xrpl/test/models/trustSet.test.ts b/packages/xrpl/test/models/trustSet.test.ts index fea1f39ace..031c894ebf 100644 --- a/packages/xrpl/test/models/trustSet.test.ts +++ b/packages/xrpl/test/models/trustSet.test.ts @@ -1,7 +1,9 @@ -import { assert } from 'chai' - -import { validate, ValidationError } from '../../src' import { validateTrustSet } from '../../src/models/transactions/trustSet' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateTrustSet) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateTrustSet, message) /** * TrustSet Transaction Verification Testing. @@ -9,7 +11,7 @@ import { validateTrustSet } from '../../src/models/transactions/trustSet' * Providing runtime verification testing for each specific transaction type. */ describe('TrustSet', function () { - let trustSet + let trustSet: any beforeEach(function () { trustSet = { @@ -27,67 +29,30 @@ describe('TrustSet', function () { tfSetFreeze: true, tfSetDeepFreeze: true, }, - } as any + } }) it('verifies valid TrustSet', function () { - assert.doesNotThrow(() => validateTrustSet(trustSet)) - assert.doesNotThrow(() => validate(trustSet)) + assertValid(trustSet) }) it('throws when LimitAmount is missing', function () { delete trustSet.LimitAmount - assert.throws( - () => validateTrustSet(trustSet), - ValidationError, - 'TrustSet: missing field LimitAmount', - ) - assert.throws( - () => validate(trustSet), - ValidationError, - 'TrustSet: missing field LimitAmount', - ) + assertInvalid(trustSet, 'TrustSet: missing field LimitAmount') }) it('throws when LimitAmount is invalid', function () { trustSet.LimitAmount = 1234 - assert.throws( - () => validateTrustSet(trustSet), - ValidationError, - 'TrustSet: invalid field LimitAmount', - ) - assert.throws( - () => validate(trustSet), - ValidationError, - 'TrustSet: invalid field LimitAmount', - ) + assertInvalid(trustSet, 'TrustSet: invalid field LimitAmount') }) it('throws when QualityIn is not a number', function () { trustSet.QualityIn = 'abcd' - assert.throws( - () => validateTrustSet(trustSet), - ValidationError, - 'TrustSet: invalid field QualityIn', - ) - assert.throws( - () => validate(trustSet), - ValidationError, - 'TrustSet: invalid field QualityIn', - ) + assertInvalid(trustSet, 'TrustSet: invalid field QualityIn') }) it('throws when QualityOut is not a number', function () { trustSet.QualityOut = 'dcba' - assert.throws( - () => validateTrustSet(trustSet), - ValidationError, - 'TrustSet: invalid field QualityOut', - ) - assert.throws( - () => validate(trustSet), - ValidationError, - 'TrustSet: invalid field QualityOut', - ) + assertInvalid(trustSet, 'TrustSet: invalid field QualityOut') }) }) diff --git a/packages/xrpl/test/testUtils.ts b/packages/xrpl/test/testUtils.ts index ee922a63e4..654fbfe3cf 100644 --- a/packages/xrpl/test/testUtils.ts +++ b/packages/xrpl/test/testUtils.ts @@ -5,7 +5,12 @@ import net from 'net' import { assert } from 'chai' import omit from 'lodash/omit' -import { rippleTimeToUnixTime, unixTimeToRippleTime } from '../src' +import { + rippleTimeToUnixTime, + unixTimeToRippleTime, + validate, + ValidationError, +} from '../src' import addresses from './fixtures/addresses.json' @@ -52,6 +57,33 @@ export function assertResultMatch( ) } +/** + * Check that a transaction error validation fails properly. + * + * @param tx The transaction that should fail validation. + * @param validateTx The transaction-specific validation function (e.g. `validatePayment`). + */ +export function assertTxIsValid(tx: any, validateTx: (tx: any) => void): void { + assert.doesNotThrow(() => validateTx(tx)) + assert.doesNotThrow(() => validate(tx)) +} + +/** + * Check that a transaction error validation fails properly. + * + * @param tx The transaction that should fail validation. + * @param validateTx The transaction-specific validation function (e.g. `validatePayment`). + * @param errorMessage The error message that should be included in the error. + */ +export function assertTxValidationError( + tx: any, + validateTx: (tx: any) => void, + errorMessage: string, +): void { + assert.throws(() => validateTx(tx), ValidationError, errorMessage) + assert.throws(() => validate(tx), ValidationError, errorMessage) +} + /** * Check that the promise rejects with an expected error. * From 5ff418fc14f43b437c89227240f2072521715d3d Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 12 Feb 2025 18:27:12 -0500 Subject: [PATCH 09/46] fix tests --- .../transactions/MPTokenIssuanceCreate.ts | 4 +- .../models/transactions/MPTokenIssuanceSet.ts | 2 +- .../models/transactions/NFTokenCreateOffer.ts | 13 +- .../xrpl/src/models/transactions/common.ts | 6 + packages/xrpl/src/models/utils/index.ts | 16 +- .../xrpl/test/models/CredentialAccept.test.ts | 88 +---------- .../xrpl/test/models/CredentialCreate.test.ts | 143 ++---------------- .../xrpl/test/models/CredentialDelete.test.ts | 99 ++---------- .../xrpl/test/models/MPTokenAuthorize.test.ts | 2 +- .../test/models/MPTokenIssuanceCreate.test.ts | 5 +- .../models/MPTokenIssuanceDestroy.test.ts | 10 +- .../test/models/MPTokenIssuanceSet.test.ts | 13 +- .../test/models/NFTokenAcceptOffer.test.ts | 16 +- packages/xrpl/test/models/NFTokenBurn.test.ts | 9 +- .../test/models/NFTokenCancelOffer.test.ts | 10 +- .../test/models/NFTokenCreateOffer.test.ts | 13 +- packages/xrpl/test/models/NFTokenMint.test.ts | 2 +- .../xrpl/test/models/NFTokenModify.test.ts | 10 +- .../xrpl/test/models/baseTransaction.test.ts | 2 +- packages/xrpl/test/models/clawback.test.ts | 5 +- packages/xrpl/test/models/offerCreate.test.ts | 6 +- .../xrpl/test/models/signerListSet.test.ts | 22 +-- 22 files changed, 139 insertions(+), 357 deletions(-) diff --git a/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts b/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts index 6566e4ce05..76d37ddee3 100644 --- a/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts +++ b/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts @@ -157,7 +157,9 @@ export function validateMPTokenIssuanceCreate( if (typeof tx.TransferFee === 'number') { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Not necessary - const flags = tx.Flags as number | MPTokenIssuanceCreateFlagsInterface + const flags = (tx.Flags ?? 0) as + | number + | MPTokenIssuanceCreateFlagsInterface const isTfMPTCanTransfer = typeof flags === 'number' ? isFlagEnabled(flags, MPTokenIssuanceCreateFlags.tfMPTCanTransfer) diff --git a/packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts b/packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts index 7e1c723382..da1b1d2aec 100644 --- a/packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts +++ b/packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts @@ -69,7 +69,7 @@ export function validateMPTokenIssuanceSet(tx: Record): void { validateOptionalField(tx, 'Holder', isAccount) // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Not necessary - const flags = tx.Flags as number | MPTokenIssuanceSetFlagsInterface + const flags = (tx.Flags ?? 0) as number | MPTokenIssuanceSetFlagsInterface const isTfMPTLock = typeof flags === 'number' ? isFlagEnabled(flags, MPTokenIssuanceSetFlags.tfMPTLock) diff --git a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts index 040a1675c2..3b1c0fe5d0 100644 --- a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts +++ b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts @@ -144,10 +144,15 @@ export function validateNFTokenCreateOffer(tx: Record): void { validateOptionalField(tx, 'Expiration', isNumber) validateOptionalField(tx, 'Destination', isAccount) - if ( - typeof tx.Flags === 'number' && - isFlagEnabled(tx.Flags, NFTokenCreateOfferFlags.tfSellNFToken) - ) { + let isSellOffer = false + if (typeof tx.Flags === 'number') { + isSellOffer = isFlagEnabled(tx.Flags, NFTokenCreateOfferFlags.tfSellNFToken) + } else if (typeof tx.Flags === 'object') { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Needed here + isSellOffer = (tx.Flags as Record).tfSellNFToken === true + } + + if (isSellOffer) { validateNFTokenSellOfferCases(tx) } else { validateNFTokenBuyOfferCases(tx) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 034616fdb4..be8dca0791 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -370,6 +370,12 @@ export function validateBaseTransaction(common: Record): void { validateOptionalField(common, 'LastLedgerSequence', isNumber) + validateOptionalField( + common, + 'Flags', + (inp) => isNumber(inp) || typeof inp === 'object', + ) + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS const memos = common.Memos as Array<{ Memo?: unknown }> | undefined if (memos !== undefined && !memos.every(isMemo)) { diff --git a/packages/xrpl/src/models/utils/index.ts b/packages/xrpl/src/models/utils/index.ts index 54029bbd3c..a17e948aef 100644 --- a/packages/xrpl/src/models/utils/index.ts +++ b/packages/xrpl/src/models/utils/index.ts @@ -18,13 +18,19 @@ export function onlyHasFields( /** * Perform bitwise AND (&) to check if a flag is enabled within Flags (as a number). * - * @param Flags - A number that represents flags enabled. - * @param checkFlag - A specific flag to check if it's enabled within Flags. - * @returns True if checkFlag is enabled within Flags. + * @param flags - A number that represents flags enabled. + * @param checkFlag - A specific flag to check if it's enabled within flags. + * @returns True if checkFlag is enabled within flags. */ -export function isFlagEnabled(Flags: number, checkFlag: number): boolean { +export function isFlagEnabled( + flags: number | object, + checkFlag: number, +): boolean { + if (typeof flags === 'object') { + return false + } // eslint-disable-next-line no-bitwise -- flags need bitwise - return (BigInt(checkFlag) & BigInt(Flags)) === BigInt(checkFlag) + return (BigInt(checkFlag) & BigInt(flags)) === BigInt(checkFlag) } /** diff --git a/packages/xrpl/test/models/CredentialAccept.test.ts b/packages/xrpl/test/models/CredentialAccept.test.ts index 27f8ca2859..df49f3aac0 100644 --- a/packages/xrpl/test/models/CredentialAccept.test.ts +++ b/packages/xrpl/test/models/CredentialAccept.test.ts @@ -34,123 +34,51 @@ describe('CredentialAccept', function () { it(`throws w/ missing field Account`, function () { credentialAccept.Account = undefined const errorMessage = 'CredentialAccept: missing field Account' - assert.throws( - () => validateCredentialAccept(credentialAccept), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialAccept), - ValidationError, - errorMessage, - ) + assertInvalid(credentialAccept, errorMessage) }) it(`throws w/ Account not a string`, function () { credentialAccept.Account = 123 const errorMessage = 'CredentialAccept: invalid field Account' - assert.throws( - () => validateCredentialAccept(credentialAccept), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialAccept), - ValidationError, - errorMessage, - ) + assertInvalid(credentialAccept, errorMessage) }) it(`throws w/ missing field Issuer`, function () { credentialAccept.Issuer = undefined const errorMessage = 'CredentialAccept: missing field Issuer' - assert.throws( - () => validateCredentialAccept(credentialAccept), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialAccept), - ValidationError, - errorMessage, - ) + assertInvalid(credentialAccept, errorMessage) }) it(`throws w/ Issuer not a string`, function () { credentialAccept.Issuer = 123 const errorMessage = 'CredentialAccept: invalid field Issuer' - assert.throws( - () => validateCredentialAccept(credentialAccept), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialAccept), - ValidationError, - errorMessage, - ) + assertInvalid(credentialAccept, errorMessage) }) it(`throws w/ missing field CredentialType`, function () { credentialAccept.CredentialType = undefined const errorMessage = 'CredentialAccept: missing field CredentialType' - assert.throws( - () => validateCredentialAccept(credentialAccept), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialAccept), - ValidationError, - errorMessage, - ) + assertInvalid(credentialAccept, errorMessage) }) it(`throws w/ credentialType field too long`, function () { credentialAccept.CredentialType = stringToHex('A'.repeat(129)) const errorMessage = 'CredentialAccept: CredentialType length cannot be > 128' - assert.throws( - () => validateCredentialAccept(credentialAccept), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialAccept), - ValidationError, - errorMessage, - ) + assertInvalid(credentialAccept, errorMessage) }) it(`throws w/ credentialType field empty`, function () { credentialAccept.CredentialType = '' const errorMessage = 'CredentialAccept: CredentialType cannot be an empty string' - assert.throws( - () => validateCredentialAccept(credentialAccept), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialAccept), - ValidationError, - errorMessage, - ) + assertInvalid(credentialAccept, errorMessage) }) it(`throws w/ credentialType field not hex`, function () { credentialAccept.CredentialType = 'this is not hex' const errorMessage = 'CredentialAccept: CredentialType must be encoded in hex' - assert.throws( - () => validateCredentialAccept(credentialAccept), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialAccept), - ValidationError, - errorMessage, - ) + assertInvalid(credentialAccept, errorMessage) }) }) diff --git a/packages/xrpl/test/models/CredentialCreate.test.ts b/packages/xrpl/test/models/CredentialCreate.test.ts index 277bf717d5..d43f86b380 100644 --- a/packages/xrpl/test/models/CredentialCreate.test.ts +++ b/packages/xrpl/test/models/CredentialCreate.test.ts @@ -36,198 +36,81 @@ describe('credentialCreate', function () { it(`throws w/ missing field Account`, function () { credentialCreate.Account = undefined const errorMessage = 'CredentialCreate: missing field Account' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ Account not string`, function () { credentialCreate.Account = 123 const errorMessage = 'CredentialCreate: invalid field Account' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ missing field Subject`, function () { credentialCreate.Subject = undefined const errorMessage = 'CredentialCreate: missing field Subject' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ Subject not string`, function () { credentialCreate.Subject = 123 const errorMessage = 'CredentialCreate: invalid field Subject' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ missing field credentialType`, function () { credentialCreate.CredentialType = undefined const errorMessage = 'CredentialCreate: missing field CredentialType' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ credentialType field too long`, function () { credentialCreate.CredentialType = stringToHex('A'.repeat(129)) const errorMessage = 'CredentialCreate: CredentialType length cannot be > 128' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ credentialType field empty`, function () { credentialCreate.CredentialType = '' const errorMessage = 'CredentialCreate: CredentialType cannot be an empty string' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ credentialType field not hex`, function () { credentialCreate.CredentialType = 'this is not hex' const errorMessage = 'CredentialCreate: CredentialType must be encoded in hex' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ Expiration field not number`, function () { credentialCreate.Expiration = 'this is not a number' const errorMessage = 'CredentialCreate: invalid field Expiration' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ URI field not a string`, function () { credentialCreate.URI = 123 const errorMessage = 'CredentialCreate: invalid field URI' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ URI field empty`, function () { credentialCreate.URI = '' const errorMessage = 'CredentialCreate: URI cannot be an empty string' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ URI field too long`, function () { credentialCreate.URI = stringToHex('A'.repeat(129)) const errorMessage = 'CredentialCreate: URI length must be <= 256' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ URI field not hex`, function () { credentialCreate.URI = 'this is not hex' const errorMessage = 'CredentialCreate: URI must be encoded in hex' - assert.throws( - () => validateCredentialCreate(credentialCreate), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialCreate), - ValidationError, - errorMessage, - ) + assertInvalid(credentialCreate, errorMessage) }) }) diff --git a/packages/xrpl/test/models/CredentialDelete.test.ts b/packages/xrpl/test/models/CredentialDelete.test.ts index 838dfa2f02..6397652a94 100644 --- a/packages/xrpl/test/models/CredentialDelete.test.ts +++ b/packages/xrpl/test/models/CredentialDelete.test.ts @@ -35,61 +35,25 @@ describe('CredentialDelete', function () { it(`throws w/ missing field Account`, function () { credentialDelete.Account = undefined const errorMessage = 'CredentialDelete: missing field Account' - assert.throws( - () => validateCredentialDelete(credentialDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialDelete), - ValidationError, - errorMessage, - ) + assertInvalid(credentialDelete, errorMessage) }) it(`throws w/ Account not string`, function () { credentialDelete.Account = 123 const errorMessage = 'CredentialDelete: invalid field Account' - assert.throws( - () => validateCredentialDelete(credentialDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialDelete), - ValidationError, - errorMessage, - ) + assertInvalid(credentialDelete, errorMessage) }) it(`throws w/ Subject not string`, function () { credentialDelete.Subject = 123 const errorMessage = 'CredentialDelete: invalid field Subject' - assert.throws( - () => validateCredentialDelete(credentialDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialDelete), - ValidationError, - errorMessage, - ) + assertInvalid(credentialDelete, errorMessage) }) it(`throws w/ Issuer not string`, function () { credentialDelete.Issuer = 123 const errorMessage = 'CredentialDelete: invalid field Issuer' - assert.throws( - () => validateCredentialDelete(credentialDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialDelete), - ValidationError, - errorMessage, - ) + assertInvalid(credentialDelete, errorMessage) }) it(`throws w/ missing field Subject and Issuer`, function () { @@ -97,78 +61,33 @@ describe('CredentialDelete', function () { credentialDelete.Issuer = undefined const errorMessage = 'CredentialDelete: either `Issuer` or `Subject` must be provided' - assert.throws( - () => validateCredentialDelete(credentialDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialDelete), - ValidationError, - errorMessage, - ) + assertInvalid(credentialDelete, errorMessage) }) it(`throws w/ missing field credentialType`, function () { credentialDelete.CredentialType = undefined const errorMessage = 'CredentialDelete: missing field CredentialType' - assert.throws( - () => validateCredentialDelete(credentialDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialDelete), - ValidationError, - errorMessage, - ) + assertInvalid(credentialDelete, errorMessage) }) it(`throws w/ credentialType field too long`, function () { credentialDelete.CredentialType = stringToHex('A'.repeat(129)) const errorMessage = 'CredentialDelete: CredentialType length cannot be > 128' - assert.throws( - () => validateCredentialDelete(credentialDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialDelete), - ValidationError, - errorMessage, - ) + assertInvalid(credentialDelete, errorMessage) }) it(`throws w/ credentialType field empty`, function () { credentialDelete.CredentialType = '' const errorMessage = 'CredentialDelete: CredentialType cannot be an empty string' - assert.throws( - () => validateCredentialDelete(credentialDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialDelete), - ValidationError, - errorMessage, - ) + assertInvalid(credentialDelete, errorMessage) }) it(`throws w/ credentialType field not hex`, function () { credentialDelete.CredentialType = 'this is not hex' const errorMessage = 'CredentialDelete: CredentialType must be encoded in hex' - assert.throws( - () => validateCredentialDelete(credentialDelete), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(credentialDelete), - ValidationError, - errorMessage, - ) + assertInvalid(credentialDelete, errorMessage) }) }) diff --git a/packages/xrpl/test/models/MPTokenAuthorize.test.ts b/packages/xrpl/test/models/MPTokenAuthorize.test.ts index debe77aa75..c722128b65 100644 --- a/packages/xrpl/test/models/MPTokenAuthorize.test.ts +++ b/packages/xrpl/test/models/MPTokenAuthorize.test.ts @@ -1,5 +1,5 @@ import { MPTokenAuthorizeFlags } from '../../src' -import { validateMPTokenAuthorize } from '../../src/models/transactions/mptokenAuthorize' +import { validateMPTokenAuthorize } from '../../src/models/transactions/MPTokenAuthorize' import { assertTxIsValid, assertTxValidationError } from '../testUtils' const assertValid = (tx: any): void => diff --git a/packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts b/packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts index 21a1f40de3..b0f34737b5 100644 --- a/packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts +++ b/packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts @@ -1,12 +1,13 @@ import { stringToHex } from '@xrplf/isomorphic/src/utils' import { MPTokenIssuanceCreateFlags } from '../../src' +import { validateMPTokenIssuanceCreate } from '../../src/models/transactions/MPTokenIssuanceCreate' import { assertTxIsValid, assertTxValidationError } from '../testUtils' const assertValid = (tx: any): void => - assertTxIsValid(tx, validatePermissionedDomainSet) + assertTxIsValid(tx, validateMPTokenIssuanceCreate) const assertInvalid = (tx: any, message: string): void => - assertTxValidationError(tx, validatePermissionedDomainSet, message) + assertTxValidationError(tx, validateMPTokenIssuanceCreate, message) /** * MPTokenIssuanceCreate Transaction Verification Testing. diff --git a/packages/xrpl/test/models/MPTokenIssuanceDestroy.test.ts b/packages/xrpl/test/models/MPTokenIssuanceDestroy.test.ts index a9cc03533b..2fbc858738 100644 --- a/packages/xrpl/test/models/MPTokenIssuanceDestroy.test.ts +++ b/packages/xrpl/test/models/MPTokenIssuanceDestroy.test.ts @@ -1,3 +1,11 @@ +import { validateMPTokenIssuanceDestroy } from '../../src/models/transactions/MPTokenIssuanceDestroy' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateMPTokenIssuanceDestroy) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateMPTokenIssuanceDestroy, message) + const TOKEN_ID = '000004C463C52827307480341125DA0577DEFC38405B0E3E' /** @@ -13,7 +21,7 @@ describe('MPTokenIssuanceDestroy', function () { MPTokenIssuanceID: TOKEN_ID, } as any - assert.doesNotThrow(() => validate(validMPTokenIssuanceDestroy)) + assertValid(validMPTokenIssuanceDestroy) }) it(`throws w/ missing MPTokenIssuanceID`, function () { diff --git a/packages/xrpl/test/models/MPTokenIssuanceSet.test.ts b/packages/xrpl/test/models/MPTokenIssuanceSet.test.ts index 08f2755478..2a05f2a71a 100644 --- a/packages/xrpl/test/models/MPTokenIssuanceSet.test.ts +++ b/packages/xrpl/test/models/MPTokenIssuanceSet.test.ts @@ -1,4 +1,11 @@ import { MPTokenIssuanceSetFlags } from '../../src' +import { validateMPTokenIssuanceSet } from '../../src/models/transactions/MPTokenIssuanceSet' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateMPTokenIssuanceSet) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateMPTokenIssuanceSet, message) const TOKEN_ID = '000004C463C52827307480341125DA0577DEFC38405B0E3E' @@ -16,7 +23,7 @@ describe('MPTokenIssuanceSet', function () { Flags: MPTokenIssuanceSetFlags.tfMPTLock, } as any - assert.doesNotThrow(() => validate(validMPTokenIssuanceSet)) + assertValid(validMPTokenIssuanceSet) validMPTokenIssuanceSet = { TransactionType: 'MPTokenIssuanceSet', @@ -26,7 +33,7 @@ describe('MPTokenIssuanceSet', function () { Flags: MPTokenIssuanceSetFlags.tfMPTLock, } as any - assert.doesNotThrow(() => validate(validMPTokenIssuanceSet)) + assertValid(validMPTokenIssuanceSet) // It's fine to not specify any flag, it means only tx fee is deducted validMPTokenIssuanceSet = { @@ -36,7 +43,7 @@ describe('MPTokenIssuanceSet', function () { Holder: 'rajgkBmMxmz161r8bWYH7CQAFZP5bA9oSG', } as any - assert.doesNotThrow(() => validate(validMPTokenIssuanceSet)) + assertValid(validMPTokenIssuanceSet) }) it(`throws w/ missing MPTokenIssuanceID`, function () { diff --git a/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts b/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts index 30f51909ad..edf7da7ecd 100644 --- a/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts +++ b/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts @@ -1,3 +1,11 @@ +import { validateNFTokenAcceptOffer } from '../../src/models/transactions/NFTokenAcceptOffer' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateNFTokenAcceptOffer) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateNFTokenAcceptOffer, message) + const NFTOKEN_BUY_OFFER = 'AED08CC1F50DD5F23A1948AF86153A3F3B7593E5EC77D65A02BB1B29E05AB6AF' const NFTOKEN_SELL_OFFER = @@ -19,7 +27,7 @@ describe('NFTokenAcceptOffer', function () { Flags: 2147483648, } as any - assert.doesNotThrow(() => validate(validNFTokenAcceptOffer)) + assertValid(validNFTokenAcceptOffer) }) it(`verifies valid NFTokenAcceptOffer with NFTokenSellOffer`, function () { @@ -32,7 +40,7 @@ describe('NFTokenAcceptOffer', function () { Flags: 2147483648, } as any - assert.doesNotThrow(() => validate(validNFTokenAcceptOffer)) + assertValid(validNFTokenAcceptOffer) }) it(`throws w/ missing NFTokenSellOffer and NFTokenBuyOffer`, function () { @@ -95,7 +103,7 @@ describe('NFTokenAcceptOffer', function () { Flags: 2147483648, } as any - assert.doesNotThrow(() => validate(validNFTokenAcceptOffer)) + assertValid(validNFTokenAcceptOffer) }) it(`verifies valid NFTokenAcceptOffer with NFTokenBrokerFee`, function () { @@ -110,7 +118,7 @@ describe('NFTokenAcceptOffer', function () { Flags: 2147483648, } as any - assert.doesNotThrow(() => validate(validNFTokenAcceptOffer)) + assertValid(validNFTokenAcceptOffer) }) it(`throws w/ NFTokenBrokerFee === 0`, function () { diff --git a/packages/xrpl/test/models/NFTokenBurn.test.ts b/packages/xrpl/test/models/NFTokenBurn.test.ts index c73c86999f..33d56c26da 100644 --- a/packages/xrpl/test/models/NFTokenBurn.test.ts +++ b/packages/xrpl/test/models/NFTokenBurn.test.ts @@ -1,3 +1,10 @@ +import { validateNFTokenBurn } from '../../src/models/transactions/NFTokenBurn' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => assertTxIsValid(tx, validateNFTokenBurn) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateNFTokenBurn, message) + const TOKEN_ID = '00090032B5F762798A53D543A014CAF8B297CFF8F2F937E844B17C9E00000003' @@ -17,7 +24,7 @@ describe('NFTokenBurn', function () { Flags: 2147483648, } as any - assert.doesNotThrow(() => validate(validNFTokenBurn)) + assertValid(validNFTokenBurn) }) it(`throws w/ missing NFTokenID`, function () { diff --git a/packages/xrpl/test/models/NFTokenCancelOffer.test.ts b/packages/xrpl/test/models/NFTokenCancelOffer.test.ts index 63c23c5fb7..e488dcee20 100644 --- a/packages/xrpl/test/models/NFTokenCancelOffer.test.ts +++ b/packages/xrpl/test/models/NFTokenCancelOffer.test.ts @@ -1,3 +1,11 @@ +import { validateNFTokenCancelOffer } from '../../src/models/transactions/NFTokenCancelOffer' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateNFTokenCancelOffer) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateNFTokenCancelOffer, message) + const BUY_OFFER = 'AED08CC1F50DD5F23A1948AF86153A3F3B7593E5EC77D65A02BB1B29E05AB6AF' @@ -17,7 +25,7 @@ describe('NFTokenCancelOffer', function () { Flags: 2147483648, } as any - assert.doesNotThrow(() => validate(validNFTokenCancelOffer)) + assertValid(validNFTokenCancelOffer) }) it(`throws w/ missing NFTokenOffers`, function () { diff --git a/packages/xrpl/test/models/NFTokenCreateOffer.test.ts b/packages/xrpl/test/models/NFTokenCreateOffer.test.ts index 196f9283de..d4737f758e 100644 --- a/packages/xrpl/test/models/NFTokenCreateOffer.test.ts +++ b/packages/xrpl/test/models/NFTokenCreateOffer.test.ts @@ -1,4 +1,11 @@ import { NFTokenCreateOfferFlags } from '../../src' +import { validateNFTokenCreateOffer } from '../../src/models/transactions/NFTokenCreateOffer' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateNFTokenCreateOffer) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateNFTokenCreateOffer, message) const NFTOKEN_ID = '00090032B5F762798A53D543A014CAF8B297CFF8F2F937E844B17C9E00000003' @@ -22,7 +29,7 @@ describe('NFTokenCreateOffer', function () { Sequence: 2470665, } as any - assert.doesNotThrow(() => validate(validNFTokenCreateOffer)) + assertValid(validNFTokenCreateOffer) }) it(`verifies valid NFTokenCreateOffer sellside`, function () { @@ -40,7 +47,7 @@ describe('NFTokenCreateOffer', function () { Sequence: 2470665, } as any - assert.doesNotThrow(() => validate(validNFTokenCreateOffer)) + assertValid(validNFTokenCreateOffer) }) it(`verifies w/ 0 Amount NFTokenCreateOffer sellside`, function () { @@ -56,7 +63,7 @@ describe('NFTokenCreateOffer', function () { Sequence: 2470665, } as any - assert.doesNotThrow(() => validate(validNFTokenCreateOffer)) + assertValid(validNFTokenCreateOffer) }) it(`throws w/ Account === Owner`, function () { diff --git a/packages/xrpl/test/models/NFTokenMint.test.ts b/packages/xrpl/test/models/NFTokenMint.test.ts index f508479a2f..cecb63a8df 100644 --- a/packages/xrpl/test/models/NFTokenMint.test.ts +++ b/packages/xrpl/test/models/NFTokenMint.test.ts @@ -1,7 +1,7 @@ import { stringToHex } from '@xrplf/isomorphic/src/utils' import { NFTokenMintFlags } from '../../src' -import { validateNFTokenMint } from '../../src/models/transactions/nftokenMint' +import { validateNFTokenMint } from '../../src/models/transactions/NFTokenMint' import { assertTxIsValid, assertTxValidationError } from '../testUtils' const assertValid = (tx: any): void => assertTxIsValid(tx, validateNFTokenMint) diff --git a/packages/xrpl/test/models/NFTokenModify.test.ts b/packages/xrpl/test/models/NFTokenModify.test.ts index 624b61fe13..f139884f5e 100644 --- a/packages/xrpl/test/models/NFTokenModify.test.ts +++ b/packages/xrpl/test/models/NFTokenModify.test.ts @@ -1,5 +1,13 @@ import { stringToHex } from '@xrplf/isomorphic/src/utils' +import { validateNFTokenModify } from '../../src' +import { assertTxIsValid, assertTxValidationError } from '../testUtils' + +const assertValid = (tx: any): void => + assertTxIsValid(tx, validateNFTokenModify) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validateNFTokenModify, message) + const TOKEN_ID = '00090032B5F762798A53D543A014CAF8B297CFF8F2F937E844B17C9E00000003' @@ -19,7 +27,7 @@ describe('NFTokenModify', function () { URI: stringToHex('http://xrpl.org'), } as any - assert.doesNotThrow(() => validate(validNFTokenModify)) + assertValid(validNFTokenModify) }) it(`throws w/ missing NFTokenID`, function () { diff --git a/packages/xrpl/test/models/baseTransaction.test.ts b/packages/xrpl/test/models/baseTransaction.test.ts index d99c1942c3..13c640831c 100644 --- a/packages/xrpl/test/models/baseTransaction.test.ts +++ b/packages/xrpl/test/models/baseTransaction.test.ts @@ -1,7 +1,7 @@ import { assert } from 'chai' import { ValidationError } from '../../src' -import { validateBaseTransaction } from '../../src/models/transactions/BaseTransaction' +import { validateBaseTransaction } from '../../src/models/transactions/common' /** * Transaction Verification Testing. diff --git a/packages/xrpl/test/models/clawback.test.ts b/packages/xrpl/test/models/clawback.test.ts index d6393c22de..a078142721 100644 --- a/packages/xrpl/test/models/clawback.test.ts +++ b/packages/xrpl/test/models/clawback.test.ts @@ -22,8 +22,7 @@ describe('Clawback', function () { Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assert.doesNotThrow(() => validate(validClawback)) - assert.doesNotThrow(() => validateClawback(validClawback)) + assertValid(validClawback) }) it(`throws w/ missing Amount`, function () { @@ -78,7 +77,7 @@ describe('Clawback', function () { Holder: 'rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy', } as any - assert.doesNotThrow(() => validate(validClawback)) + assertValid(validClawback) }) it(`throws w/ invalid Holder Account`, function () { diff --git a/packages/xrpl/test/models/offerCreate.test.ts b/packages/xrpl/test/models/offerCreate.test.ts index 66c6ff81e4..d34ac46922 100644 --- a/packages/xrpl/test/models/offerCreate.test.ts +++ b/packages/xrpl/test/models/offerCreate.test.ts @@ -57,8 +57,7 @@ describe('OfferCreate', function () { '3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91', } as any - assert.doesNotThrow(() => validateOfferCreate(offer2)) - assert.doesNotThrow(() => validate(offer2)) + assertValid(offer2) const offer3 = { Account: 'r3rhWeE31Jt5sWmi4QiGLMZnY3ENgqw96W', @@ -83,8 +82,7 @@ describe('OfferCreate', function () { '3045022100D874CDDD6BB24ED66E83B1D3574D3ECAC753A78F26DB7EBA89EAB8E7D72B95F802207C8CCD6CEA64E4AE2014E59EE9654E02CA8F03FE7FCE0539E958EAE182234D91', } as any - assert.doesNotThrow(() => validateOfferCreate(offer3)) - assert.doesNotThrow(() => validate(offer3)) + assertValid(offer3) }) it(`throws w/ invalid Expiration`, function () { diff --git a/packages/xrpl/test/models/signerListSet.test.ts b/packages/xrpl/test/models/signerListSet.test.ts index cb159cee99..6d605d5291 100644 --- a/packages/xrpl/test/models/signerListSet.test.ts +++ b/packages/xrpl/test/models/signerListSet.test.ts @@ -118,16 +118,7 @@ describe('SignerListSet', function () { const errorMessage = 'SignerListSet: maximum of 32 members allowed in SignerEntries' - assert.throws( - () => validateSignerListSet(signerListSetTx), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(signerListSetTx), - ValidationError, - errorMessage, - ) + assertInvalid(signerListSetTx, errorMessage) }) it(`verifies valid WalletLocator in SignerEntries`, function () { @@ -179,15 +170,6 @@ describe('SignerListSet', function () { ] const errorMessage = 'SignerListSet: WalletLocator in SignerEntry must be a 256-bit (32-byte) hexadecimal value' - assert.throws( - () => validateSignerListSet(signerListSetTx), - ValidationError, - errorMessage, - ) - assert.throws( - () => validate(signerListSetTx), - ValidationError, - errorMessage, - ) + assertInvalid(signerListSetTx, errorMessage) }) }) From 2bcdf22ac8af903969cea09e6d04b069b26ecdf2 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 12 Feb 2025 18:36:15 -0500 Subject: [PATCH 10/46] clean up --- packages/ripple-binary-codec/src/types/st-array.ts | 1 + .../src/models/transactions/NFTokenCreateOffer.ts | 8 ++++---- packages/xrpl/src/models/transactions/common.ts | 11 ++++++++--- packages/xrpl/src/models/utils/index.ts | 8 +------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/ripple-binary-codec/src/types/st-array.ts b/packages/ripple-binary-codec/src/types/st-array.ts index c705d4d864..684a69ea03 100644 --- a/packages/ripple-binary-codec/src/types/st-array.ts +++ b/packages/ripple-binary-codec/src/types/st-array.ts @@ -17,6 +17,7 @@ function isObjects(args): args is Array { Array.isArray(args) && args.every( (arg) => + arg != null && typeof arg === 'object' && Object.keys(arg).length === 1 && typeof Object.values(arg)[0] === 'object', diff --git a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts index 3b1c0fe5d0..8f2b209e23 100644 --- a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts +++ b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts @@ -14,6 +14,7 @@ import { validateRequiredField, isString, isNumber, + isRecord, } from './common' import type { TransactionMetadataBase } from './metadata' @@ -145,11 +146,10 @@ export function validateNFTokenCreateOffer(tx: Record): void { validateOptionalField(tx, 'Destination', isAccount) let isSellOffer = false - if (typeof tx.Flags === 'number') { + if (isNumber(tx.Flags)) { isSellOffer = isFlagEnabled(tx.Flags, NFTokenCreateOfferFlags.tfSellNFToken) - } else if (typeof tx.Flags === 'object') { - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Needed here - isSellOffer = (tx.Flags as Record).tfSellNFToken === true + } else if (isRecord(tx.Flags)) { + isSellOffer = tx.Flags.tfSellNFToken === true } if (isSellOffer) { diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index be8dca0791..e1147faf32 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -68,8 +68,13 @@ const ISSUED_CURRENCY_SIZE = 3 const XCHAIN_BRIDGE_SIZE = 4 const MPTOKEN_SIZE = 2 const AUTHORIZE_CREDENTIAL_SIZE = 1 - -function isRecord(value: unknown): value is Record { +/** + * Verify the form and type of an object/record at runtime. + * + * @param value - The object to check the form and type of. + * @returns Whether the object is properly formed. + */ +export function isRecord(value: unknown): value is Record { return value !== null && typeof value === 'object' } @@ -373,7 +378,7 @@ export function validateBaseTransaction(common: Record): void { validateOptionalField( common, 'Flags', - (inp) => isNumber(inp) || typeof inp === 'object', + (inp) => isNumber(inp) || isRecord(inp), ) // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS diff --git a/packages/xrpl/src/models/utils/index.ts b/packages/xrpl/src/models/utils/index.ts index a17e948aef..c03d9d3f6f 100644 --- a/packages/xrpl/src/models/utils/index.ts +++ b/packages/xrpl/src/models/utils/index.ts @@ -22,13 +22,7 @@ export function onlyHasFields( * @param checkFlag - A specific flag to check if it's enabled within flags. * @returns True if checkFlag is enabled within flags. */ -export function isFlagEnabled( - flags: number | object, - checkFlag: number, -): boolean { - if (typeof flags === 'object') { - return false - } +export function isFlagEnabled(flags: number, checkFlag: number): boolean { // eslint-disable-next-line no-bitwise -- flags need bitwise return (BigInt(checkFlag) & BigInt(flags)) === BigInt(checkFlag) } From 5b749061d735dff64600ceaddf08ac0f50e45dfd Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 12 Feb 2025 18:42:38 -0500 Subject: [PATCH 11/46] add flag validation tests --- .../xrpl/test/models/baseTransaction.test.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/xrpl/test/models/baseTransaction.test.ts b/packages/xrpl/test/models/baseTransaction.test.ts index 13c640831c..4a9c21de46 100644 --- a/packages/xrpl/test/models/baseTransaction.test.ts +++ b/packages/xrpl/test/models/baseTransaction.test.ts @@ -57,6 +57,10 @@ describe('BaseTransaction', function () { } assert.doesNotThrow(() => validateBaseTransaction(txJson)) + + // check flag map + txJson.Flags = { tfSellToken: true } + assert.doesNotThrow(() => validateBaseTransaction(txJson)) }) it(`Verifies only required BaseTransaction`, function () { @@ -138,6 +142,20 @@ describe('BaseTransaction', function () { ) }) + it(`Handles invalid Flags`, function () { + const invalidFlags = { + Account: 'r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe', + TransactionType: 'Payment', + Flags: 'abcd', + } as any + + assert.throws( + () => validateBaseTransaction(invalidFlags), + ValidationError, + 'Payment: invalid field Flags', + ) + }) + it(`Handles invalid SigningPubKey`, function () { const invalidSigningPubKey = { Account: 'r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe', From 5b8956710c8eda29fdd4f5d6eae6c952f52fbbe0 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 12 Feb 2025 18:47:04 -0500 Subject: [PATCH 12/46] clean up --- packages/xrpl/src/models/transactions/common.ts | 3 ++- packages/xrpl/test/models/baseTransaction.test.ts | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index e1147faf32..ed3737d30e 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -89,7 +89,8 @@ export function isString(str: unknown): str is string { } /** - * Verify the form and type of a number at runtime. + * Verify the form and type of a number at runtime. Includes + * numbers in the form of strings (e.g. `"7"`). * * @param num - The object to check the form and type of. * @returns Whether the number is properly formed. diff --git a/packages/xrpl/test/models/baseTransaction.test.ts b/packages/xrpl/test/models/baseTransaction.test.ts index 4a9c21de46..e8384287fc 100644 --- a/packages/xrpl/test/models/baseTransaction.test.ts +++ b/packages/xrpl/test/models/baseTransaction.test.ts @@ -59,10 +59,18 @@ describe('BaseTransaction', function () { assert.doesNotThrow(() => validateBaseTransaction(txJson)) // check flag map - txJson.Flags = { tfSellToken: true } - assert.doesNotThrow(() => validateBaseTransaction(txJson)) + }) + it('Verifies flag map', function () { + const txJson = { + Account: 'r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe', + TransactionType: 'Payment', + Flags: { tfSellToken: true } + } + assert.doesNotThrow(() => validateBaseTransaction(txJson)) + } + it(`Verifies only required BaseTransaction`, function () { const txJson = { Account: 'r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe', From 92c50ecca4b115598bce7a611db78fda1e274930 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 12 Feb 2025 18:50:19 -0500 Subject: [PATCH 13/46] update models --- packages/xrpl/tools/createValidateTests.js | 33 ++++++---------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/packages/xrpl/tools/createValidateTests.js b/packages/xrpl/tools/createValidateTests.js index d51e883dcc..0a67243475 100644 --- a/packages/xrpl/tools/createValidateTests.js +++ b/packages/xrpl/tools/createValidateTests.js @@ -128,16 +128,7 @@ function processModel(model, txName) { output += ` it("throws w/ missing ${param}", function () { delete tx.${param} - assert.throws( - () => validate${txName}(tx), - ValidationError, - '${txName}: missing field ${param}', - ) - assert.throws( - () => validate(tx), - ValidationError, - '${txName}: missing field ${param}', - ) + assertInvalid(tx, '${txName}: missing field ${param}') }) ` @@ -147,16 +138,7 @@ function processModel(model, txName) { output += ` it('throws w/ invalid ${param}', function () { tx.${param} = ${fakeValue} - assert.throws( - () => validate${txName}(tx), - ValidationError, - '${txName}: invalid field ${param}', - ) - assert.throws( - () => validate(tx), - ValidationError, - '${txName}: invalid field ${param}', - ) + assertInvalid(tx, '${txName}: invalid field ${param}') }) ` @@ -165,10 +147,12 @@ function processModel(model, txName) { output = output.substring(0, output.length - 2) output += '\n})\n' output = - `import { assert } from 'chai' + `import { validate${txName} } from '../../src/models/transactions/${txName}' -import { validate, ValidationError } from '../../src' -import { validate${txName} } from '../../src/models/transactions/${txName}' +const assertValid = (tx: any): void => + assertTxIsValid(tx, validate${txName}) +const assertInvalid = (tx: any, message: string): void => + assertTxValidationError(tx, validate${txName}, message) /** * ${txName} Transaction Verification Testing. @@ -183,8 +167,7 @@ describe('${txName}', function () { }) it('verifies valid ${txName}', function () { - assert.doesNotThrow(() => validate${txName}(tx)) - assert.doesNotThrow(() => validate(tx)) + assertValid(tx) }) ` + output From 870c965253bf5b22c7810933a227647fa073bc31 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 12 Feb 2025 18:57:33 -0500 Subject: [PATCH 14/46] fix build/test issues --- packages/xrpl/test/models/baseTransaction.test.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/xrpl/test/models/baseTransaction.test.ts b/packages/xrpl/test/models/baseTransaction.test.ts index e8384287fc..c75c3805b3 100644 --- a/packages/xrpl/test/models/baseTransaction.test.ts +++ b/packages/xrpl/test/models/baseTransaction.test.ts @@ -57,19 +57,16 @@ describe('BaseTransaction', function () { } assert.doesNotThrow(() => validateBaseTransaction(txJson)) - - // check flag map - }) it('Verifies flag map', function () { const txJson = { Account: 'r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe', TransactionType: 'Payment', - Flags: { tfSellToken: true } + Flags: { tfSellToken: true }, } assert.doesNotThrow(() => validateBaseTransaction(txJson)) - } + }) it(`Verifies only required BaseTransaction`, function () { const txJson = { From 22b6a1fad1d57dce6245dd3aa4337115160a55c5 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 13 Feb 2025 00:46:28 -0500 Subject: [PATCH 15/46] more cleanup --- .vscode/settings.json | 4 +++- .../src/models/transactions/MPTokenIssuanceCreate.ts | 12 +++++------- .../src/models/transactions/MPTokenIssuanceSet.ts | 8 ++++---- packages/xrpl/src/models/transactions/common.ts | 11 +++-------- 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 60d9371aad..1fcd9e5702 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,7 @@ "hostid", "keypair", "keypairs", + "mptoken", "multisign", "multisigned", "multisigning", @@ -16,7 +17,8 @@ "secp256k1", "Setf", "Sidechains", - "xchain" + "xchain", + "xrplf" ], "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode", diff --git a/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts b/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts index 76d37ddee3..86779696fa 100644 --- a/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts +++ b/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts @@ -130,19 +130,19 @@ export function validateMPTokenIssuanceCreate( validateOptionalField(tx, 'TransferFee', isNumber) validateOptionalField(tx, 'AssetScale', isNumber) - if (typeof tx.MPTokenMetadata === 'string' && tx.MPTokenMetadata === '') { + if (isString(tx.MPTokenMetadata) && tx.MPTokenMetadata === '') { throw new ValidationError( 'MPTokenIssuanceCreate: MPTokenMetadata must not be empty string', ) } - if (typeof tx.MPTokenMetadata === 'string' && !isHex(tx.MPTokenMetadata)) { + if (isString(tx.MPTokenMetadata) && !isHex(tx.MPTokenMetadata)) { throw new ValidationError( 'MPTokenIssuanceCreate: MPTokenMetadata must be in hex format', ) } - if (typeof tx.MaximumAmount === 'string') { + if (isString(tx.MaximumAmount)) { if (!INTEGER_SANITY_CHECK.exec(tx.MaximumAmount)) { throw new ValidationError('MPTokenIssuanceCreate: Invalid MaximumAmount') } else if ( @@ -157,13 +157,11 @@ export function validateMPTokenIssuanceCreate( if (typeof tx.TransferFee === 'number') { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Not necessary - const flags = (tx.Flags ?? 0) as - | number - | MPTokenIssuanceCreateFlagsInterface + const flags = (tx.Flags ?? 0) as number | Record const isTfMPTCanTransfer = typeof flags === 'number' ? isFlagEnabled(flags, MPTokenIssuanceCreateFlags.tfMPTCanTransfer) - : flags.tfMPTCanTransfer ?? false + : flags.tfMPTCanTransfer === true if (tx.TransferFee < 0 || tx.TransferFee > MAX_TRANSFER_FEE) { throw new ValidationError( diff --git a/packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts b/packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts index da1b1d2aec..6d142884ae 100644 --- a/packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts +++ b/packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts @@ -69,16 +69,16 @@ export function validateMPTokenIssuanceSet(tx: Record): void { validateOptionalField(tx, 'Holder', isAccount) // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Not necessary - const flags = (tx.Flags ?? 0) as number | MPTokenIssuanceSetFlagsInterface - const isTfMPTLock = + const flags = (tx.Flags ?? 0) as number | Record + const isTfMPTLock: boolean = typeof flags === 'number' ? isFlagEnabled(flags, MPTokenIssuanceSetFlags.tfMPTLock) - : flags.tfMPTLock ?? false + : flags.tfMPTLock === true const isTfMPTUnlock = typeof flags === 'number' ? isFlagEnabled(flags, MPTokenIssuanceSetFlags.tfMPTUnlock) - : flags.tfMPTUnlock ?? false + : flags.tfMPTUnlock === true if (isTfMPTLock && isTfMPTUnlock) { throw new ValidationError('MPTokenIssuanceSet: flag conflict') diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index ed3737d30e..51a4a7c481 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -354,15 +354,10 @@ export interface BaseTransaction { * @throws When the common param is malformed. */ export function validateBaseTransaction(common: Record): void { - if (common.TransactionType === undefined) { - throw new ValidationError('BaseTransaction: missing field TransactionType') - } - - if (typeof common.TransactionType !== 'string') { - throw new ValidationError('BaseTransaction: TransactionType not string') - } + validateRequiredField(common, 'TransactionType', isString) - if (!TRANSACTION_TYPES.includes(common.TransactionType)) { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Checked above + if (!TRANSACTION_TYPES.includes(common.TransactionType as string)) { throw new ValidationError('BaseTransaction: Unknown TransactionType') } From 3ac297b89c20d62865d6aa221d306bfcadc041a1 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 14 Feb 2025 15:44:30 -0500 Subject: [PATCH 16/46] isNumberWithBounds --- .../xrpl/src/models/transactions/AMMCreate.ts | 17 +++++-------- .../xrpl/src/models/transactions/AMMVote.ts | 14 +++++------ .../src/models/transactions/accountSet.ts | 17 +++++-------- .../xrpl/src/models/transactions/common.ts | 24 ++++++++++++++++++- .../src/models/transactions/ticketCreate.ts | 16 ++----------- packages/xrpl/test/models/AMMCreate.test.ts | 4 ++-- packages/xrpl/test/models/AMMVote.test.ts | 4 ++-- packages/xrpl/test/models/accountSet.test.ts | 1 + .../xrpl/test/models/ticketCreate.test.ts | 15 +++--------- 9 files changed, 51 insertions(+), 61 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMCreate.ts b/packages/xrpl/src/models/transactions/AMMCreate.ts index 4849bb464a..e1e3bbdc4a 100644 --- a/packages/xrpl/src/models/transactions/AMMCreate.ts +++ b/packages/xrpl/src/models/transactions/AMMCreate.ts @@ -1,10 +1,9 @@ -import { ValidationError } from '../../errors' import { Amount } from '../common' import { BaseTransaction, isAmount, - isNumber, + isNumberWithBounds, validateBaseTransaction, validateRequiredField, } from './common' @@ -56,13 +55,9 @@ export function validateAMMCreate(tx: Record): void { validateRequiredField(tx, 'Amount', isAmount) validateRequiredField(tx, 'Amount2', isAmount) - validateRequiredField(tx, 'TradingFee', isNumber) - - const tradingFee = Number(tx.TradingFee) - - if (tradingFee < 0 || tradingFee > AMM_MAX_TRADING_FEE) { - throw new ValidationError( - `AMMCreate: TradingFee must be between 0 and ${AMM_MAX_TRADING_FEE}`, - ) - } + validateRequiredField( + tx, + 'TradingFee', + isNumberWithBounds(0, AMM_MAX_TRADING_FEE), + ) } diff --git a/packages/xrpl/src/models/transactions/AMMVote.ts b/packages/xrpl/src/models/transactions/AMMVote.ts index c900cbcf8a..faab8184fb 100644 --- a/packages/xrpl/src/models/transactions/AMMVote.ts +++ b/packages/xrpl/src/models/transactions/AMMVote.ts @@ -1,4 +1,3 @@ -import { ValidationError } from '../../errors' import { Currency } from '../common' import { AMM_MAX_TRADING_FEE } from './AMMCreate' @@ -6,6 +5,7 @@ import { BaseTransaction, isCurrency, isNumber, + isNumberWithBounds, validateBaseTransaction, validateRequiredField, } from './common' @@ -48,11 +48,9 @@ export function validateAMMVote(tx: Record): void { validateRequiredField(tx, 'Asset', isCurrency) validateRequiredField(tx, 'Asset2', isCurrency) validateRequiredField(tx, 'TradingFee', isNumber) - - const tradingFee = Number(tx.TradingFee) - if (tradingFee < 0 || tradingFee > AMM_MAX_TRADING_FEE) { - throw new ValidationError( - `AMMVote: TradingFee must be between 0 and ${AMM_MAX_TRADING_FEE}`, - ) - } + validateRequiredField( + tx, + 'TradingFee', + isNumberWithBounds(0, AMM_MAX_TRADING_FEE), + ) } diff --git a/packages/xrpl/src/models/transactions/accountSet.ts b/packages/xrpl/src/models/transactions/accountSet.ts index 47933652a0..4d6448848c 100644 --- a/packages/xrpl/src/models/transactions/accountSet.ts +++ b/packages/xrpl/src/models/transactions/accountSet.ts @@ -5,6 +5,7 @@ import { BaseTransaction, isAccount, isNumber, + isNumberWithBounds, isString, validateBaseTransaction, validateOptionalField, @@ -202,15 +203,9 @@ export function validateAccountSet(tx: Record): void { validateOptionalField(tx, 'TransferRate', isNumber) - if (tx.TickSize !== undefined) { - if (typeof tx.TickSize !== 'number') { - throw new ValidationError('AccountSet: invalid field TickSize') - } - if ( - tx.TickSize !== 0 && - (tx.TickSize < MIN_TICK_SIZE || tx.TickSize > MAX_TICK_SIZE) - ) { - throw new ValidationError('AccountSet: invalid field TickSize') - } - } + validateOptionalField( + tx, + 'TickSize', + isNumberWithBounds(MIN_TICK_SIZE, MAX_TICK_SIZE), + ) } diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 51a4a7c481..af161766e3 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -96,7 +96,29 @@ export function isString(str: unknown): str is string { * @returns Whether the number is properly formed. */ export function isNumber(num: unknown): num is number { - return typeof num === 'number' || !Number.isNaN(Number(num)) + return ( + (typeof num === 'number' || !Number.isNaN(Number(num))) && + Number.isInteger(Number(num)) + ) +} + +/** + * Verify the form and type of a number at runtime. Includes + * numbers in the form of strings (e.g. `"7"`). + * + * @param num - The object to check the form and type of. + * @param lower + * @param upper + * @returns Whether the number is properly formed. + */ +export function isNumberWithBounds( + lower: number, + upper: number, +): (num: unknown) => num is number { + // eslint-disable-next-line func-style -- returning a function + const func = (num: unknown): num is number => + isNumber(num) && num >= lower && num <= upper + return func } /** diff --git a/packages/xrpl/src/models/transactions/ticketCreate.ts b/packages/xrpl/src/models/transactions/ticketCreate.ts index b25d8258e7..72d9903d3d 100644 --- a/packages/xrpl/src/models/transactions/ticketCreate.ts +++ b/packages/xrpl/src/models/transactions/ticketCreate.ts @@ -1,8 +1,6 @@ -import { ValidationError } from '../../errors' - import { BaseTransaction, - isNumber, + isNumberWithBounds, validateBaseTransaction, validateRequiredField, } from './common' @@ -34,15 +32,5 @@ const MAX_TICKETS = 250 export function validateTicketCreate(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'TicketCount', isNumber) - const ticketCount = Number(tx.TicketCount) - if ( - !Number.isInteger(ticketCount) || - ticketCount < 1 || - ticketCount > MAX_TICKETS - ) { - throw new ValidationError( - 'TicketCreate: TicketCount must be an integer from 1 to 250', - ) - } + validateRequiredField(tx, 'TicketCount', isNumberWithBounds(1, MAX_TICKETS)) } diff --git a/packages/xrpl/test/models/AMMCreate.test.ts b/packages/xrpl/test/models/AMMCreate.test.ts index 10805b31f7..1fb6270ee2 100644 --- a/packages/xrpl/test/models/AMMCreate.test.ts +++ b/packages/xrpl/test/models/AMMCreate.test.ts @@ -70,13 +70,13 @@ describe('AMMCreate', function () { it(`throws when TradingFee is greater than 1000`, function () { ammCreate.TradingFee = 1001 - const errorMessage = 'AMMCreate: TradingFee must be between 0 and 1000' + const errorMessage = 'AMMCreate: invalid field TradingFee' assertInvalid(ammCreate, errorMessage) }) it(`throws when TradingFee is a negative number`, function () { ammCreate.TradingFee = -1 - const errorMessage = 'AMMCreate: TradingFee must be between 0 and 1000' + const errorMessage = 'AMMCreate: invalid field TradingFee' assertInvalid(ammCreate, errorMessage) }) }) diff --git a/packages/xrpl/test/models/AMMVote.test.ts b/packages/xrpl/test/models/AMMVote.test.ts index 08604b0c31..c35de2efb3 100644 --- a/packages/xrpl/test/models/AMMVote.test.ts +++ b/packages/xrpl/test/models/AMMVote.test.ts @@ -71,13 +71,13 @@ describe('AMMVote', function () { it(`throws when TradingFee is greater than AMM_MAX_TRADING_FEE`, function () { vote.TradingFee = 1001 - const errorMessage = 'AMMVote: TradingFee must be between 0 and 1000' + const errorMessage = 'AMMVote: invalid field TradingFee' assertInvalid(vote, errorMessage) }) it(`throws when TradingFee is a negative number`, function () { vote.TradingFee = -1 - const errorMessage = 'AMMVote: TradingFee must be between 0 and 1000' + const errorMessage = 'AMMVote: invalid field TradingFee' assertInvalid(vote, errorMessage) }) }) diff --git a/packages/xrpl/test/models/accountSet.test.ts b/packages/xrpl/test/models/accountSet.test.ts index 2679177382..cc70f4c644 100644 --- a/packages/xrpl/test/models/accountSet.test.ts +++ b/packages/xrpl/test/models/accountSet.test.ts @@ -1,4 +1,5 @@ import { validateAccountSet } from '../../src/models/transactions/accountSet' +import { isNumberWithBounds } from '../../src/models/transactions/common' import { assertTxIsValid, assertTxValidationError } from '../testUtils' const assertValid = (tx: any): void => assertTxIsValid(tx, validateAccountSet) diff --git a/packages/xrpl/test/models/ticketCreate.test.ts b/packages/xrpl/test/models/ticketCreate.test.ts index d0e92302dd..9b32a1e632 100644 --- a/packages/xrpl/test/models/ticketCreate.test.ts +++ b/packages/xrpl/test/models/ticketCreate.test.ts @@ -37,25 +37,16 @@ describe('TicketCreate', function () { it('throws when TicketCount is not an integer', function () { ticketCreate.TicketCount = 12.5 - assertInvalid( - ticketCreate, - 'TicketCreate: TicketCount must be an integer from 1 to 250', - ) + assertInvalid(ticketCreate, 'TicketCreate: invalid field TicketCount') }) it('throws when TicketCount is < 1', function () { ticketCreate.TicketCount = 0 - assertInvalid( - ticketCreate, - 'TicketCreate: TicketCount must be an integer from 1 to 250', - ) + assertInvalid(ticketCreate, 'TicketCreate: invalid field TicketCount') }) it('throws when TicketCount is > 250', function () { ticketCreate.TicketCount = 251 - assertInvalid( - ticketCreate, - 'TicketCreate: TicketCount must be an integer from 1 to 250', - ) + assertInvalid(ticketCreate, 'TicketCreate: invalid field TicketCount') }) }) From fa25caf4bc32a56280dec760d632d53042db8f80 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 14 Feb 2025 16:38:37 -0500 Subject: [PATCH 17/46] fix linting --- packages/xrpl/src/models/transactions/common.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index af161766e3..d372b6b275 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -103,13 +103,13 @@ export function isNumber(num: unknown): num is number { } /** - * Verify the form and type of a number at runtime. Includes - * numbers in the form of strings (e.g. `"7"`). + * Verify the form and type of a number at runtime, and ensures that the + * number is within the provided bounds. Includes numbers in the form of + * strings (e.g. `"7"`). * - * @param num - The object to check the form and type of. - * @param lower - * @param upper - * @returns Whether the number is properly formed. + * @param lower The lower bound (inclusive). + * @param upper The upper bound (inclusive). + * @returns Whether the number is properly formed and within the bounds. */ export function isNumberWithBounds( lower: number, @@ -117,7 +117,7 @@ export function isNumberWithBounds( ): (num: unknown) => num is number { // eslint-disable-next-line func-style -- returning a function const func = (num: unknown): num is number => - isNumber(num) && num >= lower && num <= upper + isNumber(num) && Number(num) >= lower && Number(num) <= upper return func } From ecf26e48a4b96438d7d1fb7bf4461cf3a521f238 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Tue, 18 Feb 2025 17:05:50 -0500 Subject: [PATCH 18/46] fix linter error --- packages/xrpl/.eslintrc.js | 1 + packages/xrpl/test/models/accountSet.test.ts | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/xrpl/.eslintrc.js b/packages/xrpl/.eslintrc.js index 2321616dfa..ea20cd1e79 100644 --- a/packages/xrpl/.eslintrc.js +++ b/packages/xrpl/.eslintrc.js @@ -107,6 +107,7 @@ module.exports = { '@typescript-eslint/no-unsafe-assignment': 'off', '@typescript-eslint/no-unsafe-call': 'off', '@typescript-eslint/consistent-type-assertions': 'off', + '@typescript-eslint/no-unsafe-return': 'off', // We need to mess with internal things to generate certain testing situations '@typescript-eslint/no-unsafe-member-access': 'off', diff --git a/packages/xrpl/test/models/accountSet.test.ts b/packages/xrpl/test/models/accountSet.test.ts index cc70f4c644..2679177382 100644 --- a/packages/xrpl/test/models/accountSet.test.ts +++ b/packages/xrpl/test/models/accountSet.test.ts @@ -1,5 +1,4 @@ import { validateAccountSet } from '../../src/models/transactions/accountSet' -import { isNumberWithBounds } from '../../src/models/transactions/common' import { assertTxIsValid, assertTxValidationError } from '../testUtils' const assertValid = (tx: any): void => assertTxIsValid(tx, validateAccountSet) From cbbcdab83c82b5c35ef4dfc1bc01081eddc700c8 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 27 Feb 2025 09:38:27 -0700 Subject: [PATCH 19/46] more test updates - more specific helpers, better error messages --- .vscode/settings.json | 2 + .../xrpl/src/models/transactions/DIDSet.ts | 8 +-- .../models/transactions/MPTokenAuthorize.ts | 4 +- .../transactions/MPTokenIssuanceCreate.ts | 3 +- .../transactions/MPTokenIssuanceDestroy.ts | 4 +- .../models/transactions/MPTokenIssuanceSet.ts | 4 +- .../models/transactions/NFTokenAcceptOffer.ts | 6 +- .../src/models/transactions/NFTokenBurn.ts | 4 +- .../models/transactions/NFTokenCreateOffer.ts | 4 +- .../src/models/transactions/NFTokenMint.ts | 4 +- .../src/models/transactions/NFTokenModify.ts | 6 +- .../XChainAddAccountCreateAttestation.ts | 5 +- .../transactions/XChainAddClaimAttestation.ts | 5 +- .../src/models/transactions/accountSet.ts | 20 ++++--- .../src/models/transactions/checkCancel.ts | 2 +- .../xrpl/src/models/transactions/checkCash.ts | 2 +- .../src/models/transactions/checkCreate.ts | 2 +- .../xrpl/src/models/transactions/common.ts | 60 +++++++++++++++---- .../models/transactions/credentialAccept.ts | 4 +- .../models/transactions/credentialCreate.ts | 6 +- .../models/transactions/credentialDelete.ts | 8 +-- .../src/models/transactions/escrowCreate.ts | 4 +- .../src/models/transactions/escrowFinish.ts | 6 +- .../xrpl/src/models/transactions/oracleSet.ts | 6 +- .../xrpl/src/models/transactions/payment.ts | 2 +- .../transactions/paymentChannelClaim.ts | 6 +- .../transactions/paymentChannelCreate.ts | 2 +- .../models/transactions/paymentChannelFund.ts | 2 +- .../transactions/permissionedDomainDelete.ts | 2 +- .../transactions/permissionedDomainSet.ts | 2 +- .../src/models/transactions/setRegularKey.ts | 4 +- 31 files changed, 121 insertions(+), 78 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 1fcd9e5702..651e07fb1b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,12 +11,14 @@ "multisign", "multisigned", "multisigning", + "nftoken", "Permissioned", "preauthorization", "rippletest", "secp256k1", "Setf", "Sidechains", + "Trustlines", "xchain", "xrplf" ], diff --git a/packages/xrpl/src/models/transactions/DIDSet.ts b/packages/xrpl/src/models/transactions/DIDSet.ts index 11416899fd..996b9a6655 100644 --- a/packages/xrpl/src/models/transactions/DIDSet.ts +++ b/packages/xrpl/src/models/transactions/DIDSet.ts @@ -2,7 +2,7 @@ import { ValidationError } from '../../errors' import { BaseTransaction, - isString, + isHexString, validateBaseTransaction, validateOptionalField, } from './common' @@ -31,11 +31,11 @@ export interface DIDSet extends BaseTransaction { export function validateDIDSet(tx: Record): void { validateBaseTransaction(tx) - validateOptionalField(tx, 'Data', isString) + validateOptionalField(tx, 'Data', isHexString) - validateOptionalField(tx, 'DIDDocument', isString) + validateOptionalField(tx, 'DIDDocument', isHexString) - validateOptionalField(tx, 'URI', isString) + validateOptionalField(tx, 'URI', isHexString) if ( tx.Data === undefined && diff --git a/packages/xrpl/src/models/transactions/MPTokenAuthorize.ts b/packages/xrpl/src/models/transactions/MPTokenAuthorize.ts index 4453f571e7..e38c591f48 100644 --- a/packages/xrpl/src/models/transactions/MPTokenAuthorize.ts +++ b/packages/xrpl/src/models/transactions/MPTokenAuthorize.ts @@ -1,12 +1,12 @@ import { BaseTransaction, - isString, validateBaseTransaction, validateRequiredField, Account, validateOptionalField, isAccount, GlobalFlags, + isHexString, } from './common' /** @@ -62,6 +62,6 @@ export interface MPTokenAuthorize extends BaseTransaction { */ export function validateMPTokenAuthorize(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'MPTokenIssuanceID', isString) + validateRequiredField(tx, 'MPTokenIssuanceID', isHexString) validateOptionalField(tx, 'Holder', isAccount) } diff --git a/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts b/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts index 86779696fa..3af14f525a 100644 --- a/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts +++ b/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts @@ -8,6 +8,7 @@ import { validateOptionalField, isString, isNumber, + isHexString, } from './common' import type { TransactionMetadataBase } from './metadata' @@ -126,7 +127,7 @@ export function validateMPTokenIssuanceCreate( ): void { validateBaseTransaction(tx) validateOptionalField(tx, 'MaximumAmount', isString) - validateOptionalField(tx, 'MPTokenMetadata', isString) + validateOptionalField(tx, 'MPTokenMetadata', isHexString) validateOptionalField(tx, 'TransferFee', isNumber) validateOptionalField(tx, 'AssetScale', isNumber) diff --git a/packages/xrpl/src/models/transactions/MPTokenIssuanceDestroy.ts b/packages/xrpl/src/models/transactions/MPTokenIssuanceDestroy.ts index 06cbfe9471..98112d1624 100644 --- a/packages/xrpl/src/models/transactions/MPTokenIssuanceDestroy.ts +++ b/packages/xrpl/src/models/transactions/MPTokenIssuanceDestroy.ts @@ -1,6 +1,6 @@ import { BaseTransaction, - isString, + isHexString, validateBaseTransaction, validateRequiredField, } from './common' @@ -30,5 +30,5 @@ export function validateMPTokenIssuanceDestroy( tx: Record, ): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'MPTokenIssuanceID', isString) + validateRequiredField(tx, 'MPTokenIssuanceID', isHexString) } diff --git a/packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts b/packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts index 6d142884ae..aa9ea9c77e 100644 --- a/packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts +++ b/packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts @@ -3,13 +3,13 @@ import { isFlagEnabled } from '../utils' import { BaseTransaction, - isString, validateBaseTransaction, validateRequiredField, Account, validateOptionalField, isAccount, GlobalFlags, + isHexString, } from './common' /** @@ -65,7 +65,7 @@ export interface MPTokenIssuanceSet extends BaseTransaction { */ export function validateMPTokenIssuanceSet(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'MPTokenIssuanceID', isString) + validateRequiredField(tx, 'MPTokenIssuanceID', isHexString) validateOptionalField(tx, 'Holder', isAccount) // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Not necessary diff --git a/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts b/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts index 950b0387b6..49b3cd0d5c 100644 --- a/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts +++ b/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts @@ -4,7 +4,7 @@ import { Amount } from '../common' import { BaseTransaction, isAmount, - isString, + isHexString, parseAmountValue, validateBaseTransaction, validateOptionalField, @@ -103,8 +103,8 @@ function validateNFTokenBrokerFee(tx: Record): void { export function validateNFTokenAcceptOffer(tx: Record): void { validateBaseTransaction(tx) - validateOptionalField(tx, 'NFTokenSellOffer', isString) - validateOptionalField(tx, 'NFTokenBuyOffer', isString) + validateOptionalField(tx, 'NFTokenSellOffer', isHexString) + validateOptionalField(tx, 'NFTokenBuyOffer', isHexString) validateOptionalField(tx, 'NFTokenBrokerFee', isAmount) if (tx.NFTokenBrokerFee != null) { diff --git a/packages/xrpl/src/models/transactions/NFTokenBurn.ts b/packages/xrpl/src/models/transactions/NFTokenBurn.ts index 00df462459..672c3f4a16 100644 --- a/packages/xrpl/src/models/transactions/NFTokenBurn.ts +++ b/packages/xrpl/src/models/transactions/NFTokenBurn.ts @@ -2,7 +2,7 @@ import { Account, BaseTransaction, isAccount, - isString, + isHexString, validateBaseTransaction, validateOptionalField, validateRequiredField, @@ -47,6 +47,6 @@ export interface NFTokenBurn extends BaseTransaction { */ export function validateNFTokenBurn(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'NFTokenID', isString) + validateRequiredField(tx, 'NFTokenID', isHexString) validateOptionalField(tx, 'Owner', isAccount) } diff --git a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts index 8f2b209e23..938d73ae93 100644 --- a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts +++ b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts @@ -12,9 +12,9 @@ import { validateOptionalField, Account, validateRequiredField, - isString, isNumber, isRecord, + isHexString, } from './common' import type { TransactionMetadataBase } from './metadata' @@ -139,7 +139,7 @@ export function validateNFTokenCreateOffer(tx: Record): void { ) } - validateRequiredField(tx, 'NFTokenID', isString) + validateRequiredField(tx, 'NFTokenID', isHexString) validateRequiredField(tx, 'Amount', isAmount) validateOptionalField(tx, 'Owner', isAccount) validateOptionalField(tx, 'Expiration', isNumber) diff --git a/packages/xrpl/src/models/transactions/NFTokenMint.ts b/packages/xrpl/src/models/transactions/NFTokenMint.ts index 4463bf3140..b2b6b31d3f 100644 --- a/packages/xrpl/src/models/transactions/NFTokenMint.ts +++ b/packages/xrpl/src/models/transactions/NFTokenMint.ts @@ -7,7 +7,7 @@ import { GlobalFlags, isAccount, isNumber, - isString, + isHexString, validateBaseTransaction, validateOptionalField, validateRequiredField, @@ -127,7 +127,7 @@ export function validateNFTokenMint(tx: Record): void { validateRequiredField(tx, 'NFTokenTaxon', isNumber) validateOptionalField(tx, 'Issuer', isAccount) validateOptionalField(tx, 'TransferFee', isNumber) - validateOptionalField(tx, 'URI', isString) + validateOptionalField(tx, 'URI', isHexString) if (tx.Account === tx.Issuer) { throw new ValidationError( diff --git a/packages/xrpl/src/models/transactions/NFTokenModify.ts b/packages/xrpl/src/models/transactions/NFTokenModify.ts index 4246509671..70734aea7f 100644 --- a/packages/xrpl/src/models/transactions/NFTokenModify.ts +++ b/packages/xrpl/src/models/transactions/NFTokenModify.ts @@ -5,10 +5,10 @@ import { BaseTransaction, validateBaseTransaction, isAccount, - isString, validateOptionalField, Account, validateRequiredField, + isHexString, } from './common' /** @@ -52,9 +52,9 @@ export interface NFTokenModify extends BaseTransaction { export function validateNFTokenModify(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'NFTokenID', isString) + validateRequiredField(tx, 'NFTokenID', isHexString) validateOptionalField(tx, 'Owner', isAccount) - validateOptionalField(tx, 'URI', isString) + validateOptionalField(tx, 'URI', isHexString) if (tx.URI !== undefined && typeof tx.URI === 'string') { if (tx.URI === '') { diff --git a/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts b/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts index 16d27035a1..badfc63473 100644 --- a/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts +++ b/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts @@ -5,6 +5,7 @@ import { BaseTransaction, isAccount, isAmount, + isHexString, isNumber, isString, isXChainBridge, @@ -101,9 +102,9 @@ export function validateXChainAddAccountCreateAttestation( validateRequiredField(tx, 'OtherChainSource', isAccount) - validateRequiredField(tx, 'PublicKey', isString) + validateRequiredField(tx, 'PublicKey', isHexString) - validateRequiredField(tx, 'Signature', isString) + validateRequiredField(tx, 'Signature', isHexString) validateRequiredField(tx, 'SignatureReward', isAmount) diff --git a/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts b/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts index 90f09c0bc7..7f3dd5503e 100644 --- a/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts +++ b/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts @@ -5,6 +5,7 @@ import { BaseTransaction, isAccount, isAmount, + isHexString, isNumber, isString, isXChainBridge, @@ -97,9 +98,9 @@ export function validateXChainAddClaimAttestation( validateRequiredField(tx, 'OtherChainSource', isAccount) - validateRequiredField(tx, 'PublicKey', isString) + validateRequiredField(tx, 'PublicKey', isHexString) - validateRequiredField(tx, 'Signature', isString) + validateRequiredField(tx, 'Signature', isHexString) validateRequiredField( tx, diff --git a/packages/xrpl/src/models/transactions/accountSet.ts b/packages/xrpl/src/models/transactions/accountSet.ts index 4d6448848c..fb71107c46 100644 --- a/packages/xrpl/src/models/transactions/accountSet.ts +++ b/packages/xrpl/src/models/transactions/accountSet.ts @@ -4,9 +4,9 @@ import { Account, BaseTransaction, isAccount, + isHexString, isNumber, isNumberWithBounds, - isString, validateBaseTransaction, validateOptionalField, } from './common' @@ -181,23 +181,27 @@ export function validateAccountSet(tx: Record): void { if (tx.ClearFlag !== undefined) { if (typeof tx.ClearFlag !== 'number') { - throw new ValidationError('AccountSet: invalid field ClearFlag') + throw new ValidationError( + 'AccountSet: invalid field ClearFlag, expected a valid number', + ) } if (!Object.values(AccountSetAsfFlags).includes(tx.ClearFlag)) { - throw new ValidationError('AccountSet: invalid field ClearFlag') + throw new ValidationError('AccountSet: not a valid ClearFlag value') } } - validateOptionalField(tx, 'Domain', isString) - validateOptionalField(tx, 'EmailHash', isString) - validateOptionalField(tx, 'MessageKey', isString) + validateOptionalField(tx, 'Domain', isHexString) + validateOptionalField(tx, 'EmailHash', isHexString) + validateOptionalField(tx, 'MessageKey', isHexString) if (tx.SetFlag !== undefined) { if (typeof tx.SetFlag !== 'number') { - throw new ValidationError('AccountSet: invalid field SetFlag') + throw new ValidationError( + 'AccountSet: invalid field SetFlag, expected a valid number', + ) } if (!Object.values(AccountSetAsfFlags).includes(tx.SetFlag)) { - throw new ValidationError('AccountSet: invalid field SetFlag') + throw new ValidationError('AccountSet: not a valid SetFlag value') } } diff --git a/packages/xrpl/src/models/transactions/checkCancel.ts b/packages/xrpl/src/models/transactions/checkCancel.ts index 7d8aaad0f3..9efc0908b1 100644 --- a/packages/xrpl/src/models/transactions/checkCancel.ts +++ b/packages/xrpl/src/models/transactions/checkCancel.ts @@ -31,5 +31,5 @@ export interface CheckCancel extends BaseTransaction { export function validateCheckCancel(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'CheckID', isString) + validateRequiredField(tx, 'CheckID', isHexString) } diff --git a/packages/xrpl/src/models/transactions/checkCash.ts b/packages/xrpl/src/models/transactions/checkCash.ts index 4d867a6679..971db27773 100644 --- a/packages/xrpl/src/models/transactions/checkCash.ts +++ b/packages/xrpl/src/models/transactions/checkCash.ts @@ -47,7 +47,7 @@ export interface CheckCash extends BaseTransaction { export function validateCheckCash(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'CheckID', isString) + validateRequiredField(tx, 'CheckID', isHexString) validateOptionalField(tx, 'Amount', isAmount) validateOptionalField(tx, 'DeliverMin', isAmount) diff --git a/packages/xrpl/src/models/transactions/checkCreate.ts b/packages/xrpl/src/models/transactions/checkCreate.ts index b17a56a521..9c2cc0c77f 100644 --- a/packages/xrpl/src/models/transactions/checkCreate.ts +++ b/packages/xrpl/src/models/transactions/checkCreate.ts @@ -61,5 +61,5 @@ export function validateCheckCreate(tx: Record): void { validateRequiredField(tx, 'Destination', isAccount) validateOptionalField(tx, 'DestinationTag', isNumber) validateOptionalField(tx, 'Expiration', isNumber) - validateOptionalField(tx, 'InvoiceID', isString) + validateOptionalField(tx, 'InvoiceID', isHexString) } diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index d372b6b275..92663d9ee5 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -14,7 +14,7 @@ import { Signer, XChainBridge, } from '../common' -import { onlyHasFields } from '../utils' +import { isHex, onlyHasFields } from '../utils' const MEMO_SIZE = 3 export const MAX_AUTHORIZED_CREDENTIALS = 8 @@ -68,6 +68,7 @@ const ISSUED_CURRENCY_SIZE = 3 const XCHAIN_BRIDGE_SIZE = 4 const MPTOKEN_SIZE = 2 const AUTHORIZE_CREDENTIAL_SIZE = 1 + /** * Verify the form and type of an object/record at runtime. * @@ -88,6 +89,16 @@ export function isString(str: unknown): str is string { return typeof str === 'string' } +/** + * Verify the form and type of a hex string at runtime. + * + * @param str - The object to check the form and type of. + * @returns Whether the hex string is properly formed. + */ +export function isHexString(str: unknown): str is string { + return typeof str === 'string' && isHex(str) +} + /** * Verify the form and type of a number at runtime. Includes * numbers in the form of strings (e.g. `"7"`). @@ -116,9 +127,9 @@ export function isNumberWithBounds( upper: number, ): (num: unknown) => num is number { // eslint-disable-next-line func-style -- returning a function - const func = (num: unknown): num is number => + const isNumberWithBoundsInternal = (num: unknown): num is number => isNumber(num) && Number(num) >= lower && Number(num) <= upper - return func + return isNumberWithBoundsInternal } /** @@ -238,6 +249,22 @@ export function isXChainBridge(input: unknown): input is XChainBridge { ) } +const invalidMessagesMap: Record = { + isAccount: 'expected a valid account address', + isAmount: 'expected a valid Amount', + isCurrency: 'expected a valid Currency', + isIssuedCurrency: 'expected a valid IssuedCurrencyAmount', + isMPTAmount: 'expected a valid MPTAmount', + isXChainBridge: 'expected a valid XChainBridge', + isMemo: 'expected a valid Memo', + isSigner: 'expected a valid Signer', + isRecord: 'expected a valid Record', + isString: 'expected a valid string', + isHexString: 'expected a valid hex string', + isNumber: 'expected a valid number', + isNumberWithBoundsInternal: 'expected a valid number', +} + /* eslint-disable @typescript-eslint/restrict-template-expressions -- tx.TransactionType is checked before any calls */ /** @@ -260,9 +287,13 @@ export function validateRequiredField( } if (!checkValidity(tx[paramName])) { - throw new ValidationError( - `${tx.TransactionType}: invalid field ${paramName}`, - ) + let errorMessage = `${tx.TransactionType}: invalid field ${paramName}` + const invalidMessage = invalidMessagesMap[checkValidity.name] + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- okay + if (invalidMessage != null) { + errorMessage += `, ${invalidMessage}` + } + throw new ValidationError(errorMessage) } } @@ -280,9 +311,12 @@ export function validateOptionalField( checkValidity: (inp: unknown) => boolean, ): void { if (tx[paramName] !== undefined && !checkValidity(tx[paramName])) { - throw new ValidationError( - `${tx.TransactionType}: invalid field ${paramName}`, - ) + let errorMessage = `${tx.TransactionType}: invalid field ${paramName}` + const invalidMessage = invalidMessagesMap[checkValidity.name] + if (invalidMessage) { + errorMessage += `, ${invalidMessage}` + } + throw new ValidationError(errorMessage) } } @@ -383,13 +417,13 @@ export function validateBaseTransaction(common: Record): void { throw new ValidationError('BaseTransaction: Unknown TransactionType') } - validateRequiredField(common, 'Account', isString) + validateRequiredField(common, 'Account', isAccount) validateOptionalField(common, 'Fee', isString) validateOptionalField(common, 'Sequence', isNumber) - validateOptionalField(common, 'AccountTxnID', isString) + validateOptionalField(common, 'AccountTxnID', isHexString) validateOptionalField(common, 'LastLedgerSequence', isNumber) @@ -417,11 +451,11 @@ export function validateBaseTransaction(common: Record): void { validateOptionalField(common, 'SourceTag', isNumber) - validateOptionalField(common, 'SigningPubKey', isString) + validateOptionalField(common, 'SigningPubKey', isHexString) validateOptionalField(common, 'TicketSequence', isNumber) - validateOptionalField(common, 'TxnSignature', isString) + validateOptionalField(common, 'TxnSignature', isHexString) validateOptionalField(common, 'NetworkID', isNumber) } diff --git a/packages/xrpl/src/models/transactions/credentialAccept.ts b/packages/xrpl/src/models/transactions/credentialAccept.ts index cd0906fc71..d45790d749 100644 --- a/packages/xrpl/src/models/transactions/credentialAccept.ts +++ b/packages/xrpl/src/models/transactions/credentialAccept.ts @@ -36,9 +36,9 @@ export interface CredentialAccept extends BaseTransaction { export function validateCredentialAccept(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'Account', isString) + validateRequiredField(tx, 'Account', isAccount) - validateRequiredField(tx, 'Issuer', isString) + validateRequiredField(tx, 'Issuer', isAccount) validateCredentialType(tx) } diff --git a/packages/xrpl/src/models/transactions/credentialCreate.ts b/packages/xrpl/src/models/transactions/credentialCreate.ts index 8c82b7c74c..97edb24030 100644 --- a/packages/xrpl/src/models/transactions/credentialCreate.ts +++ b/packages/xrpl/src/models/transactions/credentialCreate.ts @@ -4,8 +4,8 @@ import { ValidationError } from '../../errors' import { BaseTransaction, + isAccount, isNumber, - isString, validateBaseTransaction, validateCredentialType, validateOptionalField, @@ -47,9 +47,9 @@ export interface CredentialCreate extends BaseTransaction { export function validateCredentialCreate(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'Account', isString) + validateRequiredField(tx, 'Account', isAccount) - validateRequiredField(tx, 'Subject', isString) + validateRequiredField(tx, 'Subject', isAccount) validateCredentialType(tx) diff --git a/packages/xrpl/src/models/transactions/credentialDelete.ts b/packages/xrpl/src/models/transactions/credentialDelete.ts index d1b4ab0244..64e8f82e8c 100644 --- a/packages/xrpl/src/models/transactions/credentialDelete.ts +++ b/packages/xrpl/src/models/transactions/credentialDelete.ts @@ -2,7 +2,7 @@ import { ValidationError } from '../../errors' import { BaseTransaction, - isString, + isAccount, validateBaseTransaction, validateCredentialType, validateOptionalField, @@ -45,11 +45,11 @@ export function validateCredentialDelete(tx: Record): void { ) } - validateRequiredField(tx, 'Account', isString) + validateRequiredField(tx, 'Account', isAccount) validateCredentialType(tx) - validateOptionalField(tx, 'Subject', isString) + validateOptionalField(tx, 'Subject', isAccount) - validateOptionalField(tx, 'Issuer', isString) + validateOptionalField(tx, 'Issuer', isAccount) } diff --git a/packages/xrpl/src/models/transactions/escrowCreate.ts b/packages/xrpl/src/models/transactions/escrowCreate.ts index 1e3fddcbb3..ea1ce8cb05 100644 --- a/packages/xrpl/src/models/transactions/escrowCreate.ts +++ b/packages/xrpl/src/models/transactions/escrowCreate.ts @@ -5,8 +5,8 @@ import { BaseTransaction, isAccount, isAmount, + isHexString, isNumber, - isString, validateBaseTransaction, validateOptionalField, validateRequiredField, @@ -65,7 +65,7 @@ export function validateEscrowCreate(tx: Record): void { validateOptionalField(tx, 'DestinationTag', isNumber) validateOptionalField(tx, 'CancelAfter', isNumber) validateOptionalField(tx, 'FinishAfter', isNumber) - validateOptionalField(tx, 'Condition', isString) + validateOptionalField(tx, 'Condition', isHexString) if (tx.CancelAfter === undefined && tx.FinishAfter === undefined) { throw new ValidationError( diff --git a/packages/xrpl/src/models/transactions/escrowFinish.ts b/packages/xrpl/src/models/transactions/escrowFinish.ts index b7f3866848..ed7d1c2bb1 100644 --- a/packages/xrpl/src/models/transactions/escrowFinish.ts +++ b/packages/xrpl/src/models/transactions/escrowFinish.ts @@ -3,12 +3,12 @@ import { BaseTransaction, isAccount, isNumber, - isString, validateBaseTransaction, validateCredentialsList, validateOptionalField, validateRequiredField, MAX_AUTHORIZED_CREDENTIALS, + isHexString, } from './common' /** @@ -61,6 +61,6 @@ export function validateEscrowFinish(tx: Record): void { ) validateRequiredField(tx, 'OfferSequence', isNumber) - validateOptionalField(tx, 'Condition', isString) - validateOptionalField(tx, 'Fulfillment', isString) + validateOptionalField(tx, 'Condition', isHexString) + validateOptionalField(tx, 'Fulfillment', isHexString) } diff --git a/packages/xrpl/src/models/transactions/oracleSet.ts b/packages/xrpl/src/models/transactions/oracleSet.ts index 6b3f395d0d..694e0dc62a 100644 --- a/packages/xrpl/src/models/transactions/oracleSet.ts +++ b/packages/xrpl/src/models/transactions/oracleSet.ts @@ -76,11 +76,11 @@ export function validateOracleSet(tx: Record): void { validateRequiredField(tx, 'LastUpdateTime', isNumber) - validateOptionalField(tx, 'Provider', isString) + validateOptionalField(tx, 'Provider', isHexString) - validateOptionalField(tx, 'URI', isString) + validateOptionalField(tx, 'URI', isHexString) - validateOptionalField(tx, 'AssetClass', isString) + validateOptionalField(tx, 'AssetClass', isHexString) // eslint-disable-next-line max-lines-per-function -- necessary to validate many fields validateRequiredField(tx, 'PriceDataSeries', (value) => { diff --git a/packages/xrpl/src/models/transactions/payment.ts b/packages/xrpl/src/models/transactions/payment.ts index 1a983a5d80..1d93416279 100644 --- a/packages/xrpl/src/models/transactions/payment.ts +++ b/packages/xrpl/src/models/transactions/payment.ts @@ -177,7 +177,7 @@ export function validatePayment(tx: Record): void { validateRequiredField(tx, 'Amount', isAmount) validateRequiredField(tx, 'Destination', isAccount) validateOptionalField(tx, 'DestinationTag', isNumber) - validateOptionalField(tx, 'InvoiceID', isString) + validateOptionalField(tx, 'InvoiceID', isHexString) if ( tx.Paths !== undefined && diff --git a/packages/xrpl/src/models/transactions/paymentChannelClaim.ts b/packages/xrpl/src/models/transactions/paymentChannelClaim.ts index 72ec62f4e5..ffe751a315 100644 --- a/packages/xrpl/src/models/transactions/paymentChannelClaim.ts +++ b/packages/xrpl/src/models/transactions/paymentChannelClaim.ts @@ -150,11 +150,11 @@ export interface PaymentChannelClaim extends BaseTransaction { export function validatePaymentChannelClaim(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'Channel', isString) + validateRequiredField(tx, 'Channel', isHexString) validateOptionalField(tx, 'Balance', isString) validateOptionalField(tx, 'Amount', isString) - validateOptionalField(tx, 'Signature', isString) - validateOptionalField(tx, 'PublicKey', isString) + validateOptionalField(tx, 'Signature', isHexString) + validateOptionalField(tx, 'PublicKey', isHexString) validateCredentialsList( tx.CredentialIDs, diff --git a/packages/xrpl/src/models/transactions/paymentChannelCreate.ts b/packages/xrpl/src/models/transactions/paymentChannelCreate.ts index b6308cfff0..6799df8ef9 100644 --- a/packages/xrpl/src/models/transactions/paymentChannelCreate.ts +++ b/packages/xrpl/src/models/transactions/paymentChannelCreate.ts @@ -70,6 +70,6 @@ export function validatePaymentChannelCreate( validateRequiredField(tx, 'Destination', isAccount) validateOptionalField(tx, 'DestinationTag', isNumber) validateRequiredField(tx, 'SettleDelay', isNumber) - validateRequiredField(tx, 'PublicKey', isString) + validateRequiredField(tx, 'PublicKey', isHexString) validateOptionalField(tx, 'CancelAfter', isNumber) } diff --git a/packages/xrpl/src/models/transactions/paymentChannelFund.ts b/packages/xrpl/src/models/transactions/paymentChannelFund.ts index 33dba39d83..83ac41859e 100644 --- a/packages/xrpl/src/models/transactions/paymentChannelFund.ts +++ b/packages/xrpl/src/models/transactions/paymentChannelFund.ts @@ -48,7 +48,7 @@ export interface PaymentChannelFund extends BaseTransaction { export function validatePaymentChannelFund(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'Channel', isString) + validateRequiredField(tx, 'Channel', isHexString) validateRequiredField(tx, 'Amount', isString) validateOptionalField(tx, 'Expiration', isNumber) } diff --git a/packages/xrpl/src/models/transactions/permissionedDomainDelete.ts b/packages/xrpl/src/models/transactions/permissionedDomainDelete.ts index 8a2a0db6c8..8bfd4492a6 100644 --- a/packages/xrpl/src/models/transactions/permissionedDomainDelete.ts +++ b/packages/xrpl/src/models/transactions/permissionedDomainDelete.ts @@ -24,5 +24,5 @@ export function validatePermissionedDomainDelete( ): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'DomainID', isString) + validateRequiredField(tx, 'DomainID', isHexString) } diff --git a/packages/xrpl/src/models/transactions/permissionedDomainSet.ts b/packages/xrpl/src/models/transactions/permissionedDomainSet.ts index 5e57c0de90..5876c4ee8c 100644 --- a/packages/xrpl/src/models/transactions/permissionedDomainSet.ts +++ b/packages/xrpl/src/models/transactions/permissionedDomainSet.ts @@ -35,7 +35,7 @@ export function validatePermissionedDomainSet( ): void { validateBaseTransaction(tx) - validateOptionalField(tx, 'DomainID', isString) + validateOptionalField(tx, 'DomainID', isHexString) validateRequiredField( tx, 'AcceptedCredentials', diff --git a/packages/xrpl/src/models/transactions/setRegularKey.ts b/packages/xrpl/src/models/transactions/setRegularKey.ts index 452d593d9a..a546f41058 100644 --- a/packages/xrpl/src/models/transactions/setRegularKey.ts +++ b/packages/xrpl/src/models/transactions/setRegularKey.ts @@ -1,6 +1,6 @@ import { BaseTransaction, - isString, + isAccount, validateBaseTransaction, validateOptionalField, } from './common' @@ -30,5 +30,5 @@ export interface SetRegularKey extends BaseTransaction { export function validateSetRegularKey(tx: Record): void { validateBaseTransaction(tx) - validateOptionalField(tx, 'RegularKey', isString) + validateOptionalField(tx, 'RegularKey', isAccount) } From aa6dcac1031d9988ad1defd660c3d26c3552ef3b Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 27 Feb 2025 09:38:36 -0700 Subject: [PATCH 20/46] [WIP] start fixing tests based on previous commit --- .../xrpl/test/models/accountDelete.test.ts | 9 +++-- packages/xrpl/test/models/accountSet.test.ts | 36 ++++++++++++++----- packages/xrpl/test/models/checkCreate.test.ts | 22 +++++++++--- packages/xrpl/test/testUtils.ts | 14 ++++++-- 4 files changed, 62 insertions(+), 19 deletions(-) diff --git a/packages/xrpl/test/models/accountDelete.test.ts b/packages/xrpl/test/models/accountDelete.test.ts index 6316b7a904..29a8533b3a 100644 --- a/packages/xrpl/test/models/accountDelete.test.ts +++ b/packages/xrpl/test/models/accountDelete.test.ts @@ -40,13 +40,15 @@ describe('AccountDelete', function () { it(`throws w/ invalid Destination`, function () { validAccountDelete.Destination = 65478965 - const errorMessage = 'AccountDelete: invalid field Destination' + const errorMessage = + 'AccountDelete: invalid field Destination, expected a valid account address' assertInvalid(validAccountDelete, errorMessage) }) it(`throws w/ invalid DestinationTag`, function () { validAccountDelete.DestinationTag = 'gvftyujnbv' - const errorMessage = 'AccountDelete: invalid field DestinationTag' + const errorMessage = + 'AccountDelete: invalid field DestinationTag, expected a valid number' assertInvalid(validAccountDelete, errorMessage) }) @@ -54,7 +56,8 @@ describe('AccountDelete', function () { validAccountDelete.CredentialIDs = 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66A' - const errorMessage = 'AccountDelete: invalid field Credentials' + const errorMessage = + 'AccountDelete: invalid field Credentials, expected a valid array' assertInvalid(validAccountDelete, errorMessage) }) diff --git a/packages/xrpl/test/models/accountSet.test.ts b/packages/xrpl/test/models/accountSet.test.ts index 2679177382..f8e5a8b9ad 100644 --- a/packages/xrpl/test/models/accountSet.test.ts +++ b/packages/xrpl/test/models/accountSet.test.ts @@ -32,46 +32,64 @@ describe('AccountSet', function () { it(`throws w/ invalid SetFlag (out of range)`, function () { tx.SetFlag = 20 - assertInvalid(tx, 'AccountSet: invalid field SetFlag') + assertInvalid(tx, 'AccountSet: not a valid SetFlag') }) it(`throws w/ invalid SetFlag (incorrect type)`, function () { tx.SetFlag = 'abc' - assertInvalid(tx, 'AccountSet: invalid field SetFlag') + assertInvalid( + tx, + 'AccountSet: invalid field SetFlag, expected a valid number', + ) }) it(`throws w/ invalid ClearFlag`, function () { tx.ClearFlag = 20 - assertInvalid(tx, 'AccountSet: invalid field ClearFlag') + assertInvalid(tx, 'AccountSet: not a valid ClearFlag') }) it(`throws w/ invalid Domain`, function () { tx.Domain = 6578616 - assertInvalid(tx, 'AccountSet: invalid field Domain') + assertInvalid(tx, 'AccountSet: invalid field Domain, expected a hex string') }) it(`throws w/ invalid EmailHash`, function () { tx.EmailHash = 6578656789876543 - assertInvalid(tx, 'AccountSet: invalid field EmailHash') + assertInvalid( + tx, + 'AccountSet: invalid field EmailHash, expected a hex string', + ) }) it(`throws w/ invalid MessageKey`, function () { tx.MessageKey = 6578656789876543 - assertInvalid(tx, 'AccountSet: invalid field MessageKey') + assertInvalid( + tx, + 'AccountSet: invalid field MessageKey, expected a hex string', + ) }) it(`throws w/ invalid TransferRate`, function () { tx.TransferRate = 'abcd' - assertInvalid(tx, 'AccountSet: invalid field TransferRate') + assertInvalid( + tx, + 'AccountSet: invalid field TransferRate, expected a valid number', + ) }) it(`throws w/ invalid TickSize`, function () { tx.TickSize = 20 - assertInvalid(tx, 'AccountSet: invalid field TickSize') + assertInvalid( + tx, + 'AccountSet: invalid field TickSize, expected a valid number between bounds', + ) }) it(`throws w/ invalid NFTokenMinter`, function () { tx.NFTokenMinter = '' - assertInvalid(tx, 'AccountSet: invalid field NFTokenMinter') + assertInvalid( + tx, + 'AccountSet: invalid field NFTokenMinter, expected a valid account address', + ) }) }) diff --git a/packages/xrpl/test/models/checkCreate.test.ts b/packages/xrpl/test/models/checkCreate.test.ts index de1d86d5e6..69347590e6 100644 --- a/packages/xrpl/test/models/checkCreate.test.ts +++ b/packages/xrpl/test/models/checkCreate.test.ts @@ -40,7 +40,10 @@ describe('CheckCreate', function () { Fee: '12', } as any - assertInvalid(invalidDestination, 'CheckCreate: invalid field Destination') + assertInvalid( + invalidDestination, + 'CheckCreate: invalid field Destination, expected a valid account address', + ) }) it(`throws w/ invalid SendMax`, function () { @@ -56,7 +59,10 @@ describe('CheckCreate', function () { Fee: '12', } as any - assertInvalid(invalidSendMax, 'CheckCreate: invalid field SendMax') + assertInvalid( + invalidSendMax, + 'CheckCreate: invalid field SendMax, expected a valid Amount', + ) }) it(`throws w/ invalid DestinationTag`, function () { @@ -74,7 +80,7 @@ describe('CheckCreate', function () { assertInvalid( invalidDestinationTag, - 'CheckCreate: invalid field DestinationTag', + 'CheckCreate: invalid field DestinationTag, expected a valid number', ) }) @@ -91,7 +97,10 @@ describe('CheckCreate', function () { Fee: '12', } as any - assertInvalid(invalidExpiration, 'CheckCreate: invalid field Expiration') + assertInvalid( + invalidExpiration, + 'CheckCreate: invalid field Expiration, expected a valid number', + ) }) it(`throws w/ invalid InvoiceID`, function () { @@ -106,6 +115,9 @@ describe('CheckCreate', function () { Fee: '12', } as any - assertInvalid(invalidInvoiceID, 'CheckCreate: invalid field InvoiceID') + assertInvalid( + invalidInvoiceID, + 'CheckCreate: invalid field InvoiceID, expected a valid hex string', + ) }) }) diff --git a/packages/xrpl/test/testUtils.ts b/packages/xrpl/test/testUtils.ts index 654fbfe3cf..88801a6f83 100644 --- a/packages/xrpl/test/testUtils.ts +++ b/packages/xrpl/test/testUtils.ts @@ -80,8 +80,18 @@ export function assertTxValidationError( validateTx: (tx: any) => void, errorMessage: string, ): void { - assert.throws(() => validateTx(tx), ValidationError, errorMessage) - assert.throws(() => validate(tx), ValidationError, errorMessage) + assert.throws( + () => validateTx(tx), + ValidationError, + // eslint-disable-next-line require-unicode-regexp -- TS complains if it's included + new RegExp(`^${errorMessage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, 'u'), + ) + assert.throws( + () => validate(tx), + ValidationError, + // eslint-disable-next-line require-unicode-regexp -- TS complains if it's included + new RegExp(`^${errorMessage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, 'u'), + ) } /** From 79f82d65a3fa9150b7092c73b291a12275c478d2 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 27 Feb 2025 10:35:54 -0700 Subject: [PATCH 21/46] fix rest of tests --- packages/xrpl/src/models/common/index.ts | 4 +- .../transactions/MPTokenIssuanceCreate.ts | 12 +--- .../models/transactions/NFTokenAcceptOffer.ts | 3 +- .../src/models/transactions/NFTokenMint.ts | 5 -- .../src/models/transactions/NFTokenModify.ts | 4 -- .../XChainAddAccountCreateAttestation.ts | 3 +- .../transactions/XChainAddClaimAttestation.ts | 4 +- .../src/models/transactions/XChainClaim.ts | 5 +- .../src/models/transactions/XChainCommit.ts | 5 +- .../src/models/transactions/checkCancel.ts | 2 +- .../xrpl/src/models/transactions/checkCash.ts | 2 +- .../src/models/transactions/checkCreate.ts | 2 +- .../xrpl/src/models/transactions/clawback.ts | 1 + .../xrpl/src/models/transactions/common.ts | 68 +++++++++++++------ .../models/transactions/credentialAccept.ts | 2 +- .../models/transactions/credentialCreate.ts | 39 ++++------- .../xrpl/src/models/transactions/oracleSet.ts | 2 +- .../xrpl/src/models/transactions/payment.ts | 6 +- .../transactions/paymentChannelClaim.ts | 7 +- .../transactions/paymentChannelCreate.ts | 5 +- .../models/transactions/paymentChannelFund.ts | 5 +- .../transactions/permissionedDomainDelete.ts | 2 +- .../transactions/permissionedDomainSet.ts | 2 +- packages/xrpl/src/models/utils/index.ts | 2 +- packages/xrpl/test/models/AMMBid.test.ts | 10 +-- packages/xrpl/test/models/AMMClawback.test.ts | 12 ++-- packages/xrpl/test/models/AMMCreate.test.ts | 15 ++-- packages/xrpl/test/models/AMMDelete.test.ts | 6 +- packages/xrpl/test/models/AMMDeposit.test.ts | 18 +++-- packages/xrpl/test/models/AMMVote.test.ts | 15 ++-- packages/xrpl/test/models/AMMWithdraw.test.ts | 18 +++-- .../xrpl/test/models/CredentialAccept.test.ts | 9 +-- .../xrpl/test/models/CredentialCreate.test.ts | 18 +++-- .../xrpl/test/models/CredentialDelete.test.ts | 12 ++-- packages/xrpl/test/models/DIDSet.test.ts | 9 ++- .../test/models/MPTokenIssuanceCreate.test.ts | 2 +- .../test/models/NFTokenAcceptOffer.test.ts | 5 +- .../test/models/NFTokenCreateOffer.test.ts | 5 +- packages/xrpl/test/models/NFTokenMint.test.ts | 5 +- .../xrpl/test/models/NFTokenModify.test.ts | 5 +- .../models/XChainAccountCreateCommit.test.ts | 17 +++-- .../XChainAddAccountCreateAttestation.test.ts | 21 +++--- .../models/XChainAddClaimAttestation.test.ts | 36 +++++++--- packages/xrpl/test/models/XChainClaim.test.ts | 25 +++++-- .../xrpl/test/models/XChainCommit.test.ts | 20 ++++-- .../test/models/XChainCreateBridge.test.ts | 12 +++- .../test/models/XChainCreateClaimID.test.ts | 15 +++- .../test/models/XChainModifyBridge.test.ts | 12 +++- packages/xrpl/test/models/accountSet.test.ts | 15 ++-- packages/xrpl/test/models/checkCancel.test.ts | 5 +- packages/xrpl/test/models/checkCash.test.ts | 15 +++- packages/xrpl/test/models/clawback.test.ts | 10 ++- .../xrpl/test/models/depositPreauth.test.ts | 6 +- .../xrpl/test/models/escrowCancel.test.ts | 10 ++- .../xrpl/test/models/escrowCreate.test.ts | 30 ++++++-- .../xrpl/test/models/escrowFinish.test.ts | 23 +++++-- packages/xrpl/test/models/offerCancel.test.ts | 5 +- packages/xrpl/test/models/offerCreate.test.ts | 20 ++++-- .../xrpl/test/models/oracleDelete.test.ts | 3 +- packages/xrpl/test/models/oracleSet.test.ts | 15 ++-- packages/xrpl/test/models/payment.test.ts | 43 +++++++++--- .../test/models/paymentChannelClaim.test.ts | 25 +++++-- .../test/models/paymentChannelCreate.test.ts | 30 ++++++-- .../test/models/paymentChannelFund.test.ts | 15 +++- .../models/permissionedDomainDelete.test.ts | 3 +- .../test/models/permissionedDomainSet.test.ts | 3 +- .../xrpl/test/models/setRegularKey.test.ts | 5 +- .../xrpl/test/models/ticketCreate.test.ts | 20 ++++-- packages/xrpl/test/models/trustSet.test.ts | 15 +++- packages/xrpl/test/wallet/index.test.ts | 2 +- 70 files changed, 574 insertions(+), 258 deletions(-) diff --git a/packages/xrpl/src/models/common/index.ts b/packages/xrpl/src/models/common/index.ts index cd16b08a49..0da6a5eb39 100644 --- a/packages/xrpl/src/models/common/index.ts +++ b/packages/xrpl/src/models/common/index.ts @@ -16,6 +16,8 @@ export interface IssuedCurrency { export type Currency = IssuedCurrency | XRP +export type XRPAmount = string + export interface IssuedCurrencyAmount extends IssuedCurrency { value: string } @@ -25,7 +27,7 @@ export interface MPTAmount { value: string } -export type Amount = IssuedCurrencyAmount | string +export type Amount = IssuedCurrencyAmount | XRPAmount export interface Balance { currency: string diff --git a/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts b/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts index 3af14f525a..14df23086e 100644 --- a/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts +++ b/packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts @@ -1,5 +1,5 @@ import { ValidationError } from '../../errors' -import { isHex, INTEGER_SANITY_CHECK, isFlagEnabled } from '../utils' +import { INTEGER_SANITY_CHECK, isFlagEnabled } from '../utils' import { BaseTransaction, @@ -107,7 +107,7 @@ export interface MPTokenIssuanceCreate extends BaseTransaction { /** * Arbitrary metadata about this issuance, in hex format. */ - MPTokenMetadata?: string | null + MPTokenMetadata?: string Flags?: number | MPTokenIssuanceCreateFlagsInterface } @@ -131,18 +131,12 @@ export function validateMPTokenIssuanceCreate( validateOptionalField(tx, 'TransferFee', isNumber) validateOptionalField(tx, 'AssetScale', isNumber) - if (isString(tx.MPTokenMetadata) && tx.MPTokenMetadata === '') { + if (isHexString(tx.MPTokenMetadata) && tx.MPTokenMetadata === '') { throw new ValidationError( 'MPTokenIssuanceCreate: MPTokenMetadata must not be empty string', ) } - if (isString(tx.MPTokenMetadata) && !isHex(tx.MPTokenMetadata)) { - throw new ValidationError( - 'MPTokenIssuanceCreate: MPTokenMetadata must be in hex format', - ) - } - if (isString(tx.MaximumAmount)) { if (!INTEGER_SANITY_CHECK.exec(tx.MaximumAmount)) { throw new ValidationError('MPTokenIssuanceCreate: Invalid MaximumAmount') diff --git a/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts b/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts index 49b3cd0d5c..3398bee3b5 100644 --- a/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts +++ b/packages/xrpl/src/models/transactions/NFTokenAcceptOffer.ts @@ -76,8 +76,9 @@ export interface NFTokenAcceptOfferMetadata extends TransactionMetadataBase { function validateNFTokenBrokerFee(tx: Record): void { const value = parseAmountValue(tx.NFTokenBrokerFee) if (Number.isNaN(value)) { + // already checked, additional sanity check throw new ValidationError( - 'NFTokenAcceptOffer: invalid field NFTokenBrokerFee', + 'NFTokenAcceptOffer: invalid field NFTokenBrokerFee, expected a valid Amount', ) } diff --git a/packages/xrpl/src/models/transactions/NFTokenMint.ts b/packages/xrpl/src/models/transactions/NFTokenMint.ts index b2b6b31d3f..1b0adcb18c 100644 --- a/packages/xrpl/src/models/transactions/NFTokenMint.ts +++ b/packages/xrpl/src/models/transactions/NFTokenMint.ts @@ -1,5 +1,4 @@ import { ValidationError } from '../../errors' -import { isHex } from '../utils' import { Account, @@ -138,8 +137,4 @@ export function validateNFTokenMint(tx: Record): void { if (typeof tx.URI === 'string' && tx.URI === '') { throw new ValidationError('NFTokenMint: URI must not be empty string') } - - if (typeof tx.URI === 'string' && !isHex(tx.URI)) { - throw new ValidationError('NFTokenMint: URI must be in hex format') - } } diff --git a/packages/xrpl/src/models/transactions/NFTokenModify.ts b/packages/xrpl/src/models/transactions/NFTokenModify.ts index 70734aea7f..ecdce3af25 100644 --- a/packages/xrpl/src/models/transactions/NFTokenModify.ts +++ b/packages/xrpl/src/models/transactions/NFTokenModify.ts @@ -1,5 +1,4 @@ import { ValidationError } from '../../errors' -import { isHex } from '../utils' import { BaseTransaction, @@ -60,8 +59,5 @@ export function validateNFTokenModify(tx: Record): void { if (tx.URI === '') { throw new ValidationError('NFTokenModify: URI must not be empty string') } - if (!isHex(tx.URI)) { - throw new ValidationError('NFTokenModify: URI must be in hex format') - } } } diff --git a/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts b/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts index badfc63473..272066700f 100644 --- a/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts +++ b/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts @@ -7,7 +7,6 @@ import { isAmount, isHexString, isNumber, - isString, isXChainBridge, validateBaseTransaction, validateRequiredField, @@ -117,7 +116,7 @@ export function validateXChainAddAccountCreateAttestation( validateRequiredField( tx, 'XChainAccountCreateCount', - (inp) => isNumber(inp) || isString(inp), + (inp) => isNumber(inp) || isHexString(inp), ) validateRequiredField(tx, 'XChainBridge', isXChainBridge) diff --git a/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts b/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts index 7f3dd5503e..856ee9f3b5 100644 --- a/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts +++ b/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts @@ -7,7 +7,6 @@ import { isAmount, isHexString, isNumber, - isString, isXChainBridge, validateBaseTransaction, validateOptionalField, @@ -113,6 +112,7 @@ export function validateXChainAddClaimAttestation( validateRequiredField( tx, 'XChainClaimID', - (inp) => isNumber(inp) || isString(inp), + (inp) => isNumber(inp) || isHexString(inp), + 'expected a number or hex string', ) } diff --git a/packages/xrpl/src/models/transactions/XChainClaim.ts b/packages/xrpl/src/models/transactions/XChainClaim.ts index 124f5f468c..948c048824 100644 --- a/packages/xrpl/src/models/transactions/XChainClaim.ts +++ b/packages/xrpl/src/models/transactions/XChainClaim.ts @@ -5,8 +5,8 @@ import { BaseTransaction, isAccount, isAmount, + isHexString, isNumber, - isString, isXChainBridge, validateBaseTransaction, validateOptionalField, @@ -68,7 +68,8 @@ export function validateXChainClaim(tx: Record): void { validateRequiredField( tx, 'XChainClaimID', - (inp) => isNumber(inp) || isString(inp), + (inp) => isNumber(inp) || isHexString(inp), + 'expected a number or hex string', ) validateRequiredField(tx, 'Destination', isAccount) diff --git a/packages/xrpl/src/models/transactions/XChainCommit.ts b/packages/xrpl/src/models/transactions/XChainCommit.ts index a7434c0fbd..6b3e4834f5 100644 --- a/packages/xrpl/src/models/transactions/XChainCommit.ts +++ b/packages/xrpl/src/models/transactions/XChainCommit.ts @@ -5,8 +5,8 @@ import { BaseTransaction, isAccount, isAmount, + isHexString, isNumber, - isString, isXChainBridge, validateBaseTransaction, validateOptionalField, @@ -67,7 +67,8 @@ export function validateXChainCommit(tx: Record): void { validateRequiredField( tx, 'XChainClaimID', - (inp) => isNumber(inp) || isString(inp), + (inp) => isNumber(inp) || isHexString(inp), + 'expected a number or hex string', ) validateOptionalField(tx, 'OtherChainDestination', isAccount) diff --git a/packages/xrpl/src/models/transactions/checkCancel.ts b/packages/xrpl/src/models/transactions/checkCancel.ts index 9efc0908b1..acca857d23 100644 --- a/packages/xrpl/src/models/transactions/checkCancel.ts +++ b/packages/xrpl/src/models/transactions/checkCancel.ts @@ -1,6 +1,6 @@ import { BaseTransaction, - isString, + isHexString, validateBaseTransaction, validateRequiredField, } from './common' diff --git a/packages/xrpl/src/models/transactions/checkCash.ts b/packages/xrpl/src/models/transactions/checkCash.ts index 971db27773..33d243393e 100644 --- a/packages/xrpl/src/models/transactions/checkCash.ts +++ b/packages/xrpl/src/models/transactions/checkCash.ts @@ -6,8 +6,8 @@ import { validateBaseTransaction, isAmount, validateRequiredField, - isString, validateOptionalField, + isHexString, } from './common' /** diff --git a/packages/xrpl/src/models/transactions/checkCreate.ts b/packages/xrpl/src/models/transactions/checkCreate.ts index 9c2cc0c77f..32f9b38a27 100644 --- a/packages/xrpl/src/models/transactions/checkCreate.ts +++ b/packages/xrpl/src/models/transactions/checkCreate.ts @@ -9,7 +9,7 @@ import { isNumber, Account, isAmount, - isString, + isHexString, } from './common' /** diff --git a/packages/xrpl/src/models/transactions/clawback.ts b/packages/xrpl/src/models/transactions/clawback.ts index 6699953f4a..627451e92e 100644 --- a/packages/xrpl/src/models/transactions/clawback.ts +++ b/packages/xrpl/src/models/transactions/clawback.ts @@ -48,6 +48,7 @@ export function validateClawback(tx: Record): void { tx, 'Amount', (inp) => isIssuedCurrency(inp) || isMPTAmount(inp), + 'expected a valid non-XRP Amount', ) if (isIssuedCurrency(tx.Amount)) { diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 92663d9ee5..5c9ae4d47f 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -1,5 +1,4 @@ /* eslint-disable max-lines -- common utility file */ -import { HEX_REGEX } from '@xrplf/isomorphic/utils' import { isValidClassicAddress, isValidXAddress } from 'ripple-address-codec' import { TRANSACTION_TYPES } from 'ripple-binary-codec' @@ -13,6 +12,7 @@ import { Memo, Signer, XChainBridge, + XRPAmount, } from '../common' import { isHex, onlyHasFields } from '../utils' @@ -149,6 +149,20 @@ export function isCurrency(input: unknown): input is Currency { ) } +/** + * Verify the form and type of an IssuedCurrencyAmount at runtime. + * + * @param input - The input to check the form and type of. + * @returns Whether the IssuedCurrencyAmount is properly formed. + */ +export function isXRPAmount(input: unknown): input is XRPAmount { + return ( + isString(input) && + !Number.isNaN(Number(input)) && + Number.isInteger(Number(input)) + ) +} + /** * Verify the form and type of an IssuedCurrencyAmount at runtime. * @@ -253,9 +267,10 @@ const invalidMessagesMap: Record = { isAccount: 'expected a valid account address', isAmount: 'expected a valid Amount', isCurrency: 'expected a valid Currency', - isIssuedCurrency: 'expected a valid IssuedCurrencyAmount', - isMPTAmount: 'expected a valid MPTAmount', - isXChainBridge: 'expected a valid XChainBridge', + isXRPAmount: 'expected a valid XRP Amount', + isIssuedCurrency: 'expected a valid IssuedCurrencyAmount object', + isMPTAmount: 'expected a valid MPTAmount object', + isXChainBridge: 'expected a valid XChainBridge object', isMemo: 'expected a valid Memo', isSigner: 'expected a valid Signer', isRecord: 'expected a valid Record', @@ -273,12 +288,15 @@ const invalidMessagesMap: Record = { * @param tx - The transaction input to check the form and type of. * @param paramName - The name of the transaction parameter. * @param checkValidity - The function to use to check the type. - * @throws + * @param invalidMessage -- optional error message. + * @throws ValidationError if the field is missing or invalid. */ +// eslint-disable-next-line max-params -- okay for a helper function export function validateRequiredField( tx: Record, paramName: string, checkValidity: (inp: unknown) => boolean, + invalidMessage?: string, ): void { if (tx[paramName] == null) { throw new ValidationError( @@ -288,9 +306,13 @@ export function validateRequiredField( if (!checkValidity(tx[paramName])) { let errorMessage = `${tx.TransactionType}: invalid field ${paramName}` - const invalidMessage = invalidMessagesMap[checkValidity.name] - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- okay - if (invalidMessage != null) { + if (invalidMessage == null) { + const invalidMessageFromMap = invalidMessagesMap[checkValidity.name] + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, max-depth -- okay + if (invalidMessageFromMap != null) { + errorMessage += `, ${invalidMessageFromMap}` + } + } else { errorMessage += `, ${invalidMessage}` } throw new ValidationError(errorMessage) @@ -303,17 +325,25 @@ export function validateRequiredField( * @param tx - The transaction input to check the form and type of. * @param paramName - The name of the transaction parameter. * @param checkValidity - The function to use to check the type. - * @throws + * @param invalidMessage - optional error message. + * @throws ValidationError if the field is invalid. */ +// eslint-disable-next-line max-params -- okay for a helper function export function validateOptionalField( tx: Record, paramName: string, checkValidity: (inp: unknown) => boolean, + invalidMessage?: string, ): void { if (tx[paramName] !== undefined && !checkValidity(tx[paramName])) { let errorMessage = `${tx.TransactionType}: invalid field ${paramName}` - const invalidMessage = invalidMessagesMap[checkValidity.name] - if (invalidMessage) { + if (invalidMessage == null) { + const invalidMessageFromMap = invalidMessagesMap[checkValidity.name] + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, max-depth -- okay + if (invalidMessageFromMap != null) { + errorMessage += `, ${invalidMessageFromMap}` + } + } else { errorMessage += `, ${invalidMessage}` } throw new ValidationError(errorMessage) @@ -492,9 +522,9 @@ export function validateCredentialType(tx: Record): void { ) } - if (!isString(tx.CredentialType)) { + if (!isHexString(tx.CredentialType)) { throw new ValidationError( - `${tx.TransactionType}: CredentialType must be a string`, + `${tx.TransactionType}: CredentialType must be a hex string`, ) } if (tx.CredentialType.length === 0) { @@ -506,12 +536,6 @@ export function validateCredentialType(tx: Record): void { `${tx.TransactionType}: CredentialType length cannot be > ${MAX_CREDENTIAL_TYPE_LENGTH}`, ) } - - if (!HEX_REGEX.test(tx.CredentialType)) { - throw new ValidationError( - `${tx.TransactionType}: CredentialType must be encoded in hex`, - ) - } } /** @@ -524,7 +548,7 @@ export function validateCredentialType(tx: Record): void { * PermissionedDomainSet transaction uses 10, other transactions use 8. * @throws Validation Error if the formatting is incorrect */ -// eslint-disable-next-line max-params -- separating logic further will add unnecessary complexity +// eslint-disable-next-line max-params, max-lines-per-function -- separating logic further will add unnecessary complexity export function validateCredentialsList( credentials: unknown, transactionType: string, @@ -535,7 +559,9 @@ export function validateCredentialsList( return } if (!Array.isArray(credentials)) { - throw new ValidationError(`${transactionType}: invalid field Credentials`) + throw new ValidationError( + `${transactionType}: invalid field Credentials, expected a valid array`, + ) } if (credentials.length > maxCredentials) { throw new ValidationError( diff --git a/packages/xrpl/src/models/transactions/credentialAccept.ts b/packages/xrpl/src/models/transactions/credentialAccept.ts index d45790d749..f3c5d56ffd 100644 --- a/packages/xrpl/src/models/transactions/credentialAccept.ts +++ b/packages/xrpl/src/models/transactions/credentialAccept.ts @@ -1,6 +1,6 @@ import { BaseTransaction, - isString, + isAccount, validateBaseTransaction, validateCredentialType, validateRequiredField, diff --git a/packages/xrpl/src/models/transactions/credentialCreate.ts b/packages/xrpl/src/models/transactions/credentialCreate.ts index 97edb24030..f8b3d01a08 100644 --- a/packages/xrpl/src/models/transactions/credentialCreate.ts +++ b/packages/xrpl/src/models/transactions/credentialCreate.ts @@ -1,10 +1,9 @@ -import { HEX_REGEX } from '@xrplf/isomorphic/utils' - import { ValidationError } from '../../errors' import { BaseTransaction, isAccount, + isHexString, isNumber, validateBaseTransaction, validateCredentialType, @@ -55,27 +54,19 @@ export function validateCredentialCreate(tx: Record): void { validateOptionalField(tx, 'Expiration', isNumber) - validateURI(tx.URI) -} - -function validateURI(URI: unknown): void { - if (URI === undefined) { - return - } - - if (typeof URI !== 'string') { - throw new ValidationError('CredentialCreate: invalid field URI') - } - - if (URI.length === 0) { - throw new ValidationError('CredentialCreate: URI cannot be an empty string') - } else if (URI.length > MAX_URI_LENGTH) { - throw new ValidationError( - `CredentialCreate: URI length must be <= ${MAX_URI_LENGTH}`, - ) - } - - if (!HEX_REGEX.test(URI)) { - throw new ValidationError('CredentialCreate: URI must be encoded in hex') + validateOptionalField(tx, 'URI', isHexString) + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- checked above + const uriLength = (tx.URI as string | undefined)?.length + if (uriLength !== undefined) { + if (uriLength === 0) { + throw new ValidationError( + 'CredentialCreate: URI cannot be an empty string', + ) + } + if (uriLength > MAX_URI_LENGTH) { + throw new ValidationError( + `CredentialCreate: URI length must be <= ${MAX_URI_LENGTH}`, + ) + } } } diff --git a/packages/xrpl/src/models/transactions/oracleSet.ts b/packages/xrpl/src/models/transactions/oracleSet.ts index 694e0dc62a..64aad55fa5 100644 --- a/packages/xrpl/src/models/transactions/oracleSet.ts +++ b/packages/xrpl/src/models/transactions/oracleSet.ts @@ -3,8 +3,8 @@ import { PriceData } from '../common' import { BaseTransaction, + isHexString, isNumber, - isString, validateBaseTransaction, validateOptionalField, validateRequiredField, diff --git a/packages/xrpl/src/models/transactions/payment.ts b/packages/xrpl/src/models/transactions/payment.ts index 1d93416279..20d79e6c22 100644 --- a/packages/xrpl/src/models/transactions/payment.ts +++ b/packages/xrpl/src/models/transactions/payment.ts @@ -13,8 +13,8 @@ import { isNumber, Account, validateCredentialsList, - isString, MAX_AUTHORIZED_CREDENTIALS, + isHexString, } from './common' import type { TransactionMetadataBase } from './metadata' @@ -223,7 +223,9 @@ function checkPartialPayment(tx: Record): void { } if (!isAmount(tx.DeliverMin)) { - throw new ValidationError('Payment: invalid field DeliverMin') + throw new ValidationError( + 'Payment: invalid field DeliverMin, expected a valid Amount', + ) } } } diff --git a/packages/xrpl/src/models/transactions/paymentChannelClaim.ts b/packages/xrpl/src/models/transactions/paymentChannelClaim.ts index ffe751a315..1b80fd4390 100644 --- a/packages/xrpl/src/models/transactions/paymentChannelClaim.ts +++ b/packages/xrpl/src/models/transactions/paymentChannelClaim.ts @@ -1,12 +1,13 @@ import { BaseTransaction, GlobalFlags, - isString, validateBaseTransaction, validateCredentialsList, validateOptionalField, validateRequiredField, MAX_AUTHORIZED_CREDENTIALS, + isHexString, + isXRPAmount, } from './common' /** @@ -151,8 +152,8 @@ export function validatePaymentChannelClaim(tx: Record): void { validateBaseTransaction(tx) validateRequiredField(tx, 'Channel', isHexString) - validateOptionalField(tx, 'Balance', isString) - validateOptionalField(tx, 'Amount', isString) + validateOptionalField(tx, 'Balance', isXRPAmount) + validateOptionalField(tx, 'Amount', isXRPAmount) validateOptionalField(tx, 'Signature', isHexString) validateOptionalField(tx, 'PublicKey', isHexString) diff --git a/packages/xrpl/src/models/transactions/paymentChannelCreate.ts b/packages/xrpl/src/models/transactions/paymentChannelCreate.ts index 6799df8ef9..53130905bd 100644 --- a/packages/xrpl/src/models/transactions/paymentChannelCreate.ts +++ b/packages/xrpl/src/models/transactions/paymentChannelCreate.ts @@ -2,8 +2,9 @@ import { Account, BaseTransaction, isAccount, + isHexString, isNumber, - isString, + isXRPAmount, validateBaseTransaction, validateOptionalField, validateRequiredField, @@ -66,7 +67,7 @@ export function validatePaymentChannelCreate( ): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'Amount', isString) + validateRequiredField(tx, 'Amount', isXRPAmount) validateRequiredField(tx, 'Destination', isAccount) validateOptionalField(tx, 'DestinationTag', isNumber) validateRequiredField(tx, 'SettleDelay', isNumber) diff --git a/packages/xrpl/src/models/transactions/paymentChannelFund.ts b/packages/xrpl/src/models/transactions/paymentChannelFund.ts index 83ac41859e..57064908fc 100644 --- a/packages/xrpl/src/models/transactions/paymentChannelFund.ts +++ b/packages/xrpl/src/models/transactions/paymentChannelFund.ts @@ -1,7 +1,8 @@ import { BaseTransaction, + isHexString, isNumber, - isString, + isXRPAmount, validateBaseTransaction, validateOptionalField, validateRequiredField, @@ -49,6 +50,6 @@ export function validatePaymentChannelFund(tx: Record): void { validateBaseTransaction(tx) validateRequiredField(tx, 'Channel', isHexString) - validateRequiredField(tx, 'Amount', isString) + validateRequiredField(tx, 'Amount', isXRPAmount) validateOptionalField(tx, 'Expiration', isNumber) } diff --git a/packages/xrpl/src/models/transactions/permissionedDomainDelete.ts b/packages/xrpl/src/models/transactions/permissionedDomainDelete.ts index 8bfd4492a6..a96607dfd0 100644 --- a/packages/xrpl/src/models/transactions/permissionedDomainDelete.ts +++ b/packages/xrpl/src/models/transactions/permissionedDomainDelete.ts @@ -1,6 +1,6 @@ import { BaseTransaction, - isString, + isHexString, validateBaseTransaction, validateRequiredField, } from './common' diff --git a/packages/xrpl/src/models/transactions/permissionedDomainSet.ts b/packages/xrpl/src/models/transactions/permissionedDomainSet.ts index 5876c4ee8c..f04dffad56 100644 --- a/packages/xrpl/src/models/transactions/permissionedDomainSet.ts +++ b/packages/xrpl/src/models/transactions/permissionedDomainSet.ts @@ -2,11 +2,11 @@ import { AuthorizeCredential } from '../common' import { BaseTransaction, - isString, validateBaseTransaction, validateOptionalField, validateRequiredField, validateCredentialsList, + isHexString, } from './common' const MAX_ACCEPTED_CREDENTIALS = 10 diff --git a/packages/xrpl/src/models/utils/index.ts b/packages/xrpl/src/models/utils/index.ts index c03d9d3f6f..8848f3f318 100644 --- a/packages/xrpl/src/models/utils/index.ts +++ b/packages/xrpl/src/models/utils/index.ts @@ -1,4 +1,4 @@ -const HEX_REGEX = /^[0-9A-Fa-f]+$/u +const HEX_REGEX = /^[0-9A-Fa-f]*$/u export const INTEGER_SANITY_CHECK = /^[0-9]+$/u /** diff --git a/packages/xrpl/test/models/AMMBid.test.ts b/packages/xrpl/test/models/AMMBid.test.ts index 1e372cc4f7..d6ce1ce7e2 100644 --- a/packages/xrpl/test/models/AMMBid.test.ts +++ b/packages/xrpl/test/models/AMMBid.test.ts @@ -72,7 +72,8 @@ describe('AMMBid', function () { it(`throws w/ Asset must be a Currency`, function () { bid.Asset = 1234 - const errorMessage = 'AMMBid: invalid field Asset' + const errorMessage = + 'AMMBid: invalid field Asset, expected a valid Currency' assertInvalid(bid, errorMessage) }) @@ -84,19 +85,20 @@ describe('AMMBid', function () { it(`throws w/ Asset2 must be a Currency`, function () { bid.Asset2 = 1234 - const errorMessage = 'AMMBid: invalid field Asset2' + const errorMessage = + 'AMMBid: invalid field Asset2, expected a valid Currency' assertInvalid(bid, errorMessage) }) it(`throws w/ BidMin must be an Amount`, function () { bid.BidMin = 5 - const errorMessage = 'AMMBid: invalid field BidMin' + const errorMessage = 'AMMBid: invalid field BidMin, expected a valid Amount' assertInvalid(bid, errorMessage) }) it(`throws w/ BidMax must be an Amount`, function () { bid.BidMax = 10 - const errorMessage = 'AMMBid: invalid field BidMax' + const errorMessage = 'AMMBid: invalid field BidMax, expected a valid Amount' assertInvalid(bid, errorMessage) }) diff --git a/packages/xrpl/test/models/AMMClawback.test.ts b/packages/xrpl/test/models/AMMClawback.test.ts index 065839ee8f..9e38594685 100644 --- a/packages/xrpl/test/models/AMMClawback.test.ts +++ b/packages/xrpl/test/models/AMMClawback.test.ts @@ -59,7 +59,8 @@ describe('AMMClawback', function () { it(`throws w/ invalid field Holder`, function () { ammClawback.Holder = 1234 - const errorMessage = 'AMMClawback: invalid field Holder' + const errorMessage = + 'AMMClawback: invalid field Holder, expected a valid account address' assertInvalid(ammClawback, errorMessage) }) @@ -77,7 +78,8 @@ describe('AMMClawback', function () { it(`throws w/ invalid field Asset`, function () { ammClawback.Asset = '1000' - const errorMessage = 'AMMClawback: invalid field Asset' + const errorMessage = + 'AMMClawback: invalid field Asset, expected a valid Currency' assertInvalid(ammClawback, errorMessage) }) @@ -95,13 +97,15 @@ describe('AMMClawback', function () { it(`throws w/ invalid field Asset2`, function () { ammClawback.Asset2 = '1000' - const errorMessage = 'AMMClawback: invalid field Asset2' + const errorMessage = + 'AMMClawback: invalid field Asset2, expected a valid Currency' assertInvalid(ammClawback, errorMessage) }) it(`throws w/ invalid field Amount`, function () { ammClawback.Amount = 1000 - const errorMessage = 'AMMClawback: invalid field Amount' + const errorMessage = + 'AMMClawback: invalid field Amount, expected a valid Amount' assertInvalid(ammClawback, errorMessage) }) diff --git a/packages/xrpl/test/models/AMMCreate.test.ts b/packages/xrpl/test/models/AMMCreate.test.ts index 1fb6270ee2..b8e0ca6ecb 100644 --- a/packages/xrpl/test/models/AMMCreate.test.ts +++ b/packages/xrpl/test/models/AMMCreate.test.ts @@ -40,7 +40,8 @@ describe('AMMCreate', function () { it(`throws w/ Amount must be an Amount`, function () { ammCreate.Amount = 1000 - const errorMessage = 'AMMCreate: invalid field Amount' + const errorMessage = + 'AMMCreate: invalid field Amount, expected a valid Amount' assertInvalid(ammCreate, errorMessage) }) @@ -52,7 +53,8 @@ describe('AMMCreate', function () { it(`throws w/ Amount2 must be an Amount`, function () { ammCreate.Amount2 = 1000 - const errorMessage = 'AMMCreate: invalid field Amount2' + const errorMessage = + 'AMMCreate: invalid field Amount2, expected a valid Amount' assertInvalid(ammCreate, errorMessage) }) @@ -64,19 +66,22 @@ describe('AMMCreate', function () { it(`throws w/ TradingFee must be a number`, function () { ammCreate.TradingFee = 'abcd' - const errorMessage = 'AMMCreate: invalid field TradingFee' + const errorMessage = + 'AMMCreate: invalid field TradingFee, expected a valid number' assertInvalid(ammCreate, errorMessage) }) it(`throws when TradingFee is greater than 1000`, function () { ammCreate.TradingFee = 1001 - const errorMessage = 'AMMCreate: invalid field TradingFee' + const errorMessage = + 'AMMCreate: invalid field TradingFee, expected a valid number' assertInvalid(ammCreate, errorMessage) }) it(`throws when TradingFee is a negative number`, function () { ammCreate.TradingFee = -1 - const errorMessage = 'AMMCreate: invalid field TradingFee' + const errorMessage = + 'AMMCreate: invalid field TradingFee, expected a valid number' assertInvalid(ammCreate, errorMessage) }) }) diff --git a/packages/xrpl/test/models/AMMDelete.test.ts b/packages/xrpl/test/models/AMMDelete.test.ts index d669341f7f..0f4761eb7b 100644 --- a/packages/xrpl/test/models/AMMDelete.test.ts +++ b/packages/xrpl/test/models/AMMDelete.test.ts @@ -41,7 +41,8 @@ describe('AMMDelete', function () { it(`throws w/ Asset must be a Currency`, function () { ammDelete.Asset = 1234 - const errorMessage = 'AMMDelete: invalid field Asset' + const errorMessage = + 'AMMDelete: invalid field Asset, expected a valid Currency' assertInvalid(ammDelete, errorMessage) }) @@ -53,7 +54,8 @@ describe('AMMDelete', function () { it(`throws w/ Asset2 must be a Currency`, function () { ammDelete.Asset2 = 1234 - const errorMessage = 'AMMDelete: invalid field Asset2' + const errorMessage = + 'AMMDelete: invalid field Asset2, expected a valid Currency' assertInvalid(ammDelete, errorMessage) }) }) diff --git a/packages/xrpl/test/models/AMMDeposit.test.ts b/packages/xrpl/test/models/AMMDeposit.test.ts index f5e7fdbb18..9dade37786 100644 --- a/packages/xrpl/test/models/AMMDeposit.test.ts +++ b/packages/xrpl/test/models/AMMDeposit.test.ts @@ -82,7 +82,8 @@ describe('AMMDeposit', function () { it(`throws w/ Asset must be a Currency`, function () { deposit.Asset = 1234 - const errorMessage = 'AMMDeposit: invalid field Asset' + const errorMessage = + 'AMMDeposit: invalid field Asset, expected a valid Currency' assertInvalid(deposit, errorMessage) }) @@ -94,7 +95,8 @@ describe('AMMDeposit', function () { it(`throws w/ Asset2 must be a Currency`, function () { deposit.Asset2 = 1234 - const errorMessage = 'AMMDeposit: invalid field Asset2' + const errorMessage = + 'AMMDeposit: invalid field Asset2, expected a valid Currency' assertInvalid(deposit, errorMessage) }) @@ -121,27 +123,31 @@ describe('AMMDeposit', function () { it(`throws w/ LPTokenOut must be an IssuedCurrencyAmount`, function () { deposit.LPTokenOut = 1234 - const errorMessage = 'AMMDeposit: invalid field LPTokenOut' + const errorMessage = + 'AMMDeposit: invalid field LPTokenOut, expected a valid IssuedCurrencyAmount object' assertInvalid(deposit, errorMessage) }) it(`throws w/ Amount must be an Amount`, function () { deposit.Amount = 1234 - const errorMessage = 'AMMDeposit: invalid field Amount' + const errorMessage = + 'AMMDeposit: invalid field Amount, expected a valid Amount' assertInvalid(deposit, errorMessage) }) it(`throws w/ Amount2 must be an Amount`, function () { deposit.Amount = '1000' deposit.Amount2 = 1234 - const errorMessage = 'AMMDeposit: invalid field Amount2' + const errorMessage = + 'AMMDeposit: invalid field Amount2, expected a valid Amount' assertInvalid(deposit, errorMessage) }) it(`throws w/ EPrice must be an Amount`, function () { deposit.Amount = '1000' deposit.EPrice = 1234 - const errorMessage = 'AMMDeposit: invalid field EPrice' + const errorMessage = + 'AMMDeposit: invalid field EPrice, expected a valid Amount' assertInvalid(deposit, errorMessage) }) }) diff --git a/packages/xrpl/test/models/AMMVote.test.ts b/packages/xrpl/test/models/AMMVote.test.ts index c35de2efb3..1dc8b80fb1 100644 --- a/packages/xrpl/test/models/AMMVote.test.ts +++ b/packages/xrpl/test/models/AMMVote.test.ts @@ -41,7 +41,8 @@ describe('AMMVote', function () { it(`throws w/ Asset must be a Currency`, function () { vote.Asset = 1234 - const errorMessage = 'AMMVote: invalid field Asset' + const errorMessage = + 'AMMVote: invalid field Asset, expected a valid Currency' assertInvalid(vote, errorMessage) }) @@ -53,7 +54,8 @@ describe('AMMVote', function () { it(`throws w/ Asset2 must be a Currency`, function () { vote.Asset2 = 1234 - const errorMessage = 'AMMVote: invalid field Asset2' + const errorMessage = + 'AMMVote: invalid field Asset2, expected a valid Currency' assertInvalid(vote, errorMessage) }) @@ -65,19 +67,22 @@ describe('AMMVote', function () { it(`throws w/ TradingFee must be a number`, function () { vote.TradingFee = 'abcd' - const errorMessage = 'AMMVote: invalid field TradingFee' + const errorMessage = + 'AMMVote: invalid field TradingFee, expected a valid number' assertInvalid(vote, errorMessage) }) it(`throws when TradingFee is greater than AMM_MAX_TRADING_FEE`, function () { vote.TradingFee = 1001 - const errorMessage = 'AMMVote: invalid field TradingFee' + const errorMessage = + 'AMMVote: invalid field TradingFee, expected a valid number' assertInvalid(vote, errorMessage) }) it(`throws when TradingFee is a negative number`, function () { vote.TradingFee = -1 - const errorMessage = 'AMMVote: invalid field TradingFee' + const errorMessage = + 'AMMVote: invalid field TradingFee, expected a valid number' assertInvalid(vote, errorMessage) }) }) diff --git a/packages/xrpl/test/models/AMMWithdraw.test.ts b/packages/xrpl/test/models/AMMWithdraw.test.ts index 3824c9a425..c7480246df 100644 --- a/packages/xrpl/test/models/AMMWithdraw.test.ts +++ b/packages/xrpl/test/models/AMMWithdraw.test.ts @@ -93,7 +93,8 @@ describe('AMMWithdraw', function () { it(`throws w/ Asset must be a Currency`, function () { withdraw.Asset = 1234 - const errorMessage = 'AMMWithdraw: invalid field Asset' + const errorMessage = + 'AMMWithdraw: invalid field Asset, expected a valid Currency' assertInvalid(withdraw, errorMessage) }) @@ -105,7 +106,8 @@ describe('AMMWithdraw', function () { it(`throws w/ Asset2 must be a Currency`, function () { withdraw.Asset2 = 1234 - const errorMessage = 'AMMWithdraw: invalid field Asset2' + const errorMessage = + 'AMMWithdraw: invalid field Asset2, expected a valid Currency' assertInvalid(withdraw, errorMessage) }) @@ -127,27 +129,31 @@ describe('AMMWithdraw', function () { it(`throws w/ LPTokenIn must be an IssuedCurrencyAmount`, function () { withdraw.LPTokenIn = 1234 - const errorMessage = 'AMMWithdraw: invalid field LPTokenIn' + const errorMessage = + 'AMMWithdraw: invalid field LPTokenIn, expected a valid IssuedCurrencyAmount object' assertInvalid(withdraw, errorMessage) }) it(`throws w/ Amount must be an Amount`, function () { withdraw.Amount = 1234 - const errorMessage = 'AMMWithdraw: invalid field Amount' + const errorMessage = + 'AMMWithdraw: invalid field Amount, expected a valid Amount' assertInvalid(withdraw, errorMessage) }) it(`throws w/ Amount2 must be an Amount`, function () { withdraw.Amount = '1000' withdraw.Amount2 = 1234 - const errorMessage = 'AMMWithdraw: invalid field Amount2' + const errorMessage = + 'AMMWithdraw: invalid field Amount2, expected a valid Amount' assertInvalid(withdraw, errorMessage) }) it(`throws w/ EPrice must be an Amount`, function () { withdraw.Amount = '1000' withdraw.EPrice = 1234 - const errorMessage = 'AMMWithdraw: invalid field EPrice' + const errorMessage = + 'AMMWithdraw: invalid field EPrice, expected a valid Amount' assertInvalid(withdraw, errorMessage) }) }) diff --git a/packages/xrpl/test/models/CredentialAccept.test.ts b/packages/xrpl/test/models/CredentialAccept.test.ts index df49f3aac0..f0f890e614 100644 --- a/packages/xrpl/test/models/CredentialAccept.test.ts +++ b/packages/xrpl/test/models/CredentialAccept.test.ts @@ -39,7 +39,8 @@ describe('CredentialAccept', function () { it(`throws w/ Account not a string`, function () { credentialAccept.Account = 123 - const errorMessage = 'CredentialAccept: invalid field Account' + const errorMessage = + 'CredentialAccept: invalid field Account, expected a valid account address' assertInvalid(credentialAccept, errorMessage) }) @@ -51,7 +52,8 @@ describe('CredentialAccept', function () { it(`throws w/ Issuer not a string`, function () { credentialAccept.Issuer = 123 - const errorMessage = 'CredentialAccept: invalid field Issuer' + const errorMessage = + 'CredentialAccept: invalid field Issuer, expected a valid account address' assertInvalid(credentialAccept, errorMessage) }) @@ -77,8 +79,7 @@ describe('CredentialAccept', function () { it(`throws w/ credentialType field not hex`, function () { credentialAccept.CredentialType = 'this is not hex' - const errorMessage = - 'CredentialAccept: CredentialType must be encoded in hex' + const errorMessage = 'CredentialAccept: CredentialType must be a hex string' assertInvalid(credentialAccept, errorMessage) }) }) diff --git a/packages/xrpl/test/models/CredentialCreate.test.ts b/packages/xrpl/test/models/CredentialCreate.test.ts index d43f86b380..b811ea9e03 100644 --- a/packages/xrpl/test/models/CredentialCreate.test.ts +++ b/packages/xrpl/test/models/CredentialCreate.test.ts @@ -41,7 +41,8 @@ describe('credentialCreate', function () { it(`throws w/ Account not string`, function () { credentialCreate.Account = 123 - const errorMessage = 'CredentialCreate: invalid field Account' + const errorMessage = + 'CredentialCreate: invalid field Account, expected a valid account address' assertInvalid(credentialCreate, errorMessage) }) @@ -53,7 +54,8 @@ describe('credentialCreate', function () { it(`throws w/ Subject not string`, function () { credentialCreate.Subject = 123 - const errorMessage = 'CredentialCreate: invalid field Subject' + const errorMessage = + 'CredentialCreate: invalid field Subject, expected a valid account address' assertInvalid(credentialCreate, errorMessage) }) @@ -79,20 +81,21 @@ describe('credentialCreate', function () { it(`throws w/ credentialType field not hex`, function () { credentialCreate.CredentialType = 'this is not hex' - const errorMessage = - 'CredentialCreate: CredentialType must be encoded in hex' + const errorMessage = 'CredentialCreate: CredentialType must be a hex string' assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ Expiration field not number`, function () { credentialCreate.Expiration = 'this is not a number' - const errorMessage = 'CredentialCreate: invalid field Expiration' + const errorMessage = + 'CredentialCreate: invalid field Expiration, expected a valid number' assertInvalid(credentialCreate, errorMessage) }) it(`throws w/ URI field not a string`, function () { credentialCreate.URI = 123 - const errorMessage = 'CredentialCreate: invalid field URI' + const errorMessage = + 'CredentialCreate: invalid field URI, expected a valid hex string' assertInvalid(credentialCreate, errorMessage) }) @@ -110,7 +113,8 @@ describe('credentialCreate', function () { it(`throws w/ URI field not hex`, function () { credentialCreate.URI = 'this is not hex' - const errorMessage = 'CredentialCreate: URI must be encoded in hex' + const errorMessage = + 'CredentialCreate: invalid field URI, expected a valid hex string' assertInvalid(credentialCreate, errorMessage) }) }) diff --git a/packages/xrpl/test/models/CredentialDelete.test.ts b/packages/xrpl/test/models/CredentialDelete.test.ts index 6397652a94..01ceeb09dd 100644 --- a/packages/xrpl/test/models/CredentialDelete.test.ts +++ b/packages/xrpl/test/models/CredentialDelete.test.ts @@ -40,19 +40,22 @@ describe('CredentialDelete', function () { it(`throws w/ Account not string`, function () { credentialDelete.Account = 123 - const errorMessage = 'CredentialDelete: invalid field Account' + const errorMessage = + 'CredentialDelete: invalid field Account, expected a valid account address' assertInvalid(credentialDelete, errorMessage) }) it(`throws w/ Subject not string`, function () { credentialDelete.Subject = 123 - const errorMessage = 'CredentialDelete: invalid field Subject' + const errorMessage = + 'CredentialDelete: invalid field Subject, expected a valid account address' assertInvalid(credentialDelete, errorMessage) }) it(`throws w/ Issuer not string`, function () { credentialDelete.Issuer = 123 - const errorMessage = 'CredentialDelete: invalid field Issuer' + const errorMessage = + 'CredentialDelete: invalid field Issuer, expected a valid account address' assertInvalid(credentialDelete, errorMessage) }) @@ -86,8 +89,7 @@ describe('CredentialDelete', function () { it(`throws w/ credentialType field not hex`, function () { credentialDelete.CredentialType = 'this is not hex' - const errorMessage = - 'CredentialDelete: CredentialType must be encoded in hex' + const errorMessage = 'CredentialDelete: CredentialType must be a hex string' assertInvalid(credentialDelete, errorMessage) }) }) diff --git a/packages/xrpl/test/models/DIDSet.test.ts b/packages/xrpl/test/models/DIDSet.test.ts index 0aae8287b2..8e9dba5bac 100644 --- a/packages/xrpl/test/models/DIDSet.test.ts +++ b/packages/xrpl/test/models/DIDSet.test.ts @@ -33,19 +33,22 @@ describe('DIDSet', function () { it('throws w/ invalid Data', function () { tx.Data = 123 - assertInvalid(tx, 'DIDSet: invalid field Data') + assertInvalid(tx, 'DIDSet: invalid field Data, expected a valid hex string') }) it('throws w/ invalid DIDDocument', function () { tx.DIDDocument = 123 - assertInvalid(tx, 'DIDSet: invalid field DIDDocument') + assertInvalid( + tx, + 'DIDSet: invalid field DIDDocument, expected a valid hex string', + ) }) it('throws w/ invalid URI', function () { tx.URI = 123 - assertInvalid(tx, 'DIDSet: invalid field URI') + assertInvalid(tx, 'DIDSet: invalid field URI, expected a valid hex string') }) it('throws w/ empty DID', function () { diff --git a/packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts b/packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts index b0f34737b5..b3f0b0a47d 100644 --- a/packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts +++ b/packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts @@ -54,7 +54,7 @@ describe('MPTokenIssuanceCreate', function () { assertInvalid( invalid, - 'MPTokenIssuanceCreate: MPTokenMetadata must be in hex format', + 'MPTokenIssuanceCreate: invalid field MPTokenMetadata, expected a valid hex string', ) }) diff --git a/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts b/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts index edf7da7ecd..8e84925880 100644 --- a/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts +++ b/packages/xrpl/test/models/NFTokenAcceptOffer.test.ts @@ -169,6 +169,9 @@ describe('NFTokenAcceptOffer', function () { Flags: 2147483648, } as any - assertInvalid(invalid, 'NFTokenAcceptOffer: invalid field NFTokenBrokerFee') + assertInvalid( + invalid, + 'NFTokenAcceptOffer: invalid field NFTokenBrokerFee, expected a valid Amount', + ) }) }) diff --git a/packages/xrpl/test/models/NFTokenCreateOffer.test.ts b/packages/xrpl/test/models/NFTokenCreateOffer.test.ts index d4737f758e..8fe50c9afb 100644 --- a/packages/xrpl/test/models/NFTokenCreateOffer.test.ts +++ b/packages/xrpl/test/models/NFTokenCreateOffer.test.ts @@ -131,7 +131,10 @@ describe('NFTokenCreateOffer', function () { Sequence: 2470665, } as any - assertInvalid(invalid, 'NFTokenCreateOffer: invalid field Amount') + assertInvalid( + invalid, + 'NFTokenCreateOffer: invalid field Amount, expected a valid Amount', + ) }) it(`throws w/ missing Amount`, function () { diff --git a/packages/xrpl/test/models/NFTokenMint.test.ts b/packages/xrpl/test/models/NFTokenMint.test.ts index cecb63a8df..453275252a 100644 --- a/packages/xrpl/test/models/NFTokenMint.test.ts +++ b/packages/xrpl/test/models/NFTokenMint.test.ts @@ -92,6 +92,9 @@ describe('NFTokenMint', function () { URI: 'http://xrpl.org', } as any - assertInvalid(invalid, 'NFTokenMint: URI must be in hex format') + assertInvalid( + invalid, + 'NFTokenMint: invalid field URI, expected a valid hex string', + ) }) }) diff --git a/packages/xrpl/test/models/NFTokenModify.test.ts b/packages/xrpl/test/models/NFTokenModify.test.ts index f139884f5e..7504799b4e 100644 --- a/packages/xrpl/test/models/NFTokenModify.test.ts +++ b/packages/xrpl/test/models/NFTokenModify.test.ts @@ -64,6 +64,9 @@ describe('NFTokenModify', function () { URI: '--', } as any - assertInvalid(invalid, 'NFTokenModify: URI must be in hex format') + assertInvalid( + invalid, + 'NFTokenModify: invalid field URI, expected a valid hex string', + ) }) }) diff --git a/packages/xrpl/test/models/XChainAccountCreateCommit.test.ts b/packages/xrpl/test/models/XChainAccountCreateCommit.test.ts index fa75c98e26..a77328420c 100644 --- a/packages/xrpl/test/models/XChainAccountCreateCommit.test.ts +++ b/packages/xrpl/test/models/XChainAccountCreateCommit.test.ts @@ -50,7 +50,10 @@ describe('XChainAccountCreateCommit', function () { it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assertInvalid(tx, 'XChainAccountCreateCommit: invalid field XChainBridge') + assertInvalid( + tx, + 'XChainAccountCreateCommit: invalid field XChainBridge, expected a valid XChainBridge object', + ) }) it('throws w/ missing SignatureReward', function () { @@ -67,7 +70,7 @@ describe('XChainAccountCreateCommit', function () { assertInvalid( tx, - 'XChainAccountCreateCommit: invalid field SignatureReward', + 'XChainAccountCreateCommit: invalid field SignatureReward, expected a valid Amount', ) }) @@ -80,7 +83,10 @@ describe('XChainAccountCreateCommit', function () { it('throws w/ invalid Destination', function () { tx.Destination = 123 - assertInvalid(tx, 'XChainAccountCreateCommit: invalid field Destination') + assertInvalid( + tx, + 'XChainAccountCreateCommit: invalid field Destination, expected a valid account address', + ) }) it('throws w/ missing Amount', function () { @@ -92,6 +98,9 @@ describe('XChainAccountCreateCommit', function () { it('throws w/ invalid Amount', function () { tx.Amount = { currency: 'ETH' } - assertInvalid(tx, 'XChainAccountCreateCommit: invalid field Amount') + assertInvalid( + tx, + 'XChainAccountCreateCommit: invalid field Amount, expected a valid Amount', + ) }) }) diff --git a/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts b/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts index 144a43a584..864dac83ed 100644 --- a/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts +++ b/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts @@ -64,7 +64,10 @@ describe('XChainAddAccountCreateAttestation', function () { it('throws w/ invalid Amount', function () { tx.Amount = { currency: 'ETH' } - assertInvalid(tx, 'XChainAddAccountCreateAttestation: invalid field Amount') + assertInvalid( + tx, + 'XChainAddAccountCreateAttestation: invalid field Amount, expected a valid Amount', + ) }) it('throws w/ missing AttestationRewardAccount', function () { @@ -81,7 +84,7 @@ describe('XChainAddAccountCreateAttestation', function () { assertInvalid( tx, - 'XChainAddAccountCreateAttestation: invalid field AttestationRewardAccount', + 'XChainAddAccountCreateAttestation: invalid field AttestationRewardAccount, expected a valid account address', ) }) @@ -99,7 +102,7 @@ describe('XChainAddAccountCreateAttestation', function () { assertInvalid( tx, - 'XChainAddAccountCreateAttestation: invalid field AttestationSignerAccount', + 'XChainAddAccountCreateAttestation: invalid field AttestationSignerAccount, expected a valid account address', ) }) @@ -117,7 +120,7 @@ describe('XChainAddAccountCreateAttestation', function () { assertInvalid( tx, - 'XChainAddAccountCreateAttestation: invalid field Destination', + 'XChainAddAccountCreateAttestation: invalid field Destination, expected a valid account address', ) }) @@ -135,7 +138,7 @@ describe('XChainAddAccountCreateAttestation', function () { assertInvalid( tx, - 'XChainAddAccountCreateAttestation: invalid field OtherChainSource', + 'XChainAddAccountCreateAttestation: invalid field OtherChainSource, expected a valid account address', ) }) @@ -153,7 +156,7 @@ describe('XChainAddAccountCreateAttestation', function () { assertInvalid( tx, - 'XChainAddAccountCreateAttestation: invalid field PublicKey', + 'XChainAddAccountCreateAttestation: invalid field PublicKey, expected a valid hex string', ) }) @@ -171,7 +174,7 @@ describe('XChainAddAccountCreateAttestation', function () { assertInvalid( tx, - 'XChainAddAccountCreateAttestation: invalid field Signature', + 'XChainAddAccountCreateAttestation: invalid field Signature, expected a valid hex string', ) }) @@ -189,7 +192,7 @@ describe('XChainAddAccountCreateAttestation', function () { assertInvalid( tx, - 'XChainAddAccountCreateAttestation: invalid field SignatureReward', + 'XChainAddAccountCreateAttestation: invalid field SignatureReward, expected a valid Amount', ) }) @@ -243,7 +246,7 @@ describe('XChainAddAccountCreateAttestation', function () { assertInvalid( tx, - 'XChainAddAccountCreateAttestation: invalid field XChainBridge', + 'XChainAddAccountCreateAttestation: invalid field XChainBridge, expected a valid XChainBridge object', ) }) }) diff --git a/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts b/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts index 92783d9219..f9c7778c2f 100644 --- a/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts +++ b/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts @@ -58,7 +58,10 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ invalid Amount', function () { tx.Amount = { currency: 'ETH' } - assertInvalid(tx, 'XChainAddClaimAttestation: invalid field Amount') + assertInvalid( + tx, + 'XChainAddClaimAttestation: invalid field Amount, expected a valid Amount', + ) }) it('throws w/ missing AttestationRewardAccount', function () { @@ -75,7 +78,7 @@ describe('XChainAddClaimAttestation', function () { assertInvalid( tx, - 'XChainAddClaimAttestation: invalid field AttestationRewardAccount', + 'XChainAddClaimAttestation: invalid field AttestationRewardAccount, expected a valid account address', ) }) @@ -93,14 +96,17 @@ describe('XChainAddClaimAttestation', function () { assertInvalid( tx, - 'XChainAddClaimAttestation: invalid field AttestationSignerAccount', + 'XChainAddClaimAttestation: invalid field AttestationSignerAccount, expected a valid account address', ) }) it('throws w/ invalid Destination', function () { tx.Destination = 123 - assertInvalid(tx, 'XChainAddClaimAttestation: invalid field Destination') + assertInvalid( + tx, + 'XChainAddClaimAttestation: invalid field Destination, expected a valid account address', + ) }) it('throws w/ missing OtherChainSource', function () { @@ -117,7 +123,7 @@ describe('XChainAddClaimAttestation', function () { assertInvalid( tx, - 'XChainAddClaimAttestation: invalid field OtherChainSource', + 'XChainAddClaimAttestation: invalid field OtherChainSource, expected a valid account address', ) }) @@ -130,7 +136,10 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ invalid PublicKey', function () { tx.PublicKey = 123 - assertInvalid(tx, 'XChainAddClaimAttestation: invalid field PublicKey') + assertInvalid( + tx, + 'XChainAddClaimAttestation: invalid field PublicKey, expected a valid hex string', + ) }) it('throws w/ missing Signature', function () { @@ -142,7 +151,10 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ invalid Signature', function () { tx.Signature = 123 - assertInvalid(tx, 'XChainAddClaimAttestation: invalid field Signature') + assertInvalid( + tx, + 'XChainAddClaimAttestation: invalid field Signature, expected a valid hex string', + ) }) it('throws w/ missing WasLockingChainSend', function () { @@ -172,7 +184,10 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assertInvalid(tx, 'XChainAddClaimAttestation: invalid field XChainBridge') + assertInvalid( + tx, + 'XChainAddClaimAttestation: invalid field XChainBridge, expected a valid XChainBridge object', + ) }) it('throws w/ missing XChainClaimID', function () { @@ -184,6 +199,9 @@ describe('XChainAddClaimAttestation', function () { it('throws w/ invalid XChainClaimID', function () { tx.XChainClaimID = { currency: 'ETH' } - assertInvalid(tx, 'XChainAddClaimAttestation: invalid field XChainClaimID') + assertInvalid( + tx, + 'XChainAddClaimAttestation: invalid field XChainClaimID, expected a number or hex string', + ) }) }) diff --git a/packages/xrpl/test/models/XChainClaim.test.ts b/packages/xrpl/test/models/XChainClaim.test.ts index 8ec461224d..9480779dca 100644 --- a/packages/xrpl/test/models/XChainClaim.test.ts +++ b/packages/xrpl/test/models/XChainClaim.test.ts @@ -49,7 +49,10 @@ describe('XChainClaim', function () { it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assertInvalid(tx, 'XChainClaim: invalid field XChainBridge') + assertInvalid( + tx, + 'XChainClaim: invalid field XChainBridge, expected a valid XChainBridge object', + ) }) it('throws w/ missing XChainClaimID', function () { @@ -61,7 +64,10 @@ describe('XChainClaim', function () { it('throws w/ invalid XChainClaimID', function () { tx.XChainClaimID = { currency: 'ETH' } - assertInvalid(tx, 'XChainClaim: invalid field XChainClaimID') + assertInvalid( + tx, + 'XChainClaim: invalid field XChainClaimID, expected a number or hex string', + ) }) it('throws w/ missing Destination', function () { @@ -73,13 +79,19 @@ describe('XChainClaim', function () { it('throws w/ invalid Destination', function () { tx.Destination = 123 - assertInvalid(tx, 'XChainClaim: invalid field Destination') + assertInvalid( + tx, + 'XChainClaim: invalid field Destination, expected a valid account address', + ) }) it('throws w/ invalid DestinationTag', function () { tx.DestinationTag = 'number' - assertInvalid(tx, 'XChainClaim: invalid field DestinationTag') + assertInvalid( + tx, + 'XChainClaim: invalid field DestinationTag, expected a valid number', + ) }) it('throws w/ missing Amount', function () { @@ -91,6 +103,9 @@ describe('XChainClaim', function () { it('throws w/ invalid Amount', function () { tx.Amount = { currency: 'ETH' } - assertInvalid(tx, 'XChainClaim: invalid field Amount') + assertInvalid( + tx, + 'XChainClaim: invalid field Amount, expected a valid Amount', + ) }) }) diff --git a/packages/xrpl/test/models/XChainCommit.test.ts b/packages/xrpl/test/models/XChainCommit.test.ts index 2d2952a8eb..66a793bb16 100644 --- a/packages/xrpl/test/models/XChainCommit.test.ts +++ b/packages/xrpl/test/models/XChainCommit.test.ts @@ -48,7 +48,10 @@ describe('XChainCommit', function () { it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assertInvalid(tx, 'XChainCommit: invalid field XChainBridge') + assertInvalid( + tx, + 'XChainCommit: invalid field XChainBridge, expected a valid XChainBridge object', + ) }) it('throws w/ missing XChainClaimID', function () { @@ -60,13 +63,19 @@ describe('XChainCommit', function () { it('throws w/ invalid XChainClaimID', function () { tx.XChainClaimID = { currency: 'ETH' } - assertInvalid(tx, 'XChainCommit: invalid field XChainClaimID') + assertInvalid( + tx, + 'XChainCommit: invalid field XChainClaimID, expected a number or hex string', + ) }) it('throws w/ invalid OtherChainDestination', function () { tx.OtherChainDestination = 123 - assertInvalid(tx, 'XChainCommit: invalid field OtherChainDestination') + assertInvalid( + tx, + 'XChainCommit: invalid field OtherChainDestination, expected a valid account address', + ) }) it('throws w/ missing Amount', function () { @@ -78,6 +87,9 @@ describe('XChainCommit', function () { it('throws w/ invalid Amount', function () { tx.Amount = { currency: 'ETH' } - assertInvalid(tx, 'XChainCommit: invalid field Amount') + assertInvalid( + tx, + 'XChainCommit: invalid field Amount, expected a valid Amount', + ) }) }) diff --git a/packages/xrpl/test/models/XChainCreateBridge.test.ts b/packages/xrpl/test/models/XChainCreateBridge.test.ts index 740c92030d..7675eea5a7 100644 --- a/packages/xrpl/test/models/XChainCreateBridge.test.ts +++ b/packages/xrpl/test/models/XChainCreateBridge.test.ts @@ -49,7 +49,10 @@ describe('XChainCreateBridge', function () { it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assertInvalid(tx, 'XChainCreateBridge: invalid field XChainBridge') + assertInvalid( + tx, + 'XChainCreateBridge: invalid field XChainBridge, expected a valid XChainBridge object', + ) }) it('throws w/ missing SignatureReward', function () { @@ -61,7 +64,10 @@ describe('XChainCreateBridge', function () { it('throws w/ invalid SignatureReward', function () { tx.SignatureReward = { currency: 'ETH' } - assertInvalid(tx, 'XChainCreateBridge: invalid field SignatureReward') + assertInvalid( + tx, + 'XChainCreateBridge: invalid field SignatureReward, expected a valid Amount', + ) }) it('throws w/ invalid MinAccountCreateAmount', function () { @@ -69,7 +75,7 @@ describe('XChainCreateBridge', function () { assertInvalid( tx, - 'XChainCreateBridge: invalid field MinAccountCreateAmount', + 'XChainCreateBridge: invalid field MinAccountCreateAmount, expected a valid Amount', ) }) }) diff --git a/packages/xrpl/test/models/XChainCreateClaimID.test.ts b/packages/xrpl/test/models/XChainCreateClaimID.test.ts index 620e830954..2054c27bda 100644 --- a/packages/xrpl/test/models/XChainCreateClaimID.test.ts +++ b/packages/xrpl/test/models/XChainCreateClaimID.test.ts @@ -49,7 +49,10 @@ describe('XChainCreateClaimID', function () { it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assertInvalid(tx, 'XChainCreateClaimID: invalid field XChainBridge') + assertInvalid( + tx, + 'XChainCreateClaimID: invalid field XChainBridge, expected a valid XChainBridge object', + ) }) it('throws w/ missing SignatureReward', function () { @@ -61,7 +64,10 @@ describe('XChainCreateClaimID', function () { it('throws w/ invalid SignatureReward', function () { tx.SignatureReward = { currency: 'ETH' } - assertInvalid(tx, 'XChainCreateClaimID: invalid field SignatureReward') + assertInvalid( + tx, + 'XChainCreateClaimID: invalid field SignatureReward, expected a valid Amount', + ) }) it('throws w/ missing OtherChainSource', function () { @@ -73,6 +79,9 @@ describe('XChainCreateClaimID', function () { it('throws w/ invalid OtherChainSource', function () { tx.OtherChainSource = 123 - assertInvalid(tx, 'XChainCreateClaimID: invalid field OtherChainSource') + assertInvalid( + tx, + 'XChainCreateClaimID: invalid field OtherChainSource, expected a valid account address', + ) }) }) diff --git a/packages/xrpl/test/models/XChainModifyBridge.test.ts b/packages/xrpl/test/models/XChainModifyBridge.test.ts index 4ad095c999..3d6b6aec04 100644 --- a/packages/xrpl/test/models/XChainModifyBridge.test.ts +++ b/packages/xrpl/test/models/XChainModifyBridge.test.ts @@ -49,13 +49,19 @@ describe('XChainModifyBridge', function () { it('throws w/ invalid XChainBridge', function () { tx.XChainBridge = { XChainDoor: 'test' } - assertInvalid(tx, 'XChainModifyBridge: invalid field XChainBridge') + assertInvalid( + tx, + 'XChainModifyBridge: invalid field XChainBridge, expected a valid XChainBridge object', + ) }) it('throws w/ invalid SignatureReward', function () { tx.SignatureReward = { currency: 'ETH' } - assertInvalid(tx, 'XChainModifyBridge: invalid field SignatureReward') + assertInvalid( + tx, + 'XChainModifyBridge: invalid field SignatureReward, expected a valid Amount', + ) }) it('throws w/ invalid MinAccountCreateAmount', function () { @@ -63,7 +69,7 @@ describe('XChainModifyBridge', function () { assertInvalid( tx, - 'XChainModifyBridge: invalid field MinAccountCreateAmount', + 'XChainModifyBridge: invalid field MinAccountCreateAmount, expected a valid Amount', ) }) }) diff --git a/packages/xrpl/test/models/accountSet.test.ts b/packages/xrpl/test/models/accountSet.test.ts index f8e5a8b9ad..a27058213a 100644 --- a/packages/xrpl/test/models/accountSet.test.ts +++ b/packages/xrpl/test/models/accountSet.test.ts @@ -32,7 +32,7 @@ describe('AccountSet', function () { it(`throws w/ invalid SetFlag (out of range)`, function () { tx.SetFlag = 20 - assertInvalid(tx, 'AccountSet: not a valid SetFlag') + assertInvalid(tx, 'AccountSet: not a valid SetFlag value') }) it(`throws w/ invalid SetFlag (incorrect type)`, function () { @@ -45,19 +45,22 @@ describe('AccountSet', function () { it(`throws w/ invalid ClearFlag`, function () { tx.ClearFlag = 20 - assertInvalid(tx, 'AccountSet: not a valid ClearFlag') + assertInvalid(tx, 'AccountSet: not a valid ClearFlag value') }) it(`throws w/ invalid Domain`, function () { tx.Domain = 6578616 - assertInvalid(tx, 'AccountSet: invalid field Domain, expected a hex string') + assertInvalid( + tx, + 'AccountSet: invalid field Domain, expected a valid hex string', + ) }) it(`throws w/ invalid EmailHash`, function () { tx.EmailHash = 6578656789876543 assertInvalid( tx, - 'AccountSet: invalid field EmailHash, expected a hex string', + 'AccountSet: invalid field EmailHash, expected a valid hex string', ) }) @@ -65,7 +68,7 @@ describe('AccountSet', function () { tx.MessageKey = 6578656789876543 assertInvalid( tx, - 'AccountSet: invalid field MessageKey, expected a hex string', + 'AccountSet: invalid field MessageKey, expected a valid hex string', ) }) @@ -81,7 +84,7 @@ describe('AccountSet', function () { tx.TickSize = 20 assertInvalid( tx, - 'AccountSet: invalid field TickSize, expected a valid number between bounds', + 'AccountSet: invalid field TickSize, expected a valid number', ) }) diff --git a/packages/xrpl/test/models/checkCancel.test.ts b/packages/xrpl/test/models/checkCancel.test.ts index 7a890a5406..2950f3292e 100644 --- a/packages/xrpl/test/models/checkCancel.test.ts +++ b/packages/xrpl/test/models/checkCancel.test.ts @@ -29,6 +29,9 @@ describe('CheckCancel', function () { CheckID: 4964734566545678, } as any - assertInvalid(invalidCheckID, 'CheckCancel: invalid field CheckID') + assertInvalid( + invalidCheckID, + 'CheckCancel: invalid field CheckID, expected a valid hex string', + ) }) }) diff --git a/packages/xrpl/test/models/checkCash.test.ts b/packages/xrpl/test/models/checkCash.test.ts index ddab5bfc63..6c07dd4e1e 100644 --- a/packages/xrpl/test/models/checkCash.test.ts +++ b/packages/xrpl/test/models/checkCash.test.ts @@ -32,7 +32,10 @@ describe('CheckCash', function () { CheckID: 83876645678567890, } as any - assertInvalid(invalidCheckID, 'CheckCash: invalid field CheckID') + assertInvalid( + invalidCheckID, + 'CheckCash: invalid field CheckID, expected a valid hex string', + ) }) it(`throws w/ invalid Amount`, function () { @@ -44,7 +47,10 @@ describe('CheckCash', function () { '838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334', } as any - assertInvalid(invalidAmount, 'CheckCash: invalid field Amount') + assertInvalid( + invalidAmount, + 'CheckCash: invalid field Amount, expected a valid Amount', + ) }) it(`throws w/ having both Amount and DeliverMin`, function () { @@ -72,6 +78,9 @@ describe('CheckCash', function () { '838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334', } as any - assertInvalid(invalidDeliverMin, 'CheckCash: invalid field DeliverMin') + assertInvalid( + invalidDeliverMin, + 'CheckCash: invalid field DeliverMin, expected a valid Amount', + ) }) }) diff --git a/packages/xrpl/test/models/clawback.test.ts b/packages/xrpl/test/models/clawback.test.ts index a078142721..a96330d5e8 100644 --- a/packages/xrpl/test/models/clawback.test.ts +++ b/packages/xrpl/test/models/clawback.test.ts @@ -41,7 +41,10 @@ describe('Clawback', function () { Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assertInvalid(invalidAmount, 'Clawback: invalid field Amount') + assertInvalid( + invalidAmount, + 'Clawback: invalid field Amount, expected a valid non-XRP Amount', + ) const invalidStrAmount = { TransactionType: 'Clawback', @@ -49,7 +52,10 @@ describe('Clawback', function () { Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assertInvalid(invalidStrAmount, 'Clawback: invalid field Amount') + assertInvalid( + invalidStrAmount, + 'Clawback: invalid field Amount, expected a valid non-XRP Amount', + ) }) it(`throws w/ invalid holder Account`, function () { diff --git a/packages/xrpl/test/models/depositPreauth.test.ts b/packages/xrpl/test/models/depositPreauth.test.ts index 3662ad29d5..61d68ccb25 100644 --- a/packages/xrpl/test/models/depositPreauth.test.ts +++ b/packages/xrpl/test/models/depositPreauth.test.ts @@ -109,14 +109,16 @@ describe('DepositPreauth', function () { }) it('throws when AuthorizeCredentials is not an array', function () { - const errorMessage = 'DepositPreauth: invalid field Credentials' + const errorMessage = + 'DepositPreauth: invalid field Credentials, expected a valid array' depositPreauth.AuthorizeCredentials = validCredential assertInvalid(depositPreauth, errorMessage) }) it('throws when UnauthorizeCredentials is not an array', function () { - const errorMessage = 'DepositPreauth: invalid field Credentials' + const errorMessage = + 'DepositPreauth: invalid field Credentials, expected a valid array' depositPreauth.UnauthorizeCredentials = validCredential assertInvalid(depositPreauth, errorMessage) diff --git a/packages/xrpl/test/models/escrowCancel.test.ts b/packages/xrpl/test/models/escrowCancel.test.ts index 3a69cf7eb0..d3d502c893 100644 --- a/packages/xrpl/test/models/escrowCancel.test.ts +++ b/packages/xrpl/test/models/escrowCancel.test.ts @@ -47,12 +47,18 @@ describe('EscrowCancel', function () { it(`Invalid Owner`, function () { cancel.Owner = 10 - assertInvalid(cancel, 'EscrowCancel: invalid field Owner') + assertInvalid( + cancel, + 'EscrowCancel: invalid field Owner, expected a valid account address', + ) }) it(`Invalid OfferSequence`, function () { cancel.OfferSequence = 'random' - assertInvalid(cancel, 'EscrowCancel: invalid field OfferSequence') + assertInvalid( + cancel, + 'EscrowCancel: invalid field OfferSequence, expected a valid number', + ) }) }) diff --git a/packages/xrpl/test/models/escrowCreate.test.ts b/packages/xrpl/test/models/escrowCreate.test.ts index 6c4f148fca..d5cac0e912 100644 --- a/packages/xrpl/test/models/escrowCreate.test.ts +++ b/packages/xrpl/test/models/escrowCreate.test.ts @@ -47,37 +47,55 @@ describe('EscrowCreate', function () { it(`throws w/ invalid Destination`, function () { escrow.Destination = 10 - assertInvalid(escrow, 'EscrowCreate: invalid field Destination') + assertInvalid( + escrow, + 'EscrowCreate: invalid field Destination, expected a valid account address', + ) }) it(`throws w/ invalid Amount`, function () { escrow.Amount = 1000 - assertInvalid(escrow, 'EscrowCreate: invalid field Amount') + assertInvalid( + escrow, + 'EscrowCreate: invalid field Amount, expected a valid Amount', + ) }) it(`invalid CancelAfter`, function () { escrow.CancelAfter = 'abcd' - assertInvalid(escrow, 'EscrowCreate: invalid field CancelAfter') + assertInvalid( + escrow, + 'EscrowCreate: invalid field CancelAfter, expected a valid number', + ) }) it(`invalid FinishAfter`, function () { escrow.FinishAfter = 'abcd' - assertInvalid(escrow, 'EscrowCreate: invalid field FinishAfter') + assertInvalid( + escrow, + 'EscrowCreate: invalid field FinishAfter, expected a valid number', + ) }) it(`invalid Condition`, function () { escrow.Condition = 0x141243 - assertInvalid(escrow, 'EscrowCreate: invalid field Condition') + assertInvalid( + escrow, + 'EscrowCreate: invalid field Condition, expected a valid hex string', + ) }) it(`invalid DestinationTag`, function () { escrow.DestinationTag = 'abcd' - assertInvalid(escrow, 'EscrowCreate: invalid field DestinationTag') + assertInvalid( + escrow, + 'EscrowCreate: invalid field DestinationTag, expected a valid number', + ) }) it(`Missing both CancelAfter and FinishAfter`, function () { diff --git a/packages/xrpl/test/models/escrowFinish.test.ts b/packages/xrpl/test/models/escrowFinish.test.ts index f7077e3307..e088cee101 100644 --- a/packages/xrpl/test/models/escrowFinish.test.ts +++ b/packages/xrpl/test/models/escrowFinish.test.ts @@ -48,32 +48,45 @@ describe('EscrowFinish', function () { it(`throws w/ invalid Owner`, function () { escrow.Owner = 0x15415253 - assertInvalid(escrow, 'EscrowFinish: invalid field Owner') + assertInvalid( + escrow, + 'EscrowFinish: invalid field Owner, expected a valid account address', + ) }) it(`throws w/ invalid OfferSequence`, function () { escrow.OfferSequence = 'random' - assertInvalid(escrow, 'EscrowFinish: invalid field OfferSequence') + assertInvalid( + escrow, + 'EscrowFinish: invalid field OfferSequence, expected a valid number', + ) }) it(`throws w/ invalid Condition`, function () { escrow.Condition = 10 - assertInvalid(escrow, 'EscrowFinish: invalid field Condition') + assertInvalid( + escrow, + 'EscrowFinish: invalid field Condition, expected a valid hex string', + ) }) it(`throws w/ invalid Fulfillment`, function () { escrow.Fulfillment = 0x142341 - assertInvalid(escrow, 'EscrowFinish: invalid field Fulfillment') + assertInvalid( + escrow, + 'EscrowFinish: invalid field Fulfillment, expected a valid hex string', + ) }) it(`throws w/ non-array CredentialIDs`, function () { escrow.CredentialIDs = 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66A' - const errorMessage = 'EscrowFinish: invalid field Credentials' + const errorMessage = + 'EscrowFinish: invalid field Credentials, expected a valid array' assertInvalid(escrow, errorMessage) }) diff --git a/packages/xrpl/test/models/offerCancel.test.ts b/packages/xrpl/test/models/offerCancel.test.ts index 53edc1931c..ec7811e439 100644 --- a/packages/xrpl/test/models/offerCancel.test.ts +++ b/packages/xrpl/test/models/offerCancel.test.ts @@ -40,7 +40,10 @@ describe('OfferCancel', function () { it(`throws w/ OfferSequence must be a number`, function () { offer.OfferSequence = 'abcd' - assertInvalid(offer, 'OfferCancel: invalid field OfferSequence') + assertInvalid( + offer, + 'OfferCancel: invalid field OfferSequence, expected a valid number', + ) }) it(`throws w/ missing OfferSequence`, function () { diff --git a/packages/xrpl/test/models/offerCreate.test.ts b/packages/xrpl/test/models/offerCreate.test.ts index d34ac46922..6b2ff81dd4 100644 --- a/packages/xrpl/test/models/offerCreate.test.ts +++ b/packages/xrpl/test/models/offerCreate.test.ts @@ -88,24 +88,36 @@ describe('OfferCreate', function () { it(`throws w/ invalid Expiration`, function () { offer.Expiration = 'abcd' - assertInvalid(offer, 'OfferCreate: invalid field Expiration') + assertInvalid( + offer, + 'OfferCreate: invalid field Expiration, expected a valid number', + ) }) it(`throws w/ invalid OfferSequence`, function () { offer.OfferSequence = 'abcd' - assertInvalid(offer, 'OfferCreate: invalid field OfferSequence') + assertInvalid( + offer, + 'OfferCreate: invalid field OfferSequence, expected a valid number', + ) }) it(`throws w/ invalid TakerPays`, function () { offer.TakerPays = 10 - assertInvalid(offer, 'OfferCreate: invalid field TakerPays') + assertInvalid( + offer, + 'OfferCreate: invalid field TakerPays, expected a valid Amount', + ) }) it(`throws w/ invalid TakerGets`, function () { offer.TakerGets = 11 - assertInvalid(offer, 'OfferCreate: invalid field TakerGets') + assertInvalid( + offer, + 'OfferCreate: invalid field TakerGets, expected a valid Amount', + ) }) }) diff --git a/packages/xrpl/test/models/oracleDelete.test.ts b/packages/xrpl/test/models/oracleDelete.test.ts index 684b0dc3fe..9d22db7300 100644 --- a/packages/xrpl/test/models/oracleDelete.test.ts +++ b/packages/xrpl/test/models/oracleDelete.test.ts @@ -33,7 +33,8 @@ describe('OracleDelete', function () { it(`throws w/ invalid OracleDocumentID`, function () { tx.OracleDocumentID = 'abcd' - const errorMessage = 'OracleDelete: invalid field OracleDocumentID' + const errorMessage = + 'OracleDelete: invalid field OracleDocumentID, expected a valid number' assertInvalid(tx, errorMessage) }) }) diff --git a/packages/xrpl/test/models/oracleSet.test.ts b/packages/xrpl/test/models/oracleSet.test.ts index 5dc5a1652f..fb397b5a7f 100644 --- a/packages/xrpl/test/models/oracleSet.test.ts +++ b/packages/xrpl/test/models/oracleSet.test.ts @@ -49,7 +49,8 @@ describe('OracleSet', function () { it(`throws w/ invalid OracleDocumentID`, function () { tx.OracleDocumentID = 'abcd' - const errorMessage = 'OracleSet: invalid field OracleDocumentID' + const errorMessage = + 'OracleSet: invalid field OracleDocumentID, expected a valid number' assertInvalid(tx, errorMessage) }) @@ -61,25 +62,29 @@ describe('OracleSet', function () { it(`throws w/ invalid LastUpdateTime`, function () { tx.LastUpdateTime = 'abcd' - const errorMessage = 'OracleSet: invalid field LastUpdateTime' + const errorMessage = + 'OracleSet: invalid field LastUpdateTime, expected a valid number' assertInvalid(tx, errorMessage) }) it(`throws w/ missing invalid Provider`, function () { tx.Provider = 1234 - const errorMessage = 'OracleSet: invalid field Provider' + const errorMessage = + 'OracleSet: invalid field Provider, expected a valid hex string' assertInvalid(tx, errorMessage) }) it(`throws w/ missing invalid URI`, function () { tx.URI = 1234 - const errorMessage = 'OracleSet: invalid field URI' + const errorMessage = + 'OracleSet: invalid field URI, expected a valid hex string' assertInvalid(tx, errorMessage) }) it(`throws w/ missing invalid AssetClass`, function () { tx.AssetClass = 1234 - const errorMessage = 'OracleSet: invalid field AssetClass' + const errorMessage = + 'OracleSet: invalid field AssetClass, expected a valid hex string' assertInvalid(tx, errorMessage) }) diff --git a/packages/xrpl/test/models/payment.test.ts b/packages/xrpl/test/models/payment.test.ts index 6a75acd976..89b9d26989 100644 --- a/packages/xrpl/test/models/payment.test.ts +++ b/packages/xrpl/test/models/payment.test.ts @@ -76,7 +76,10 @@ describe('Payment', function () { it(`throws when Amount is invalid`, function () { payment.Amount = 1234 - assertInvalid(payment, 'Payment: invalid field Amount') + assertInvalid( + payment, + 'Payment: invalid field Amount, expected a valid Amount', + ) }) it(`throws when Destination is missing`, function () { @@ -86,12 +89,18 @@ describe('Payment', function () { it(`throws when Destination is invalid`, function () { payment.Destination = 7896214 - assertInvalid(payment, 'Payment: invalid field Destination') + assertInvalid( + payment, + 'Payment: invalid field Destination, expected a valid account address', + ) }) it(`throws when Destination is invalid classic address`, function () { payment.Destination = 'rABCD' - assertInvalid(payment, 'Payment: invalid field Destination') + assertInvalid( + payment, + 'Payment: invalid field Destination, expected a valid account address', + ) }) it(`does not throw when Destination is a valid x-address`, function () { @@ -101,17 +110,26 @@ describe('Payment', function () { it(`throws when Destination is an empty string`, function () { payment.Destination = '' - assertInvalid(payment, 'Payment: invalid field Destination') + assertInvalid( + payment, + 'Payment: invalid field Destination, expected a valid account address', + ) }) it(`throws when DestinationTag is not a number`, function () { payment.DestinationTag = 'abcd' - assertInvalid(payment, 'Payment: invalid field DestinationTag') + assertInvalid( + payment, + 'Payment: invalid field DestinationTag, expected a valid number', + ) }) it(`throws when InvoiceID is not a string`, function () { payment.InvoiceID = 19832 - assertInvalid(payment, 'Payment: invalid field InvoiceID') + assertInvalid( + payment, + 'Payment: invalid field InvoiceID, expected a valid hex string', + ) }) it(`throws when Paths is invalid`, function () { @@ -121,7 +139,10 @@ describe('Payment', function () { it(`throws when SendMax is invalid`, function () { payment.SendMax = 100000000 - assertInvalid(payment, 'Payment: invalid field SendMax') + assertInvalid( + payment, + 'Payment: invalid field SendMax, expected a valid Amount', + ) }) it(`verifies valid DeliverMin with tfPartialPayment flag set as a number`, function () { @@ -139,7 +160,10 @@ describe('Payment', function () { it(`throws when DeliverMin is invalid`, function () { payment.DeliverMin = 10000 payment.Flags = { tfPartialPayment: true } - assertInvalid(payment, 'Payment: invalid field DeliverMin') + assertInvalid( + payment, + 'Payment: invalid field DeliverMin, expected a valid Amount', + ) }) it(`throws when tfPartialPayment flag is missing with valid DeliverMin`, function () { @@ -167,7 +191,8 @@ describe('Payment', function () { payment.CredentialIDs = 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66A' - const errorMessage = 'Payment: invalid field Credentials' + const errorMessage = + 'Payment: invalid field Credentials, expected a valid array' assertInvalid(payment, errorMessage) }) diff --git a/packages/xrpl/test/models/paymentChannelClaim.test.ts b/packages/xrpl/test/models/paymentChannelClaim.test.ts index 225fcbff4a..ab22e1a80e 100644 --- a/packages/xrpl/test/models/paymentChannelClaim.test.ts +++ b/packages/xrpl/test/models/paymentChannelClaim.test.ts @@ -51,30 +51,45 @@ describe('PaymentChannelClaim', function () { it(`throws w/ invalid Channel`, function () { channel.Channel = 100 - assertInvalid(channel, 'PaymentChannelClaim: invalid field Channel') + assertInvalid( + channel, + 'PaymentChannelClaim: invalid field Channel, expected a valid hex string', + ) }) it(`throws w/ invalid Balance`, function () { channel.Balance = 100 - assertInvalid(channel, 'PaymentChannelClaim: invalid field Balance') + assertInvalid( + channel, + 'PaymentChannelClaim: invalid field Balance, expected a valid XRP Amount', + ) }) it(`throws w/ invalid Amount`, function () { channel.Amount = 1000 - assertInvalid(channel, 'PaymentChannelClaim: invalid field Amount') + assertInvalid( + channel, + 'PaymentChannelClaim: invalid field Amount, expected a valid XRP Amount', + ) }) it(`throws w/ invalid Signature`, function () { channel.Signature = 1000 - assertInvalid(channel, 'PaymentChannelClaim: invalid field Signature') + assertInvalid( + channel, + 'PaymentChannelClaim: invalid field Signature, expected a valid hex string', + ) }) it(`throws w/ invalid PublicKey`, function () { channel.PublicKey = ['100000'] - assertInvalid(channel, 'PaymentChannelClaim: invalid field PublicKey') + assertInvalid( + channel, + 'PaymentChannelClaim: invalid field PublicKey, expected a valid hex string', + ) }) }) diff --git a/packages/xrpl/test/models/paymentChannelCreate.test.ts b/packages/xrpl/test/models/paymentChannelCreate.test.ts index b090bbac73..8d33179d1a 100644 --- a/packages/xrpl/test/models/paymentChannelCreate.test.ts +++ b/packages/xrpl/test/models/paymentChannelCreate.test.ts @@ -68,36 +68,54 @@ describe('PaymentChannelCreate', function () { it(`invalid Amount`, function () { channel.Amount = 1000 - assertInvalid(channel, 'PaymentChannelCreate: invalid field Amount') + assertInvalid( + channel, + 'PaymentChannelCreate: invalid field Amount, expected a valid XRP Amount', + ) }) it(`invalid Destination`, function () { channel.Destination = 10 - assertInvalid(channel, 'PaymentChannelCreate: invalid field Destination') + assertInvalid( + channel, + 'PaymentChannelCreate: invalid field Destination, expected a valid account address', + ) }) it(`invalid SettleDelay`, function () { channel.SettleDelay = 'abcd' - assertInvalid(channel, 'PaymentChannelCreate: invalid field SettleDelay') + assertInvalid( + channel, + 'PaymentChannelCreate: invalid field SettleDelay, expected a valid number', + ) }) it(`invalid PublicKey`, function () { channel.PublicKey = 10 - assertInvalid(channel, 'PaymentChannelCreate: invalid field PublicKey') + assertInvalid( + channel, + 'PaymentChannelCreate: invalid field PublicKey, expected a valid hex string', + ) }) it(`invalid DestinationTag`, function () { channel.DestinationTag = 'abcd' - assertInvalid(channel, 'PaymentChannelCreate: invalid field DestinationTag') + assertInvalid( + channel, + 'PaymentChannelCreate: invalid field DestinationTag, expected a valid number', + ) }) it(`invalid CancelAfter`, function () { channel.CancelAfter = 'abcd' - assertInvalid(channel, 'PaymentChannelCreate: invalid field CancelAfter') + assertInvalid( + channel, + 'PaymentChannelCreate: invalid field CancelAfter, expected a valid number', + ) }) }) diff --git a/packages/xrpl/test/models/paymentChannelFund.test.ts b/packages/xrpl/test/models/paymentChannelFund.test.ts index 82c795082d..43f7068362 100644 --- a/packages/xrpl/test/models/paymentChannelFund.test.ts +++ b/packages/xrpl/test/models/paymentChannelFund.test.ts @@ -50,18 +50,27 @@ describe('PaymentChannelFund', function () { it(`throws w/ invalid Amount`, function () { channel.Amount = 100 - assertInvalid(channel, 'PaymentChannelFund: invalid field Amount') + assertInvalid( + channel, + 'PaymentChannelFund: invalid field Amount, expected a valid XRP Amount', + ) }) it(`throws w/ invalid Channel`, function () { channel.Channel = 1000 - assertInvalid(channel, 'PaymentChannelFund: invalid field Channel') + assertInvalid( + channel, + 'PaymentChannelFund: invalid field Channel, expected a valid hex string', + ) }) it(`throws w/ invalid Expiration`, function () { channel.Expiration = 'abcd' - assertInvalid(channel, 'PaymentChannelFund: invalid field Expiration') + assertInvalid( + channel, + 'PaymentChannelFund: invalid field Expiration, expected a valid number', + ) }) }) diff --git a/packages/xrpl/test/models/permissionedDomainDelete.test.ts b/packages/xrpl/test/models/permissionedDomainDelete.test.ts index 269f873dd9..692abcff3e 100644 --- a/packages/xrpl/test/models/permissionedDomainDelete.test.ts +++ b/packages/xrpl/test/models/permissionedDomainDelete.test.ts @@ -35,7 +35,8 @@ describe('PermissionedDomainDelete', function () { it(`throws w/ invalid DomainID`, function () { tx.DomainID = 1234 - const errorMessage = 'PermissionedDomainDelete: invalid field DomainID' + const errorMessage = + 'PermissionedDomainDelete: invalid field DomainID, expected a valid hex string' assertInvalid(tx, errorMessage) }) }) diff --git a/packages/xrpl/test/models/permissionedDomainSet.test.ts b/packages/xrpl/test/models/permissionedDomainSet.test.ts index c4df71c995..b736bba851 100644 --- a/packages/xrpl/test/models/permissionedDomainSet.test.ts +++ b/packages/xrpl/test/models/permissionedDomainSet.test.ts @@ -40,7 +40,8 @@ describe('PermissionedDomainSet', function () { it(`throws with invalid field DomainID`, function () { // DomainID is expected to be a string tx.DomainID = 1234 - const errorMessage = 'PermissionedDomainSet: invalid field DomainID' + const errorMessage = + 'PermissionedDomainSet: invalid field DomainID, expected a valid hex string' assertInvalid(tx, errorMessage) }) diff --git a/packages/xrpl/test/models/setRegularKey.test.ts b/packages/xrpl/test/models/setRegularKey.test.ts index 2d4a668ebb..797fa8c9d7 100644 --- a/packages/xrpl/test/models/setRegularKey.test.ts +++ b/packages/xrpl/test/models/setRegularKey.test.ts @@ -36,6 +36,9 @@ describe('SetRegularKey', function () { it(`throws w/ invalid RegularKey`, function () { account.RegularKey = 12369846963 - assertInvalid(account, 'SetRegularKey: invalid field RegularKey') + assertInvalid( + account, + 'SetRegularKey: invalid field RegularKey, expected a valid account address', + ) }) }) diff --git a/packages/xrpl/test/models/ticketCreate.test.ts b/packages/xrpl/test/models/ticketCreate.test.ts index 9b32a1e632..6ee501c75a 100644 --- a/packages/xrpl/test/models/ticketCreate.test.ts +++ b/packages/xrpl/test/models/ticketCreate.test.ts @@ -32,21 +32,33 @@ describe('TicketCreate', function () { it('throws when TicketCount is not a number', function () { ticketCreate.TicketCount = 'abcd' - assertInvalid(ticketCreate, 'TicketCreate: invalid field TicketCount') + assertInvalid( + ticketCreate, + 'TicketCreate: invalid field TicketCount, expected a valid number', + ) }) it('throws when TicketCount is not an integer', function () { ticketCreate.TicketCount = 12.5 - assertInvalid(ticketCreate, 'TicketCreate: invalid field TicketCount') + assertInvalid( + ticketCreate, + 'TicketCreate: invalid field TicketCount, expected a valid number', + ) }) it('throws when TicketCount is < 1', function () { ticketCreate.TicketCount = 0 - assertInvalid(ticketCreate, 'TicketCreate: invalid field TicketCount') + assertInvalid( + ticketCreate, + 'TicketCreate: invalid field TicketCount, expected a valid number', + ) }) it('throws when TicketCount is > 250', function () { ticketCreate.TicketCount = 251 - assertInvalid(ticketCreate, 'TicketCreate: invalid field TicketCount') + assertInvalid( + ticketCreate, + 'TicketCreate: invalid field TicketCount, expected a valid number', + ) }) }) diff --git a/packages/xrpl/test/models/trustSet.test.ts b/packages/xrpl/test/models/trustSet.test.ts index 031c894ebf..2c7800f82d 100644 --- a/packages/xrpl/test/models/trustSet.test.ts +++ b/packages/xrpl/test/models/trustSet.test.ts @@ -43,16 +43,25 @@ describe('TrustSet', function () { it('throws when LimitAmount is invalid', function () { trustSet.LimitAmount = 1234 - assertInvalid(trustSet, 'TrustSet: invalid field LimitAmount') + assertInvalid( + trustSet, + 'TrustSet: invalid field LimitAmount, expected a valid IssuedCurrencyAmount object', + ) }) it('throws when QualityIn is not a number', function () { trustSet.QualityIn = 'abcd' - assertInvalid(trustSet, 'TrustSet: invalid field QualityIn') + assertInvalid( + trustSet, + 'TrustSet: invalid field QualityIn, expected a valid number', + ) }) it('throws when QualityOut is not a number', function () { trustSet.QualityOut = 'dcba' - assertInvalid(trustSet, 'TrustSet: invalid field QualityOut') + assertInvalid( + trustSet, + 'TrustSet: invalid field QualityOut, expected a valid number', + ) }) }) diff --git a/packages/xrpl/test/wallet/index.test.ts b/packages/xrpl/test/wallet/index.test.ts index bbb454108f..059ac73ba3 100644 --- a/packages/xrpl/test/wallet/index.test.ts +++ b/packages/xrpl/test/wallet/index.test.ts @@ -1184,7 +1184,7 @@ describe('Wallet', function () { assert.throws(() => { wallet.sign(tx) - }, /URI must be in hex format/u) + }, /^NFTokenMint: invalid field URI, expected a valid hex string$/u) }) }) From e92244d915e3cd29a251403b37c87554b7f94cb3 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 27 Feb 2025 12:07:59 -0700 Subject: [PATCH 22/46] fix dupe --- packages/xrpl/test/models/depositPreauth.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/xrpl/test/models/depositPreauth.test.ts b/packages/xrpl/test/models/depositPreauth.test.ts index 61d68ccb25..d5ef543da1 100644 --- a/packages/xrpl/test/models/depositPreauth.test.ts +++ b/packages/xrpl/test/models/depositPreauth.test.ts @@ -102,10 +102,6 @@ describe('DepositPreauth', function () { depositPreauth, "DepositPreauth: Account can't unauthorize its own address", ) - assertInvalid( - depositPreauth, - "DepositPreauth: Account can't unauthorize its own address", - ) }) it('throws when AuthorizeCredentials is not an array', function () { From 16b51280348be7abbe7ab633f397ed9853ed25c4 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 27 Feb 2025 12:11:12 -0700 Subject: [PATCH 23/46] add docs --- packages/xrpl/src/models/transactions/DIDDelete.ts | 4 ++-- packages/xrpl/src/models/transactions/DIDSet.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/xrpl/src/models/transactions/DIDDelete.ts b/packages/xrpl/src/models/transactions/DIDDelete.ts index 1cc2a4214d..ea374fda19 100644 --- a/packages/xrpl/src/models/transactions/DIDDelete.ts +++ b/packages/xrpl/src/models/transactions/DIDDelete.ts @@ -1,8 +1,8 @@ import { BaseTransaction, validateBaseTransaction } from './common' -// TODO: add docs - /** + * Delete the DID ledger entry associated with the specified Account field. + * * @category Transaction Models */ export interface DIDDelete extends BaseTransaction { diff --git a/packages/xrpl/src/models/transactions/DIDSet.ts b/packages/xrpl/src/models/transactions/DIDSet.ts index 996b9a6655..a9c00dc9a7 100644 --- a/packages/xrpl/src/models/transactions/DIDSet.ts +++ b/packages/xrpl/src/models/transactions/DIDSet.ts @@ -7,9 +7,9 @@ import { validateOptionalField, } from './common' -// TODO: add docs - /** + * Creates a new DID ledger entry or updates the fields of an existing one. + * * @category Transaction Models */ export interface DIDSet extends BaseTransaction { From 01900b09dc90a9b926b14f7b298060ee5ab75444 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 27 Feb 2025 12:24:45 -0700 Subject: [PATCH 24/46] more cleanup --- .../src/models/transactions/NFTokenCreateOffer.ts | 1 + packages/xrpl/src/models/transactions/NFTokenMint.ts | 9 ++++++++- packages/xrpl/src/models/transactions/clawback.ts | 8 ++++++-- packages/xrpl/src/models/transactions/payment.ts | 11 ++--------- packages/xrpl/test/models/AMMWithdraw.test.ts | 10 +++++----- packages/xrpl/test/models/clawback.test.ts | 10 ++++++++-- packages/xrpl/test/models/payment.test.ts | 5 ++++- 7 files changed, 34 insertions(+), 20 deletions(-) diff --git a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts index 938d73ae93..1879964be4 100644 --- a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts +++ b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts @@ -146,6 +146,7 @@ export function validateNFTokenCreateOffer(tx: Record): void { validateOptionalField(tx, 'Destination', isAccount) let isSellOffer = false + // TODO: refactor some of this flag logic if (isNumber(tx.Flags)) { isSellOffer = isFlagEnabled(tx.Flags, NFTokenCreateOfferFlags.tfSellNFToken) } else if (isRecord(tx.Flags)) { diff --git a/packages/xrpl/src/models/transactions/NFTokenMint.ts b/packages/xrpl/src/models/transactions/NFTokenMint.ts index 1b0adcb18c..29a83d3542 100644 --- a/packages/xrpl/src/models/transactions/NFTokenMint.ts +++ b/packages/xrpl/src/models/transactions/NFTokenMint.ts @@ -10,9 +10,12 @@ import { validateBaseTransaction, validateOptionalField, validateRequiredField, + isNumberWithBounds, } from './common' import type { TransactionMetadataBase } from './metadata' +const MAX_TRANSFER_FEE = 50000 + /** * Transaction Flags for an NFTokenMint Transaction. * @@ -125,7 +128,11 @@ export function validateNFTokenMint(tx: Record): void { validateRequiredField(tx, 'NFTokenTaxon', isNumber) validateOptionalField(tx, 'Issuer', isAccount) - validateOptionalField(tx, 'TransferFee', isNumber) + validateOptionalField( + tx, + 'TransferFee', + isNumberWithBounds(0, MAX_TRANSFER_FEE), + ) validateOptionalField(tx, 'URI', isHexString) if (tx.Account === tx.Issuer) { diff --git a/packages/xrpl/src/models/transactions/clawback.ts b/packages/xrpl/src/models/transactions/clawback.ts index 627451e92e..42e62017d0 100644 --- a/packages/xrpl/src/models/transactions/clawback.ts +++ b/packages/xrpl/src/models/transactions/clawback.ts @@ -53,7 +53,9 @@ export function validateClawback(tx: Record): void { if (isIssuedCurrency(tx.Amount)) { if (tx.Account === tx.Amount.issuer) { - throw new ValidationError('Clawback: invalid holder Account') + throw new ValidationError( + 'Clawback: Amount.issuer and Account cannot be the same', + ) } if (tx.Holder) { @@ -61,7 +63,9 @@ export function validateClawback(tx: Record): void { } } else if (isMPTAmount(tx.Amount)) { if (tx.Account === tx.Holder) { - throw new ValidationError('Clawback: invalid holder Account') + throw new ValidationError( + 'Clawback: Account and Holder cannot be the same', + ) } if (!tx.Holder) { diff --git a/packages/xrpl/src/models/transactions/payment.ts b/packages/xrpl/src/models/transactions/payment.ts index 20d79e6c22..7a02c1eca9 100644 --- a/packages/xrpl/src/models/transactions/payment.ts +++ b/packages/xrpl/src/models/transactions/payment.ts @@ -178,14 +178,7 @@ export function validatePayment(tx: Record): void { validateRequiredField(tx, 'Destination', isAccount) validateOptionalField(tx, 'DestinationTag', isNumber) validateOptionalField(tx, 'InvoiceID', isHexString) - - if ( - tx.Paths !== undefined && - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS - !isPaths(tx.Paths as Array>>) - ) { - throw new ValidationError('Payment: invalid field Paths') - } + validateOptionalField(tx, 'Paths', isPaths, 'expected a valid Paths array') validateOptionalField(tx, 'SendMax', isAmount) validateOptionalField(tx, 'DeliverMin', isAmount) @@ -265,7 +258,7 @@ function isPath(path: Array>): boolean { return true } -function isPaths(paths: Array>>): boolean { +function isPaths(paths: unknown): boolean { if (!Array.isArray(paths) || paths.length === 0) { return false } diff --git a/packages/xrpl/test/models/AMMWithdraw.test.ts b/packages/xrpl/test/models/AMMWithdraw.test.ts index c7480246df..83b572e0e7 100644 --- a/packages/xrpl/test/models/AMMWithdraw.test.ts +++ b/packages/xrpl/test/models/AMMWithdraw.test.ts @@ -104,7 +104,7 @@ describe('AMMWithdraw', function () { assertInvalid(withdraw, errorMessage) }) - it(`throws w/ Asset2 must be a Currency`, function () { + it(`throws when Asset2 is not a Currency`, function () { withdraw.Asset2 = 1234 const errorMessage = 'AMMWithdraw: invalid field Asset2, expected a valid Currency' @@ -127,21 +127,21 @@ describe('AMMWithdraw', function () { assertInvalid(withdraw, errorMessage) }) - it(`throws w/ LPTokenIn must be an IssuedCurrencyAmount`, function () { + it(`throws when LPTokenIn is not an IssuedCurrencyAmount`, function () { withdraw.LPTokenIn = 1234 const errorMessage = 'AMMWithdraw: invalid field LPTokenIn, expected a valid IssuedCurrencyAmount object' assertInvalid(withdraw, errorMessage) }) - it(`throws w/ Amount must be an Amount`, function () { + it(`throws when Amount is not an Amount`, function () { withdraw.Amount = 1234 const errorMessage = 'AMMWithdraw: invalid field Amount, expected a valid Amount' assertInvalid(withdraw, errorMessage) }) - it(`throws w/ Amount2 must be an Amount`, function () { + it(`throws when Amount2 is not an Amount`, function () { withdraw.Amount = '1000' withdraw.Amount2 = 1234 const errorMessage = @@ -149,7 +149,7 @@ describe('AMMWithdraw', function () { assertInvalid(withdraw, errorMessage) }) - it(`throws w/ EPrice must be an Amount`, function () { + it(`throws when EPrice is not an Amount`, function () { withdraw.Amount = '1000' withdraw.EPrice = 1234 const errorMessage = diff --git a/packages/xrpl/test/models/clawback.test.ts b/packages/xrpl/test/models/clawback.test.ts index a96330d5e8..9aae4ca623 100644 --- a/packages/xrpl/test/models/clawback.test.ts +++ b/packages/xrpl/test/models/clawback.test.ts @@ -69,7 +69,10 @@ describe('Clawback', function () { Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assertInvalid(invalidAccount, 'Clawback: invalid holder Account') + assertInvalid( + invalidAccount, + 'Clawback: Amount.issuer and Account cannot be the same', + ) }) it(`verifies valid MPT Clawback`, function () { @@ -97,7 +100,10 @@ describe('Clawback', function () { Holder: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', } as any - assertInvalid(invalidAccount, 'Clawback: invalid holder Account') + assertInvalid( + invalidAccount, + 'Clawback: Account and Holder cannot be the same', + ) }) it(`throws w/ invalid Holder`, function () { diff --git a/packages/xrpl/test/models/payment.test.ts b/packages/xrpl/test/models/payment.test.ts index 89b9d26989..625cdb839e 100644 --- a/packages/xrpl/test/models/payment.test.ts +++ b/packages/xrpl/test/models/payment.test.ts @@ -134,7 +134,10 @@ describe('Payment', function () { it(`throws when Paths is invalid`, function () { payment.Paths = [[{ account: 123 }]] - assertInvalid(payment, 'Payment: invalid field Paths') + assertInvalid( + payment, + 'Payment: invalid field Paths, expected a valid Paths array', + ) }) it(`throws when SendMax is invalid`, function () { From b3e0007b4d5b42bead6021c49638b3b130d48b93 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 27 Feb 2025 12:54:43 -0700 Subject: [PATCH 25/46] more cleanup --- .../ripple-binary-codec/src/types/amount.ts | 2 +- .../xrpl/src/models/transactions/AMMBid.ts | 4 +- .../XChainAddAccountCreateAttestation.ts | 2 + .../transactions/XChainAddClaimAttestation.ts | 1 + .../xrpl/src/models/transactions/common.ts | 68 ++++++----- .../src/models/transactions/depositPreauth.ts | 13 +-- .../xrpl/src/models/transactions/oracleSet.ts | 8 +- .../transactions/permissionedDomainSet.ts | 6 +- .../src/models/transactions/signerListSet.ts | 3 +- packages/xrpl/test/models/AMMBid.test.ts | 9 +- .../XChainAddAccountCreateAttestation.test.ts | 4 +- .../models/XChainAddClaimAttestation.test.ts | 2 +- .../xrpl/test/models/baseTransaction.test.ts | 109 +++++++++--------- .../xrpl/test/models/depositPreauth.test.ts | 10 +- packages/xrpl/test/models/oracleSet.test.ts | 6 +- packages/xrpl/test/models/payment.test.ts | 5 +- .../test/models/permissionedDomainSet.test.ts | 2 +- .../xrpl/test/models/signerListSet.test.ts | 5 +- packages/xrpl/test/wallet/index.test.ts | 4 +- 19 files changed, 148 insertions(+), 115 deletions(-) diff --git a/packages/ripple-binary-codec/src/types/amount.ts b/packages/ripple-binary-codec/src/types/amount.ts index 44fb567441..d0450aacba 100644 --- a/packages/ripple-binary-codec/src/types/amount.ts +++ b/packages/ripple-binary-codec/src/types/amount.ts @@ -257,7 +257,7 @@ class Amount extends SerializedType { * @returns void, but will throw if invalid amount */ private static assertXrpIsValid(amount: string): void { - if (amount.indexOf('.') !== -1) { + if (!Number.isInteger(Number(amount))) { throw new Error(`${amount.toString()} is an illegal amount`) } diff --git a/packages/xrpl/src/models/transactions/AMMBid.ts b/packages/xrpl/src/models/transactions/AMMBid.ts index 3468f7116d..d7059a3fd6 100644 --- a/packages/xrpl/src/models/transactions/AMMBid.ts +++ b/packages/xrpl/src/models/transactions/AMMBid.ts @@ -97,7 +97,9 @@ function validateAuthAccounts( authAccount.AuthAccount == null || typeof authAccount.AuthAccount !== 'object' ) { - throw new ValidationError(`AMMBid: invalid field AuthAccounts`) + throw new ValidationError( + `AMMBid: invalid field AuthAccounts, expected objects in array`, + ) } // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- used for null check // @ts-expect-error -- used for null check diff --git a/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts b/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts index 272066700f..e204dbbe0d 100644 --- a/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts +++ b/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts @@ -111,12 +111,14 @@ export function validateXChainAddAccountCreateAttestation( tx, 'WasLockingChainSend', (inp) => inp === 0 || inp === 1, + 'expected 0 or 1', ) validateRequiredField( tx, 'XChainAccountCreateCount', (inp) => isNumber(inp) || isHexString(inp), + 'expected a valid number or hex string', ) validateRequiredField(tx, 'XChainBridge', isXChainBridge) diff --git a/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts b/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts index 856ee9f3b5..2bdb8d2c77 100644 --- a/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts +++ b/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts @@ -105,6 +105,7 @@ export function validateXChainAddClaimAttestation( tx, 'WasLockingChainSend', (inp) => inp === 0 || inp === 1, + 'expected 0 or 1', ) validateRequiredField(tx, 'XChainBridge', isXChainBridge) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 5c9ae4d47f..c6052ac564 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -28,10 +28,9 @@ function isMemo(obj: { Memo?: unknown }): boolean { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS const memo = obj.Memo as Record const size = Object.keys(memo).length - const validData = memo.MemoData == null || typeof memo.MemoData === 'string' - const validFormat = - memo.MemoFormat == null || typeof memo.MemoFormat === 'string' - const validType = memo.MemoType == null || typeof memo.MemoType === 'string' + const validData = memo.MemoData == null || isHexString(memo.MemoData) + const validFormat = memo.MemoFormat == null || isHexString(memo.MemoFormat) + const validType = memo.MemoType == null || isHexString(memo.MemoType) return ( size >= 1 && @@ -79,6 +78,16 @@ export function isRecord(value: unknown): value is Record { return value !== null && typeof value === 'object' } +/** + * Verify the form and type of an array at runtime. + * + * @param value - The object to check the form and type of. + * @returns Whether the array is properly formed. + */ +export function isArray(value: unknown): value is unknown[] { + return Array.isArray(value) +} + /** * Verify the form and type of a string at runtime. * @@ -278,6 +287,7 @@ const invalidMessagesMap: Record = { isHexString: 'expected a valid hex string', isNumber: 'expected a valid number', isNumberWithBoundsInternal: 'expected a valid number', + isArray: 'expected a valid array', } /* eslint-disable @typescript-eslint/restrict-template-expressions -- tx.TransactionType is checked before any calls */ @@ -439,6 +449,7 @@ export interface BaseTransaction { * @param common - An interface w/ common transaction fields. * @throws When the common param is malformed. */ +// eslint-disable-next-line max-lines-per-function, max-statements -- not worth refactoring export function validateBaseTransaction(common: Record): void { validateRequiredField(common, 'TransactionType', isString) @@ -448,45 +459,52 @@ export function validateBaseTransaction(common: Record): void { } validateRequiredField(common, 'Account', isAccount) - - validateOptionalField(common, 'Fee', isString) - + validateOptionalField(common, 'Fee', isXRPAmount) validateOptionalField(common, 'Sequence', isNumber) - validateOptionalField(common, 'AccountTxnID', isHexString) - validateOptionalField(common, 'LastLedgerSequence', isNumber) - validateOptionalField( common, 'Flags', (inp) => isNumber(inp) || isRecord(inp), + 'expected a valid number or Flags object', ) // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS const memos = common.Memos as Array<{ Memo?: unknown }> | undefined - if (memos !== undefined && !memos.every(isMemo)) { - throw new ValidationError('BaseTransaction: invalid field Memos') + if (memos !== undefined) { + if (!isArray(memos)) { + throw new ValidationError( + 'BaseTransaction: invalid field Memos, expected an array', + ) + } + if (!memos.every(isMemo)) { + throw new ValidationError( + 'BaseTransaction: invalid field Memos, expected an array of valid Memo objects', + ) + } } // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS const signers = common.Signers as Array> | undefined - if ( - signers !== undefined && - (signers.length === 0 || !signers.every(isSigner)) - ) { - throw new ValidationError('BaseTransaction: invalid field Signers') + if (signers !== undefined) { + if (!isArray(signers)) { + throw new ValidationError( + 'BaseTransaction: invalid field Signers, expected an array', + ) + } + if (signers.length === 0 || !signers.every(isSigner)) { + throw new ValidationError( + 'BaseTransaction: invalid field Signers, expected an array of valid Signer objects', + ) + } } validateOptionalField(common, 'SourceTag', isNumber) - validateOptionalField(common, 'SigningPubKey', isHexString) - validateOptionalField(common, 'TicketSequence', isNumber) - validateOptionalField(common, 'TxnSignature', isHexString) - validateOptionalField(common, 'NetworkID', isNumber) } @@ -558,7 +576,7 @@ export function validateCredentialsList( if (credentials == null) { return } - if (!Array.isArray(credentials)) { + if (!isArray(credentials)) { throw new ValidationError( `${transactionType}: invalid field Credentials, expected a valid array`, ) @@ -595,7 +613,7 @@ export function validateCredentialsList( // Type guard to ensure we're working with AuthorizeCredential[] // Note: This is not a rigorous type-guard. A more thorough solution would be to iterate over the array and check each item. function isAuthorizeCredentialArray( - list: AuthorizeCredential[] | string[], + list: unknown[], ): list is AuthorizeCredential[] { return typeof list[0] !== 'string' } @@ -606,9 +624,7 @@ function isAuthorizeCredentialArray( * @param objectList - Array of objects to check for duplicates * @returns True if duplicates exist, false otherwise */ -export function containsDuplicates( - objectList: AuthorizeCredential[] | string[], -): boolean { +export function containsDuplicates(objectList: unknown[]): boolean { // Case-1: Process a list of string-IDs if (typeof objectList[0] === 'string') { const objSet = new Set(objectList.map((obj) => JSON.stringify(obj))) diff --git a/packages/xrpl/src/models/transactions/depositPreauth.ts b/packages/xrpl/src/models/transactions/depositPreauth.ts index f4396cdf68..70fe127300 100644 --- a/packages/xrpl/src/models/transactions/depositPreauth.ts +++ b/packages/xrpl/src/models/transactions/depositPreauth.ts @@ -6,6 +6,8 @@ import { validateBaseTransaction, validateCredentialsList, MAX_AUTHORIZED_CREDENTIALS, + validateOptionalField, + isAccount, } from './common' /** @@ -47,21 +49,16 @@ export function validateDepositPreauth(tx: Record): void { validateSingleAuthorizationFieldProvided(tx) - if (tx.Authorize !== undefined) { - if (typeof tx.Authorize !== 'string') { - throw new ValidationError('DepositPreauth: invalid field Authorize') - } + validateOptionalField(tx, 'Authorize', isAccount) + validateOptionalField(tx, 'Unauthorize', isAccount) + if (tx.Authorize !== undefined) { if (tx.Account === tx.Authorize) { throw new ValidationError( "DepositPreauth: Account can't preauthorize its own address", ) } } else if (tx.Unauthorize !== undefined) { - if (typeof tx.Unauthorize !== 'string') { - throw new ValidationError('DepositPreauth: invalid field Unauthorize') - } - if (tx.Account === tx.Unauthorize) { throw new ValidationError( "DepositPreauth: Account can't unauthorize its own address", diff --git a/packages/xrpl/src/models/transactions/oracleSet.ts b/packages/xrpl/src/models/transactions/oracleSet.ts index 64aad55fa5..0748c72c10 100644 --- a/packages/xrpl/src/models/transactions/oracleSet.ts +++ b/packages/xrpl/src/models/transactions/oracleSet.ts @@ -148,7 +148,9 @@ export function validateOracleSet(tx: Record): void { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type !isNumber(priceData.PriceData.AssetPrice) ) { - throw new ValidationError('OracleSet: invalid field AssetPrice') + throw new ValidationError( + 'OracleSet: invalid field AssetPrice, expected a valid number', + ) } if ( @@ -157,7 +159,9 @@ export function validateOracleSet(tx: Record): void { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type !isNumber(priceData.PriceData.Scale) ) { - throw new ValidationError('OracleSet: invalid field Scale') + throw new ValidationError( + 'OracleSet: invalid field Scale, expected a valid number', + ) } if ( diff --git a/packages/xrpl/src/models/transactions/permissionedDomainSet.ts b/packages/xrpl/src/models/transactions/permissionedDomainSet.ts index f04dffad56..5570050984 100644 --- a/packages/xrpl/src/models/transactions/permissionedDomainSet.ts +++ b/packages/xrpl/src/models/transactions/permissionedDomainSet.ts @@ -36,11 +36,7 @@ export function validatePermissionedDomainSet( validateBaseTransaction(tx) validateOptionalField(tx, 'DomainID', isHexString) - validateRequiredField( - tx, - 'AcceptedCredentials', - () => tx.AcceptedCredentials instanceof Array, - ) + validateRequiredField(tx, 'AcceptedCredentials', Array.isArray) validateCredentialsList( tx.AcceptedCredentials, diff --git a/packages/xrpl/src/models/transactions/signerListSet.ts b/packages/xrpl/src/models/transactions/signerListSet.ts index 201efafa2d..7f4a10cfca 100644 --- a/packages/xrpl/src/models/transactions/signerListSet.ts +++ b/packages/xrpl/src/models/transactions/signerListSet.ts @@ -3,6 +3,7 @@ import { SignerEntry } from '../common' import { BaseTransaction, + isArray, isNumber, validateBaseTransaction, validateRequiredField, @@ -51,7 +52,7 @@ export function validateSignerListSet(tx: Record): void { return } - validateRequiredField(tx, 'SignerEntries', Array.isArray) + validateRequiredField(tx, 'SignerEntries', isArray) // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- checked above const signerEntries = tx.SignerEntries as unknown[] diff --git a/packages/xrpl/test/models/AMMBid.test.ts b/packages/xrpl/test/models/AMMBid.test.ts index d6ce1ce7e2..5f5370844b 100644 --- a/packages/xrpl/test/models/AMMBid.test.ts +++ b/packages/xrpl/test/models/AMMBid.test.ts @@ -123,7 +123,8 @@ describe('AMMBid', function () { bid.AuthAccounts[0] = { AuthAccount: null, } - const errorMessage = 'AMMBid: invalid field AuthAccounts' + const errorMessage = + 'AMMBid: invalid field AuthAccounts, expected objects in array' assertInvalid(bid, errorMessage) }) @@ -131,7 +132,8 @@ describe('AMMBid', function () { bid.AuthAccounts[0] = { AuthAccount: undefined, } - const errorMessage = 'AMMBid: invalid field AuthAccounts' + const errorMessage = + 'AMMBid: invalid field AuthAccounts, expected objects in array' assertInvalid(bid, errorMessage) }) @@ -139,7 +141,8 @@ describe('AMMBid', function () { bid.AuthAccounts[0] = { AuthAccount: 1234, } - const errorMessage = 'AMMBid: invalid field AuthAccounts' + const errorMessage = + 'AMMBid: invalid field AuthAccounts, expected objects in array' assertInvalid(bid, errorMessage) }) diff --git a/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts b/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts index 864dac83ed..a84c783e1d 100644 --- a/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts +++ b/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts @@ -210,7 +210,7 @@ describe('XChainAddAccountCreateAttestation', function () { assertInvalid( tx, - 'XChainAddAccountCreateAttestation: invalid field WasLockingChainSend', + 'XChainAddAccountCreateAttestation: invalid field WasLockingChainSend, expected 0 or 1', ) }) @@ -228,7 +228,7 @@ describe('XChainAddAccountCreateAttestation', function () { assertInvalid( tx, - 'XChainAddAccountCreateAttestation: invalid field XChainAccountCreateCount', + 'XChainAddAccountCreateAttestation: invalid field XChainAccountCreateCount, expected a valid number or hex string', ) }) diff --git a/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts b/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts index f9c7778c2f..838113b93e 100644 --- a/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts +++ b/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts @@ -171,7 +171,7 @@ describe('XChainAddClaimAttestation', function () { assertInvalid( tx, - 'XChainAddClaimAttestation: invalid field WasLockingChainSend', + 'XChainAddClaimAttestation: invalid field WasLockingChainSend, expected 0 or 1', ) }) diff --git a/packages/xrpl/test/models/baseTransaction.test.ts b/packages/xrpl/test/models/baseTransaction.test.ts index c75c3805b3..f6fda4e4f9 100644 --- a/packages/xrpl/test/models/baseTransaction.test.ts +++ b/packages/xrpl/test/models/baseTransaction.test.ts @@ -3,6 +3,17 @@ import { assert } from 'chai' import { ValidationError } from '../../src' import { validateBaseTransaction } from '../../src/models/transactions/common' +const assertValid = (tx: any): void => + assert.doesNotThrow(() => validateBaseTransaction(tx)) +const assertInvalid = (tx: any, message: string): void => { + assert.throws( + () => validateBaseTransaction(tx), + ValidationError, + // eslint-disable-next-line require-unicode-regexp -- TS complains if it's included + new RegExp(`^${message.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, 'u'), + ) +} + /** * Transaction Verification Testing. * @@ -55,17 +66,16 @@ describe('BaseTransaction', function () { TxnSignature: '3045022100C6708538AE5A697895937C758E99A595B57A16393F370F11B8D4C032E80B532002207776A8E85BB9FAF460A92113B9C60F170CD964196B1F084E0DAB65BAEC368B66', } - - assert.doesNotThrow(() => validateBaseTransaction(txJson)) + assertValid(txJson) }) it('Verifies flag map', function () { const txJson = { Account: 'r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe', TransactionType: 'Payment', - Flags: { tfSellToken: true }, + Flags: { tfNoRippleDirect: true }, } - assert.doesNotThrow(() => validateBaseTransaction(txJson)) + assertValid(txJson) }) it(`Verifies only required BaseTransaction`, function () { @@ -84,10 +94,9 @@ describe('BaseTransaction', function () { Fee: 1000, } as any - assert.throws( - () => validateBaseTransaction(invalidFee), - ValidationError, - 'Payment: invalid field Fee', + assertInvalid( + invalidFee, + 'Payment: invalid field Fee, expected a valid XRP Amount', ) }) @@ -98,10 +107,9 @@ describe('BaseTransaction', function () { Sequence: 'abcd', } as any - assert.throws( - () => validateBaseTransaction(invalidSeq), - ValidationError, - 'Payment: invalid field Sequence', + assertInvalid( + invalidSeq, + 'Payment: invalid field Sequence, expected a valid number', ) }) @@ -112,10 +120,9 @@ describe('BaseTransaction', function () { AccountTxnID: ['WRONG'], } as any - assert.throws( - () => validateBaseTransaction(invalidID), - ValidationError, - 'Payment: invalid field AccountTxnID', + assertInvalid( + invalidID, + 'Payment: invalid field AccountTxnID, expected a valid hex string', ) }) @@ -126,10 +133,9 @@ describe('BaseTransaction', function () { LastLedgerSequence: 'abcd', } as any - assert.throws( - () => validateBaseTransaction(invalidLastLedgerSequence), - ValidationError, - 'Payment: invalid field LastLedgerSequence', + assertInvalid( + invalidLastLedgerSequence, + 'Payment: invalid field LastLedgerSequence, expected a valid number', ) }) @@ -140,10 +146,9 @@ describe('BaseTransaction', function () { SourceTag: ['ARRAY'], } as any - assert.throws( - () => validateBaseTransaction(invalidSourceTag), - ValidationError, - 'Payment: invalid field SourceTag', + assertInvalid( + invalidSourceTag, + 'Payment: invalid field SourceTag, expected a valid number', ) }) @@ -154,10 +159,9 @@ describe('BaseTransaction', function () { Flags: 'abcd', } as any - assert.throws( - () => validateBaseTransaction(invalidFlags), - ValidationError, - 'Payment: invalid field Flags', + assertInvalid( + invalidFlags, + 'Payment: invalid field Flags, expected a valid number or Flags object', ) }) @@ -168,10 +172,9 @@ describe('BaseTransaction', function () { SigningPubKey: 1000, } as any - assert.throws( - () => validateBaseTransaction(invalidSigningPubKey), - ValidationError, - 'Payment: invalid field SigningPubKey', + assertInvalid( + invalidSigningPubKey, + 'Payment: invalid field SigningPubKey, expected a valid hex string', ) }) @@ -182,10 +185,9 @@ describe('BaseTransaction', function () { TicketSequence: 'abcd', } as any - assert.throws( - () => validateBaseTransaction(invalidTicketSequence), - ValidationError, - 'Payment: invalid field TicketSequence', + assertInvalid( + invalidTicketSequence, + 'Payment: invalid field TicketSequence, expected a valid number', ) }) @@ -196,10 +198,9 @@ describe('BaseTransaction', function () { TxnSignature: 1000, } as any - assert.throws( - () => validateBaseTransaction(invalidTxnSignature), - ValidationError, - 'Payment: invalid field TxnSignature', + assertInvalid( + invalidTxnSignature, + 'Payment: invalid field TxnSignature, expected a valid hex string', ) }) @@ -210,10 +211,9 @@ describe('BaseTransaction', function () { Signers: [], } as any - assert.throws( - () => validateBaseTransaction(invalidSigners), - ValidationError, - 'BaseTransaction: invalid field Signers', + assertInvalid( + invalidSigners, + 'BaseTransaction: invalid field Signers, expected an array of valid Signer objects', ) const invalidSigners2 = { @@ -228,10 +228,9 @@ describe('BaseTransaction', function () { ], } as any - assert.throws( - () => validateBaseTransaction(invalidSigners2), - ValidationError, - 'BaseTransaction: invalid field Signers', + assertInvalid( + invalidSigners2, + 'BaseTransaction: invalid field Signers, expected an array of valid Signer objects', ) }) @@ -249,10 +248,9 @@ describe('BaseTransaction', function () { ], } as any - assert.throws( - () => validateBaseTransaction(invalidMemo), - ValidationError, - 'BaseTransaction: invalid field Memos', + assertInvalid( + invalidMemo, + 'BaseTransaction: invalid field Memos, expected an array of valid Memo objects', ) }) @@ -262,10 +260,9 @@ describe('BaseTransaction', function () { TransactionType: 'Payment', NetworkID: 'abcd', } - assert.throws( - () => validateBaseTransaction(invalidNetworkID), - ValidationError, - 'Payment: invalid field NetworkID', + assertInvalid( + invalidNetworkID, + 'Payment: invalid field NetworkID, expected a valid number', ) }) }) diff --git a/packages/xrpl/test/models/depositPreauth.test.ts b/packages/xrpl/test/models/depositPreauth.test.ts index d5ef543da1..7d0cace466 100644 --- a/packages/xrpl/test/models/depositPreauth.test.ts +++ b/packages/xrpl/test/models/depositPreauth.test.ts @@ -80,7 +80,10 @@ describe('DepositPreauth', function () { it('throws when Authorize is not a string', function () { depositPreauth.Authorize = 1234 - assertInvalid(depositPreauth, 'DepositPreauth: invalid field Authorize') + assertInvalid( + depositPreauth, + 'DepositPreauth: invalid field Authorize, expected a valid account address', + ) }) it('throws when an Account attempts to preauthorize its own address', function () { @@ -93,7 +96,10 @@ describe('DepositPreauth', function () { it('throws when Unauthorize is not a string', function () { depositPreauth.Unauthorize = 1234 - assertInvalid(depositPreauth, 'DepositPreauth: invalid field Unauthorize') + assertInvalid( + depositPreauth, + 'DepositPreauth: invalid field Unauthorize, expected a valid account address', + ) }) it('throws when an Account attempts to unauthorize its own address', function () { diff --git a/packages/xrpl/test/models/oracleSet.test.ts b/packages/xrpl/test/models/oracleSet.test.ts index fb397b5a7f..0b031eaee4 100644 --- a/packages/xrpl/test/models/oracleSet.test.ts +++ b/packages/xrpl/test/models/oracleSet.test.ts @@ -159,13 +159,15 @@ describe('OracleSet', function () { it(`throws w/ invalid AssetPrice of PriceDataSeries`, function () { tx.PriceDataSeries[0].PriceData.AssetPrice = 'abcd' - const errorMessage = 'OracleSet: invalid field AssetPrice' + const errorMessage = + 'OracleSet: invalid field AssetPrice, expected a valid number' assertInvalid(tx, errorMessage) }) it(`throws w/ invalid Scale of PriceDataSeries`, function () { tx.PriceDataSeries[0].PriceData.Scale = 'abcd' - const errorMessage = 'OracleSet: invalid field Scale' + const errorMessage = + 'OracleSet: invalid field Scale, expected a valid number' assertInvalid(tx, errorMessage) }) diff --git a/packages/xrpl/test/models/payment.test.ts b/packages/xrpl/test/models/payment.test.ts index 625cdb839e..3627e71d4b 100644 --- a/packages/xrpl/test/models/payment.test.ts +++ b/packages/xrpl/test/models/payment.test.ts @@ -66,7 +66,10 @@ describe('Payment', function () { }, ] - assertInvalid(payment, 'BaseTransaction: invalid field Memos') + assertInvalid( + payment, + 'BaseTransaction: invalid field Memos, expected an array of valid Memo objects', + ) }) it(`throws when Amount is missing`, function () { diff --git a/packages/xrpl/test/models/permissionedDomainSet.test.ts b/packages/xrpl/test/models/permissionedDomainSet.test.ts index b736bba851..6c043924e3 100644 --- a/packages/xrpl/test/models/permissionedDomainSet.test.ts +++ b/packages/xrpl/test/models/permissionedDomainSet.test.ts @@ -73,7 +73,7 @@ describe('PermissionedDomainSet', function () { tx.AcceptedCredentials = 'AcceptedCredentials is not an array' assertInvalid( tx, - 'PermissionedDomainSet: invalid field AcceptedCredentials', + 'PermissionedDomainSet: invalid field AcceptedCredentials, expected a valid array', ) }) diff --git a/packages/xrpl/test/models/signerListSet.test.ts b/packages/xrpl/test/models/signerListSet.test.ts index 6d605d5291..01dfb2e95f 100644 --- a/packages/xrpl/test/models/signerListSet.test.ts +++ b/packages/xrpl/test/models/signerListSet.test.ts @@ -66,7 +66,10 @@ describe('SignerListSet', function () { it(`throws w/ invalid SignerEntries`, function () { signerListSetTx.SignerEntries = 'khgfgyhujk' - assertInvalid(signerListSetTx, 'SignerListSet: invalid field SignerEntries') + assertInvalid( + signerListSetTx, + 'SignerListSet: invalid field SignerEntries, expected a valid array', + ) }) it(`throws w/ maximum of 32 members allowed in SignerEntries`, function () { diff --git a/packages/xrpl/test/wallet/index.test.ts b/packages/xrpl/test/wallet/index.test.ts index 059ac73ba3..76495b2d18 100644 --- a/packages/xrpl/test/wallet/index.test.ts +++ b/packages/xrpl/test/wallet/index.test.ts @@ -711,7 +711,7 @@ describe('Wallet', function () { assert.throws(() => { wallet.sign(tx) - }, /1\.2 is an illegal amount/u) + }, /AccountSet: invalid field Fee, expected a valid XRP Amount/u) }) it('sign throws when encoded tx does not match decoded tx because of illegal higher fee', async function () { @@ -729,7 +729,7 @@ describe('Wallet', function () { assert.throws(() => { wallet.sign(tx) - }, /1123456\.7 is an illegal amount/u) + }, /AccountSet: invalid field Fee, expected a valid XRP Amount/u) }) it('sign with a ticket transaction', async function () { From 7e9d563143221888b1b9fb2367030ee9248cd125 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 27 Feb 2025 13:05:51 -0700 Subject: [PATCH 26/46] undo bad change --- packages/ripple-binary-codec/src/types/amount.ts | 2 +- packages/xrpl/test/wallet/index.test.ts | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/ripple-binary-codec/src/types/amount.ts b/packages/ripple-binary-codec/src/types/amount.ts index d0450aacba..44fb567441 100644 --- a/packages/ripple-binary-codec/src/types/amount.ts +++ b/packages/ripple-binary-codec/src/types/amount.ts @@ -257,7 +257,7 @@ class Amount extends SerializedType { * @returns void, but will throw if invalid amount */ private static assertXrpIsValid(amount: string): void { - if (!Number.isInteger(Number(amount))) { + if (amount.indexOf('.') !== -1) { throw new Error(`${amount.toString()} is an illegal amount`) } diff --git a/packages/xrpl/test/wallet/index.test.ts b/packages/xrpl/test/wallet/index.test.ts index 76495b2d18..9b5709974a 100644 --- a/packages/xrpl/test/wallet/index.test.ts +++ b/packages/xrpl/test/wallet/index.test.ts @@ -810,6 +810,22 @@ describe('Wallet', function () { }, /^1.1234567 is an illegal amount/u) }) + it('sign throws when an illegal amount is provided', async function () { + const payment: Transaction = { + TransactionType: 'Payment', + Account: 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59', + Destination: 'rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r', + Amount: '1.0', + Flags: 2147483648, + Sequence: 23, + LastLedgerSequence: 8819954, + Fee: '12', + } + assert.throws(() => { + wallet.sign(payment) + }, /^1.0 is an illegal amount/u) + }) + const issuedCurrencyPayment: Transaction = { TransactionType: 'Payment', Account: 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59', From 52edce3a594ac60454fcb8c9dfae301b8c562da4 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 10 Apr 2025 15:33:55 -0400 Subject: [PATCH 27/46] minor cleanup --- .../xrpl/src/models/transactions/common.ts | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index c6052ac564..558e9b8916 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -273,21 +273,21 @@ export function isXChainBridge(input: unknown): input is XChainBridge { } const invalidMessagesMap: Record = { - isAccount: 'expected a valid account address', - isAmount: 'expected a valid Amount', - isCurrency: 'expected a valid Currency', - isXRPAmount: 'expected a valid XRP Amount', - isIssuedCurrency: 'expected a valid IssuedCurrencyAmount object', - isMPTAmount: 'expected a valid MPTAmount object', - isXChainBridge: 'expected a valid XChainBridge object', - isMemo: 'expected a valid Memo', - isSigner: 'expected a valid Signer', - isRecord: 'expected a valid Record', - isString: 'expected a valid string', - isHexString: 'expected a valid hex string', - isNumber: 'expected a valid number', - isNumberWithBoundsInternal: 'expected a valid number', - isArray: 'expected a valid array', + isAccount: 'account address', + isAmount: 'Amount', + isCurrency: 'Currency', + isXRPAmount: 'XRP Amount', + isIssuedCurrency: 'IssuedCurrencyAmount object', + isMPTAmount: 'MPTAmount object', + isXChainBridge: 'XChainBridge object', + isMemo: 'Memo', + isSigner: 'Signer', + isRecord: 'Record', + isString: 'string', + isHexString: 'hex string', + isNumber: 'number', + isNumberWithBoundsInternal: 'number', + isArray: 'array', } /* eslint-disable @typescript-eslint/restrict-template-expressions -- tx.TransactionType is checked before any calls */ @@ -320,10 +320,10 @@ export function validateRequiredField( const invalidMessageFromMap = invalidMessagesMap[checkValidity.name] // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, max-depth -- okay if (invalidMessageFromMap != null) { - errorMessage += `, ${invalidMessageFromMap}` + errorMessage += `, expected a valid ${invalidMessageFromMap}` } } else { - errorMessage += `, ${invalidMessage}` + errorMessage += `, expected a valid ${invalidMessage}` } throw new ValidationError(errorMessage) } From 8ac77a7646c33ed5551f208d9f8c64e746b21327 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 10 Apr 2025 15:39:55 -0400 Subject: [PATCH 28/46] fix tests --- packages/xrpl/src/models/transactions/common.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 558e9b8916..4275a1c82d 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -323,7 +323,7 @@ export function validateRequiredField( errorMessage += `, expected a valid ${invalidMessageFromMap}` } } else { - errorMessage += `, expected a valid ${invalidMessage}` + errorMessage += `, ${invalidMessage}` } throw new ValidationError(errorMessage) } @@ -351,7 +351,7 @@ export function validateOptionalField( const invalidMessageFromMap = invalidMessagesMap[checkValidity.name] // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, max-depth -- okay if (invalidMessageFromMap != null) { - errorMessage += `, ${invalidMessageFromMap}` + errorMessage += `, expected a valid ${invalidMessageFromMap}` } } else { errorMessage += `, ${invalidMessage}` From 556b55ca0ff4ae80a651a2e160cca1e8d05708be Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 16 Apr 2025 11:52:47 -0400 Subject: [PATCH 29/46] improve type-checking --- .../xrpl/src/models/transactions/common.ts | 51 +++++++++++-------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 4275a1c82d..79899c439b 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -79,13 +79,13 @@ export function isRecord(value: unknown): value is Record { } /** - * Verify the form and type of an array at runtime. + * Verify the form and type of an Array at runtime. * - * @param value - The object to check the form and type of. - * @returns Whether the array is properly formed. + * @param input - The object to check the form and type of. + * @returns Whether the Array is properly formed. */ -export function isArray(value: unknown): value is unknown[] { - return Array.isArray(value) +export function isArray(input: unknown): input is T[] { + return Array.isArray(input) } /** @@ -302,20 +302,26 @@ const invalidMessagesMap: Record = { * @throws ValidationError if the field is missing or invalid. */ // eslint-disable-next-line max-params -- okay for a helper function -export function validateRequiredField( - tx: Record, - paramName: string, - checkValidity: (inp: unknown) => boolean, +export function validateRequiredField< + T extends Record, + K extends keyof T, + V, +>( + tx: T, + paramName: K, + checkValidity: (inp: unknown) => inp is V, invalidMessage?: string, -): void { +): asserts tx is T & { [P in K]: V } { if (tx[paramName] == null) { throw new ValidationError( - `${tx.TransactionType}: missing field ${paramName}`, + `${tx.TransactionType}: missing field ${String(paramName)}`, ) } if (!checkValidity(tx[paramName])) { - let errorMessage = `${tx.TransactionType}: invalid field ${paramName}` + let errorMessage = `${tx.TransactionType}: invalid field ${String( + paramName, + )}` if (invalidMessage == null) { const invalidMessageFromMap = invalidMessagesMap[checkValidity.name] // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, max-depth -- okay @@ -339,14 +345,20 @@ export function validateRequiredField( * @throws ValidationError if the field is invalid. */ // eslint-disable-next-line max-params -- okay for a helper function -export function validateOptionalField( - tx: Record, - paramName: string, - checkValidity: (inp: unknown) => boolean, +export function validateOptionalField< + T extends Record, + K extends keyof T, + V, +>( + tx: T, + paramName: K, + checkValidity: (inp: unknown) => inp is V, invalidMessage?: string, -): void { +): asserts tx is T & { [P in K]: V | undefined } { if (tx[paramName] !== undefined && !checkValidity(tx[paramName])) { - let errorMessage = `${tx.TransactionType}: invalid field ${paramName}` + let errorMessage = `${tx.TransactionType}: invalid field ${String( + paramName, + )}` if (invalidMessage == null) { const invalidMessageFromMap = invalidMessagesMap[checkValidity.name] // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, max-depth -- okay @@ -453,8 +465,7 @@ export interface BaseTransaction { export function validateBaseTransaction(common: Record): void { validateRequiredField(common, 'TransactionType', isString) - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Checked above - if (!TRANSACTION_TYPES.includes(common.TransactionType as string)) { + if (!TRANSACTION_TYPES.includes(common.TransactionType)) { throw new ValidationError('BaseTransaction: Unknown TransactionType') } From fd9a8826ec98d2bf072ab9f02d8645f7a020c0c7 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 16 Apr 2025 12:02:14 -0400 Subject: [PATCH 30/46] fix errors --- packages/xrpl/src/client/index.ts | 8 +- packages/xrpl/src/client/partialPayment.ts | 7 +- .../xrpl/src/models/transactions/AMMBid.ts | 3 +- .../XChainAddAccountCreateAttestation.ts | 4 +- .../transactions/XChainAddClaimAttestation.ts | 4 +- .../src/models/transactions/XChainClaim.ts | 2 +- .../src/models/transactions/XChainCommit.ts | 2 +- .../src/models/transactions/accountDelete.ts | 3 +- .../xrpl/src/models/transactions/clawback.ts | 3 +- .../xrpl/src/models/transactions/common.ts | 8 +- .../models/transactions/credentialCreate.ts | 4 +- .../src/models/transactions/depositPreauth.ts | 6 +- .../src/models/transactions/escrowFinish.ts | 3 +- .../xrpl/src/models/transactions/oracleSet.ts | 190 +++++++++--------- .../xrpl/src/models/transactions/payment.ts | 5 +- .../transactions/paymentChannelClaim.ts | 3 +- .../transactions/permissionedDomainSet.ts | 6 +- .../src/models/transactions/signerListSet.ts | 8 +- packages/xrpl/src/sugar/autofill.ts | 38 ++-- 19 files changed, 151 insertions(+), 156 deletions(-) diff --git a/packages/xrpl/src/client/index.ts b/packages/xrpl/src/client/index.ts index 91186d99bf..1996056949 100644 --- a/packages/xrpl/src/client/index.ts +++ b/packages/xrpl/src/client/index.ts @@ -689,20 +689,16 @@ class Client extends EventEmitter { promises.push(checkAccountDeleteBlockers(this, tx)) } - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- ignore type-assertions on the DeliverMax property - // @ts-expect-error -- DeliverMax property exists only at the RPC level, not at the protocol level if (tx.TransactionType === 'Payment' && tx.DeliverMax != null) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- This is a valid null check for Amount if (tx.Amount == null) { // If only DeliverMax is provided, use it to populate the Amount field // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- ignore type-assertions on the DeliverMax property // @ts-expect-error -- DeliverMax property exists only at the RPC level, not at the protocol level - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- DeliverMax is a known RPC-level property + tx.Amount = tx.DeliverMax } - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- ignore type-assertions on the DeliverMax property - // @ts-expect-error -- DeliverMax property exists only at the RPC level, not at the protocol level // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- This is a valid null check for Amount if (tx.Amount != null && tx.Amount !== tx.DeliverMax) { return Promise.reject( @@ -712,8 +708,6 @@ class Client extends EventEmitter { ) } - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- ignore type-assertions on the DeliverMax property - // @ts-expect-error -- DeliverMax property exists only at the RPC level, not at the protocol level delete tx.DeliverMax } diff --git a/packages/xrpl/src/client/partialPayment.ts b/packages/xrpl/src/client/partialPayment.ts index 8176fb7839..2d91008ef4 100644 --- a/packages/xrpl/src/client/partialPayment.ts +++ b/packages/xrpl/src/client/partialPayment.ts @@ -96,10 +96,9 @@ function isPartialPayment( } const delivered = meta.delivered_amount - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- DeliverMax is a valid field on Payment response - // @ts-expect-error -- DeliverMax is a valid field on Payment response - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- DeliverMax is a valid field on Payment response - const amount = tx.DeliverMax + + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- needed here + const amount = tx.DeliverMax as Amount | MPTAmount if (delivered === undefined) { return false diff --git a/packages/xrpl/src/models/transactions/AMMBid.ts b/packages/xrpl/src/models/transactions/AMMBid.ts index d7059a3fd6..2e5c6f6eea 100644 --- a/packages/xrpl/src/models/transactions/AMMBid.ts +++ b/packages/xrpl/src/models/transactions/AMMBid.ts @@ -80,8 +80,7 @@ export function validateAMMBid(tx: Record): void { ) } validateAuthAccounts( - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS - tx.Account as string, + tx.Account, // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS tx.AuthAccounts as Array>, ) diff --git a/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts b/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts index e204dbbe0d..adc0068372 100644 --- a/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts +++ b/packages/xrpl/src/models/transactions/XChainAddAccountCreateAttestation.ts @@ -110,14 +110,14 @@ export function validateXChainAddAccountCreateAttestation( validateRequiredField( tx, 'WasLockingChainSend', - (inp) => inp === 0 || inp === 1, + (inp: unknown): inp is 0 | 1 => inp === 0 || inp === 1, 'expected 0 or 1', ) validateRequiredField( tx, 'XChainAccountCreateCount', - (inp) => isNumber(inp) || isHexString(inp), + (inp: unknown): inp is number | string => isNumber(inp) || isHexString(inp), 'expected a valid number or hex string', ) diff --git a/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts b/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts index 2bdb8d2c77..24470ff897 100644 --- a/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts +++ b/packages/xrpl/src/models/transactions/XChainAddClaimAttestation.ts @@ -104,7 +104,7 @@ export function validateXChainAddClaimAttestation( validateRequiredField( tx, 'WasLockingChainSend', - (inp) => inp === 0 || inp === 1, + (inp: unknown): inp is 0 | 1 => inp === 0 || inp === 1, 'expected 0 or 1', ) @@ -113,7 +113,7 @@ export function validateXChainAddClaimAttestation( validateRequiredField( tx, 'XChainClaimID', - (inp) => isNumber(inp) || isHexString(inp), + (inp: unknown): inp is number | string => isNumber(inp) || isHexString(inp), 'expected a number or hex string', ) } diff --git a/packages/xrpl/src/models/transactions/XChainClaim.ts b/packages/xrpl/src/models/transactions/XChainClaim.ts index 948c048824..5d322355d3 100644 --- a/packages/xrpl/src/models/transactions/XChainClaim.ts +++ b/packages/xrpl/src/models/transactions/XChainClaim.ts @@ -68,7 +68,7 @@ export function validateXChainClaim(tx: Record): void { validateRequiredField( tx, 'XChainClaimID', - (inp) => isNumber(inp) || isHexString(inp), + (inp: unknown): inp is number | string => isNumber(inp) || isHexString(inp), 'expected a number or hex string', ) diff --git a/packages/xrpl/src/models/transactions/XChainCommit.ts b/packages/xrpl/src/models/transactions/XChainCommit.ts index 6b3e4834f5..ec7c2b61d2 100644 --- a/packages/xrpl/src/models/transactions/XChainCommit.ts +++ b/packages/xrpl/src/models/transactions/XChainCommit.ts @@ -67,7 +67,7 @@ export function validateXChainCommit(tx: Record): void { validateRequiredField( tx, 'XChainClaimID', - (inp) => isNumber(inp) || isHexString(inp), + (inp: unknown): inp is number | string => isNumber(inp) || isHexString(inp), 'expected a number or hex string', ) diff --git a/packages/xrpl/src/models/transactions/accountDelete.ts b/packages/xrpl/src/models/transactions/accountDelete.ts index 1af47685d7..b4c2eef158 100644 --- a/packages/xrpl/src/models/transactions/accountDelete.ts +++ b/packages/xrpl/src/models/transactions/accountDelete.ts @@ -52,8 +52,7 @@ export function validateAccountDelete(tx: Record): void { validateCredentialsList( tx.CredentialIDs, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- known from base check - tx.TransactionType as string, + tx.TransactionType, true, MAX_AUTHORIZED_CREDENTIALS, ) diff --git a/packages/xrpl/src/models/transactions/clawback.ts b/packages/xrpl/src/models/transactions/clawback.ts index 42e62017d0..c0f748c17d 100644 --- a/packages/xrpl/src/models/transactions/clawback.ts +++ b/packages/xrpl/src/models/transactions/clawback.ts @@ -47,7 +47,8 @@ export function validateClawback(tx: Record): void { validateRequiredField( tx, 'Amount', - (inp) => isIssuedCurrency(inp) || isMPTAmount(inp), + (inp): inp is IssuedCurrencyAmount | MPTAmount => + isIssuedCurrency(inp) || isMPTAmount(inp), 'expected a valid non-XRP Amount', ) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 79899c439b..68bf94086e 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -380,7 +380,7 @@ export interface GlobalFlags {} /** * Every transaction has the same set of common fields. */ -export interface BaseTransaction { +export interface BaseTransaction extends Record { /** The unique address of the transaction sender. */ Account: Account /** @@ -462,7 +462,9 @@ export interface BaseTransaction { * @throws When the common param is malformed. */ // eslint-disable-next-line max-lines-per-function, max-statements -- not worth refactoring -export function validateBaseTransaction(common: Record): void { +export function validateBaseTransaction( + common: Record, +): asserts common is BaseTransaction { validateRequiredField(common, 'TransactionType', isString) if (!TRANSACTION_TYPES.includes(common.TransactionType)) { @@ -477,7 +479,7 @@ export function validateBaseTransaction(common: Record): void { validateOptionalField( common, 'Flags', - (inp) => isNumber(inp) || isRecord(inp), + (inp): inp is number | object => isNumber(inp) || isRecord(inp), 'expected a valid number or Flags object', ) diff --git a/packages/xrpl/src/models/transactions/credentialCreate.ts b/packages/xrpl/src/models/transactions/credentialCreate.ts index f8b3d01a08..711385913e 100644 --- a/packages/xrpl/src/models/transactions/credentialCreate.ts +++ b/packages/xrpl/src/models/transactions/credentialCreate.ts @@ -55,8 +55,8 @@ export function validateCredentialCreate(tx: Record): void { validateOptionalField(tx, 'Expiration', isNumber) validateOptionalField(tx, 'URI', isHexString) - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- checked above - const uriLength = (tx.URI as string | undefined)?.length + + const uriLength = tx.URI?.length if (uriLength !== undefined) { if (uriLength === 0) { throw new ValidationError( diff --git a/packages/xrpl/src/models/transactions/depositPreauth.ts b/packages/xrpl/src/models/transactions/depositPreauth.ts index 70fe127300..38681bde94 100644 --- a/packages/xrpl/src/models/transactions/depositPreauth.ts +++ b/packages/xrpl/src/models/transactions/depositPreauth.ts @@ -67,16 +67,14 @@ export function validateDepositPreauth(tx: Record): void { } else if (tx.AuthorizeCredentials !== undefined) { validateCredentialsList( tx.AuthorizeCredentials, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- confirmed in base transaction check - tx.TransactionType as string, + tx.TransactionType, false, MAX_AUTHORIZED_CREDENTIALS, ) } else if (tx.UnauthorizeCredentials !== undefined) { validateCredentialsList( tx.UnauthorizeCredentials, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- confirmed in base transaction check - tx.TransactionType as string, + tx.TransactionType, false, MAX_AUTHORIZED_CREDENTIALS, ) diff --git a/packages/xrpl/src/models/transactions/escrowFinish.ts b/packages/xrpl/src/models/transactions/escrowFinish.ts index ed7d1c2bb1..bcf9729169 100644 --- a/packages/xrpl/src/models/transactions/escrowFinish.ts +++ b/packages/xrpl/src/models/transactions/escrowFinish.ts @@ -54,8 +54,7 @@ export function validateEscrowFinish(tx: Record): void { validateCredentialsList( tx.CredentialIDs, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- known from base check - tx.TransactionType as string, + tx.TransactionType, true, MAX_AUTHORIZED_CREDENTIALS, ) diff --git a/packages/xrpl/src/models/transactions/oracleSet.ts b/packages/xrpl/src/models/transactions/oracleSet.ts index 9a03834375..f0c0d2af89 100644 --- a/packages/xrpl/src/models/transactions/oracleSet.ts +++ b/packages/xrpl/src/models/transactions/oracleSet.ts @@ -86,115 +86,119 @@ export function validateOracleSet(tx: Record): void { validateOptionalField(tx, 'AssetClass', isHexString) /* eslint-disable max-statements, max-lines-per-function -- necessary to validate many fields */ - validateRequiredField(tx, 'PriceDataSeries', (value) => { - if (!Array.isArray(value)) { - throw new ValidationError('OracleSet: PriceDataSeries must be an array') - } - - if (value.length > PRICE_DATA_SERIES_MAX_LENGTH) { - throw new ValidationError( - `OracleSet: PriceDataSeries must have at most ${PRICE_DATA_SERIES_MAX_LENGTH} PriceData objects`, - ) - } - - // TODO: add support for handling inner objects easier (similar to validateRequiredField/validateOptionalField) - for (const priceData of value) { - if (typeof priceData !== 'object') { - throw new ValidationError( - 'OracleSet: PriceDataSeries must be an array of objects', - ) + validateRequiredField( + tx, + 'PriceDataSeries', + (value: unknown): value is PriceData => { + if (!Array.isArray(value)) { + throw new ValidationError('OracleSet: PriceDataSeries must be an array') } - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type - if (priceData.PriceData == null) { + if (value.length > PRICE_DATA_SERIES_MAX_LENGTH) { throw new ValidationError( - 'OracleSet: PriceDataSeries must have a `PriceData` object', + `OracleSet: PriceDataSeries must have at most ${PRICE_DATA_SERIES_MAX_LENGTH} PriceData objects`, ) } - // check if priceData only has PriceData - if (Object.keys(priceData).length !== 1) { - throw new ValidationError( - 'OracleSet: PriceDataSeries must only have a single PriceData object', - ) - } + // TODO: add support for handling inner objects easier (similar to validateRequiredField/validateOptionalField) + for (const priceData of value) { + if (typeof priceData !== 'object') { + throw new ValidationError( + 'OracleSet: PriceDataSeries must be an array of objects', + ) + } - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type - if (typeof priceData.PriceData.BaseAsset !== 'string') { - throw new ValidationError( - 'OracleSet: PriceDataSeries must have a `BaseAsset` string', - ) - } + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type + if (priceData.PriceData == null) { + throw new ValidationError( + 'OracleSet: PriceDataSeries must have a `PriceData` object', + ) + } - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type - if (typeof priceData.PriceData.QuoteAsset !== 'string') { - throw new ValidationError( - 'OracleSet: PriceDataSeries must have a `QuoteAsset` string', - ) - } + // check if priceData only has PriceData + if (Object.keys(priceData).length !== 1) { + throw new ValidationError( + 'OracleSet: PriceDataSeries must only have a single PriceData object', + ) + } - // Either AssetPrice and Scale are both present or both excluded - if ( // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type - (priceData.PriceData.AssetPrice == null) !== + if (typeof priceData.PriceData.BaseAsset !== 'string') { + throw new ValidationError( + 'OracleSet: PriceDataSeries must have a `BaseAsset` string', + ) + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type - (priceData.PriceData.Scale == null) - ) { - throw new ValidationError( - 'OracleSet: PriceDataSeries must have both `AssetPrice` and `Scale` if any are present', - ) - } + if (typeof priceData.PriceData.QuoteAsset !== 'string') { + throw new ValidationError( + 'OracleSet: PriceDataSeries must have a `QuoteAsset` string', + ) + } - /* eslint-disable @typescript-eslint/no-unsafe-member-access, max-depth -- + // Either AssetPrice and Scale are both present or both excluded + if ( + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type + (priceData.PriceData.AssetPrice == null) !== + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type + (priceData.PriceData.Scale == null) + ) { + throw new ValidationError( + 'OracleSet: PriceDataSeries must have both `AssetPrice` and `Scale` if any are present', + ) + } + + /* eslint-disable @typescript-eslint/no-unsafe-member-access, max-depth -- we need to validate priceData.PriceData.AssetPrice value */ - if ('AssetPrice' in priceData.PriceData) { - if (!isNumber(priceData.PriceData.AssetPrice)) { - if (typeof priceData.PriceData.AssetPrice !== 'string') { - throw new ValidationError( - 'OracleSet: Field AssetPrice must be a string or a number', - ) - } - if (!isHex(priceData.PriceData.AssetPrice)) { - throw new ValidationError( - 'OracleSet: Field AssetPrice must be a valid hex string', - ) - } - if ( - priceData.PriceData.AssetPrice.length < - MINIMUM_ASSET_PRICE_LENGTH || - priceData.PriceData.AssetPrice.length > MAXIMUM_ASSET_PRICE_LENGTH - ) { - throw new ValidationError( - `OracleSet: Length of AssetPrice field must be between ${MINIMUM_ASSET_PRICE_LENGTH} and ${MAXIMUM_ASSET_PRICE_LENGTH} characters long`, - ) + if ('AssetPrice' in priceData.PriceData) { + if (!isNumber(priceData.PriceData.AssetPrice)) { + if (typeof priceData.PriceData.AssetPrice !== 'string') { + throw new ValidationError( + 'OracleSet: Field AssetPrice must be a string or a number', + ) + } + if (!isHex(priceData.PriceData.AssetPrice)) { + throw new ValidationError( + 'OracleSet: Field AssetPrice must be a valid hex string', + ) + } + if ( + priceData.PriceData.AssetPrice.length < + MINIMUM_ASSET_PRICE_LENGTH || + priceData.PriceData.AssetPrice.length > MAXIMUM_ASSET_PRICE_LENGTH + ) { + throw new ValidationError( + `OracleSet: Length of AssetPrice field must be between ${MINIMUM_ASSET_PRICE_LENGTH} and ${MAXIMUM_ASSET_PRICE_LENGTH} characters long`, + ) + } } } - } - /* eslint-enable @typescript-eslint/no-unsafe-member-access, max-depth */ - - if ( - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type - 'Scale' in priceData.PriceData && - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type - !isNumber(priceData.PriceData.Scale) - ) { - throw new ValidationError( - 'OracleSet: invalid field Scale, expected a valid number', - ) - } + /* eslint-enable @typescript-eslint/no-unsafe-member-access, max-depth */ + + if ( + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type + 'Scale' in priceData.PriceData && + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type + !isNumber(priceData.PriceData.Scale) + ) { + throw new ValidationError( + 'OracleSet: invalid field Scale, expected a valid number', + ) + } - if ( - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type - priceData.PriceData.Scale < 0 || - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type - priceData.PriceData.Scale > SCALE_MAX - ) { - throw new ValidationError( - `OracleSet: Scale must be in range 0-${SCALE_MAX}`, - ) + if ( + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type + priceData.PriceData.Scale < 0 || + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- we are validating the type + priceData.PriceData.Scale > SCALE_MAX + ) { + throw new ValidationError( + `OracleSet: Scale must be in range 0-${SCALE_MAX}`, + ) + } } - } - return true - }) + return true + }, + ) /* eslint-enable max-statements, max-lines-per-function */ } diff --git a/packages/xrpl/src/models/transactions/payment.ts b/packages/xrpl/src/models/transactions/payment.ts index 7a02c1eca9..d0853f3670 100644 --- a/packages/xrpl/src/models/transactions/payment.ts +++ b/packages/xrpl/src/models/transactions/payment.ts @@ -185,8 +185,7 @@ export function validatePayment(tx: Record): void { validateCredentialsList( tx.CredentialIDs, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- known from base check - tx.TransactionType as string, + tx.TransactionType, true, MAX_AUTHORIZED_CREDENTIALS, ) @@ -258,7 +257,7 @@ function isPath(path: Array>): boolean { return true } -function isPaths(paths: unknown): boolean { +function isPaths(paths: unknown): paths is Path[] { if (!Array.isArray(paths) || paths.length === 0) { return false } diff --git a/packages/xrpl/src/models/transactions/paymentChannelClaim.ts b/packages/xrpl/src/models/transactions/paymentChannelClaim.ts index 1b80fd4390..dec8c89a31 100644 --- a/packages/xrpl/src/models/transactions/paymentChannelClaim.ts +++ b/packages/xrpl/src/models/transactions/paymentChannelClaim.ts @@ -159,8 +159,7 @@ export function validatePaymentChannelClaim(tx: Record): void { validateCredentialsList( tx.CredentialIDs, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- known from base check - tx.TransactionType as string, + tx.TransactionType, true, MAX_AUTHORIZED_CREDENTIALS, ) diff --git a/packages/xrpl/src/models/transactions/permissionedDomainSet.ts b/packages/xrpl/src/models/transactions/permissionedDomainSet.ts index 5570050984..f0e442f9f7 100644 --- a/packages/xrpl/src/models/transactions/permissionedDomainSet.ts +++ b/packages/xrpl/src/models/transactions/permissionedDomainSet.ts @@ -7,6 +7,7 @@ import { validateRequiredField, validateCredentialsList, isHexString, + isArray, } from './common' const MAX_ACCEPTED_CREDENTIALS = 10 @@ -36,12 +37,11 @@ export function validatePermissionedDomainSet( validateBaseTransaction(tx) validateOptionalField(tx, 'DomainID', isHexString) - validateRequiredField(tx, 'AcceptedCredentials', Array.isArray) + validateRequiredField(tx, 'AcceptedCredentials', isArray) validateCredentialsList( tx.AcceptedCredentials, - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- known from base check - tx.TransactionType as string, + tx.TransactionType, // PermissionedDomainSet uses AuthorizeCredential nested objects only, strings are not allowed false, // PermissionedDomainSet uses at most 10 accepted credentials. This is different from Credential-feature transactions. diff --git a/packages/xrpl/src/models/transactions/signerListSet.ts b/packages/xrpl/src/models/transactions/signerListSet.ts index 7f4a10cfca..01fb68765b 100644 --- a/packages/xrpl/src/models/transactions/signerListSet.ts +++ b/packages/xrpl/src/models/transactions/signerListSet.ts @@ -54,21 +54,19 @@ export function validateSignerListSet(tx: Record): void { validateRequiredField(tx, 'SignerEntries', isArray) - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- checked above - const signerEntries = tx.SignerEntries as unknown[] - if (signerEntries.length === 0) { + if (tx.SignerEntries.length === 0) { throw new ValidationError( 'SignerListSet: need at least 1 member in SignerEntries', ) } - if (signerEntries.length > MAX_SIGNERS) { + if (tx.SignerEntries.length > MAX_SIGNERS) { throw new ValidationError( `SignerListSet: maximum of ${MAX_SIGNERS} members allowed in SignerEntries`, ) } - for (const entry of signerEntries) { + for (const entry of tx.SignerEntries) { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Should be a SignerEntry const signerEntry = entry as SignerEntry const { WalletLocator } = signerEntry.SignerEntry diff --git a/packages/xrpl/src/sugar/autofill.ts b/packages/xrpl/src/sugar/autofill.ts index ca0757611d..4884fe0b51 100644 --- a/packages/xrpl/src/sugar/autofill.ts +++ b/packages/xrpl/src/sugar/autofill.ts @@ -140,41 +140,46 @@ export function setValidAddresses(tx: Transaction): void { * @param tagField - The field name for the tag in the transaction object. * @throws {ValidationError} If the tag field does not match the tag of the account address. */ -function validateAccountAddress( - tx: Transaction, - accountField: string, - tagField: string, -): void { +function validateAccountAddress< + T extends Transaction, + K extends keyof T & string, + K2 extends keyof T & string, +>(tx: T, accountField: K, tagField: K2): void { + const val = tx[accountField] + + if (typeof val !== 'string') { + throw new Error(`${accountField} must be a string`) + } // if X-address is given, convert it to classic address - const { classicAccount, tag } = getClassicAccountAndTag(tx[accountField]) - // eslint-disable-next-line no-param-reassign -- param reassign is safe - tx[accountField] = classicAccount + const { classicAccount, tag } = getClassicAccountAndTag(val) + // eslint-disable-next-line no-param-reassign, @typescript-eslint/consistent-type-assertions -- param reassign is safe + ;(tx as Record)[accountField] = classicAccount if (tag != null && tag !== false) { - if (tx[tagField] && tx[tagField] !== tag) { + if (tagField in tx && tx[tagField] !== tag) { throw new ValidationError( `The ${tagField}, if present, must match the tag of the ${accountField} X-address`, ) } - // eslint-disable-next-line no-param-reassign -- param reassign is safe - tx[tagField] = tag + // eslint-disable-next-line no-param-reassign, @typescript-eslint/consistent-type-assertions -- param reassign is safe + ;(tx as Record)[tagField] = tag } } /** * Retrieves the classic account and tag from an account address. * - * @param Account - The account address. + * @param account - The account address. * @param [expectedTag] - The expected tag for the account address. * @returns The classic account and tag. * @throws {ValidationError} If the address includes a tag that does not match the tag specified in the transaction. */ function getClassicAccountAndTag( - Account: string, + account: string, expectedTag?: number, ): ClassicAccountAndTag { - if (isValidXAddress(Account)) { - const classic = xAddressToClassicAddress(Account) + if (isValidXAddress(account)) { + const classic = xAddressToClassicAddress(account) if (expectedTag != null && classic.tag !== expectedTag) { throw new ValidationError( 'address includes a tag that does not match the tag specified in the transaction', @@ -186,7 +191,7 @@ function getClassicAccountAndTag( } } return { - classicAccount: Account, + classicAccount: account, tag: expectedTag, } } @@ -198,7 +203,6 @@ function getClassicAccountAndTag( * @param fieldName - The name of the field to convert.export */ function convertToClassicAddress(tx: Transaction, fieldName: string): void { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- assignment is safe const account = tx[fieldName] if (typeof account === 'string') { const { classicAccount } = getClassicAccountAndTag(account) From df2e235ce8832ea68ead2bcb49a5a6804d1d9ff4 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 16 Apr 2025 13:49:07 -0400 Subject: [PATCH 31/46] fix ts issues --- packages/xrpl/src/client/index.ts | 1 - packages/xrpl/test/client/autofill.test.ts | 3 --- 2 files changed, 4 deletions(-) diff --git a/packages/xrpl/src/client/index.ts b/packages/xrpl/src/client/index.ts index 1996056949..e1d3091548 100644 --- a/packages/xrpl/src/client/index.ts +++ b/packages/xrpl/src/client/index.ts @@ -695,7 +695,6 @@ class Client extends EventEmitter { // If only DeliverMax is provided, use it to populate the Amount field // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- ignore type-assertions on the DeliverMax property // @ts-expect-error -- DeliverMax property exists only at the RPC level, not at the protocol level - tx.Amount = tx.DeliverMax } diff --git a/packages/xrpl/test/client/autofill.test.ts b/packages/xrpl/test/client/autofill.test.ts index 8c2d9b5ec8..41b1bfa5a4 100644 --- a/packages/xrpl/test/client/autofill.test.ts +++ b/packages/xrpl/test/client/autofill.test.ts @@ -79,7 +79,6 @@ describe('client.autofill', function () { }) it('Validate Payment transaction API v2: Payment Transaction: Specify Only DeliverMax field', async function () { - // @ts-expect-error -- DeliverMax is a non-protocol, RPC level field in Payment transactions paymentTx.DeliverMax = paymentTx.Amount // @ts-expect-error -- DeliverMax is a non-protocol, RPC level field in Payment transactions delete paymentTx.Amount @@ -89,7 +88,6 @@ describe('client.autofill', function () { }) it('Validate Payment transaction API v2: Payment Transaction: identical DeliverMax and Amount fields', async function () { - // @ts-expect-error -- DeliverMax is a non-protocol, RPC level field in Payment transactions paymentTx.DeliverMax = paymentTx.Amount const txResult = await testContext.client.autofill(paymentTx) @@ -99,7 +97,6 @@ describe('client.autofill', function () { }) it('Validate Payment transaction API v2: Payment Transaction: differing DeliverMax and Amount fields', async function () { - // @ts-expect-error -- DeliverMax is a non-protocol, RPC level field in Payment transactions paymentTx.DeliverMax = '6789' paymentTx.Amount = '1234' From 20f8a7192fed4552f5078fb4aeab3e5fc1d60b09 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 16 Apr 2025 13:57:54 -0400 Subject: [PATCH 32/46] more fixes --- packages/xrpl/test/integration/requests/accountTx.test.ts | 1 - packages/xrpl/test/integration/transactions/payment.test.ts | 2 -- 2 files changed, 3 deletions(-) diff --git a/packages/xrpl/test/integration/requests/accountTx.test.ts b/packages/xrpl/test/integration/requests/accountTx.test.ts index a0af38444b..4d578d8603 100644 --- a/packages/xrpl/test/integration/requests/accountTx.test.ts +++ b/packages/xrpl/test/integration/requests/accountTx.test.ts @@ -100,7 +100,6 @@ describe('account_tx', function () { responseTx.Flags, responseTx.TransactionType, responseTx.Account, - // @ts-expect-error -- DeliverMax is a valid field on Payment response responseTx.DeliverMax, responseTx.Destination, ], diff --git a/packages/xrpl/test/integration/transactions/payment.test.ts b/packages/xrpl/test/integration/transactions/payment.test.ts index 2cccfc2c77..2a076b8eb8 100644 --- a/packages/xrpl/test/integration/transactions/payment.test.ts +++ b/packages/xrpl/test/integration/transactions/payment.test.ts @@ -74,7 +74,6 @@ describe('Payment', function () { it( 'Validate Payment transaction API v2: Payment Transaction: Specify Only DeliverMax field', async () => { - // @ts-expect-error -- DeliverMax is a non-protocol, RPC level field in Payment transactions paymentTx.DeliverMax = paymentTx.Amount // @ts-expect-error -- DeliverMax is a non-protocol, RPC level field in Payment transactions delete paymentTx.Amount @@ -94,7 +93,6 @@ describe('Payment', function () { it( 'Validate Payment transaction API v2: Payment Transaction: identical DeliverMax and Amount fields', async () => { - // @ts-expect-error -- DeliverMax is a non-protocol, RPC level field in Payment transactions paymentTx.DeliverMax = paymentTx.Amount const result = await testTransaction( From 85514c626ca86d11e83d1b86d8fdbbf967220216 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 16 Apr 2025 15:17:17 -0400 Subject: [PATCH 33/46] more cleanup --- packages/xrpl/src/models/transactions/common.ts | 16 ++-------------- .../xrpl/test/models/CredentialAccept.test.ts | 3 ++- .../xrpl/test/models/CredentialCreate.test.ts | 3 ++- .../xrpl/test/models/CredentialDelete.test.ts | 3 ++- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 68bf94086e..ce0f069632 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -543,21 +543,9 @@ export function parseAmountValue(amount: unknown): number { * @param tx A CredentialType Transaction. * @throws when the CredentialType is malformed. */ -export function validateCredentialType(tx: Record): void { - if (typeof tx.TransactionType !== 'string') { - throw new ValidationError('Invalid TransactionType') - } - if (tx.CredentialType === undefined) { - throw new ValidationError( - `${tx.TransactionType}: missing field CredentialType`, - ) - } +export function validateCredentialType(tx: T): void { + validateRequiredField(tx, 'CredentialType', isHexString) - if (!isHexString(tx.CredentialType)) { - throw new ValidationError( - `${tx.TransactionType}: CredentialType must be a hex string`, - ) - } if (tx.CredentialType.length === 0) { throw new ValidationError( `${tx.TransactionType}: CredentialType cannot be an empty string`, diff --git a/packages/xrpl/test/models/CredentialAccept.test.ts b/packages/xrpl/test/models/CredentialAccept.test.ts index f0f890e614..371985d900 100644 --- a/packages/xrpl/test/models/CredentialAccept.test.ts +++ b/packages/xrpl/test/models/CredentialAccept.test.ts @@ -79,7 +79,8 @@ describe('CredentialAccept', function () { it(`throws w/ credentialType field not hex`, function () { credentialAccept.CredentialType = 'this is not hex' - const errorMessage = 'CredentialAccept: CredentialType must be a hex string' + const errorMessage = + 'CredentialAccept: invalid field CredentialType, expected a valid hex string' assertInvalid(credentialAccept, errorMessage) }) }) diff --git a/packages/xrpl/test/models/CredentialCreate.test.ts b/packages/xrpl/test/models/CredentialCreate.test.ts index b811ea9e03..977ed2fcd6 100644 --- a/packages/xrpl/test/models/CredentialCreate.test.ts +++ b/packages/xrpl/test/models/CredentialCreate.test.ts @@ -81,7 +81,8 @@ describe('credentialCreate', function () { it(`throws w/ credentialType field not hex`, function () { credentialCreate.CredentialType = 'this is not hex' - const errorMessage = 'CredentialCreate: CredentialType must be a hex string' + const errorMessage = + 'CredentialCreate: invalid field CredentialType, expected a valid hex string' assertInvalid(credentialCreate, errorMessage) }) diff --git a/packages/xrpl/test/models/CredentialDelete.test.ts b/packages/xrpl/test/models/CredentialDelete.test.ts index 01ceeb09dd..f056d19795 100644 --- a/packages/xrpl/test/models/CredentialDelete.test.ts +++ b/packages/xrpl/test/models/CredentialDelete.test.ts @@ -89,7 +89,8 @@ describe('CredentialDelete', function () { it(`throws w/ credentialType field not hex`, function () { credentialDelete.CredentialType = 'this is not hex' - const errorMessage = 'CredentialDelete: CredentialType must be a hex string' + const errorMessage = + 'CredentialDelete: invalid field CredentialType, expected a valid hex string' assertInvalid(credentialDelete, errorMessage) }) }) From acb7bfdd997872a30ce7944f0a781f0c84dba5f9 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 17 Apr 2025 18:16:46 -0400 Subject: [PATCH 34/46] consolidate code --- .../xrpl/src/models/transactions/common.ts | 62 +++++++++++-------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index ce0f069632..7493fae76e 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -290,6 +290,26 @@ const invalidMessagesMap: Record = { isArray: 'array', } +// eslint-disable-next-line max-params -- okay for a helper function +function getErrorMessage( + txType: string, + paramName: string, + functionName: string, + invalidMessage?: string, +): string { + let errorMessage = `${txType}: invalid field ${paramName}` + if (invalidMessage == null) { + const invalidMessageFromMap = invalidMessagesMap[functionName] + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- okay + if (invalidMessageFromMap != null) { + errorMessage += `, expected a valid ${invalidMessageFromMap}` + } + } else { + errorMessage += `, ${invalidMessage}` + } + return errorMessage +} + /* eslint-disable @typescript-eslint/restrict-template-expressions -- tx.TransactionType is checked before any calls */ /** @@ -319,19 +339,14 @@ export function validateRequiredField< } if (!checkValidity(tx[paramName])) { - let errorMessage = `${tx.TransactionType}: invalid field ${String( - paramName, - )}` - if (invalidMessage == null) { - const invalidMessageFromMap = invalidMessagesMap[checkValidity.name] - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, max-depth -- okay - if (invalidMessageFromMap != null) { - errorMessage += `, expected a valid ${invalidMessageFromMap}` - } - } else { - errorMessage += `, ${invalidMessage}` - } - throw new ValidationError(errorMessage) + throw new ValidationError( + getErrorMessage( + String(tx.TransactionType), + String(paramName), + checkValidity.name, + invalidMessage, + ), + ) } } @@ -356,19 +371,14 @@ export function validateOptionalField< invalidMessage?: string, ): asserts tx is T & { [P in K]: V | undefined } { if (tx[paramName] !== undefined && !checkValidity(tx[paramName])) { - let errorMessage = `${tx.TransactionType}: invalid field ${String( - paramName, - )}` - if (invalidMessage == null) { - const invalidMessageFromMap = invalidMessagesMap[checkValidity.name] - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, max-depth -- okay - if (invalidMessageFromMap != null) { - errorMessage += `, expected a valid ${invalidMessageFromMap}` - } - } else { - errorMessage += `, ${invalidMessage}` - } - throw new ValidationError(errorMessage) + throw new ValidationError( + getErrorMessage( + String(tx.TransactionType), + String(paramName), + checkValidity.name, + invalidMessage, + ), + ) } } From ac4359248d1bf787fc7d5b28d4f8883a36234275 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 18 Apr 2025 14:57:16 -0400 Subject: [PATCH 35/46] respond to comments --- packages/xrpl/.eslintrc.js | 1 - .../src/models/transactions/NFTokenCreateOffer.ts | 15 +++++++-------- packages/xrpl/src/models/transactions/common.ts | 8 ++++++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/xrpl/.eslintrc.js b/packages/xrpl/.eslintrc.js index ea20cd1e79..2321616dfa 100644 --- a/packages/xrpl/.eslintrc.js +++ b/packages/xrpl/.eslintrc.js @@ -107,7 +107,6 @@ module.exports = { '@typescript-eslint/no-unsafe-assignment': 'off', '@typescript-eslint/no-unsafe-call': 'off', '@typescript-eslint/consistent-type-assertions': 'off', - '@typescript-eslint/no-unsafe-return': 'off', // We need to mess with internal things to generate certain testing situations '@typescript-eslint/no-unsafe-member-access': 'off', diff --git a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts index 1879964be4..123736a319 100644 --- a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts +++ b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts @@ -145,15 +145,14 @@ export function validateNFTokenCreateOffer(tx: Record): void { validateOptionalField(tx, 'Expiration', isNumber) validateOptionalField(tx, 'Destination', isAccount) - let isSellOffer = false - // TODO: refactor some of this flag logic - if (isNumber(tx.Flags)) { - isSellOffer = isFlagEnabled(tx.Flags, NFTokenCreateOfferFlags.tfSellNFToken) - } else if (isRecord(tx.Flags)) { - isSellOffer = tx.Flags.tfSellNFToken === true - } + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- checked in BaseTransaction + const flags = (tx.Flags ?? 0) as number | NFTokenCreateOfferFlagsInterface + const isTfSellNFToken = + typeof flags === 'number' + ? isFlagEnabled(flags, NFTokenCreateOfferFlags.tfSellNFToken) + : flags.tfSellNFToken ?? false - if (isSellOffer) { + if (isTfSellNFToken) { validateNFTokenSellOfferCases(tx) } else { validateNFTokenBuyOfferCases(tx) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 7493fae76e..186bdcaff0 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -117,8 +117,11 @@ export function isHexString(str: unknown): str is string { */ export function isNumber(num: unknown): num is number { return ( - (typeof num === 'number' || !Number.isNaN(Number(num))) && - Number.isInteger(Number(num)) + (typeof num === 'number' && Number.isInteger(num)) || + (typeof num === 'string' && + num.trim() !== '' && + !Number.isNaN(Number(num)) && + Number.isInteger(Number(num))) ) } @@ -167,6 +170,7 @@ export function isCurrency(input: unknown): input is Currency { export function isXRPAmount(input: unknown): input is XRPAmount { return ( isString(input) && + input.trim() !== '' && !Number.isNaN(Number(input)) && Number.isInteger(Number(input)) ) From 3b25438e8f7134f86cc670a25ca4f14ead82b09b Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 18 Apr 2025 14:59:37 -0400 Subject: [PATCH 36/46] fix tests --- packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts index 123736a319..7aaa598df8 100644 --- a/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts +++ b/packages/xrpl/src/models/transactions/NFTokenCreateOffer.ts @@ -13,7 +13,6 @@ import { Account, validateRequiredField, isNumber, - isRecord, isHexString, } from './common' import type { TransactionMetadataBase } from './metadata' From 362bc61a2b4ce5d0926de851fd370acca8069b9a Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 8 May 2025 15:53:47 -0400 Subject: [PATCH 37/46] simplify generics --- packages/xrpl/src/sugar/autofill.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/xrpl/src/sugar/autofill.ts b/packages/xrpl/src/sugar/autofill.ts index de6ab1d501..675411d916 100644 --- a/packages/xrpl/src/sugar/autofill.ts +++ b/packages/xrpl/src/sugar/autofill.ts @@ -141,10 +141,9 @@ export function setValidAddresses(tx: Transaction): void { * @throws {ValidationError} If the tag field does not match the tag of the account address. */ function validateAccountAddress< - T extends Transaction, - K extends keyof T & string, - K2 extends keyof T & string, ->(tx: T, accountField: K, tagField: K2): void { + K extends keyof Transaction & string, + K2 extends keyof Transaction & string, +>(tx: Transaction, accountField: K, tagField: K2): void { const val = tx[accountField] if (typeof val !== 'string') { From 4bec30b4be3f4d97100056b6dd2b35d1e0b8dbb1 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 8 May 2025 15:54:35 -0400 Subject: [PATCH 38/46] more generics --- packages/xrpl/src/sugar/autofill.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/xrpl/src/sugar/autofill.ts b/packages/xrpl/src/sugar/autofill.ts index 675411d916..c5018b797a 100644 --- a/packages/xrpl/src/sugar/autofill.ts +++ b/packages/xrpl/src/sugar/autofill.ts @@ -201,7 +201,10 @@ function getClassicAccountAndTag( * @param tx - The transaction object. * @param fieldName - The name of the field to convert.export */ -function convertToClassicAddress(tx: Transaction, fieldName: string): void { +function convertToClassicAddress( + tx: Transaction, + fieldName: K, +): void { const account = tx[fieldName] if (typeof account === 'string') { const { classicAccount } = getClassicAccountAndTag(account) From ac2796b4adecf00bd7c80dc08a5b9388aa9ac8f5 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 8 May 2025 15:55:35 -0400 Subject: [PATCH 39/46] not a valid -> invalid --- packages/xrpl/src/models/transactions/accountSet.ts | 4 ++-- packages/xrpl/test/models/accountSet.test.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/xrpl/src/models/transactions/accountSet.ts b/packages/xrpl/src/models/transactions/accountSet.ts index fb71107c46..694eb18e5d 100644 --- a/packages/xrpl/src/models/transactions/accountSet.ts +++ b/packages/xrpl/src/models/transactions/accountSet.ts @@ -186,7 +186,7 @@ export function validateAccountSet(tx: Record): void { ) } if (!Object.values(AccountSetAsfFlags).includes(tx.ClearFlag)) { - throw new ValidationError('AccountSet: not a valid ClearFlag value') + throw new ValidationError('AccountSet: invalid ClearFlag value') } } @@ -201,7 +201,7 @@ export function validateAccountSet(tx: Record): void { ) } if (!Object.values(AccountSetAsfFlags).includes(tx.SetFlag)) { - throw new ValidationError('AccountSet: not a valid SetFlag value') + throw new ValidationError('AccountSet: invalid SetFlag value') } } diff --git a/packages/xrpl/test/models/accountSet.test.ts b/packages/xrpl/test/models/accountSet.test.ts index a27058213a..f2de04105c 100644 --- a/packages/xrpl/test/models/accountSet.test.ts +++ b/packages/xrpl/test/models/accountSet.test.ts @@ -32,7 +32,7 @@ describe('AccountSet', function () { it(`throws w/ invalid SetFlag (out of range)`, function () { tx.SetFlag = 20 - assertInvalid(tx, 'AccountSet: not a valid SetFlag value') + assertInvalid(tx, 'AccountSet: invalid SetFlag value') }) it(`throws w/ invalid SetFlag (incorrect type)`, function () { @@ -45,7 +45,7 @@ describe('AccountSet', function () { it(`throws w/ invalid ClearFlag`, function () { tx.ClearFlag = 20 - assertInvalid(tx, 'AccountSet: not a valid ClearFlag value') + assertInvalid(tx, 'AccountSet: invalid ClearFlag value') }) it(`throws w/ invalid Domain`, function () { From 3d03c6e3380a78ae8dac2f9acaa5b4556213a7bb Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 8 May 2025 16:24:12 -0400 Subject: [PATCH 40/46] clean up types --- packages/xrpl/src/client/index.ts | 9 +++- packages/xrpl/src/client/partialPayment.ts | 2 + .../xrpl/src/models/transactions/common.ts | 13 +++-- packages/xrpl/src/sugar/autofill.ts | 48 +++++++++++-------- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/packages/xrpl/src/client/index.ts b/packages/xrpl/src/client/index.ts index e1d3091548..82d6fd0479 100644 --- a/packages/xrpl/src/client/index.ts +++ b/packages/xrpl/src/client/index.ts @@ -689,15 +689,20 @@ class Client extends EventEmitter { promises.push(checkAccountDeleteBlockers(this, tx)) } + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- needed here + // @ts-expect-error -- This is intended to correct the type if (tx.TransactionType === 'Payment' && tx.DeliverMax != null) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- This is a valid null check for Amount if (tx.Amount == null) { // If only DeliverMax is provided, use it to populate the Amount field // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- ignore type-assertions on the DeliverMax property // @ts-expect-error -- DeliverMax property exists only at the RPC level, not at the protocol level - tx.Amount = tx.DeliverMax + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/consistent-type-assertions -- okay + tx.Amount = tx.DeliverMax as Amount | MPTAmount } + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- needed here + // @ts-expect-error -- This is intended to correct the type // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- This is a valid null check for Amount if (tx.Amount != null && tx.Amount !== tx.DeliverMax) { return Promise.reject( @@ -707,6 +712,8 @@ class Client extends EventEmitter { ) } + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- needed here + // @ts-expect-error -- This is intended to correct the type delete tx.DeliverMax } diff --git a/packages/xrpl/src/client/partialPayment.ts b/packages/xrpl/src/client/partialPayment.ts index 2d91008ef4..9c99ec3a0a 100644 --- a/packages/xrpl/src/client/partialPayment.ts +++ b/packages/xrpl/src/client/partialPayment.ts @@ -97,6 +97,8 @@ function isPartialPayment( const delivered = meta.delivered_amount + // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- needed here + // @ts-expect-error -- this line is intended to correct the type properly // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- needed here const amount = tx.DeliverMax as Amount | MPTAmount diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 186bdcaff0..78d4b6f865 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -394,7 +394,7 @@ export interface GlobalFlags {} /** * Every transaction has the same set of common fields. */ -export interface BaseTransaction extends Record { +export interface BaseTransaction { /** The unique address of the transaction sender. */ Account: Account /** @@ -477,8 +477,13 @@ export interface BaseTransaction extends Record { */ // eslint-disable-next-line max-lines-per-function, max-statements -- not worth refactoring export function validateBaseTransaction( - common: Record, + common: unknown, ): asserts common is BaseTransaction { + if (!isRecord(common)) { + throw new ValidationError( + 'BaseTransaction: invalid, expected a valid object', + ) + } validateRequiredField(common, 'TransactionType', isString) if (!TRANSACTION_TYPES.includes(common.TransactionType)) { @@ -557,7 +562,9 @@ export function parseAmountValue(amount: unknown): number { * @param tx A CredentialType Transaction. * @throws when the CredentialType is malformed. */ -export function validateCredentialType(tx: T): void { +export function validateCredentialType< + T extends BaseTransaction & Record, +>(tx: T): void { validateRequiredField(tx, 'CredentialType', isHexString) if (tx.CredentialType.length === 0) { diff --git a/packages/xrpl/src/sugar/autofill.ts b/packages/xrpl/src/sugar/autofill.ts index c5018b797a..0181934b48 100644 --- a/packages/xrpl/src/sugar/autofill.ts +++ b/packages/xrpl/src/sugar/autofill.ts @@ -4,7 +4,7 @@ import { xAddressToClassicAddress, isValidXAddress } from 'ripple-address-codec' import { type Client } from '..' import { ValidationError, XrplError } from '../errors' import { AccountInfoRequest, AccountObjectsRequest } from '../models/methods' -import { Transaction } from '../models/transactions' +import { BaseTransaction, Transaction } from '../models/transactions' import { xrpToDrops } from '../utils' import getFeeXrp from './getFeeXrp' @@ -116,10 +116,10 @@ interface ClassicAccountAndTag { * * @param tx - The transaction object. */ -export function setValidAddresses(tx: Transaction): void { +export function setValidAddresses(tx: T): void { validateAccountAddress(tx, 'Account', 'SourceTag') - // eslint-disable-next-line @typescript-eslint/dot-notation -- Destination can exist on Transaction - if (tx['Destination'] != null) { + + if ('Destination' in tx) { validateAccountAddress(tx, 'Destination', 'DestinationTag') } @@ -140,19 +140,23 @@ export function setValidAddresses(tx: Transaction): void { * @param tagField - The field name for the tag in the transaction object. * @throws {ValidationError} If the tag field does not match the tag of the account address. */ -function validateAccountAddress< - K extends keyof Transaction & string, - K2 extends keyof Transaction & string, ->(tx: Transaction, accountField: K, tagField: K2): void { - const val = tx[accountField] +function validateAccountAddress( + tx: T, + accountField: string, + tagField: string, +): void { + if (!(accountField in tx)) { + throw new ValidationError(`Missing field: ${accountField}`) + } + const val: unknown = tx[accountField] if (typeof val !== 'string') { throw new Error(`${accountField} must be a string`) } // if X-address is given, convert it to classic address const { classicAccount, tag } = getClassicAccountAndTag(val) - // eslint-disable-next-line no-param-reassign, @typescript-eslint/consistent-type-assertions -- param reassign is safe - ;(tx as Record)[accountField] = classicAccount + // eslint-disable-next-line no-param-reassign -- param reassign is safe + tx[accountField] = classicAccount if (tag != null && tag !== false) { if (tagField in tx && tx[tagField] !== tag) { @@ -160,8 +164,8 @@ function validateAccountAddress< `The ${tagField}, if present, must match the tag of the ${accountField} X-address`, ) } - // eslint-disable-next-line no-param-reassign, @typescript-eslint/consistent-type-assertions -- param reassign is safe - ;(tx as Record)[tagField] = tag + // eslint-disable-next-line no-param-reassign -- param reassign is safe + tx[tagField] = tag } } @@ -201,15 +205,17 @@ function getClassicAccountAndTag( * @param tx - The transaction object. * @param fieldName - The name of the field to convert.export */ -function convertToClassicAddress( - tx: Transaction, - fieldName: K, +function convertToClassicAddress( + tx: T, + fieldName: string, ): void { - const account = tx[fieldName] - if (typeof account === 'string') { - const { classicAccount } = getClassicAccountAndTag(account) - // eslint-disable-next-line no-param-reassign -- param reassign is safe - tx[fieldName] = classicAccount + if (fieldName in tx) { + const account: unknown = tx[fieldName] + if (fieldName in tx && typeof account === 'string') { + const { classicAccount } = getClassicAccountAndTag(account) + // eslint-disable-next-line no-param-reassign -- param reassign is safe + tx[fieldName] = classicAccount + } } } From 39b64e88c7c6f09496783ea0811d0a48723e5963 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 8 May 2025 16:27:54 -0400 Subject: [PATCH 41/46] respond to comments --- packages/xrpl/src/models/transactions/common.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 78d4b6f865..17e7600b47 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -168,12 +168,7 @@ export function isCurrency(input: unknown): input is Currency { * @returns Whether the IssuedCurrencyAmount is properly formed. */ export function isXRPAmount(input: unknown): input is XRPAmount { - return ( - isString(input) && - input.trim() !== '' && - !Number.isNaN(Number(input)) && - Number.isInteger(Number(input)) - ) + return isString(input) && isNumber(input) } /** From 4be6ff2f385040ac35a3e85dc4a41cdd1944adef Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Thu, 8 May 2025 16:28:58 -0400 Subject: [PATCH 42/46] clean up DeliverMax typing --- packages/xrpl/src/client/index.ts | 11 +---------- packages/xrpl/src/client/partialPayment.ts | 2 -- packages/xrpl/src/models/transactions/payment.ts | 9 +++++++++ 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/xrpl/src/client/index.ts b/packages/xrpl/src/client/index.ts index 82d6fd0479..4c3748fd6e 100644 --- a/packages/xrpl/src/client/index.ts +++ b/packages/xrpl/src/client/index.ts @@ -689,20 +689,13 @@ class Client extends EventEmitter { promises.push(checkAccountDeleteBlockers(this, tx)) } - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- needed here - // @ts-expect-error -- This is intended to correct the type if (tx.TransactionType === 'Payment' && tx.DeliverMax != null) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- This is a valid null check for Amount if (tx.Amount == null) { // If only DeliverMax is provided, use it to populate the Amount field - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- ignore type-assertions on the DeliverMax property - // @ts-expect-error -- DeliverMax property exists only at the RPC level, not at the protocol level - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/consistent-type-assertions -- okay - tx.Amount = tx.DeliverMax as Amount | MPTAmount + tx.Amount = tx.DeliverMax } - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- needed here - // @ts-expect-error -- This is intended to correct the type // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- This is a valid null check for Amount if (tx.Amount != null && tx.Amount !== tx.DeliverMax) { return Promise.reject( @@ -712,8 +705,6 @@ class Client extends EventEmitter { ) } - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- needed here - // @ts-expect-error -- This is intended to correct the type delete tx.DeliverMax } diff --git a/packages/xrpl/src/client/partialPayment.ts b/packages/xrpl/src/client/partialPayment.ts index 9c99ec3a0a..2d91008ef4 100644 --- a/packages/xrpl/src/client/partialPayment.ts +++ b/packages/xrpl/src/client/partialPayment.ts @@ -97,8 +97,6 @@ function isPartialPayment( const delivered = meta.delivered_amount - // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- needed here - // @ts-expect-error -- this line is intended to correct the type properly // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- needed here const amount = tx.DeliverMax as Amount | MPTAmount diff --git a/packages/xrpl/src/models/transactions/payment.ts b/packages/xrpl/src/models/transactions/payment.ts index d0853f3670..9acec38dfc 100644 --- a/packages/xrpl/src/models/transactions/payment.ts +++ b/packages/xrpl/src/models/transactions/payment.ts @@ -120,6 +120,9 @@ export interface Payment extends BaseTransaction { * to this amount instead. */ Amount: Amount | MPTAmount + + DeliverMax?: Amount | MPTAmount + /** The unique address of the account receiving the payment. */ Destination: Account /** @@ -191,6 +194,12 @@ export function validatePayment(tx: Record): void { ) checkPartialPayment(tx) + + if (tx.DeliverMax != null) { + throw new ValidationError( + 'Payment: DeliverMax is not allowed when submitting a transaction', + ) + } } function checkPartialPayment(tx: Record): void { From 0d54755db3dc3c809f0d84b5423718a3774a0de7 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 4 Jul 2025 01:24:26 +0530 Subject: [PATCH 43/46] fix tests --- packages/xrpl/jest.config.unit.js | 1 + .../xrpl/src/models/transactions/AMMBid.ts | 28 ++++++---- .../src/models/transactions/AMMClawback.ts | 3 +- .../src/models/transactions/AMMDeposit.ts | 4 +- .../src/models/transactions/AMMWithdraw.ts | 3 +- .../xrpl/src/models/transactions/batch.ts | 2 +- .../xrpl/src/models/transactions/clawback.ts | 3 +- .../xrpl/src/models/transactions/common.ts | 52 ++++++++++++++----- .../src/models/transactions/delegateSet.ts | 43 +++++++-------- .../xrpl/src/models/transactions/oracleSet.ts | 14 +++-- .../src/models/transactions/signerListSet.ts | 3 +- packages/xrpl/test/models/AMMBid.test.ts | 9 ++-- packages/xrpl/test/models/AMMClawback.test.ts | 4 +- packages/xrpl/test/models/AMMDeposit.test.ts | 2 +- packages/xrpl/test/models/AMMWithdraw.test.ts | 2 +- .../models/XChainAddClaimAttestation.test.ts | 2 +- packages/xrpl/test/models/XChainClaim.test.ts | 2 +- .../xrpl/test/models/XChainCommit.test.ts | 2 +- packages/xrpl/test/models/accountSet.test.ts | 4 +- .../xrpl/test/models/baseTransaction.test.ts | 21 +++----- packages/xrpl/test/models/batch.test.ts | 20 +++++-- packages/xrpl/test/models/delegateSet.test.ts | 17 +++--- packages/xrpl/test/models/oracleSet.test.ts | 17 +++--- packages/xrpl/test/models/payment.test.ts | 5 +- .../xrpl/test/models/signerListSet.test.ts | 2 +- packages/xrpl/test/models/trustSet.test.ts | 2 +- packages/xrpl/test/testUtils.ts | 15 +++--- packages/xrpl/test/wallet/index.test.ts | 6 +-- 28 files changed, 164 insertions(+), 124 deletions(-) diff --git a/packages/xrpl/jest.config.unit.js b/packages/xrpl/jest.config.unit.js index 8346bc46b6..94f0fed220 100644 --- a/packages/xrpl/jest.config.unit.js +++ b/packages/xrpl/jest.config.unit.js @@ -7,6 +7,7 @@ module.exports = { testMatch: ['/test/**/*.test.ts'], testPathIgnorePatterns: [ '/test/integration', + '/test/faucet', '/test/fixtures', ], displayName: 'xrpl.js', diff --git a/packages/xrpl/src/models/transactions/AMMBid.ts b/packages/xrpl/src/models/transactions/AMMBid.ts index 7b3161e510..4f6aef283a 100644 --- a/packages/xrpl/src/models/transactions/AMMBid.ts +++ b/packages/xrpl/src/models/transactions/AMMBid.ts @@ -2,7 +2,9 @@ import { ValidationError } from '../../errors' import { AuthAccount, Currency, IssuedCurrencyAmount } from '../common' import { + Account, BaseTransaction, + isAccount, isAmount, isArray, isCurrency, @@ -86,28 +88,32 @@ export function validateAMMBid(tx: Record): void { } function validateAuthAccounts( - senderAddress: string, + senderAddress: Account, authAccounts: unknown[], ): boolean { - for (const authAccount of authAccounts) { + authAccounts.forEach((authAccount, index) => { if (!isRecord(authAccount)) { - throw new ValidationError(`AMMBid: invalid AuthAccounts`) + throw new ValidationError( + `AMMBid: invalid field AuthAccounts[0], expected a valid Record`, + ) } + const paramName = `AuthAccounts[${index}].AuthAccount` if (!isRecord(authAccount.AuthAccount)) { - throw new ValidationError(`AMMBid: invalid AuthAccounts`) - } - if (authAccount.AuthAccount.Account == null) { - throw new ValidationError(`AMMBid: invalid field AuthAccounts`) - } - if (typeof authAccount.AuthAccount.Account !== 'string') { - throw new ValidationError(`AMMBid: invalid field AuthAccounts`) + throw new ValidationError( + `AMMBid: invalid field ${paramName}, expected a valid Record`, + ) } + const authAccountInner = authAccount.AuthAccount + validateRequiredField(authAccountInner, 'Account', isAccount, { + paramName, + txType: 'AMMBid', + }) if (authAccount.AuthAccount.Account === senderAddress) { throw new ValidationError( `AMMBid: AuthAccounts must not include sender's address`, ) } - } + }) return true } diff --git a/packages/xrpl/src/models/transactions/AMMClawback.ts b/packages/xrpl/src/models/transactions/AMMClawback.ts index 4afc6ecb4b..5995af3546 100644 --- a/packages/xrpl/src/models/transactions/AMMClawback.ts +++ b/packages/xrpl/src/models/transactions/AMMClawback.ts @@ -6,6 +6,7 @@ import { BaseTransaction, GlobalFlagsInterface, isAccount, + isCurrency, isIssuedCurrency, isIssuedCurrencyAmount, validateBaseTransaction, @@ -97,7 +98,7 @@ export function validateAMMClawback(tx: Record): void { ) } - validateRequiredField(tx, 'Asset2', isIssuedCurrency) + validateRequiredField(tx, 'Asset2', isCurrency) validateOptionalField(tx, 'Amount', isIssuedCurrencyAmount) diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts index 8f5df967ca..d45f98299e 100644 --- a/packages/xrpl/src/models/transactions/AMMDeposit.ts +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -6,7 +6,7 @@ import { GlobalFlagsInterface, isAmount, isCurrency, - isIssuedCurrency, + isIssuedCurrencyAmount, validateBaseTransaction, validateOptionalField, validateRequiredField, @@ -89,7 +89,7 @@ export function validateAMMDeposit(tx: Record): void { validateRequiredField(tx, 'Asset', isCurrency) validateRequiredField(tx, 'Asset2', isCurrency) - validateOptionalField(tx, 'LPTokenOut', isIssuedCurrency) + validateOptionalField(tx, 'LPTokenOut', isIssuedCurrencyAmount) validateOptionalField(tx, 'Amount', isAmount) validateOptionalField(tx, 'Amount2', isAmount) validateOptionalField(tx, 'EPrice', isAmount) diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts index 4aefa04eda..c3c360dd9e 100644 --- a/packages/xrpl/src/models/transactions/AMMWithdraw.ts +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -6,7 +6,6 @@ import { GlobalFlagsInterface, isAmount, isCurrency, - isIssuedCurrency, isIssuedCurrencyAmount, validateBaseTransaction, validateOptionalField, @@ -90,7 +89,7 @@ export function validateAMMWithdraw(tx: Record): void { validateRequiredField(tx, 'Asset2', isCurrency) validateOptionalField(tx, 'Amount', isAmount) validateOptionalField(tx, 'Amount2', isAmount) - validateOptionalField(tx, 'LPTokenIn', isIssuedCurrency) + validateOptionalField(tx, 'LPTokenIn', isIssuedCurrencyAmount) validateOptionalField(tx, 'EPrice', isAmount) if (tx.Amount2 != null && tx.Amount == null) { diff --git a/packages/xrpl/src/models/transactions/batch.ts b/packages/xrpl/src/models/transactions/batch.ts index 7498022f33..fb959ebfb9 100644 --- a/packages/xrpl/src/models/transactions/batch.ts +++ b/packages/xrpl/src/models/transactions/batch.ts @@ -92,7 +92,7 @@ export function validateBatch(tx: Record): void { tx.RawTransactions.forEach((rawTxObj, index) => { if (!isRecord(rawTxObj)) { throw new ValidationError( - `Batch: RawTransactions[${index}] is not object.`, + `Batch: invalid field RawTransactions[${index}], expected a valid Record`, ) } validateRequiredField(rawTxObj, 'RawTransaction', isRecord, { diff --git a/packages/xrpl/src/models/transactions/clawback.ts b/packages/xrpl/src/models/transactions/clawback.ts index 1961a4220d..f4936e33d1 100644 --- a/packages/xrpl/src/models/transactions/clawback.ts +++ b/packages/xrpl/src/models/transactions/clawback.ts @@ -9,7 +9,6 @@ import { isAccount, validateOptionalField, validateRequiredField, - isIssuedCurrency, } from './common' /** @@ -49,7 +48,7 @@ export function validateClawback(tx: Record): void { tx, 'Amount', (inp): inp is IssuedCurrencyAmount | MPTAmount => - isIssuedCurrency(inp) || isMPTAmount(inp), + isIssuedCurrencyAmount(inp) || isMPTAmount(inp), { invalidMessage: 'expected a valid non-XRP Amount' }, ) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 48c95263d5..6abdd262e9 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -103,6 +103,21 @@ export function isString(str: unknown): str is string { return typeof str === 'string' } +const NON_STANDARD_CURRENCY_LENGTH = 40 + +/** + * Verify the form and type of a Currency string (STCurrency) at runtime. + * + * @param inp - The object to check the form and type of. + * @returns Whether the Currency string is properly formed. + */ +export function isCurrencyString(inp: unknown): inp is string { + return ( + (isString(inp) && /^[A-Z]{3}$/u.test(inp)) || + (isHexString(inp) && inp.length === NON_STANDARD_CURRENCY_LENGTH) + ) +} + /** * Verify the form and type of a hex string at runtime. * @@ -149,6 +164,14 @@ export function isNumberWithBounds( return isNumberWithBoundsInternal } +function isXRPCurrency(input: unknown): input is Currency { + return ( + isRecord(input) && + Object.keys(input).length === XRP_CURRENCY_SIZE && + input.currency === 'XRP' + ) +} + /** * Verify the form and type of a Currency at runtime. * @@ -156,7 +179,7 @@ export function isNumberWithBounds( * @returns Whether the Currency is properly formed. */ export function isCurrency(input: unknown): input is Currency { - return isString(input) || isIssuedCurrency(input) + return isXRPCurrency(input) || isIssuedCurrency(input) } /** @@ -168,11 +191,9 @@ export function isCurrency(input: unknown): input is Currency { export function isIssuedCurrency(input: unknown): input is IssuedCurrency { return ( isRecord(input) && - ((Object.keys(input).length === ISSUE_SIZE && - isString(input.issuer) && - isString(input.currency)) || - (Object.keys(input).length === XRP_CURRENCY_SIZE && - input.currency === 'XRP')) + Object.keys(input).length === ISSUE_SIZE && + isString(input.issuer) && + isString(input.currency) ) } @@ -279,10 +300,10 @@ export function isXChainBridge(input: unknown): input is XChainBridge { return ( isRecord(input) && Object.keys(input).length === XCHAIN_BRIDGE_SIZE && - typeof input.LockingChainDoor === 'string' && - isIssuedCurrency(input.LockingChainIssue) && - typeof input.IssuingChainDoor === 'string' && - isIssuedCurrency(input.IssuingChainIssue) + isString(input.LockingChainDoor) && + isCurrency(input.LockingChainIssue) && + isString(input.IssuingChainDoor) && + isCurrency(input.IssuingChainIssue) ) } @@ -291,8 +312,8 @@ const invalidMessagesMap: Record = { isAmount: 'Amount', isCurrency: 'Currency', isXRPAmount: 'XRP Amount', - isIssuedCurrency: 'IssuedCurrencyAmount object', - isMPTAmount: 'MPTAmount object', + isIssuedCurrency: 'Issued Currency', + isMPTAmount: 'MPT Amount', isXChainBridge: 'XChainBridge object', isMemo: 'Memo', isSigner: 'Signer', @@ -302,6 +323,8 @@ const invalidMessagesMap: Record = { isNumber: 'number', isNumberWithBoundsInternal: 'number', isArray: 'array', + isIssuedCurrencyAmount: 'IOU Amount', + isCurrencyString: 'currency string', } // eslint-disable-next-line max-params -- okay for a helper function @@ -314,6 +337,7 @@ function getErrorMessage( let errorMessage = `${txType}: invalid field ${paramName}` if (invalidMessage == null) { const invalidMessageFromMap = invalidMessagesMap[functionName] + // console.log(txType, paramName, functionName, invalidMessageFromMap) // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- okay if (invalidMessageFromMap != null) { errorMessage += `, expected a valid ${invalidMessageFromMap}` @@ -543,7 +567,7 @@ export function validateBaseTransaction( const memos = common.Memos if (memos != null && (!isArray(memos) || !memos.every(isMemo))) { - throw new ValidationError('BaseTransaction: invalid Memos') + throw new ValidationError('BaseTransaction: invalid field Memos') } const signers = common.Signers @@ -552,7 +576,7 @@ export function validateBaseTransaction( signers != null && (!isArray(signers) || signers.length === 0 || !signers.every(isSigner)) ) { - throw new ValidationError('BaseTransaction: invalid Signers') + throw new ValidationError('BaseTransaction: invalid field Signers') } validateOptionalField(common, 'SourceTag', isNumber) diff --git a/packages/xrpl/src/models/transactions/delegateSet.ts b/packages/xrpl/src/models/transactions/delegateSet.ts index df9700bb6f..5b30168158 100644 --- a/packages/xrpl/src/models/transactions/delegateSet.ts +++ b/packages/xrpl/src/models/transactions/delegateSet.ts @@ -6,6 +6,9 @@ import { validateRequiredField, isAccount, Account, + isArray, + isRecord, + isString, } from './common' const PERMISSIONS_MAX_LENGTH = 10 @@ -53,7 +56,6 @@ export interface DelegateSet extends BaseTransaction { * @param tx - An DelegateSet Transaction. * @throws When the DelegateSet is malformed. */ -// eslint-disable-next-line max-lines-per-function -- necessary for validation export function validateDelegateSet(tx: Record): void { validateBaseTransaction(tx) @@ -65,46 +67,37 @@ export function validateDelegateSet(tx: Record): void { ) } - validateRequiredField(tx, 'Permissions', Array.isArray) - - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- required for validation - const permissions = tx.Permissions as DelegateSet['Permissions'] - if (permissions.length > PERMISSIONS_MAX_LENGTH) { + validateRequiredField(tx, 'Permissions', isArray) + if (tx.Permissions.length > PERMISSIONS_MAX_LENGTH) { throw new ValidationError( `DelegateSet: Permissions array length cannot be greater than ${PERMISSIONS_MAX_LENGTH}.`, ) } const permissionValueSet = new Set() - permissions.forEach((permission: Permission) => { - if ( - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- required for validation - permission == null || - Object.keys(permission).length !== 1 || - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- required for validation - permission.Permission == null || - Object.keys(permission.Permission).length !== 1 - ) { + tx.Permissions.forEach((permission, index) => { + if (!isRecord(permission) || !isRecord(permission.Permission)) { throw new ValidationError( 'DelegateSet: Permissions array element is malformed', ) } - const permissionValue = permission.Permission.PermissionValue - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- required for validation - if (permissionValue == null) { - throw new ValidationError('DelegateSet: PermissionValue must be defined') - } - if (typeof permissionValue !== 'string') { - throw new ValidationError('DelegateSet: PermissionValue must be a string') - } + const permissionInner = permission.Permission + + validateRequiredField(permissionInner, 'PermissionValue', isString, { + paramName: `Permission[${index}].PermissionValue`, + txType: 'DelegateSet', + }) + + const permissionValue = permissionInner.PermissionValue + if (NON_DELEGATABLE_TRANSACTIONS.has(permissionValue)) { throw new ValidationError( - `DelegateSet: PermissionValue contains a non-delegatable transaction ${permissionValue}`, + `DelegateSet: PermissionValue contains non-delegable transaction ${permissionValue}`, ) } permissionValueSet.add(permissionValue) }) - if (permissions.length !== permissionValueSet.size) { + if (tx.Permissions.length !== permissionValueSet.size) { throw new ValidationError( 'DelegateSet: Permissions array cannot contain duplicate values', ) diff --git a/packages/xrpl/src/models/transactions/oracleSet.ts b/packages/xrpl/src/models/transactions/oracleSet.ts index 643a7b7818..853ddc6483 100644 --- a/packages/xrpl/src/models/transactions/oracleSet.ts +++ b/packages/xrpl/src/models/transactions/oracleSet.ts @@ -1,11 +1,10 @@ import { ValidationError } from '../../errors' import { PriceData } from '../common' -import { isHex } from '../utils' import { BaseTransaction, isArray, - isCurrency, + isCurrencyString, isHexString, isNumber, isNumberWithBounds, @@ -107,11 +106,16 @@ export function validateOracleSet(tx: Record): void { // TODO: add support for handling inner objects easier (similar to validateRequiredField/validateOptionalField) value.forEach((priceData, index) => { - if (!isRecord(priceData) || !isRecord(priceData.PriceData)) { + if (!isRecord(priceData)) { throw new ValidationError( 'OracleSet: PriceDataSeries must be an array of objects', ) } + if (!isRecord(priceData.PriceData)) { + throw new ValidationError( + 'OracleSet: PriceDataSeries must have a `PriceData` object', + ) + } // check if priceData only has PriceData if (Object.keys(priceData).length !== 1) { @@ -122,12 +126,12 @@ export function validateOracleSet(tx: Record): void { const priceDataInner = priceData.PriceData - validateRequiredField(priceDataInner, 'BaseAsset', isCurrency, { + validateRequiredField(priceDataInner, 'BaseAsset', isCurrencyString, { paramName: `PriceDataSeries[${index}].BaseAsset`, txType: 'OracleSet', }) - validateRequiredField(priceDataInner, 'QuoteAsset', isCurrency, { + validateRequiredField(priceDataInner, 'QuoteAsset', isCurrencyString, { paramName: `PriceDataSeries[${index}].QuoteAsset`, txType: 'OracleSet', }) diff --git a/packages/xrpl/src/models/transactions/signerListSet.ts b/packages/xrpl/src/models/transactions/signerListSet.ts index 5dc85f6926..4831b69399 100644 --- a/packages/xrpl/src/models/transactions/signerListSet.ts +++ b/packages/xrpl/src/models/transactions/signerListSet.ts @@ -8,6 +8,7 @@ import { isNumber, isRecord, validateBaseTransaction, + validateOptionalField, validateRequiredField, } from './common' @@ -73,7 +74,7 @@ export function validateSignerListSet(tx: Record): void { ) } const signerEntry = entry.SignerEntry - validateRequiredField(signerEntry, 'WalletLocator', isHexString, { + validateOptionalField(signerEntry, 'WalletLocator', isHexString, { paramName: `SignerEntries[${index}].WalletLocator`, txType: 'SignerListSet', }) diff --git a/packages/xrpl/test/models/AMMBid.test.ts b/packages/xrpl/test/models/AMMBid.test.ts index 5f5370844b..4d224c1dac 100644 --- a/packages/xrpl/test/models/AMMBid.test.ts +++ b/packages/xrpl/test/models/AMMBid.test.ts @@ -124,7 +124,7 @@ describe('AMMBid', function () { AuthAccount: null, } const errorMessage = - 'AMMBid: invalid field AuthAccounts, expected objects in array' + 'AMMBid: invalid field AuthAccounts[0].AuthAccount, expected a valid Record' assertInvalid(bid, errorMessage) }) @@ -133,7 +133,7 @@ describe('AMMBid', function () { AuthAccount: undefined, } const errorMessage = - 'AMMBid: invalid field AuthAccounts, expected objects in array' + 'AMMBid: invalid field AuthAccounts[0].AuthAccount, expected a valid Record' assertInvalid(bid, errorMessage) }) @@ -142,7 +142,7 @@ describe('AMMBid', function () { AuthAccount: 1234, } const errorMessage = - 'AMMBid: invalid field AuthAccounts, expected objects in array' + 'AMMBid: invalid field AuthAccounts[0].AuthAccount, expected a valid Record' assertInvalid(bid, errorMessage) }) @@ -152,7 +152,8 @@ describe('AMMBid', function () { Account: 1234, }, } - const errorMessage = 'AMMBid: invalid field AuthAccounts' + const errorMessage = + 'AMMBid: invalid field AuthAccounts[0].AuthAccount, expected a valid account address' assertInvalid(bid, errorMessage) }) diff --git a/packages/xrpl/test/models/AMMClawback.test.ts b/packages/xrpl/test/models/AMMClawback.test.ts index 9e38594685..fd69d7caee 100644 --- a/packages/xrpl/test/models/AMMClawback.test.ts +++ b/packages/xrpl/test/models/AMMClawback.test.ts @@ -79,7 +79,7 @@ describe('AMMClawback', function () { it(`throws w/ invalid field Asset`, function () { ammClawback.Asset = '1000' const errorMessage = - 'AMMClawback: invalid field Asset, expected a valid Currency' + 'AMMClawback: invalid field Asset, expected a valid Issued Currency' assertInvalid(ammClawback, errorMessage) }) @@ -105,7 +105,7 @@ describe('AMMClawback', function () { it(`throws w/ invalid field Amount`, function () { ammClawback.Amount = 1000 const errorMessage = - 'AMMClawback: invalid field Amount, expected a valid Amount' + 'AMMClawback: invalid field Amount, expected a valid IOU Amount' assertInvalid(ammClawback, errorMessage) }) diff --git a/packages/xrpl/test/models/AMMDeposit.test.ts b/packages/xrpl/test/models/AMMDeposit.test.ts index 9dade37786..24fb20b273 100644 --- a/packages/xrpl/test/models/AMMDeposit.test.ts +++ b/packages/xrpl/test/models/AMMDeposit.test.ts @@ -124,7 +124,7 @@ describe('AMMDeposit', function () { it(`throws w/ LPTokenOut must be an IssuedCurrencyAmount`, function () { deposit.LPTokenOut = 1234 const errorMessage = - 'AMMDeposit: invalid field LPTokenOut, expected a valid IssuedCurrencyAmount object' + 'AMMDeposit: invalid field LPTokenOut, expected a valid IOU Amount' assertInvalid(deposit, errorMessage) }) diff --git a/packages/xrpl/test/models/AMMWithdraw.test.ts b/packages/xrpl/test/models/AMMWithdraw.test.ts index 83b572e0e7..ab4bf28650 100644 --- a/packages/xrpl/test/models/AMMWithdraw.test.ts +++ b/packages/xrpl/test/models/AMMWithdraw.test.ts @@ -130,7 +130,7 @@ describe('AMMWithdraw', function () { it(`throws when LPTokenIn is not an IssuedCurrencyAmount`, function () { withdraw.LPTokenIn = 1234 const errorMessage = - 'AMMWithdraw: invalid field LPTokenIn, expected a valid IssuedCurrencyAmount object' + 'AMMWithdraw: invalid field LPTokenIn, expected a valid IOU Amount' assertInvalid(withdraw, errorMessage) }) diff --git a/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts b/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts index 838113b93e..9cf8f0f144 100644 --- a/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts +++ b/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts @@ -201,7 +201,7 @@ describe('XChainAddClaimAttestation', function () { assertInvalid( tx, - 'XChainAddClaimAttestation: invalid field XChainClaimID, expected a number or hex string', + 'XChainAddClaimAttestation: invalid field XChainClaimID, expected a valid number or hex string', ) }) }) diff --git a/packages/xrpl/test/models/XChainClaim.test.ts b/packages/xrpl/test/models/XChainClaim.test.ts index 9480779dca..218353992c 100644 --- a/packages/xrpl/test/models/XChainClaim.test.ts +++ b/packages/xrpl/test/models/XChainClaim.test.ts @@ -66,7 +66,7 @@ describe('XChainClaim', function () { assertInvalid( tx, - 'XChainClaim: invalid field XChainClaimID, expected a number or hex string', + 'XChainClaim: invalid field XChainClaimID, expected a valid number or hex string', ) }) diff --git a/packages/xrpl/test/models/XChainCommit.test.ts b/packages/xrpl/test/models/XChainCommit.test.ts index 66a793bb16..7b6e287a86 100644 --- a/packages/xrpl/test/models/XChainCommit.test.ts +++ b/packages/xrpl/test/models/XChainCommit.test.ts @@ -65,7 +65,7 @@ describe('XChainCommit', function () { assertInvalid( tx, - 'XChainCommit: invalid field XChainClaimID, expected a number or hex string', + 'XChainCommit: invalid field XChainClaimID, expected a valid number or hex string', ) }) diff --git a/packages/xrpl/test/models/accountSet.test.ts b/packages/xrpl/test/models/accountSet.test.ts index a546cef089..f2de04105c 100644 --- a/packages/xrpl/test/models/accountSet.test.ts +++ b/packages/xrpl/test/models/accountSet.test.ts @@ -32,7 +32,7 @@ describe('AccountSet', function () { it(`throws w/ invalid SetFlag (out of range)`, function () { tx.SetFlag = 20 - assertInvalid(tx, 'AccountSet: invalid SetFlag') + assertInvalid(tx, 'AccountSet: invalid SetFlag value') }) it(`throws w/ invalid SetFlag (incorrect type)`, function () { @@ -45,7 +45,7 @@ describe('AccountSet', function () { it(`throws w/ invalid ClearFlag`, function () { tx.ClearFlag = 20 - assertInvalid(tx, 'AccountSet: invalid ClearFlag') + assertInvalid(tx, 'AccountSet: invalid ClearFlag value') }) it(`throws w/ invalid Domain`, function () { diff --git a/packages/xrpl/test/models/baseTransaction.test.ts b/packages/xrpl/test/models/baseTransaction.test.ts index 6e32a58c1e..2c2111d3a1 100644 --- a/packages/xrpl/test/models/baseTransaction.test.ts +++ b/packages/xrpl/test/models/baseTransaction.test.ts @@ -211,10 +211,7 @@ describe('BaseTransaction', function () { Signers: [], } as any - assertInvalid( - invalidSigners, - 'BaseTransaction: invalid field Signers, expected an array of valid Signer objects', - ) + assertInvalid(invalidSigners, 'BaseTransaction: invalid field Signers') const invalidSigners2 = { Account: 'r97KeayHuEsDwyU1yPBVtMLLoQr79QcRFe', @@ -228,10 +225,7 @@ describe('BaseTransaction', function () { ], } as any - assertInvalid( - invalidSigners2, - 'BaseTransaction: invalid field Signers, expected an array of valid Signer objects', - ) + assertInvalid(invalidSigners2, 'BaseTransaction: invalid field Signers') }) it(`Handles invalid Memo`, function () { @@ -248,10 +242,7 @@ describe('BaseTransaction', function () { ], } as any - assertInvalid( - invalidMemo, - 'BaseTransaction: invalid field Memos, expected an array of valid Memo objects', - ) + assertInvalid(invalidMemo, 'BaseTransaction: invalid field Memos') }) it(`Handles invalid NetworkID`, function () { @@ -263,6 +254,7 @@ describe('BaseTransaction', function () { assertInvalid( invalidNetworkID, 'Payment: invalid field NetworkID, expected a valid number', + ) }) it(`Handles invalid Delegate`, function () { @@ -271,7 +263,10 @@ describe('BaseTransaction', function () { TransactionType: 'Payment', Delegate: 1234, } - assertInvalid(invalidDelegate, 'Payment: invalid field Delegate, expected a valid account address') + assertInvalid( + invalidDelegate, + 'Payment: invalid field Delegate, expected a valid account address', + ) }) it(`Handles Account and Delegate being the same error`, function () { diff --git a/packages/xrpl/test/models/batch.test.ts b/packages/xrpl/test/models/batch.test.ts index 4ce2d8e2d0..5be46bc135 100644 --- a/packages/xrpl/test/models/batch.test.ts +++ b/packages/xrpl/test/models/batch.test.ts @@ -103,7 +103,10 @@ describe('Batch', function () { it('throws w/ invalid BatchSigners', function () { tx.BatchSigners = 0 - assertInvalid(tx, 'Batch: invalid field BatchSigners') + assertInvalid( + tx, + 'Batch: invalid field BatchSigners, expected a valid array', + ) }) it('throws w/ missing RawTransactions', function () { @@ -113,17 +116,26 @@ describe('Batch', function () { it('throws w/ invalid RawTransactions', function () { tx.RawTransactions = 0 - assertInvalid(tx, 'Batch: invalid field RawTransactions') + assertInvalid( + tx, + 'Batch: invalid field RawTransactions, expected a valid array', + ) }) it('throws w/ invalid RawTransactions object', function () { tx.RawTransactions = [0] - assertInvalid(tx, 'Batch: RawTransactions[0] is not object') + assertInvalid( + tx, + 'Batch: invalid field RawTransactions[0], expected a valid Record', + ) }) it('throws w/ invalid RawTransactions.RawTransaction object', function () { tx.RawTransactions = [{ RawTransaction: 0 }] - assertInvalid(tx, 'Batch: invalid field RawTransactions[0].RawTransaction') + assertInvalid( + tx, + 'Batch: invalid field RawTransactions[0].RawTransaction, expected a valid Record', + ) }) it('throws w/ nested Batch', function () { diff --git a/packages/xrpl/test/models/delegateSet.test.ts b/packages/xrpl/test/models/delegateSet.test.ts index 5b9cbb3dff..1349156dec 100644 --- a/packages/xrpl/test/models/delegateSet.test.ts +++ b/packages/xrpl/test/models/delegateSet.test.ts @@ -49,7 +49,8 @@ describe('DelegateSet', function () { it(`throws w/ invalid field Permissions`, function () { tx.Permissions = 'TrustlineAuthorize' - const errorMessage = 'DelegateSet: invalid field Permissions' + const errorMessage = + 'DelegateSet: invalid field Permissions, expected a valid array' assertInvalid(tx, errorMessage) }) @@ -80,27 +81,29 @@ describe('DelegateSet', function () { it(`throws w/ PermissionValue must be defined`, function () { tx.Permissions = [{ Permission: { PermissionValue: null } }] - const errorMessage = 'DelegateSet: PermissionValue must be defined' + const errorMessage = + 'DelegateSet: missing field Permission[0].PermissionValue' assertInvalid(tx, errorMessage) }) it(`throws w/ PermissionValue must be a string`, function () { tx.Permissions = [{ Permission: { PermissionValue: 123 } }] - const errorMessage = 'DelegateSet: PermissionValue must be a string' + const errorMessage = + 'DelegateSet: invalid field Permission[0].PermissionValue, expected a valid string' assertInvalid(tx, errorMessage) }) - it(`throws w/ PermissionValue contains a non-delegatable transaction`, function () { + it(`throws w/ PermissionValue contains a non-delegable transaction`, function () { tx.Permissions = [{ Permission: { PermissionValue: 'AccountSet' } }] const errorMessage = - 'DelegateSet: PermissionValue contains a non-delegatable transaction AccountSet' + 'DelegateSet: PermissionValue contains non-delegable transaction AccountSet' assertInvalid(tx, errorMessage) }) - it(`throws w/ PermissionValue contains a non-delegatable pseudo transaction`, function () { + it(`throws w/ PermissionValue contains a non-delegable pseudo transaction`, function () { tx.Permissions = [{ Permission: { PermissionValue: 'EnableAmendment' } }] const errorMessage = - 'DelegateSet: PermissionValue contains a non-delegatable transaction EnableAmendment' + 'DelegateSet: PermissionValue contains non-delegable transaction EnableAmendment' assertInvalid(tx, errorMessage) }) diff --git a/packages/xrpl/test/models/oracleSet.test.ts b/packages/xrpl/test/models/oracleSet.test.ts index bca1ecacb3..1e7d8f2963 100644 --- a/packages/xrpl/test/models/oracleSet.test.ts +++ b/packages/xrpl/test/models/oracleSet.test.ts @@ -131,15 +131,14 @@ describe('OracleSet', function () { it(`throws w/ missing BaseAsset of PriceDataSeries`, function () { delete tx.PriceDataSeries[0].PriceData.BaseAsset - const errorMessage = - 'OracleSet: PriceDataSeries must have a `BaseAsset` string' + const errorMessage = 'OracleSet: missing field PriceDataSeries[0].BaseAsset' assertInvalid(tx, errorMessage) }) it(`throws w/ missing QuoteAsset of PriceDataSeries`, function () { delete tx.PriceDataSeries[0].PriceData.QuoteAsset const errorMessage = - 'OracleSet: PriceDataSeries must have a `QuoteAsset` string' + 'OracleSet: missing field PriceDataSeries[0].QuoteAsset' assertInvalid(tx, errorMessage) }) @@ -161,7 +160,7 @@ describe('OracleSet', function () { // value cannot be parsed as hexadecimal number tx.PriceDataSeries[0].PriceData.AssetPrice = 'ghij' const errorMessage = - 'OracleSet: Field AssetPrice must be a valid hex string' + 'OracleSet: invalid field PriceDataSeries[0].AssetPrice' assertInvalid(tx, errorMessage) }) @@ -174,26 +173,28 @@ describe('OracleSet', function () { it(`throws w/ invalid AssetPrice type in PriceDataSeries`, function () { tx.PriceDataSeries[0].PriceData.AssetPrice = ['sample', 'invalid', 'type'] const errorMessage = - 'OracleSet: Field AssetPrice must be a string or a number' + 'OracleSet: invalid field PriceDataSeries[0].AssetPrice' assertInvalid(tx, errorMessage) }) it(`throws w/ invalid Scale of PriceDataSeries`, function () { tx.PriceDataSeries[0].PriceData.Scale = 'abcd' const errorMessage = - 'OracleSet: invalid field Scale, expected a valid number' + 'OracleSet: invalid field PriceDataSeries[0].Scale, expected a valid number' assertInvalid(tx, errorMessage) }) it(`throws w/ Scale must be in range 0-10 when above max`, function () { tx.PriceDataSeries[0].PriceData.Scale = 11 - const errorMessage = 'OracleSet: Scale must be in range 0-10' + const errorMessage = + 'OracleSet: invalid field PriceDataSeries[0].Scale, expected a valid number' assertInvalid(tx, errorMessage) }) it(`throws w/ Scale must be in range 0-10 when below min`, function () { tx.PriceDataSeries[0].PriceData.Scale = -1 - const errorMessage = 'OracleSet: Scale must be in range 0-10' + const errorMessage = + 'OracleSet: invalid field PriceDataSeries[0].Scale, expected a valid number' assertInvalid(tx, errorMessage) }) }) diff --git a/packages/xrpl/test/models/payment.test.ts b/packages/xrpl/test/models/payment.test.ts index 063cb96ab7..672c3e885b 100644 --- a/packages/xrpl/test/models/payment.test.ts +++ b/packages/xrpl/test/models/payment.test.ts @@ -66,10 +66,7 @@ describe('Payment', function () { }, ] - assertInvalid( - payment, - 'BaseTransaction: invalid field Memos, expected an array of valid Memo objects', - ) + assertInvalid(payment, 'BaseTransaction: invalid field Memos') }) it(`throws when Amount is missing`, function () { diff --git a/packages/xrpl/test/models/signerListSet.test.ts b/packages/xrpl/test/models/signerListSet.test.ts index 01dfb2e95f..a641424382 100644 --- a/packages/xrpl/test/models/signerListSet.test.ts +++ b/packages/xrpl/test/models/signerListSet.test.ts @@ -172,7 +172,7 @@ describe('SignerListSet', function () { }, ] const errorMessage = - 'SignerListSet: WalletLocator in SignerEntry must be a 256-bit (32-byte) hexadecimal value' + 'SignerListSet: invalid field SignerEntries[0].WalletLocator, expected a valid hex string' assertInvalid(signerListSetTx, errorMessage) }) }) diff --git a/packages/xrpl/test/models/trustSet.test.ts b/packages/xrpl/test/models/trustSet.test.ts index 2c7800f82d..0ab01c3ceb 100644 --- a/packages/xrpl/test/models/trustSet.test.ts +++ b/packages/xrpl/test/models/trustSet.test.ts @@ -45,7 +45,7 @@ describe('TrustSet', function () { trustSet.LimitAmount = 1234 assertInvalid( trustSet, - 'TrustSet: invalid field LimitAmount, expected a valid IssuedCurrencyAmount object', + 'TrustSet: invalid field LimitAmount, expected a valid IOU Amount', ) }) diff --git a/packages/xrpl/test/testUtils.ts b/packages/xrpl/test/testUtils.ts index 081c6fd1f4..f8019a88e0 100644 --- a/packages/xrpl/test/testUtils.ts +++ b/packages/xrpl/test/testUtils.ts @@ -78,13 +78,16 @@ export function assertTxIsValid(tx: any, validateTx: (tx: any) => void): void { export function assertTxValidationError( tx: any, validateTx: (tx: any) => void, - errorMessage: string, + errorMessage: string | RegExp, ): void { - const regex = new RegExp( - // eslint-disable-next-line require-unicode-regexp -- TS complains if it's included - `^${errorMessage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, - 'u', - ) + const regex = + typeof errorMessage === 'string' + ? new RegExp( + // eslint-disable-next-line require-unicode-regexp -- TS complains if it's included + `^${errorMessage.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, + 'u', + ) + : errorMessage assert.throws(() => validateTx(tx), ValidationError, regex) assert.throws(() => validate(tx), ValidationError, regex) } diff --git a/packages/xrpl/test/wallet/index.test.ts b/packages/xrpl/test/wallet/index.test.ts index 05bec5e6e5..73bb75990c 100644 --- a/packages/xrpl/test/wallet/index.test.ts +++ b/packages/xrpl/test/wallet/index.test.ts @@ -513,7 +513,7 @@ describe('Wallet', function () { } assert.throws(() => { Wallet.fromSeed(secret).sign(lowercaseMemoTx) - }, /BaseTransaction: invalid Memos/u) + }, /BaseTransaction: invalid field Memos/u) }) it('sign throws when MemoData is not a hex value', async function () { @@ -539,7 +539,7 @@ describe('Wallet', function () { } assert.throws(() => { Wallet.fromSeed(secret).sign(lowercaseMemoTx) - }, /BaseTransaction: invalid Memos/u) + }, /BaseTransaction: invalid field Memos/u) }) it('sign throws when MemoFormat is not a hex value', async function () { @@ -565,7 +565,7 @@ describe('Wallet', function () { } assert.throws(() => { Wallet.fromSeed(secret).sign(lowercaseMemoTx) - }, /BaseTransaction: invalid Memos/u) + }, /BaseTransaction: invalid field Memos/u) }) it('sign with EscrowFinish', async function () { From bee3328e4452e58b3bc992a9db0bb9c1fcb0897b Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 4 Jul 2025 01:25:16 +0530 Subject: [PATCH 44/46] fix history --- packages/xrpl/HISTORY.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/xrpl/HISTORY.md b/packages/xrpl/HISTORY.md index a74b6209e8..57ab269a46 100644 --- a/packages/xrpl/HISTORY.md +++ b/packages/xrpl/HISTORY.md @@ -35,9 +35,6 @@ Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xr * Support for the `simulate` RPC ([XLS-69](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0069-simulate)) * Support for XLS-77d Deep-Freeze amendment -### Fixed -* Better error handling for model validation - ### Changed * Deprecated `setTransactionFlagsToNumber`. Start using convertTxFlagsToNumber instead From 00595342d0b3ef3615ac7971445a3b4ecea7e5bf Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Fri, 4 Jul 2025 01:55:17 +0530 Subject: [PATCH 45/46] more cleanup --- packages/xrpl/src/models/transactions/common.ts | 2 +- packages/xrpl/test/models/accountDelete.test.ts | 2 +- packages/xrpl/test/models/depositPreauth.test.ts | 4 ++-- packages/xrpl/test/models/escrowFinish.test.ts | 2 +- packages/xrpl/test/models/payment.test.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 6abdd262e9..4f5002debf 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -655,7 +655,7 @@ export function validateCredentialsList( } if (!isArray(credentials)) { throw new ValidationError( - `${transactionType}: invalid field Credentials, expected a valid array`, + `${transactionType}: invalid field CredentialIDs, expected a valid array`, ) } if (credentials.length > maxCredentials) { diff --git a/packages/xrpl/test/models/accountDelete.test.ts b/packages/xrpl/test/models/accountDelete.test.ts index 29a8533b3a..2cd9e5a41f 100644 --- a/packages/xrpl/test/models/accountDelete.test.ts +++ b/packages/xrpl/test/models/accountDelete.test.ts @@ -57,7 +57,7 @@ describe('AccountDelete', function () { 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66A' const errorMessage = - 'AccountDelete: invalid field Credentials, expected a valid array' + 'AccountDelete: invalid field CredentialIDs, expected a valid array' assertInvalid(validAccountDelete, errorMessage) }) diff --git a/packages/xrpl/test/models/depositPreauth.test.ts b/packages/xrpl/test/models/depositPreauth.test.ts index 7b3bbdbecc..99c8067290 100644 --- a/packages/xrpl/test/models/depositPreauth.test.ts +++ b/packages/xrpl/test/models/depositPreauth.test.ts @@ -112,7 +112,7 @@ describe('DepositPreauth', function () { it('throws when AuthorizeCredentials is not an array', function () { const errorMessage = - 'DepositPreauth: invalid field Credentials, expected a valid array' + 'DepositPreauth: invalid field CredentialIDs, expected a valid array' depositPreauth.AuthorizeCredentials = validCredential assertInvalid(depositPreauth, errorMessage) @@ -120,7 +120,7 @@ describe('DepositPreauth', function () { it('throws when UnauthorizeCredentials is not an array', function () { const errorMessage = - 'DepositPreauth: invalid field Credentials, expected a valid array' + 'DepositPreauth: invalid field CredentialIDs, expected a valid array' depositPreauth.UnauthorizeCredentials = validCredential assertInvalid(depositPreauth, errorMessage) diff --git a/packages/xrpl/test/models/escrowFinish.test.ts b/packages/xrpl/test/models/escrowFinish.test.ts index e088cee101..c35f3d282c 100644 --- a/packages/xrpl/test/models/escrowFinish.test.ts +++ b/packages/xrpl/test/models/escrowFinish.test.ts @@ -86,7 +86,7 @@ describe('EscrowFinish', function () { 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66A' const errorMessage = - 'EscrowFinish: invalid field Credentials, expected a valid array' + 'EscrowFinish: invalid field CredentialIDs, expected a valid array' assertInvalid(escrow, errorMessage) }) diff --git a/packages/xrpl/test/models/payment.test.ts b/packages/xrpl/test/models/payment.test.ts index 672c3e885b..63dae12b75 100644 --- a/packages/xrpl/test/models/payment.test.ts +++ b/packages/xrpl/test/models/payment.test.ts @@ -195,7 +195,7 @@ describe('Payment', function () { 'EA85602C1B41F6F1F5E83C0E6B87142FB8957BD209469E4CC347BA2D0C26F66A' const errorMessage = - 'Payment: invalid field Credentials, expected a valid array' + 'Payment: invalid field CredentialIDs, expected a valid array' assertInvalid(payment, errorMessage) }) From 33a98b50e561f6cd7ce81decaf9ba9841cf27b83 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Tue, 8 Jul 2025 21:07:12 +0530 Subject: [PATCH 46/46] fix tests --- .../xrpl/src/models/transactions/clawback.ts | 4 +-- .../xrpl/src/models/transactions/common.ts | 2 ++ .../src/models/transactions/vaultClawback.ts | 4 +-- .../src/models/transactions/vaultCreate.ts | 19 +++-------- .../src/models/transactions/vaultDelete.ts | 4 +-- .../src/models/transactions/vaultDeposit.ts | 4 +-- .../xrpl/src/models/transactions/vaultSet.ts | 12 +++---- .../src/models/transactions/vaultWithdraw.ts | 4 +-- .../xrpl/test/models/vaultClawback.test.ts | 23 +++++++------ packages/xrpl/test/models/vaultCreate.test.ts | 26 +++++++++------ packages/xrpl/test/models/vaultDelete.test.ts | 10 +++--- .../xrpl/test/models/vaultDeposit.test.ts | 17 +++++----- packages/xrpl/test/models/vaultSet.test.ts | 32 ++++++++++++------- .../xrpl/test/models/vaultWithdraw.test.ts | 28 ++++++++-------- 14 files changed, 98 insertions(+), 91 deletions(-) diff --git a/packages/xrpl/src/models/transactions/clawback.ts b/packages/xrpl/src/models/transactions/clawback.ts index 90efb846c9..428feded46 100644 --- a/packages/xrpl/src/models/transactions/clawback.ts +++ b/packages/xrpl/src/models/transactions/clawback.ts @@ -46,9 +46,7 @@ export function validateClawback(tx: Record): void { validateBaseTransaction(tx) validateRequiredField(tx, 'Amount', isClawbackAmount) validateOptionalField(tx, 'Holder', isAccount) - validateRequiredField(tx, 'Amount', isClawbackAmount, { - invalidMessage: 'expected a valid non-XRP Amount', - }) + validateRequiredField(tx, 'Amount', isClawbackAmount) if (isIssuedCurrencyAmount(tx.Amount)) { if (tx.Account === tx.Amount.issuer) { diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index c35c6d8e16..95c06a476c 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -358,6 +358,7 @@ export function isXChainBridge(input: unknown): input is XChainBridge { const invalidMessagesMap: Record = { isAccount: 'account address', isAmount: 'Amount', + isClawbackAmount: 'non-XRP Amount', isCurrency: 'Currency', isXRPAmount: 'XRP Amount', isIssuedCurrency: 'Issued Currency', @@ -373,6 +374,7 @@ const invalidMessagesMap: Record = { isArray: 'array', isIssuedCurrencyAmount: 'IOU Amount', isCurrencyString: 'currency string', + isXRPLNumber: 'XRPLNumber', } // eslint-disable-next-line max-params -- okay for a helper function diff --git a/packages/xrpl/src/models/transactions/vaultClawback.ts b/packages/xrpl/src/models/transactions/vaultClawback.ts index 44e2991afe..babf703c36 100644 --- a/packages/xrpl/src/models/transactions/vaultClawback.ts +++ b/packages/xrpl/src/models/transactions/vaultClawback.ts @@ -4,7 +4,7 @@ import { BaseTransaction, validateBaseTransaction, validateRequiredField, - isString, + isHexString, Account, isAccount, validateOptionalField, @@ -49,7 +49,7 @@ export interface VaultClawback extends BaseTransaction { export function validateVaultClawback(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'VaultID', isString) + validateRequiredField(tx, 'VaultID', isHexString) validateRequiredField(tx, 'Holder', isAccount) validateOptionalField(tx, 'Amount', isClawbackAmount) } diff --git a/packages/xrpl/src/models/transactions/vaultCreate.ts b/packages/xrpl/src/models/transactions/vaultCreate.ts index 4c45f868d0..ce7019db3b 100644 --- a/packages/xrpl/src/models/transactions/vaultCreate.ts +++ b/packages/xrpl/src/models/transactions/vaultCreate.ts @@ -1,6 +1,6 @@ import { ValidationError } from '../../errors' import { Currency } from '../common' -import { hasFlag, isHex } from '../utils' +import { hasFlag } from '../utils' import { BaseTransaction, @@ -10,10 +10,10 @@ import { isNumber, isCurrency, validateRequiredField, - isString, VAULT_DATA_MAX_BYTE_LENGTH, XRPLNumber, isXRPLNumber, + isHexString, } from './common' const META_MAX_BYTE_LENGTH = 1024 @@ -91,22 +91,18 @@ export interface VaultCreate extends BaseTransaction { * @param tx - A {@link VaultCreate} Transaction. * @throws When the {@link VaultCreate} is malformed. */ -// eslint-disable-next-line max-lines-per-function -- required to do all field validations export function validateVaultCreate(tx: Record): void { validateBaseTransaction(tx) validateRequiredField(tx, 'Asset', isCurrency) - validateOptionalField(tx, 'Data', isString) + validateOptionalField(tx, 'Data', isHexString) validateOptionalField(tx, 'AssetsMaximum', isXRPLNumber) - validateOptionalField(tx, 'MPTokenMetadata', isString) + validateOptionalField(tx, 'MPTokenMetadata', isHexString) validateOptionalField(tx, 'WithdrawalPolicy', isNumber) - validateOptionalField(tx, 'DomainID', isString) + validateOptionalField(tx, 'DomainID', isHexString) if (tx.Data !== undefined) { const dataHex = tx.Data - if (!isHex(dataHex)) { - throw new ValidationError('VaultCreate: Data must be a valid hex string') - } const dataByteLength = dataHex.length / 2 if (dataByteLength > VAULT_DATA_MAX_BYTE_LENGTH) { throw new ValidationError( @@ -117,11 +113,6 @@ export function validateVaultCreate(tx: Record): void { if (tx.MPTokenMetadata !== undefined) { const metaHex = tx.MPTokenMetadata - if (!isHex(metaHex)) { - throw new ValidationError( - 'VaultCreate: MPTokenMetadata must be a valid hex string', - ) - } const metaByteLength = metaHex.length / 2 if (metaByteLength > META_MAX_BYTE_LENGTH) { throw new ValidationError( diff --git a/packages/xrpl/src/models/transactions/vaultDelete.ts b/packages/xrpl/src/models/transactions/vaultDelete.ts index 78aa9ed474..303853c866 100644 --- a/packages/xrpl/src/models/transactions/vaultDelete.ts +++ b/packages/xrpl/src/models/transactions/vaultDelete.ts @@ -2,7 +2,7 @@ import { BaseTransaction, validateBaseTransaction, validateRequiredField, - isString, + isHexString, } from './common' /** @@ -28,5 +28,5 @@ export interface VaultDelete extends BaseTransaction { export function validateVaultDelete(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'VaultID', isString) + validateRequiredField(tx, 'VaultID', isHexString) } diff --git a/packages/xrpl/src/models/transactions/vaultDeposit.ts b/packages/xrpl/src/models/transactions/vaultDeposit.ts index 4becb47946..6951cc0f41 100644 --- a/packages/xrpl/src/models/transactions/vaultDeposit.ts +++ b/packages/xrpl/src/models/transactions/vaultDeposit.ts @@ -4,7 +4,7 @@ import { BaseTransaction, validateBaseTransaction, validateRequiredField, - isString, + isHexString, isAmount, } from './common' @@ -36,6 +36,6 @@ export interface VaultDeposit extends BaseTransaction { export function validateVaultDeposit(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'VaultID', isString) + validateRequiredField(tx, 'VaultID', isHexString) validateRequiredField(tx, 'Amount', isAmount) } diff --git a/packages/xrpl/src/models/transactions/vaultSet.ts b/packages/xrpl/src/models/transactions/vaultSet.ts index 9bd2ca971f..a47b502439 100644 --- a/packages/xrpl/src/models/transactions/vaultSet.ts +++ b/packages/xrpl/src/models/transactions/vaultSet.ts @@ -1,15 +1,14 @@ import { ValidationError } from '../../errors' -import { isHex } from '../utils' import { BaseTransaction, validateBaseTransaction, validateOptionalField, validateRequiredField, - isString, VAULT_DATA_MAX_BYTE_LENGTH, XRPLNumber, isXRPLNumber, + isHexString, } from './common' /** @@ -51,16 +50,13 @@ export interface VaultSet extends BaseTransaction { export function validateVaultSet(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'VaultID', isString) - validateOptionalField(tx, 'Data', isString) + validateRequiredField(tx, 'VaultID', isHexString) + validateOptionalField(tx, 'Data', isHexString) validateOptionalField(tx, 'AssetsMaximum', isXRPLNumber) - validateOptionalField(tx, 'DomainID', isString) + validateOptionalField(tx, 'DomainID', isHexString) if (tx.Data !== undefined) { const dataHex = tx.Data - if (!isHex(dataHex)) { - throw new ValidationError('VaultSet: Data must be a valid hex string') - } const dataByteLength = dataHex.length / 2 if (dataByteLength > VAULT_DATA_MAX_BYTE_LENGTH) { throw new ValidationError( diff --git a/packages/xrpl/src/models/transactions/vaultWithdraw.ts b/packages/xrpl/src/models/transactions/vaultWithdraw.ts index ed44b5f591..708251e7ff 100644 --- a/packages/xrpl/src/models/transactions/vaultWithdraw.ts +++ b/packages/xrpl/src/models/transactions/vaultWithdraw.ts @@ -4,7 +4,7 @@ import { BaseTransaction, validateBaseTransaction, validateRequiredField, - isString, + isHexString, isAmount, Account, validateOptionalField, @@ -44,7 +44,7 @@ export interface VaultWithdraw extends BaseTransaction { export function validateVaultWithdraw(tx: Record): void { validateBaseTransaction(tx) - validateRequiredField(tx, 'VaultID', isString) + validateRequiredField(tx, 'VaultID', isHexString) validateRequiredField(tx, 'Amount', isAmount) validateOptionalField(tx, 'Destination', isAccount) } diff --git a/packages/xrpl/test/models/vaultClawback.test.ts b/packages/xrpl/test/models/vaultClawback.test.ts index 2b63bfdfa2..b11df68a8d 100644 --- a/packages/xrpl/test/models/vaultClawback.test.ts +++ b/packages/xrpl/test/models/vaultClawback.test.ts @@ -1,4 +1,3 @@ -import { VaultClawback } from '../../src/models/transactions' import { validateVaultClawback } from '../../src/models/transactions/vaultClawback' import { assertTxIsValid, assertTxValidationError } from '../testUtils' @@ -13,7 +12,7 @@ const assertInvalid = (tx: any, message: string): void => * Provides runtime verification testing for VaultClawback transaction type. */ describe('VaultClawback', function () { - let tx: VaultClawback + let tx: any beforeEach(function () { tx = { @@ -34,32 +33,36 @@ describe('VaultClawback', function () { }) it('throws w/ missing VaultID', function () { - // @ts-expect-error for test tx.VaultID = undefined assertInvalid(tx, 'VaultClawback: missing field VaultID') }) it('throws w/ invalid VaultID', function () { - // @ts-expect-error for test tx.VaultID = 123 - assertInvalid(tx, 'VaultClawback: invalid field VaultID') + assertInvalid( + tx, + 'VaultClawback: invalid field VaultID, expected a valid hex string', + ) }) it('throws w/ missing Holder', function () { - // @ts-expect-error for test tx.Holder = undefined assertInvalid(tx, 'VaultClawback: missing field Holder') }) it('throws w/ invalid Holder', function () { - // @ts-expect-error for test tx.Holder = 123 - assertInvalid(tx, 'VaultClawback: invalid field Holder') + assertInvalid( + tx, + 'VaultClawback: invalid field Holder, expected a valid account address', + ) }) it('throws w/ string Amount', function () { - // @ts-expect-error for test tx.Amount = '123456' - assertInvalid(tx, 'VaultClawback: invalid field Amount') + assertInvalid( + tx, + 'VaultClawback: invalid field Amount, expected a valid non-XRP Amount', + ) }) }) diff --git a/packages/xrpl/test/models/vaultCreate.test.ts b/packages/xrpl/test/models/vaultCreate.test.ts index 5dc291b819..b65b603fb0 100644 --- a/packages/xrpl/test/models/vaultCreate.test.ts +++ b/packages/xrpl/test/models/vaultCreate.test.ts @@ -1,7 +1,6 @@ import { stringToHex } from '@xrplf/isomorphic/utils' import { - VaultCreate, VaultCreateFlags, VaultWithdrawalPolicy, } from '../../src/models/transactions' @@ -18,7 +17,7 @@ const assertInvalid = (tx: any, message: string): void => * Providing runtime verification testing for each specific transaction type. */ describe('VaultCreate', function () { - let tx: VaultCreate + let tx: any beforeEach(function () { tx = { @@ -34,20 +33,24 @@ describe('VaultCreate', function () { }) it('throws w/ missing Asset', function () { - // @ts-expect-error for test tx.Asset = undefined assertInvalid(tx, 'VaultCreate: missing field Asset') }) it('throws w/ invalid Asset', function () { - // @ts-expect-error for test tx.Asset = 123 - assertInvalid(tx, 'VaultCreate: invalid field Asset') + assertInvalid( + tx, + 'VaultCreate: invalid field Asset, expected a valid Currency', + ) }) it('throws w/ Data field not hex', function () { tx.Data = 'zznothex' - assertInvalid(tx, 'VaultCreate: Data must be a valid hex string') + assertInvalid( + tx, + 'VaultCreate: invalid field Data, expected a valid hex string', + ) }) it('throws w/ Data field too large', function () { @@ -57,7 +60,10 @@ describe('VaultCreate', function () { it('throws w/ MPTokenMetadata not hex', function () { tx.MPTokenMetadata = 'ggnothex' - assertInvalid(tx, 'VaultCreate: MPTokenMetadata must be a valid hex string') + assertInvalid( + tx, + 'VaultCreate: invalid field MPTokenMetadata, expected a valid hex string', + ) }) it('throws w/ MPTokenMetadata field too large', function () { @@ -69,9 +75,11 @@ describe('VaultCreate', function () { }) it('throws w/ non-number WithdrawalPolicy', function () { - // @ts-expect-error for test tx.WithdrawalPolicy = 'invalid' - assertInvalid(tx, 'VaultCreate: invalid field WithdrawalPolicy') + assertInvalid( + tx, + 'VaultCreate: invalid field WithdrawalPolicy, expected a valid number', + ) }) it('allows DomainID when tfVaultPrivate flag set', function () { diff --git a/packages/xrpl/test/models/vaultDelete.test.ts b/packages/xrpl/test/models/vaultDelete.test.ts index da3c7f77d1..d9c251f40c 100644 --- a/packages/xrpl/test/models/vaultDelete.test.ts +++ b/packages/xrpl/test/models/vaultDelete.test.ts @@ -1,4 +1,3 @@ -import { VaultDelete } from '../../src/models/transactions' import { validateVaultDelete } from '../../src/models/transactions/vaultDelete' import { assertTxIsValid, assertTxValidationError } from '../testUtils' @@ -12,7 +11,7 @@ const assertInvalid = (tx: any, message: string): void => * Provides runtime verification testing for VaultDelete transaction type. */ describe('VaultDelete', function () { - let tx: VaultDelete + let tx: any beforeEach(function () { tx = { @@ -27,14 +26,15 @@ describe('VaultDelete', function () { }) it('throws w/ missing VaultID', function () { - // @ts-expect-error for test tx.VaultID = undefined assertInvalid(tx, 'VaultDelete: missing field VaultID') }) it('throws w/ invalid VaultID', function () { - // @ts-expect-error for test tx.VaultID = 123 - assertInvalid(tx, 'VaultDelete: invalid field VaultID') + assertInvalid( + tx, + 'VaultDelete: invalid field VaultID, expected a valid hex string', + ) }) }) diff --git a/packages/xrpl/test/models/vaultDeposit.test.ts b/packages/xrpl/test/models/vaultDeposit.test.ts index 4ebe5b97ee..ba7ee8f48f 100644 --- a/packages/xrpl/test/models/vaultDeposit.test.ts +++ b/packages/xrpl/test/models/vaultDeposit.test.ts @@ -1,4 +1,3 @@ -import { VaultDeposit } from '../../src/models/transactions' import { validateVaultDeposit } from '../../src/models/transactions/vaultDeposit' import { assertTxIsValid, assertTxValidationError } from '../testUtils' @@ -12,7 +11,7 @@ const assertInvalid = (tx: any, message: string): void => * Provides runtime verification testing for VaultDeposit transaction type. */ describe('VaultDeposit', function () { - let tx: VaultDeposit + let tx: any beforeEach(function () { tx = { @@ -28,26 +27,28 @@ describe('VaultDeposit', function () { }) it('throws w/ missing VaultID', function () { - // @ts-expect-error for test tx.VaultID = undefined assertInvalid(tx, 'VaultDeposit: missing field VaultID') }) it('throws w/ invalid VaultID', function () { - // @ts-expect-error for test tx.VaultID = 123 - assertInvalid(tx, 'VaultDeposit: invalid field VaultID') + assertInvalid( + tx, + 'VaultDeposit: invalid field VaultID, expected a valid hex string', + ) }) it('throws w/ missing Amount', function () { - // @ts-expect-error for test tx.Amount = undefined assertInvalid(tx, 'VaultDeposit: missing field Amount') }) it('throws w/ non-string Amount', function () { - // @ts-expect-error for test tx.Amount = 123 - assertInvalid(tx, 'VaultDeposit: invalid field Amount') + assertInvalid( + tx, + 'VaultDeposit: invalid field Amount, expected a valid Amount', + ) }) }) diff --git a/packages/xrpl/test/models/vaultSet.test.ts b/packages/xrpl/test/models/vaultSet.test.ts index 3261ec8d74..b450f1260f 100644 --- a/packages/xrpl/test/models/vaultSet.test.ts +++ b/packages/xrpl/test/models/vaultSet.test.ts @@ -1,6 +1,5 @@ import { stringToHex } from '@xrplf/isomorphic/utils' -import { VaultSet } from '../../src' import { validateVaultSet } from '../../src/models/transactions/vaultSet' import { assertTxIsValid, assertTxValidationError } from '../testUtils' @@ -14,7 +13,7 @@ const assertInvalid = (tx: any, message: string): void => * Providing runtime verification testing for the VaultSet transaction type. */ describe('VaultSet', function () { - let tx: VaultSet + let tx: any beforeEach(function () { tx = { @@ -29,20 +28,24 @@ describe('VaultSet', function () { }) it('throws w/ missing VaultID', function () { - // @ts-expect-error for test tx.VaultID = undefined assertInvalid(tx, 'VaultSet: missing field VaultID') }) it('throws w/ non-string VaultID', function () { - // @ts-expect-error for test tx.VaultID = 123456 - assertInvalid(tx, 'VaultSet: invalid field VaultID') + assertInvalid( + tx, + 'VaultSet: invalid field VaultID, expected a valid hex string', + ) }) it('throws w/ Data field not hex', function () { tx.Data = 'zznothex' - assertInvalid(tx, 'VaultSet: Data must be a valid hex string') + assertInvalid( + tx, + 'VaultSet: invalid field Data, expected a valid hex string', + ) }) it('throws w/ Data field too large', function () { @@ -52,18 +55,25 @@ describe('VaultSet', function () { it('throws w/ non-XRPLNumber AssetsMaximum', function () { tx.AssetsMaximum = 'notanumber' - assertInvalid(tx, 'VaultSet: invalid field AssetsMaximum') + assertInvalid( + tx, + 'VaultSet: invalid field AssetsMaximum, expected a valid XRPLNumber', + ) }) it('throws w/ non-string Data', function () { - // @ts-expect-error for test tx.Data = 1234 - assertInvalid(tx, 'VaultSet: invalid field Data') + assertInvalid( + tx, + 'VaultSet: invalid field Data, expected a valid hex string', + ) }) it('throws w/ non-string DomainID', function () { - // @ts-expect-error for test tx.DomainID = 1234 - assertInvalid(tx, 'VaultSet: invalid field DomainID') + assertInvalid( + tx, + 'VaultSet: invalid field DomainID, expected a valid hex string', + ) }) }) diff --git a/packages/xrpl/test/models/vaultWithdraw.test.ts b/packages/xrpl/test/models/vaultWithdraw.test.ts index 81341b199c..32f41b7052 100644 --- a/packages/xrpl/test/models/vaultWithdraw.test.ts +++ b/packages/xrpl/test/models/vaultWithdraw.test.ts @@ -1,7 +1,3 @@ -import { assert } from 'chai' - -import { validate } from '../../src' -import { VaultWithdraw } from '../../src/models/transactions' import { validateVaultWithdraw } from '../../src/models/transactions/vaultWithdraw' import { assertTxIsValid, assertTxValidationError } from '../testUtils' @@ -16,7 +12,7 @@ const assertInvalid = (tx: any, message: string): void => * Provides runtime verification testing for VaultWithdraw transaction type. */ describe('VaultWithdraw', function () { - let tx: VaultWithdraw + let tx: any beforeEach(function () { tx = { @@ -32,39 +28,41 @@ describe('VaultWithdraw', function () { }) it('throws w/ missing VaultID', function () { - // @ts-expect-error for test tx.VaultID = undefined assertInvalid(tx, 'VaultWithdraw: missing field VaultID') }) it('throws w/ invalid VaultID', function () { - // @ts-expect-error for test tx.VaultID = 123 - assertInvalid(tx, 'VaultWithdraw: invalid field VaultID') + assertInvalid( + tx, + 'VaultWithdraw: invalid field VaultID, expected a valid hex string', + ) }) it('throws w/ missing Amount', function () { - // @ts-expect-error for test tx.Amount = undefined assertInvalid(tx, 'VaultWithdraw: missing field Amount') }) it('throws w/ non-string Amount', function () { - // @ts-expect-error for test tx.Amount = 123 - assertInvalid(tx, 'VaultWithdraw: invalid field Amount') + assertInvalid( + tx, + 'VaultWithdraw: invalid field Amount, expected a valid Amount', + ) }) it('verifies valid VaultWithdraw with Destination', function () { tx.Destination = 'rfmDuhDyLGgx94qiwf3YF8BUV5j6KSvE8' - assert.doesNotThrow(() => validateVaultWithdraw(tx)) - assert.doesNotThrow(() => validate(tx)) assertValid(tx) }) it('throws w/ invalid Destination', function () { - // @ts-expect-error for test tx.Destination = 123 - assertInvalid(tx, 'VaultWithdraw: invalid field Destination') + assertInvalid( + tx, + 'VaultWithdraw: invalid field Destination, expected a valid account address', + ) }) })