Skip to content

feat: add specific response types for ledger_entry request variants#3230

Open
tequdev wants to merge 16 commits intoXRPLF:mainfrom
tequdev:ledger-entry-specific-response-types
Open

feat: add specific response types for ledger_entry request variants#3230
tequdev wants to merge 16 commits intoXRPLF:mainfrom
tequdev:ledger-entry-specific-response-types

Conversation

@tequdev
Copy link
Copy Markdown
Member

@tequdev tequdev commented Mar 24, 2026

High Level Overview of Change

Add type-level narrowing for LedgerEntryRequest so that client.request() returns a more specific LedgerEntryResponse based on which lookup field is provided. Previously, all ledger_entry requests
returned the generic LedgerEntryResponse (with node: LedgerEntry). Now, specifying a lookup field like account_root narrows the response to LedgerEntryResponse.

Context of Change

The LedgerEntryResponse interface already supported a generic type parameter <T = LedgerEntry>, but the RequestResponseMap always mapped LedgerEntryRequest to the unparameterized LedgerEntryResponse.
This meant users had to manually cast result.node to the expected ledger entry type after every ledger_entry call.

This follows the same pattern used for LedgerRequest subtypes (e.g., LedgerRequestExpandedTransactionsBinary).

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Tests (you added tests for code that already exists, or your PR is a test-only PR)

Changes

packages/xrpl/src/models/methods/ledgerEntry.ts

  • Added 19 narrowed request interfaces (e.g., LedgerEntryAccountRootRequest, LedgerEntryAMMRequest, etc.) that extend LedgerEntryRequest with one required lookup field each.

packages/xrpl/src/models/methods/index.ts

  • Imported 19 ledger entry types from ../ledger and 19 new request interfaces from ./ledgerEntry.
  • Added 19 conditional branches to RequestResponseMap before the generic LedgerEntryRequest fallback, each mapping to LedgerEntryResponse.
  • Exported all 19 new request interfaces.

Usage Example

 // Before: result.node is LedgerEntry (union of all types)
 const res = await client.request({
   command: 'ledger_entry',
   account_root: 'rAddr...',
 })
 // After: result.node is AccountRoot
 const res = await client.request({
   command: 'ledger_entry',
   account_root: 'rAddr...',
 })
 // binary = true still works for node_binary
 const res2 = await client.request({
   command: 'ledger_entry',
   account_root: 'rAddr...',
   binary: true,
 })
 // res2.result.node_binary is defined
 // res2.result.node is undefined (type never)
 
  // Generic fallback still works for index-based lookups
 const res3 = await client.request({
   command: 'ledger_entry',
   index: 'ABCDEF...',
 })
 // res3.result.node is LedgerEntry

Test Plan

  • TypeScript build passes (tsc --build)
  • ESLint passes with no warnings
  • Verify type inference in IDE for each lookup field
  • Run existing unit tests

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 24, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds DID to the exported LedgerEntry union; introduces ~20 new specialized LedgerEntry*Request interfaces and maps each to LedgerEntryResponse<SpecificLedgerType> in the methods index; updates tests to rely on type inference and safer null handling.

Changes

Cohort / File(s) Summary
Ledger entry model
packages/xrpl/src/models/ledger/LedgerEntry.ts
Added DID to the exported LedgerEntry union type.
LedgerEntry request interfaces
packages/xrpl/src/models/methods/ledgerEntry.ts
Added ~20 new exported interfaces (e.g., LedgerEntryAccountRootRequest, LedgerEntryAMMRequest, LedgerEntryDIDRequest, LedgerEntryMPTokenRequest, LedgerEntryMPTokenIssuanceRequest, LedgerEntryXChainOwnedClaimIDRequest, etc.), each extending LedgerEntryRequest and requiring the distinguishing property.
Request/response wiring & exports
packages/xrpl/src/models/methods/index.ts
Imported new LedgerEntry*Request types and corresponding ledger data types; extended RequestResponseMap<T, Version> to map each specific request to LedgerEntryResponse<SpecificLedgerType>; exported the new request types.
Integration tests — type handling updates
packages/xrpl/test/integration/transactions/clawback.test.ts, packages/xrpl/test/integration/transactions/delegateSet.test.ts, packages/xrpl/test/integration/transactions/permissionedDEX.test.ts
Removed explicit LedgerEntryResponse annotations in favor of inferred types; replaced some as Type casts with non-null assertions (!) and optional chaining; updated assertions to use inferred types and explicit casts where needed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • ckeshava
  • ckniffen
  • pdp2121

Poem

🐇 I found a DID and tucked it in the fold,
I stitched new requests where types were told.
Responses now match, the mappings sing,
I nibbled a carrot and did a small spring. 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding specific response types for ledger_entry request variants, which aligns with the changeset's primary objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The pull request description comprehensively covers all required template sections with clear context, rationale, usage examples, and test plan.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/xrpl/test/integration/transactions/delegateSet.test.ts (1)

6-6: ⚠️ Potential issue | 🟡 Minor

Remove unused imports.

Both LedgerEntryResponse (line 6) and Delegate (line 11) are imported but never used. Delegate appears only as a property name and string literal, not as a type annotation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/xrpl/test/integration/transactions/delegateSet.test.ts` at line 6,
Remove the unused imports LedgerEntryResponse and Delegate from the imports at
the top of delegateSet.test.ts; locate the import statement that currently lists
LedgerEntryResponse and Delegate and delete those two symbols so only
actually-used types/values are imported (keep other imports intact), ensuring no
type annotations or references to LedgerEntryResponse or Delegate remain before
committing.
🧹 Nitpick comments (2)
packages/xrpl/test/integration/transactions/permissionedDEX.test.ts (1)

262-272: Inconsistent access pattern and potentially unnecessary casts.

Line 262 uses optional chaining (?.) while line 235 uses non-null assertion (!). For consistency, consider using the non-null assertion here as well since the test expects the node to exist.

Additionally, the as DirectoryNode casts on lines 266 and 270 may no longer be necessary since the request uses the directory field, which should map to LedgerEntryResponse<DirectoryNode>.

♻️ Suggested improvement for consistency
       assert.equal(
-        ledgerEntryResponse.result.node?.index,
+        ledgerEntryResponse.result.node!.index,
         offerLedgerObject.BookDirectory,
       )
       assert.equal(
-        (ledgerEntryResponse.result.node as DirectoryNode).LedgerEntryType,
+        ledgerEntryResponse.result.node!.LedgerEntryType,
         'DirectoryNode',
       )
       assert.equal(
-        (ledgerEntryResponse.result.node as DirectoryNode).DomainID,
+        ledgerEntryResponse.result.node!.DomainID,
         permDomainLedgerObject.index,
       )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/xrpl/test/integration/transactions/permissionedDEX.test.ts` around
lines 262 - 272, Replace the optional chaining and redundant casts on the ledger
entry assertions: use non-null assertion (node!) instead of ?. when accessing
ledgerEntryResponse.result.node to match the existing non-null style, and remove
the unnecessary "as DirectoryNode" casts by relying on the typed response
(LedgerEntryResponse<DirectoryNode>) or by asserting node! and accessing
LedgerEntryType and DomainID directly; update the three assertions that
reference ledgerEntryResponse.result.node, offerLedgerObject.BookDirectory, and
permDomainLedgerObject.index to use node! and drop the explicit DirectoryNode
casts.
packages/xrpl/test/integration/transactions/clawback.test.ts (1)

13-13: Remove the unused LedgerEntryResponse import from line 13.

The import is not used anywhere in this file. The lowercase ledgerEntryResponse variable names in the test are just variable names and do not reference the imported LedgerEntryResponse type.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/xrpl/test/integration/transactions/clawback.test.ts` at line 13,
Remove the unused import symbol LedgerEntryResponse from the import list at the
top of the test file; the tests only use local variables named
ledgerEntryResponse (lowercase) and do not reference the LedgerEntryResponse
type, so delete that import to avoid the unused-import lint error and keep
imports minimal.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/xrpl/src/models/methods/index.ts`:
- Around line 654-672: Add the missing export for
LedgerEntryBridgeAccountRequest: update the export list that currently includes
LedgerEntryBridgeRequest and the other LedgerEntry* request interfaces and add
LedgerEntryBridgeAccountRequest so the interface imported earlier
(LedgerEntryBridgeAccountRequest) and used in RequestResponseMap is exported for
consumers; ensure the exact identifier LedgerEntryBridgeAccountRequest is
included in the same export block as the other LedgerEntry...Request entries.

---

Outside diff comments:
In `@packages/xrpl/test/integration/transactions/delegateSet.test.ts`:
- Line 6: Remove the unused imports LedgerEntryResponse and Delegate from the
imports at the top of delegateSet.test.ts; locate the import statement that
currently lists LedgerEntryResponse and Delegate and delete those two symbols so
only actually-used types/values are imported (keep other imports intact),
ensuring no type annotations or references to LedgerEntryResponse or Delegate
remain before committing.

---

Nitpick comments:
In `@packages/xrpl/test/integration/transactions/clawback.test.ts`:
- Line 13: Remove the unused import symbol LedgerEntryResponse from the import
list at the top of the test file; the tests only use local variables named
ledgerEntryResponse (lowercase) and do not reference the LedgerEntryResponse
type, so delete that import to avoid the unused-import lint error and keep
imports minimal.

In `@packages/xrpl/test/integration/transactions/permissionedDEX.test.ts`:
- Around line 262-272: Replace the optional chaining and redundant casts on the
ledger entry assertions: use non-null assertion (node!) instead of ?. when
accessing ledgerEntryResponse.result.node to match the existing non-null style,
and remove the unnecessary "as DirectoryNode" casts by relying on the typed
response (LedgerEntryResponse<DirectoryNode>) or by asserting node! and
accessing LedgerEntryType and DomainID directly; update the three assertions
that reference ledgerEntryResponse.result.node, offerLedgerObject.BookDirectory,
and permDomainLedgerObject.index to use node! and drop the explicit
DirectoryNode casts.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e69606bd-555d-4697-96a6-c86d61cbd9d4

📥 Commits

Reviewing files that changed from the base of the PR and between 54f55fa and 8d66a08.

📒 Files selected for processing (6)
  • packages/xrpl/src/models/ledger/LedgerEntry.ts
  • packages/xrpl/src/models/methods/index.ts
  • packages/xrpl/src/models/methods/ledgerEntry.ts
  • packages/xrpl/test/integration/transactions/clawback.test.ts
  • packages/xrpl/test/integration/transactions/delegateSet.test.ts
  • packages/xrpl/test/integration/transactions/permissionedDEX.test.ts

Comment thread packages/xrpl/src/models/methods/index.ts
Comment thread packages/xrpl/test/integration/transactions/clawback.test.ts Outdated
Patel-Raj11
Patel-Raj11 previously approved these changes Apr 2, 2026
@kuan121
Copy link
Copy Markdown
Collaborator

kuan121 commented Apr 3, 2026

/ai-review

Copy link
Copy Markdown

@xrplf-ai-reviewer xrplf-ai-reviewer Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vacuous assertion risk flagged inline — see line 262.

Review by Claude Opus 4.6 · Prompt: V13


assert.equal(
(ledgerEntryResponse.result.node as DirectoryNode).index,
ledgerEntryResponse.result.node?.index,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional chaining silently passes if node is undefined — add a guard before asserting:

Add assert.ok(ledgerEntryResponse.result.node, 'node should be present') before line 261, then restore the non-optional access:

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

| Credential
| Delegate
| DepositPreauth
| DID
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add MPToken, MPTokenIssuance and NFTokenPage as well?

@@ -6,6 +6,7 @@ import Check from './Check'
import Credential from './Credential'
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the scope of this PR? Does it aim to cover all the ledger entries listed on https://xrpl.org/docs/references/protocol/ledger-data/ledger-entry-types?

export interface LedgerEntryXChainOwnedCreateAccountClaimIDRequest extends LedgerEntryRequest {
xchain_owned_create_account_claim_id: Required<LedgerEntryRequest>['xchain_owned_create_account_claim_id']
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the scope, but do we need requests for Oracle, Vault, PermissionedDomain, Loan and LoanBroker?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if I should add those in this PR, since they didn't exist before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants