Skip to content

XLS-81D Permissioned DEX#3032

Merged
ckeshava merged 37 commits intoXRPLF:mainfrom
ckeshava:perm_dex
Jul 16, 2025
Merged

XLS-81D Permissioned DEX#3032
ckeshava merged 37 commits intoXRPLF:mainfrom
ckeshava:perm_dex

Conversation

@ckeshava
Copy link
Collaborator

@ckeshava ckeshava commented Jul 2, 2025

High Level Overview of Change

This PR implements support for the specification defined here.

The rippled C++ PR can be found here.

Context of Change

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)
  • Documentation Updates
  • Release

Did you update HISTORY.md?

  • Yes
  • No, this change does not impact library users

Test Plan

Appropriate tests have been included.

…est models are implemented; TODO -- investigate tests for path_finding requests
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 2, 2025

"""

Walkthrough

This update introduces PermissionedDEX (XLS-81d) support across the XRPL codebase. It adds domain-related fields and validation logic to offer, payment, and pathfinding models, updates configuration and changelogs, and provides comprehensive integration and unit tests to ensure correct PermissionedDEX behavior and validation.

Changes

Files/Groups Change Summary
.ci-config/rippled.cfg Enabled the PermissionedDEX amendment in the configuration under version 2.5.0.
packages/xrpl/HISTORY.md Documented PermissionedDEX (XLS-81d) support in the changelog.
packages/xrpl/src/models/ledger/DirectoryNode.ts Added optional DomainID property to the DirectoryNode interface.
packages/xrpl/src/models/ledger/Offer.ts Introduced Book interface; extended Offer with DomainID and AdditionalBooks fields; added lsfHybrid flag to OfferFlags enum.
packages/xrpl/src/models/methods/bookOffers.ts Added optional domain property to BookOffersRequest interface.
packages/xrpl/src/models/methods/pathFind.ts Added optional domain field to PathFindCreateRequest and PathFindResponse interfaces.
packages/xrpl/src/models/methods/ripplePathFind.ts Added optional domain property to RipplePathFindRequest interface.
packages/xrpl/src/models/methods/subscribe.ts Added optional domain property to SubscribeBook interface.
packages/xrpl/src/models/transactions/common.ts Added _DOMAIN_ID_LENGTH constant and exported isDomainID function to validate 64-character domain ID strings.
packages/xrpl/src/models/transactions/offerCreate.ts Added tfHybrid flag to OfferCreateFlags and interface; added DomainID property to OfferCreate; updated validateOfferCreate to validate DomainID and enforce tfHybrid requires DomainID.
packages/xrpl/src/models/transactions/payment.ts Added DomainID property to Payment interface and validation in validatePayment.
packages/xrpl/test/integration/transactions/permissionedDEX.test.ts Added a new integration test suite for PermissionedDEX, covering domain creation, credential acceptance, offer creation, book offers, subscriptions, pathfinding, and offer crossing.
packages/xrpl/test/models/offerCreate.test.ts Added unit tests for OfferCreate validation with DomainID and tfHybrid flag scenarios.
packages/xrpl/test/models/payment.test.ts Added unit tests for Payment model validating DomainID field correctness and error cases.
packages/ripple-binary-codec/test/hash.test.ts Added tests verifying hash construction fails for non-hexadecimal strings.

Possibly related PRs

  • PermissionedDomain XLS-80d #2874: Implements foundational PermissionedDomain ledger entries, transactions, and validation logic that this PR builds upon by adding PermissionedDEX amendment and domain-related fields and flags.

Suggested reviewers

  • mvadari
  • khancode

Poem

🐇
In the warren of code, a new path we see,
PermissionedDEX hops in with domain ID.
Offers and payments now know where they dwell,
Hybrid flags waving, all tests go well.
The ledger’s a meadow, domains in the sun—
With each bounding feature, the future’s begun!

"""

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE package: '@es-joy/jsdoccomment@0.36.1',
npm warn EBADENGINE required: { node: '^14 || ^16 || ^17 || ^18 || ^19' },
npm warn EBADENGINE current: { node: 'v24.3.0', npm: '11.4.2' }
npm warn EBADENGINE }
npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE package: 'eslint-plugin-jsdoc@39.9.1',
npm warn EBADENGINE required: { node: '^14 || ^16 || ^17 || ^18 || ^19' },
npm warn EBADENGINE current: { node: 'v24.3.0', npm: '11.4.2' }
npm warn EBADENGINE }
npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-07-16T17_14_32_069Z-debug-0.log


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 819ab25 and 24c32f1.

📒 Files selected for processing (1)
  • packages/xrpl/src/models/transactions/offerCreate.ts (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/xrpl/src/models/transactions/offerCreate.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: integration (22.x)
  • GitHub Check: integration (20.x)
  • GitHub Check: browser (22.x)
  • GitHub Check: unit (20.x)
  • GitHub Check: build-and-lint (22.x)
  • GitHub Check: unit (22.x)
  • GitHub Check: Analyze (javascript)
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@ckeshava
Copy link
Collaborator Author

ckeshava commented Jul 2, 2025

@CodeRabbit review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 2, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
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

🧹 Nitpick comments (5)
packages/xrpl/HISTORY.md (1)

7-9: Link to the standard for easier navigation

Readers usually jump from the changelog straight to the spec. Consider in-lining a link:

-* Support for `PermissionedDEX` (XLS-81d)
+* Support for [`PermissionedDEX` (XLS-81d)](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0081-permissioned-dex)
packages/xrpl/src/models/ledger/DirectoryNode.ts (1)

49-50: Document the expected format of DomainID

DomainID is a ledger object ID (64-char hex). Stating that up-front helps downstream tooling and prevents accidental submission of non-canonical strings.

-  /** The domain that the offer directory is a part of. */
-  DomainID?: string
+  /**
+   * Hex-encoded object ID of the PermissionedDomain that owns this directory
+   * (64-character, uppercase hexadecimal).
+   */
+  DomainID?: string
packages/xrpl/src/models/methods/subscribe.ts (1)

43-48: Use a branded type (or re-export) for domain to avoid free-form strings

Everywhere else the identifier is called DomainID and is a 64-char hex.
Exposing it here as a plain string silently accepts invalid values and shifts validation cost to runtime.

Minimal change:

-  domain?: string
+  /** 64-char hex ID of a PermissionedDomain object. */
+  domain?: DomainID

where export type DomainID = string (or an opaque branded type) can live in src/models/common.ts and be reused by all request/ledger interfaces.

This keeps compile-time safety aligned across the PermissionedDEX surface.

packages/xrpl/test/models/offerCreate.test.ts (1)

86-86: Fix typo in test name.

The test name contains a typo: verfies should be verifies.

Apply this diff to fix the typo:

-  it(`verfies valid offerCreate within permissioned domain`, function () {
+  it(`verifies valid offerCreate within permissioned domain`, function () {
packages/xrpl/test/integration/transactions/permissionedDEX.test.ts (1)

179-183: Address the TODO comment about missing Owner field.

The commented assertion indicates that the DirectoryNode object is missing the Owner field. This should be tracked and resolved to ensure complete validation of the ledger object properties.

Would you like me to create an issue to track adding the Owner field to the DirectoryNode interface?

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0eb77a9 and dad6bf8.

📒 Files selected for processing (13)
  • .ci-config/rippled.cfg (1 hunks)
  • packages/xrpl/HISTORY.md (1 hunks)
  • packages/xrpl/src/models/ledger/DirectoryNode.ts (1 hunks)
  • packages/xrpl/src/models/ledger/Offer.ts (2 hunks)
  • packages/xrpl/src/models/methods/bookOffers.ts (1 hunks)
  • packages/xrpl/src/models/methods/pathFind.ts (2 hunks)
  • packages/xrpl/src/models/methods/ripplePathFind.ts (1 hunks)
  • packages/xrpl/src/models/methods/subscribe.ts (1 hunks)
  • packages/xrpl/src/models/transactions/offerCreate.ts (5 hunks)
  • packages/xrpl/src/models/transactions/payment.ts (3 hunks)
  • packages/xrpl/src/models/utils/flags.ts (2 hunks)
  • packages/xrpl/test/integration/transactions/permissionedDEX.test.ts (1 hunks)
  • packages/xrpl/test/models/offerCreate.test.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (14)
📓 Common learnings
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2873
File: packages/xrpl/test/integration/transactions/trustSet.test.ts:0-0
Timestamp: 2025-01-31T17:46:25.375Z
Learning: For the XRPL implementation, extensive test cases for deep freeze behavior (high/low side interactions, clearing flags, etc.) are maintained in the C++ implementation and don't need to be duplicated in the JavaScript implementation.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/mptokenAuthorize.test.ts:29-118
Timestamp: 2024-12-06T19:25:15.376Z
Learning: In the XRPLF/xrpl.js TypeScript client library, when writing tests (e.g., in `packages/xrpl/test/integration/transactions/`), we generally do not need to test rippled server behaviors, because those behaviors are covered by rippled's own integration and unit tests.
.ci-config/rippled.cfg (3)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2812
File: packages/xrpl/test/integration/transactions/payment.test.ts:41-43
Timestamp: 2024-10-30T01:05:33.583Z
Learning: In tests involving fee calculations for XRPL, avoid using default fee amounts. If unable to retrieve fee values from the latest validated ledger, throw an error instead of defaulting to a specific amount.
packages/xrpl/src/models/ledger/DirectoryNode.ts (1)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
packages/xrpl/src/models/utils/flags.ts (7)
Learnt from: mvadari
PR: XRPLF/xrpl.js#2801
File: packages/xrpl/src/Wallet/batchSigner.ts:0-0
Timestamp: 2025-04-16T15:55:50.121Z
Learning: When using `encodeForSigningBatch` for Batch transactions in the XRPL.js library, the field names should use camelCase (`flags`, `txIDs`) even though the transaction object properties themselves use PascalCase (`Flags`, `TxIDs`).
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/models/MPTokenAuthorize.test.ts:60-71
Timestamp: 2024-12-06T18:44:55.095Z
Learning: In the XRPL.js library's TypeScript test file `packages/xrpl/test/models/MPTokenAuthorize.test.ts`, negative test cases for invalid `Account` address format, invalid `Holder` address format, invalid `MPTokenIssuanceID` format, and invalid flag combinations are not necessary.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2873
File: packages/xrpl/src/models/transactions/trustSet.ts:33-36
Timestamp: 2025-01-08T13:08:52.688Z
Learning: For trust-set transactions in XRPL, validation rules for flags should be implemented comprehensively rather than cherry-picking specific rules, as there are many interdependent validation rules associated with these flags.
Learnt from: achowdhry-ripple
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts:69-102
Timestamp: 2024-12-05T16:48:12.951Z
Learning: When adding validation in `validate*` functions in `packages/xrpl/src/models/transactions/`, utilize existing helper functions (e.g., `validateOptionalField`, `validateType`, `isNumber`, `isInteger`) for type checking and validation where appropriate.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/mptokenAuthorize.test.ts:29-118
Timestamp: 2024-12-06T19:25:15.376Z
Learning: In the XRPLF/xrpl.js TypeScript client library, when writing tests (e.g., in `packages/xrpl/test/integration/transactions/`), we generally do not need to test rippled server behaviors, because those behaviors are covered by rippled's own integration and unit tests.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2690
File: packages/xrpl/tools/generateModels.js:52-52
Timestamp: 2024-10-02T15:47:02.491Z
Learning: In `generateModels.js`, the regex used to match `SubmittableTransaction` in `transaction.ts` is expected to always succeed because the pattern is present in the source code. If it fails, the code needs to be updated.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2690
File: packages/xrpl/tools/generateModels.js:52-52
Timestamp: 2024-10-08T16:29:11.194Z
Learning: In `generateModels.js`, the regex used to match `SubmittableTransaction` in `transaction.ts` is expected to always succeed because the pattern is present in the source code. If it fails, the code needs to be updated.
packages/xrpl/src/models/methods/ripplePathFind.ts (3)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2829
File: packages/xrpl/src/models/ledger/Credential.ts:36-36
Timestamp: 2024-12-09T07:06:47.258Z
Learning: In TypeScript interfaces, ensure that fields documented as optional are marked with the `?` operator to denote optionality.
packages/xrpl/src/models/methods/bookOffers.ts (2)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2829
File: packages/xrpl/src/models/ledger/Credential.ts:36-36
Timestamp: 2024-12-09T07:06:47.258Z
Learning: In TypeScript interfaces, ensure that fields documented as optional are marked with the `?` operator to denote optionality.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
packages/xrpl/src/models/methods/subscribe.ts (1)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2829
File: packages/xrpl/src/models/ledger/Credential.ts:36-36
Timestamp: 2024-12-09T07:06:47.258Z
Learning: In TypeScript interfaces, ensure that fields documented as optional are marked with the `?` operator to denote optionality.
packages/xrpl/test/models/offerCreate.test.ts (9)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/models/MPTokenAuthorize.test.ts:60-71
Timestamp: 2024-12-06T18:44:55.095Z
Learning: In the XRPL.js library's TypeScript test file `packages/xrpl/test/models/MPTokenAuthorize.test.ts`, negative test cases for invalid `Account` address format, invalid `Holder` address format, invalid `MPTokenIssuanceID` format, and invalid flag combinations are not necessary.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/clawback.test.ts:165-178
Timestamp: 2024-12-06T19:27:11.147Z
Learning: In the integration tests for `clawback.test.ts`, it's acceptable to use `@ts-expect-error` to bypass type checking when verifying ledger entries, and no additional type safety improvements are needed.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/mptokenAuthorize.test.ts:29-118
Timestamp: 2024-12-06T19:25:15.376Z
Learning: In the XRPLF/xrpl.js TypeScript client library, when writing tests (e.g., in `packages/xrpl/test/integration/transactions/`), we generally do not need to test rippled server behaviors, because those behaviors are covered by rippled's own integration and unit tests.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2895
File: packages/xrpl/test/models/clawback.test.ts:0-0
Timestamp: 2025-02-12T23:28:55.377Z
Learning: The `validate` function in xrpl.js is synchronous and should be tested using `assert.doesNotThrow` rather than async assertions.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2895
File: packages/xrpl/test/models/DIDDelete.test.ts:28-31
Timestamp: 2025-02-12T23:30:40.622Z
Learning: In JavaScript/TypeScript transaction validation tests, object key validation can be performed using:
1. Object.keys() comparison with expected set
2. TypeScript interfaces with strict object literal checks
3. Object sanitization by filtering to allowed keys only
Learnt from: mvadari
PR: XRPLF/xrpl.js#2690
File: packages/xrpl/tools/generateModels.js:52-52
Timestamp: 2024-10-08T16:29:11.194Z
Learning: In `generateModels.js`, the regex used to match `SubmittableTransaction` in `transaction.ts` is expected to always succeed because the pattern is present in the source code. If it fails, the code needs to be updated.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2690
File: packages/xrpl/tools/generateModels.js:52-52
Timestamp: 2024-10-02T15:47:02.491Z
Learning: In `generateModels.js`, the regex used to match `SubmittableTransaction` in `transaction.ts` is expected to always succeed because the pattern is present in the source code. If it fails, the code needs to be updated.
packages/xrpl/HISTORY.md (3)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/mptokenAuthorize.test.ts:29-118
Timestamp: 2024-12-06T19:25:15.376Z
Learning: In the XRPLF/xrpl.js TypeScript client library, when writing tests (e.g., in `packages/xrpl/test/integration/transactions/`), we generally do not need to test rippled server behaviors, because those behaviors are covered by rippled's own integration and unit tests.
packages/xrpl/src/models/methods/pathFind.ts (3)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2829
File: packages/xrpl/src/models/ledger/Credential.ts:36-36
Timestamp: 2024-12-09T07:06:47.258Z
Learning: In TypeScript interfaces, ensure that fields documented as optional are marked with the `?` operator to denote optionality.
packages/xrpl/src/models/transactions/payment.ts (7)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: achowdhry-ripple
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts:69-102
Timestamp: 2024-12-05T16:48:12.951Z
Learning: When adding validation in `validate*` functions in `packages/xrpl/src/models/transactions/`, utilize existing helper functions (e.g., `validateOptionalField`, `validateType`, `isNumber`, `isInteger`) for type checking and validation where appropriate.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/mptokenAuthorize.test.ts:29-118
Timestamp: 2024-12-06T19:25:15.376Z
Learning: In the XRPLF/xrpl.js TypeScript client library, when writing tests (e.g., in `packages/xrpl/test/integration/transactions/`), we generally do not need to test rippled server behaviors, because those behaviors are covered by rippled's own integration and unit tests.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2801
File: packages/xrpl/src/Wallet/batchSigner.ts:0-0
Timestamp: 2025-04-16T15:55:50.121Z
Learning: When using `encodeForSigningBatch` for Batch transactions in the XRPL.js library, the field names should use camelCase (`flags`, `txIDs`) even though the transaction object properties themselves use PascalCase (`Flags`, `TxIDs`).
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2873
File: packages/xrpl/src/models/transactions/trustSet.ts:33-36
Timestamp: 2025-01-08T13:08:52.688Z
Learning: For trust-set transactions in XRPL, validation rules for flags should be implemented comprehensively rather than cherry-picking specific rules, as there are many interdependent validation rules associated with these flags.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2895
File: packages/xrpl/test/models/DIDDelete.test.ts:28-31
Timestamp: 2025-02-12T23:30:40.622Z
Learning: In JavaScript/TypeScript transaction validation tests, object key validation can be performed using:
1. Object.keys() comparison with expected set
2. TypeScript interfaces with strict object literal checks
3. Object sanitization by filtering to allowed keys only
packages/xrpl/src/models/ledger/Offer.ts (1)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2829
File: packages/xrpl/src/models/ledger/Credential.ts:36-36
Timestamp: 2024-12-09T07:06:47.258Z
Learning: In TypeScript interfaces, ensure that fields documented as optional are marked with the `?` operator to denote optionality.
packages/xrpl/test/integration/transactions/permissionedDEX.test.ts (9)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/mptokenAuthorize.test.ts:29-118
Timestamp: 2024-12-06T19:25:15.376Z
Learning: In the XRPLF/xrpl.js TypeScript client library, when writing tests (e.g., in `packages/xrpl/test/integration/transactions/`), we generally do not need to test rippled server behaviors, because those behaviors are covered by rippled's own integration and unit tests.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/models/MPTokenAuthorize.test.ts:60-71
Timestamp: 2024-12-06T18:44:55.095Z
Learning: In the XRPL.js library's TypeScript test file `packages/xrpl/test/models/MPTokenAuthorize.test.ts`, negative test cases for invalid `Account` address format, invalid `Holder` address format, invalid `MPTokenIssuanceID` format, and invalid flag combinations are not necessary.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/clawback.test.ts:165-178
Timestamp: 2024-12-06T19:27:11.147Z
Learning: In the integration tests for `clawback.test.ts`, it's acceptable to use `@ts-expect-error` to bypass type checking when verifying ledger entries, and no additional type safety improvements are needed.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2873
File: packages/xrpl/test/integration/transactions/trustSet.test.ts:0-0
Timestamp: 2025-01-31T17:46:25.375Z
Learning: For the XRPL implementation, extensive test cases for deep freeze behavior (high/low side interactions, clearing flags, etc.) are maintained in the C++ implementation and don't need to be duplicated in the JavaScript implementation.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2801
File: packages/xrpl/test/models/Batch.test.ts:0-0
Timestamp: 2025-04-16T15:22:45.633Z
Learning: Using `as any` type assertions is acceptable in test files for the XRPL.js project, as strict typing is not required for test code.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2895
File: packages/xrpl/test/models/clawback.test.ts:0-0
Timestamp: 2025-02-12T23:28:55.377Z
Learning: The `validate` function in xrpl.js is synchronous and should be tested using `assert.doesNotThrow` rather than async assertions.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2895
File: packages/xrpl/test/models/DIDDelete.test.ts:28-31
Timestamp: 2025-02-12T23:30:40.622Z
Learning: In JavaScript/TypeScript transaction validation tests, object key validation can be performed using:
1. Object.keys() comparison with expected set
2. TypeScript interfaces with strict object literal checks
3. Object sanitization by filtering to allowed keys only
packages/xrpl/src/models/transactions/offerCreate.ts (8)
Learnt from: achowdhry-ripple
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts:69-102
Timestamp: 2024-12-05T16:48:12.951Z
Learning: When adding validation in `validate*` functions in `packages/xrpl/src/models/transactions/`, utilize existing helper functions (e.g., `validateOptionalField`, `validateType`, `isNumber`, `isInteger`) for type checking and validation where appropriate.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/models/MPTokenAuthorize.test.ts:60-71
Timestamp: 2024-12-06T18:44:55.095Z
Learning: In the XRPL.js library's TypeScript test file `packages/xrpl/test/models/MPTokenAuthorize.test.ts`, negative test cases for invalid `Account` address format, invalid `Holder` address format, invalid `MPTokenIssuanceID` format, and invalid flag combinations are not necessary.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2873
File: packages/xrpl/src/models/transactions/trustSet.ts:33-36
Timestamp: 2025-01-08T13:08:52.688Z
Learning: For trust-set transactions in XRPL, validation rules for flags should be implemented comprehensively rather than cherry-picking specific rules, as there are many interdependent validation rules associated with these flags.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2801
File: packages/xrpl/src/Wallet/batchSigner.ts:0-0
Timestamp: 2025-04-16T15:55:50.121Z
Learning: When using `encodeForSigningBatch` for Batch transactions in the XRPL.js library, the field names should use camelCase (`flags`, `txIDs`) even though the transaction object properties themselves use PascalCase (`Flags`, `TxIDs`).
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2829
File: packages/xrpl/src/models/ledger/Credential.ts:36-36
Timestamp: 2024-12-09T07:06:47.258Z
Learning: In TypeScript interfaces, ensure that fields documented as optional are marked with the `?` operator to denote optionality.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2895
File: packages/xrpl/test/models/DIDDelete.test.ts:28-31
Timestamp: 2025-02-12T23:30:40.622Z
Learning: In JavaScript/TypeScript transaction validation tests, object key validation can be performed using:
1. Object.keys() comparison with expected set
2. TypeScript interfaces with strict object literal checks
3. Object sanitization by filtering to allowed keys only
🧬 Code Graph Analysis (4)
packages/xrpl/src/models/utils/flags.ts (1)
packages/xrpl/src/models/transactions/common.ts (1)
  • BaseTransaction (318-393)
packages/xrpl/test/models/offerCreate.test.ts (2)
weback.test.config.js (1)
  • assert (2-2)
packages/xrpl/src/models/transactions/offerCreate.ts (1)
  • validateOfferCreate (151-192)
packages/xrpl/src/models/transactions/payment.ts (2)
packages/xrpl/src/models/transactions/offerCreate.ts (1)
  • validateDomainID (20-34)
packages/xrpl/src/errors.ts (1)
  • ValidationError (156-156)
packages/xrpl/src/models/transactions/offerCreate.ts (2)
packages/xrpl/src/errors.ts (1)
  • ValidationError (156-156)
packages/xrpl/src/models/transactions/index.ts (1)
  • OfferCreateFlags (84-84)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: browser (22.x)
  • GitHub Check: integration (20.x)
  • GitHub Check: integration (22.x)
  • GitHub Check: unit (20.x)
  • GitHub Check: unit (22.x)
🔇 Additional comments (11)
.ci-config/rippled.cfg (1)

190-194: Ensure the runtime rippled binary actually supports PermissionedDEX

Listing the amendment here is harmless only when the node binary already contains the XLS-81d implementation.
If the CI image is older, the daemon will refuse to start with “unknown amendment” and all PermissionedDEX tests will fail.

Please double-check that the Docker image/tag used by the integration tests is built from a commit that includes the amendment, or pin it to the nightly containing PR #5161 before merging.

packages/xrpl/src/models/methods/ripplePathFind.ts (1)

42-46: LGTM! Clean implementation of domain filtering for path finding.

The optional domain field is properly typed, documented, and follows TypeScript conventions. The documentation clearly explains the filtering behavior when the field is provided.

packages/xrpl/src/models/utils/flags.ts (2)

12-12: LGTM! Appropriate type generalization for broader transaction support.

Adding BaseTransaction import to support the updated function parameter type.


102-102: LGTM! Safe type generalization from Transaction to BaseTransaction.

This change safely broadens the function to accept BaseTransaction instead of Transaction. Since the function only uses Flags and TransactionType properties (both present in BaseTransaction), this generalization supports the new domain-specific transaction types without breaking existing functionality.

packages/xrpl/src/models/methods/bookOffers.ts (1)

43-49: LGTM! Comprehensive domain filtering implementation for book offers.

The optional domain field is well-implemented with clear documentation that explains both the filtering behavior when present and the exclusion behavior when omitted. The implementation follows TypeScript best practices.

packages/xrpl/test/models/offerCreate.test.ts (1)

87-104: LGTM! Appropriate test coverage for DomainID validation.

The test correctly validates that OfferCreate transactions with DomainID pass validation. The test structure follows the existing pattern and uses appropriate assertions. Based on the retrieved learnings, focusing on happy path validation in the JS SDK is the right approach since complex error cases are handled in the rippled C++ implementation.

packages/xrpl/src/models/methods/pathFind.ts (2)

34-38: LGTM! Consistent domain filtering implementation for path finding requests.

The optional domain field is properly implemented with clear documentation explaining the filtering behavior. This aligns with similar additions in other method interfaces.


107-111: LGTM! Appropriate domain identification in path finding responses.

The optional domain field in the response properly identifies which domain the orderbook pertains to. The documentation is clear and the field is correctly typed and marked as optional.

packages/xrpl/src/models/transactions/payment.ts (1)

19-19: LGTM! Good reuse of validation logic.

The addition of DomainID to the Payment transaction is well-implemented:

  • Proper import and reuse of validateDomainID function for consistency
  • Clear documentation explaining when and how DomainID should be used
  • Correct optional field marking and validation placement

Also applies to: 162-173, 212-214

packages/xrpl/src/models/ledger/Offer.ts (1)

5-14: Well-structured additions for PermissionedDEX support.

The ledger model updates are clean and consistent:

  • Good encapsulation with the Book interface
  • Proper use of optional fields for domain-specific properties
  • Clear documentation and consistent flag naming

Also applies to: 49-56, 62-63

packages/xrpl/src/models/transactions/offerCreate.ts (1)

11-34: Clean validation utility function.

The validateDomainID function is well-implemented with clear validation logic and appropriate null/undefined handling. Good use of a constant for the domain ID length requirement.

@ckeshava ckeshava requested review from Patel-Raj11 and khancode July 7, 2025 18:48
@ckeshava ckeshava marked this pull request as ready for review July 7, 2025 18:51
Copy link
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: 0

🧹 Nitpick comments (2)
packages/xrpl/test/integration/transactions/permissionedDEX.test.ts (2)

52-209: Consider extracting setup logic into helper functions for better maintainability.

The beforeAll setup is comprehensive but quite lengthy (157 lines). Consider extracting related setup steps into helper functions to improve readability and reusability.

For example, extract credential setup:

async function setupCredentials(client: Client, issuer: Wallet, subjects: Wallet[]) {
  for (const subject of subjects) {
    await testTransaction(client, {
      TransactionType: 'CredentialCreate',
      Subject: subject.classicAddress,
      Account: issuer.classicAddress,
      CredentialType: stringToHex('Passport'),
    } as CredentialCreate, issuer)
    
    await testTransaction(client, {
      TransactionType: 'CredentialAccept',
      Account: subject.classicAddress,
      Issuer: issuer.classicAddress,
      CredentialType: stringToHex('Passport'),
    } as CredentialAccept, subject)
  }
}

Similar helper functions could be created for trust line setup and funding.


291-315: Enhance subscription test to validate actual functionality.

The current subscription test only validates that domain is an acceptable parameter but doesn't test the actual subscription functionality. The empty result validation is minimal.

Consider adding a more comprehensive subscription test:

it('Validate subscription stream receives domain-filtered offers', async () => {
  const subscribePromise = new Promise((resolve) => {
    testContext.client.on('transaction', (tx) => {
      if (tx.transaction.TransactionType === 'OfferCreate' && tx.transaction.DomainID) {
        resolve(tx)
      }
    })
  })

  await testContext.client.request({
    command: 'subscribe',
    books: [{
      taker_gets: { currency: 'XRP' },
      taker_pays: { currency: 'USD', issuer: testContext.wallet.classicAddress },
      taker: wallet1.classicAddress,
      domain: pd_ledger_object.index,
    }],
  })

  // Create a new offer to trigger the subscription
  // ... then validate the subscription response
})
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dad6bf8 and c9908ff.

📒 Files selected for processing (7)
  • .ci-config/rippled.cfg (1 hunks)
  • packages/xrpl/HISTORY.md (1 hunks)
  • packages/xrpl/src/models/transactions/offerCreate.ts (5 hunks)
  • packages/xrpl/src/models/transactions/payment.ts (3 hunks)
  • packages/xrpl/src/models/utils/flags.ts (2 hunks)
  • packages/xrpl/test/integration/transactions/permissionedDEX.test.ts (1 hunks)
  • packages/xrpl/test/models/offerCreate.test.ts (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • .ci-config/rippled.cfg
  • packages/xrpl/HISTORY.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/xrpl/src/models/utils/flags.ts
  • packages/xrpl/src/models/transactions/payment.ts
  • packages/xrpl/test/models/offerCreate.test.ts
  • packages/xrpl/src/models/transactions/offerCreate.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2873
File: packages/xrpl/test/integration/transactions/trustSet.test.ts:0-0
Timestamp: 2025-01-31T17:46:25.375Z
Learning: For the XRPL implementation, extensive test cases for deep freeze behavior (high/low side interactions, clearing flags, etc.) are maintained in the C++ implementation and don't need to be duplicated in the JavaScript implementation.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/mptokenAuthorize.test.ts:29-118
Timestamp: 2024-12-06T19:25:15.376Z
Learning: In the XRPLF/xrpl.js TypeScript client library, when writing tests (e.g., in `packages/xrpl/test/integration/transactions/`), we generally do not need to test rippled server behaviors, because those behaviors are covered by rippled's own integration and unit tests.
packages/xrpl/test/integration/transactions/permissionedDEX.test.ts (9)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/mptokenAuthorize.test.ts:29-118
Timestamp: 2024-12-06T19:25:15.376Z
Learning: In the XRPLF/xrpl.js TypeScript client library, when writing tests (e.g., in `packages/xrpl/test/integration/transactions/`), we generally do not need to test rippled server behaviors, because those behaviors are covered by rippled's own integration and unit tests.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/models/MPTokenAuthorize.test.ts:60-71
Timestamp: 2024-12-06T18:44:55.095Z
Learning: In the XRPL.js library's TypeScript test file `packages/xrpl/test/models/MPTokenAuthorize.test.ts`, negative test cases for invalid `Account` address format, invalid `Holder` address format, invalid `MPTokenIssuanceID` format, and invalid flag combinations are not necessary.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/clawback.test.ts:165-178
Timestamp: 2024-12-06T19:27:11.147Z
Learning: In the integration tests for `clawback.test.ts`, it's acceptable to use `@ts-expect-error` to bypass type checking when verifying ledger entries, and no additional type safety improvements are needed.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2873
File: packages/xrpl/test/integration/transactions/trustSet.test.ts:0-0
Timestamp: 2025-01-31T17:46:25.375Z
Learning: For the XRPL implementation, extensive test cases for deep freeze behavior (high/low side interactions, clearing flags, etc.) are maintained in the C++ implementation and don't need to be duplicated in the JavaScript implementation.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2801
File: packages/xrpl/test/models/Batch.test.ts:0-0
Timestamp: 2025-04-16T15:22:45.633Z
Learning: Using `as any` type assertions is acceptable in test files for the XRPL.js project, as strict typing is not required for test code.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2895
File: packages/xrpl/test/models/clawback.test.ts:0-0
Timestamp: 2025-02-12T23:28:55.377Z
Learning: The `validate` function in xrpl.js is synchronous and should be tested using `assert.doesNotThrow` rather than async assertions.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2895
File: packages/xrpl/test/models/DIDDelete.test.ts:28-31
Timestamp: 2025-02-12T23:30:40.622Z
Learning: In JavaScript/TypeScript transaction validation tests, object key validation can be performed using:
1. Object.keys() comparison with expected set
2. TypeScript interfaces with strict object literal checks
3. Object sanitization by filtering to allowed keys only
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: integration (20.x)
  • GitHub Check: integration (22.x)
  • GitHub Check: browser (22.x)
  • GitHub Check: unit (22.x)
  • GitHub Check: unit (20.x)
🔇 Additional comments (4)
packages/xrpl/test/integration/transactions/permissionedDEX.test.ts (4)

1-40: LGTM - Clean imports and setup structure.

The imports are well-organized and include all necessary types and utilities for the PermissionedDEX integration tests.


213-289: LGTM - Comprehensive ledger object validation.

The tests properly validate the Offer and DirectoryNode ledger objects, checking domain IDs, account ownership, and additional books. The book_offers method test correctly validates domain-scoped filtering.


317-350: LGTM - Proper ripple_path_find domain scoping test.

The test correctly validates that the ripple_path_find method accepts domain parameters and returns appropriate results for pathfinding within the permissioned domain.


352-386: Run Integration Tests from Monorepo Root

The jest: not found errors above are expected when running npm test inside packages/xrpl—the integration suite is wired up at the repo root. Please verify the “Crossing a PermissionedDEX Offer” test by running from the project root:

npm run test:integration -- --testNamePattern="Crossing a PermissionedDEX Offer"

Once you’ve confirmed it passes, the offer-crossing logic looks correct:

  • wallet1’s hybrid offer (1000 XRP ↔ 10 USD)
  • wallet2’s domain-specific counter-offer (10 USD ↔ 1000 XRP)
  • Both use the same DomainID

If the test still fails, please check:

  • Both wallets have their domain credentials accepted
  • The domain is configured to allow hybrid and domain-specific offers
  • The offer amounts are exactly complementary

Copy link
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: 0

🧹 Nitpick comments (4)
packages/xrpl/test/integration/transactions/permissionedDEX.test.ts (4)

49-217: Consider refactoring the extensive beforeAll setup for better maintainability.

The beforeAll setup is quite comprehensive (169 lines) and handles multiple distinct setup phases. While the setup is correct, it could benefit from being broken down into smaller, focused helper functions to improve readability and maintainability.

Consider extracting logical groups into helper functions:

// Helper functions that could be extracted
async function setupCredentials(client: Client, issuer: Wallet, subjects: Wallet[]) {
  // Lines 66-88: Credential creation logic
}

async function setupPermissionedDomain(client: Client, issuer: Wallet) {
  // Lines 90-106: PermissionedDomain creation
}

async function setupTrustLinesAndFunding(client: Client, issuer: Wallet, wallets: Wallet[]) {
  // Lines 139-198: Trust line and funding logic
}

async function createHybridOffer(client: Client, wallet: Wallet, domainID: string) {
  // Lines 200-216: Hybrid offer creation
}

This would make the beforeAll more readable and the setup logic reusable for other tests.


267-297: Enhance book_offers validation with additional assertions.

The test correctly validates the basic structure of the book_offers response, but could benefit from additional assertions to ensure the domain filtering is working correctly.

Consider adding assertions to validate that the offer is correctly filtered by domain:

// Additional assertions to strengthen the test
assert.equal(response.result.offers[0].Account, wallet1.classicAddress)
assert.equal(response.result.offers[0].LedgerEntryType, 'Offer')
assert.isTrue(response.result.offers[0].Flags & OfferCreateFlags.tfHybrid)

325-359: Enhance offer crossing validation beyond empty object checks.

The test validates that offers are consumed after crossing, but could benefit from additional assertions to verify that the crossing actually occurred correctly (e.g., checking account balances).

Consider adding balance validations to ensure the crossing executed properly:

// After the crossing transaction, validate balances changed correctly
const wallet1_balance = await testContext.client.request({
  command: 'account_lines',
  account: wallet1.classicAddress,
  ledger_index: 'validated'
})

const wallet2_balance = await testContext.client.request({
  command: 'account_lines', 
  account: wallet2.classicAddress,
  ledger_index: 'validated'
})

// Validate that USD balances changed as expected from the crossing
// wallet1 should have received 1000 XRP drops and given 10 USD
// wallet2 should have given 1000 XRP drops and received 10 USD

This would provide stronger validation that the crossing actually occurred correctly rather than just checking empty offer objects.


329-341: Verify the offer crossing logic aligns with PermissionedDEX requirements.

The crossing offer doesn't use the tfHybrid flag, which appears intentional since it's crossing an existing hybrid offer within the domain. However, it would be helpful to add a comment explaining this design decision.

Consider adding a comment to clarify the crossing behavior:

// wallet2 "crosses" the offer within the domain
// Note: The crossing offer doesn't need tfHybrid flag since it's consuming
// an existing hybrid offer within the specified domain
const offerCrossTx: OfferCreate = {
  // ... existing code
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c9908ff and d039439.

📒 Files selected for processing (1)
  • packages/xrpl/test/integration/transactions/permissionedDEX.test.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2873
File: packages/xrpl/test/integration/transactions/trustSet.test.ts:0-0
Timestamp: 2025-01-31T17:46:25.375Z
Learning: For the XRPL implementation, extensive test cases for deep freeze behavior (high/low side interactions, clearing flags, etc.) are maintained in the C++ implementation and don't need to be duplicated in the JavaScript implementation.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/mptokenAuthorize.test.ts:29-118
Timestamp: 2024-12-06T19:25:15.376Z
Learning: In the XRPLF/xrpl.js TypeScript client library, when writing tests (e.g., in `packages/xrpl/test/integration/transactions/`), we generally do not need to test rippled server behaviors, because those behaviors are covered by rippled's own integration and unit tests.
packages/xrpl/test/integration/transactions/permissionedDEX.test.ts (8)
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: The rippled C++ implementation (PR #5161) includes comprehensive test coverage for PermissionedDomain (XLS-80d) error cases. The JS SDK tests focus on the happy path since the error cases are already validated at the rippled level, following the principle of not duplicating complex validation testing across SDK implementations.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/mptokenAuthorize.test.ts:29-118
Timestamp: 2024-12-06T19:25:15.376Z
Learning: In the XRPLF/xrpl.js TypeScript client library, when writing tests (e.g., in `packages/xrpl/test/integration/transactions/`), we generally do not need to test rippled server behaviors, because those behaviors are covered by rippled's own integration and unit tests.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2874
File: packages/xrpl/test/integration/transactions/permissionedDomain.test.ts:25-80
Timestamp: 2025-01-08T02:12:28.489Z
Learning: For PermissionedDomain feature (XLS-80d), complex error cases like invalid credential format, duplicate credentials, and non-existent DomainID are tested in the rippled C++ implementation rather than being duplicated across SDK implementations like xrpl.js.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/models/MPTokenAuthorize.test.ts:60-71
Timestamp: 2024-12-06T18:44:55.095Z
Learning: In the XRPL.js library's TypeScript test file `packages/xrpl/test/models/MPTokenAuthorize.test.ts`, negative test cases for invalid `Account` address format, invalid `Holder` address format, invalid `MPTokenIssuanceID` format, and invalid flag combinations are not necessary.
Learnt from: shawnxie999
PR: XRPLF/xrpl.js#2661
File: packages/xrpl/test/integration/transactions/clawback.test.ts:165-178
Timestamp: 2024-12-06T19:27:11.147Z
Learning: In the integration tests for `clawback.test.ts`, it's acceptable to use `@ts-expect-error` to bypass type checking when verifying ledger entries, and no additional type safety improvements are needed.
Learnt from: ckeshava
PR: XRPLF/xrpl.js#2873
File: packages/xrpl/test/integration/transactions/trustSet.test.ts:0-0
Timestamp: 2025-01-31T17:46:25.375Z
Learning: For the XRPL implementation, extensive test cases for deep freeze behavior (high/low side interactions, clearing flags, etc.) are maintained in the C++ implementation and don't need to be duplicated in the JavaScript implementation.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2801
File: packages/xrpl/test/models/Batch.test.ts:0-0
Timestamp: 2025-04-16T15:22:45.633Z
Learning: Using `as any` type assertions is acceptable in test files for the XRPL.js project, as strict typing is not required for test code.
Learnt from: mvadari
PR: XRPLF/xrpl.js#2895
File: packages/xrpl/test/models/clawback.test.ts:0-0
Timestamp: 2025-02-12T23:28:55.377Z
Learning: The `validate` function in xrpl.js is synchronous and should be tested using `assert.doesNotThrow` rather than async assertions.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: browser (22.x)
  • GitHub Check: unit (20.x)
  • GitHub Check: unit (22.x)
  • GitHub Check: integration (20.x)
  • GitHub Check: integration (22.x)
  • GitHub Check: build-and-lint (22.x)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (2)
packages/xrpl/test/integration/transactions/permissionedDEX.test.ts (2)

221-240: Validate Offer ledger object properties are comprehensive.

The test correctly validates the basic properties of the Offer ledger object. The assertions for LedgerEntryType, DomainID, and Account are appropriate, and checking for the presence of AdditionalBooks is important for hybrid offers.


299-323: Subscription test validation is appropriate for the scope.

The test correctly validates that the domain parameter is accepted by the subscribe command. The comment explaining why the response content validation is skipped is helpful and aligns with the principle of not duplicating server behavior tests.

ckeshava and others added 11 commits July 11, 2025 16:00
Co-authored-by: Omar Khan <khancodegt@gmail.com>
Co-authored-by: Omar Khan <khancodegt@gmail.com>
Co-authored-by: Omar Khan <khancodegt@gmail.com>
Co-authored-by: Omar Khan <khancodegt@gmail.com>
Co-authored-by: Omar Khan <khancodegt@gmail.com>
Co-authored-by: Omar Khan <khancodegt@gmail.com>
Co-authored-by: Omar Khan <khancodegt@gmail.com>
Co-authored-by: Omar Khan <khancodegt@gmail.com>
@ckeshava ckeshava requested a review from khancode July 11, 2025 23:27
@ckeshava ckeshava requested a review from khancode July 15, 2025 17:31
Copy link
Contributor

@khancode khancode left a comment

Choose a reason for hiding this comment

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

One small comment to address then LGTM!

})

if (
tx.DomainID === undefined &&
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
tx.DomainID === undefined &&
tx.DomainID != null &&

It's better to use this which covers both null and undefined values.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hello Omar, I'm not sure if the != null condition is equivalent to === undefined. I incorporated your suggestion, however it causes these unit test failures: https://github.com/XRPLF/xrpl.js/actions/runs/16324764374/job/46111811992?pr=3032#step:8:551

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

image

As shown here in the Node.js interpreter, '' != null // true. An empty tx.DomainID is not evaluated truthy, in comparison with null.

I haven't looked at the internals of Javascript to be able to show the specification. I suspect it has to do with type-fiddling in == operator versus the type+value comparison in === operator.

I'll not accept your suggestion for this PR. If you come across any disparity in my observations, let me know. I can create a fix PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

@ckeshava oh, my mistake. I meant to write == null. This will cover both undefined and null values. Otherwise null === undefined resolves to false which is invalid.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

null === undefined resolves to false because of the difference in the operands' types. However, why is that pertinent to our circumstance?

Do you have a unit-test in mind which could slip through the cracks? I don't understand where null adds more value to the validation process, over using undefined.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The xrpl.js client library appears to have a higher number of === undefined (49 results) as compared against === null (4 results).

I prefer the === over the == for the more stringent comparison.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@mvadari says who?

Agreed with @khancode, == null is best practice - can we fix this?

As per MDN docs, undefined == null // true. I can update the code to use == (which performs implicit type conversion). This should placate your concerns.

However, I'm not convinced that validating against null is better than undefined.

Copy link
Collaborator

@mvadari mvadari Jul 21, 2025

Choose a reason for hiding this comment

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

The xrpl.js client library appears to have a higher number of === undefined (49 results) as compared against === null (4 results).

There are 107 results for == null. Most of the === undefined usages will be removed in #2895.

I prefer the === over the == for the more stringent comparison.

In this case, the less stringent requirements are better, because it'll cover additional cases, like null and NaN.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Alright, I have added the == null check in this fix-PR.

As per my understanding of the docs, both operand == null and operand == undefined perform identical functionality. Since the type of the operand is irrelevant, both of them evaluate to false. I don't see why you would prefer null over undefined.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's just the norm to use == null instead of == undefined. My guess is that it's because it's clearer

@ckeshava ckeshava merged commit a504482 into XRPLF:main Jul 16, 2025
13 checks passed
@ckeshava
Copy link
Collaborator Author

Thank you all the reviewers for your feedback!

* @returns true if the domainID is a valid 64-character string, false otherwise
*/
export function isDomainID(domainID: unknown): domainID is string {
return isString(domainID) && domainID.length === _DOMAIN_ID_LENGTH
Copy link
Contributor

Choose a reason for hiding this comment

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

We should add a hexadecimal check here too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have addressed your concern with code-rabbit: #3032 (comment)

ckeshava added a commit to ripple/explorer that referenced this pull request Jul 25, 2025
This PR implements support for the [Permissioned DEX
(XLS-81D)](https://github.com/XRPLF/XRPL-Standards/blob/56ba122be9f127c940fd37d433faaa2de91a4eb6/XLS-0081d-permissioned-dex/README.md).
The rippled C++ PR can be [found
here](https://github.com/XRPLF/rippled/pull/5404/files). This is [the
relevant PR](XRPLF/xrpl.js#3032) for xrpl.js
client library.
heap-coder added a commit to heap-coder/explorer that referenced this pull request Sep 27, 2025
This PR implements support for the [Permissioned DEX
(XLS-81D)](https://github.com/XRPLF/XRPL-Standards/blob/56ba122be9f127c940fd37d433faaa2de91a4eb6/XLS-0081d-permissioned-dex/README.md).
The rippled C++ PR can be [found
here](https://github.com/XRPLF/rippled/pull/5404/files). This is [the
relevant PR](XRPLF/xrpl.js#3032) for xrpl.js
client library.
pdp2121 pushed a commit to ripple/explorer that referenced this pull request Oct 8, 2025
This PR implements support for the [Permissioned DEX
(XLS-81D)](https://github.com/XRPLF/XRPL-Standards/blob/56ba122be9f127c940fd37d433faaa2de91a4eb6/XLS-0081d-permissioned-dex/README.md).
The rippled C++ PR can be [found
here](https://github.com/XRPLF/rippled/pull/5404/files). This is [the
relevant PR](XRPLF/xrpl.js#3032) for xrpl.js
client library.
pdp2121 pushed a commit to ripple/explorer that referenced this pull request Oct 8, 2025
This PR implements support for the [Permissioned DEX
(XLS-81D)](https://github.com/XRPLF/XRPL-Standards/blob/56ba122be9f127c940fd37d433faaa2de91a4eb6/XLS-0081d-permissioned-dex/README.md).
The rippled C++ PR can be [found
here](https://github.com/XRPLF/rippled/pull/5404/files). This is [the
relevant PR](XRPLF/xrpl.js#3032) for xrpl.js
client library.
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.

5 participants