Skip to content

Commit 7079ba4

Browse files
committed
feat: enhance parseTransactionFlags with string overload and includeAll option (#1903)
- Add overload accepting (txType: string, flags: number) for parsing numeric flags directly from raw API responses without constructing a full Transaction object - Add optional { includeAll: true } parameter to include all possible flags for a transaction type with their boolean values (not just enabled flags) - Improve return type from object to Record<string, boolean> - Add missing EnableAmendment and LoanSet to txToFlag mapping - Add comprehensive tests for all new functionality
1 parent 5cf0921 commit 7079ba4

2 files changed

Lines changed: 136 additions & 16 deletions

File tree

packages/xrpl/src/models/utils/flags.ts

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import { AMMDepositFlags } from '../transactions/AMMDeposit'
1010
import { AMMWithdrawFlags } from '../transactions/AMMWithdraw'
1111
import { BatchFlags } from '../transactions/batch'
1212
import { GlobalFlags } from '../transactions/common'
13+
import { EnableAmendmentFlags } from '../transactions/enableAmendment'
1314
import { LoanManageFlags } from '../transactions/loanManage'
1415
import { LoanPayFlags } from '../transactions/loanPay'
16+
import { LoanSetFlags } from '../transactions/loanSet'
1517
import { MPTokenAuthorizeFlags } from '../transactions/MPTokenAuthorize'
1618
import { MPTokenIssuanceCreateFlags } from '../transactions/MPTokenIssuanceCreate'
1719
import { MPTokenIssuanceSetFlags } from '../transactions/MPTokenIssuanceSet'
@@ -57,8 +59,10 @@ const txToFlag = {
5759
AMMDeposit: AMMDepositFlags,
5860
AMMWithdraw: AMMWithdrawFlags,
5961
Batch: BatchFlags,
62+
EnableAmendment: EnableAmendmentFlags,
6063
LoanManage: LoanManageFlags,
6164
LoanPay: LoanPayFlags,
65+
LoanSet: LoanSetFlags,
6266
MPTokenAuthorize: MPTokenAuthorizeFlags,
6367
MPTokenIssuanceCreate: MPTokenIssuanceCreateFlags,
6468
MPTokenIssuanceSet: MPTokenIssuanceSetFlags,
@@ -141,32 +145,72 @@ export function convertTxFlagsToNumber(tx: Transaction): number {
141145
/**
142146
* Convert a Transaction flags property into a map for easy interpretation.
143147
*
144-
* @param tx - A transaction to parse flags for.
145-
* @returns A map with all flags as booleans.
148+
* Can be called with a Transaction object or with a transaction type string
149+
* and numeric flags value directly (useful when working with raw API responses).
150+
*
151+
* By default, only enabled (true) flags are included in the result.
152+
* Pass `includeAll: true` in options to include all possible flags for the
153+
* transaction type with their boolean values.
154+
*
155+
* @example
156+
* ```typescript
157+
* // With a Transaction object (existing behavior)
158+
* parseTransactionFlags(tx)
159+
* // => { tfSell: true }
160+
*
161+
* // With transaction type and numeric flags
162+
* parseTransactionFlags('OfferCreate', 0x00080000)
163+
* // => { tfSell: true }
164+
*
165+
* // Include all possible flags for the transaction type
166+
* parseTransactionFlags('Payment', 0x00020000, { includeAll: true })
167+
* // => { tfNoRippleDirect: false, tfPartialPayment: true, tfLimitQuality: false }
168+
* ```
169+
*
170+
* @param txOrType - A transaction to parse flags for, or a transaction type string.
171+
* @param flagsNum - The numeric flags value (required when txOrType is a string).
172+
* @param options - Optional settings.
173+
* @param options.includeAll - Set to `true` to include disabled flags.
174+
* @returns A map of flag names to booleans.
146175
*/
147-
export function parseTransactionFlags(tx: Transaction): object {
148-
const flags = convertTxFlagsToNumber(tx)
149-
if (flags === 0) {
150-
return {}
176+
export function parseTransactionFlags(
177+
txOrType: Transaction | string,
178+
flagsNum?: number,
179+
options?: { includeAll?: boolean },
180+
): Record<string, boolean> {
181+
let flags: number
182+
let transactionType: string
183+
184+
if (typeof txOrType === 'string') {
185+
transactionType = txOrType
186+
flags = flagsNum ?? 0
187+
} else {
188+
transactionType = txOrType.TransactionType
189+
flags = convertTxFlagsToNumber(txOrType)
151190
}
152191

153-
const booleanFlagMap = {}
192+
const includeAll = options?.includeAll ?? false
154193

155-
if (isTxToFlagKey(tx.TransactionType)) {
156-
const transactionTypeFlags = txToFlag[tx.TransactionType]
194+
const booleanFlagMap: Record<string, boolean> = {}
195+
196+
if (isTxToFlagKey(transactionType)) {
197+
const transactionTypeFlags = txToFlag[transactionType]
157198
Object.values(transactionTypeFlags).forEach((flag) => {
158-
if (
159-
typeof flag === 'string' &&
160-
isFlagEnabled(flags, transactionTypeFlags[flag])
161-
) {
162-
booleanFlagMap[flag] = true
199+
if (typeof flag === 'string') {
200+
const enabled = isFlagEnabled(flags, transactionTypeFlags[flag])
201+
if (enabled || includeAll) {
202+
booleanFlagMap[flag] = enabled
203+
}
163204
}
164205
})
165206
}
166207

167208
Object.values(GlobalFlags).forEach((flag) => {
168-
if (typeof flag === 'string' && isFlagEnabled(flags, GlobalFlags[flag])) {
169-
booleanFlagMap[flag] = true
209+
if (typeof flag === 'string') {
210+
const enabled = isFlagEnabled(flags, GlobalFlags[flag])
211+
if (enabled || includeAll) {
212+
booleanFlagMap[flag] = enabled
213+
}
170214
}
171215
})
172216

packages/xrpl/test/models/utils.test.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,82 @@ describe('Models Utils', function () {
393393
const flagsMap = parseTransactionFlags(tx)
394394
assert.deepEqual(flagsMap, expected)
395395
})
396+
397+
it('parseTransactionFlags with transaction type string and numeric flags', function () {
398+
const flagsMap = parseTransactionFlags(
399+
'PaymentChannelClaim',
400+
PaymentChannelClaimFlags.tfRenew,
401+
)
402+
assert.deepEqual(flagsMap, { tfRenew: true })
403+
})
404+
405+
it('parseTransactionFlags with type string and combined numeric flags', function () {
406+
const flagsMap = parseTransactionFlags(
407+
'OfferCreate',
408+
OfferCreateFlags.tfSell | OfferCreateFlags.tfImmediateOrCancel,
409+
)
410+
assert.deepEqual(flagsMap, {
411+
tfSell: true,
412+
tfImmediateOrCancel: true,
413+
})
414+
})
415+
416+
it('parseTransactionFlags with type string and zero flags', function () {
417+
const flagsMap = parseTransactionFlags('Payment', 0)
418+
assert.deepEqual(flagsMap, {})
419+
})
420+
421+
it('parseTransactionFlags with type string, numeric flags, and includeAll', function () {
422+
const flagsMap = parseTransactionFlags(
423+
'Payment',
424+
PaymentFlags.tfPartialPayment,
425+
{ includeAll: true },
426+
)
427+
assert.deepEqual(flagsMap, {
428+
tfNoRippleDirect: false,
429+
tfPartialPayment: true,
430+
tfLimitQuality: false,
431+
tfInnerBatchTxn: false,
432+
})
433+
})
434+
435+
it('parseTransactionFlags with Transaction object and includeAll', function () {
436+
const tx: PaymentChannelClaim = {
437+
Account: 'r...',
438+
TransactionType: 'PaymentChannelClaim',
439+
Channel:
440+
'C1AE6DDDEEC05CF2978C0BAD6FE302948E9533691DC749DCDD3B9E5992CA6198',
441+
Flags: PaymentChannelClaimFlags.tfRenew,
442+
}
443+
444+
const flagsMap = parseTransactionFlags(tx, undefined, {
445+
includeAll: true,
446+
})
447+
assert.deepEqual(flagsMap, {
448+
tfRenew: true,
449+
tfClose: false,
450+
tfInnerBatchTxn: false,
451+
})
452+
})
453+
454+
it('parseTransactionFlags with unknown transaction type and global flags only', function () {
455+
const flagsMap = parseTransactionFlags(
456+
'SetRegularKey',
457+
GlobalFlags.tfInnerBatchTxn,
458+
)
459+
assert.deepEqual(flagsMap, { tfInnerBatchTxn: true })
460+
})
461+
462+
it('parseTransactionFlags with type string including global flag', function () {
463+
const flagsMap = parseTransactionFlags(
464+
'PaymentChannelClaim',
465+
PaymentChannelClaimFlags.tfRenew | GlobalFlags.tfInnerBatchTxn,
466+
)
467+
assert.deepEqual(flagsMap, {
468+
tfRenew: true,
469+
tfInnerBatchTxn: true,
470+
})
471+
})
396472
})
397473

398474
describe('convertTxFlagsToNumber', function () {

0 commit comments

Comments
 (0)