Skip to content

Commit 1006beb

Browse files
committed
fix: widen transactions type to include hash strings, normalize v1 in hashTxTree
- Widen Ledger.transactions and LedgerV1.transactions to Array<string | Expanded> to reflect both non-expanded (hash strings) and expanded response shapes - Replace unsafe cast in computeTransactionHash with proper v1→v2 normalization: detect LedgerTransactionExpandedV1 wrappers and extract tx_json/meta into the flat format expected by hashTxTree - Add missing Amount/Destination fields to Payment test fixtures - Add test case for hash-string transactions - Guard test assertions for string | object union type
1 parent 2da05b0 commit 1006beb

File tree

3 files changed

+56
-9
lines changed

3 files changed

+56
-9
lines changed

packages/xrpl/src/models/ledger/Ledger.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export interface Ledger extends BaseLedger {
9696
* full representations of the transactions as flat objects with the
9797
* transaction fields directly on the object, plus `hash` and `metaData`.
9898
*/
99-
transactions?: Array<LedgerTransactionExpanded>
99+
transactions?: Array<string | LedgerTransactionExpanded>
100100
}
101101

102102
/**
@@ -117,7 +117,7 @@ export interface LedgerV1 extends BaseLedger {
117117
* full representations of the transactions wrapped in objects with
118118
* `tx_json` and `meta` fields.
119119
*/
120-
transactions?: Array<LedgerTransactionExpandedV1>
120+
transactions?: Array<string | LedgerTransactionExpandedV1>
121121
}
122122

123123
/**

packages/xrpl/src/utils/hashes/hashLedger.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { LedgerEntry } from '../../models/ledger'
1313
import {
1414
LedgerVersionMap,
1515
LedgerTransactionExpanded,
16+
LedgerTransactionExpandedV1,
1617
} from '../../models/ledger/Ledger'
1718
import { Transaction } from '../../models/transactions'
1819
import { GlobalFlags } from '../../models/transactions/common'
@@ -180,9 +181,32 @@ function computeTransactionHash(
180181
throw new ValidationError('transactions is missing from the ledger')
181182
}
182183

183-
const transactionHash = hashTxTree(
184-
ledger.transactions as LedgerTransactionExpanded[],
184+
// Normalize transactions to the v2 flat format expected by hashTxTree.
185+
// V1 expanded transactions wrap data in { tx_json, meta }, while v2 has
186+
// the transaction fields directly on the object with metaData.
187+
const normalizedTransactions = (
188+
ledger.transactions as Array<
189+
string | LedgerTransactionExpanded | LedgerTransactionExpandedV1
190+
>
185191
)
192+
.filter(
193+
(
194+
tx,
195+
): tx is LedgerTransactionExpanded | LedgerTransactionExpandedV1 =>
196+
typeof tx !== 'string',
197+
)
198+
.map((tx) => {
199+
if ('tx_json' in tx) {
200+
// V1 wrapped format — normalize to v2 flat format
201+
return Object.assign({}, tx.tx_json, {
202+
hash: tx.hash,
203+
metaData: tx.meta,
204+
}) as LedgerTransactionExpanded
205+
}
206+
return tx
207+
})
208+
209+
const transactionHash = hashTxTree(normalizedTransactions)
186210

187211
if (transaction_hash !== transactionHash) {
188212
throw new ValidationError(

packages/xrpl/test/models/LedgerTransactionExpanded.test.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ describe('LedgerTransactionExpanded types', function () {
1111
it('Ledger (v2) transactions use flat format with metaData', function () {
1212
const tx: LedgerTransactionExpanded = {
1313
Account: 'rPrioTXJgZJF8bpdXq2X73PcVPfvYqjVKd',
14+
Amount: '1000000',
15+
Destination: 'rsRy14FvipgqudiGmptJBhr1RtpsgfzKMM',
1416
TransactionType: 'Payment',
1517
Fee: '11',
1618
Sequence: 1,
@@ -31,14 +33,31 @@ describe('LedgerTransactionExpanded types', function () {
3133
}
3234

3335
assert.isArray(ledgerV2.transactions)
34-
assert.strictEqual(ledgerV2.transactions![0].hash, tx.hash)
35-
assert.isDefined(ledgerV2.transactions![0].metaData)
36+
const firstTx = ledgerV2.transactions![0]
37+
assert.notEqual(typeof firstTx, 'string')
38+
if (typeof firstTx !== 'string') {
39+
assert.strictEqual(firstTx.hash, tx.hash)
40+
assert.isDefined(firstTx.metaData)
41+
}
42+
})
43+
44+
it('Ledger transactions can also be hash strings', function () {
45+
const ledgerV2: Pick<Ledger, 'transactions'> = {
46+
transactions: [
47+
'044314FE34236A262DA692789CE5B48CA1A3CEC078B1A4ECCD65F4B61A9EB0A7',
48+
],
49+
}
50+
51+
assert.isArray(ledgerV2.transactions)
52+
assert.strictEqual(typeof ledgerV2.transactions![0], 'string')
3653
})
3754

3855
it('LedgerV1 transactions use wrapped format with tx_json and meta', function () {
3956
const tx: LedgerTransactionExpandedV1 = {
4057
tx_json: {
4158
Account: 'rPrioTXJgZJF8bpdXq2X73PcVPfvYqjVKd',
59+
Amount: '1000000',
60+
Destination: 'rsRy14FvipgqudiGmptJBhr1RtpsgfzKMM',
4261
TransactionType: 'Payment',
4362
Fee: '11',
4463
Sequence: 1,
@@ -65,8 +84,12 @@ describe('LedgerTransactionExpanded types', function () {
6584
}
6685

6786
assert.isArray(ledgerV1.transactions)
68-
assert.strictEqual(ledgerV1.transactions![0].hash, tx.hash)
69-
assert.isDefined(ledgerV1.transactions![0].tx_json)
70-
assert.isDefined(ledgerV1.transactions![0].meta)
87+
const firstTx = ledgerV1.transactions![0]
88+
assert.notEqual(typeof firstTx, 'string')
89+
if (typeof firstTx !== 'string') {
90+
assert.strictEqual(firstTx.hash, tx.hash)
91+
assert.isDefined(firstTx.tx_json)
92+
assert.isDefined(firstTx.meta)
93+
}
7194
})
7295
})

0 commit comments

Comments
 (0)