Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0681e0a
models and integration tests for Dynamic MPTs (XLS-94D)
ckeshava Sep 15, 2025
ad316b7
unit tests suggested by rabbit
ckeshava Sep 16, 2025
fd1513d
fix linter errors
ckeshava Sep 16, 2025
2a56be3
Merge branch 'main' into xls-94d
ckeshava Sep 16, 2025
29b8e80
Merge branch 'main' into xls-94d
ckeshava Sep 16, 2025
058ad5b
updated flages in Dynamic MPT amendment to use tmf and lmf prefixes
ckeshava Sep 22, 2025
1e0aaa0
add Github Actions step to inspect Docker containter
ckeshava Sep 22, 2025
fc51d7e
helpful message in Github Actions output
ckeshava Sep 22, 2025
b792695
reorder the conditions
ckeshava Sep 22, 2025
7e2e712
Github Actions: include docker-inspect command to investigate the con…
ckeshava Sep 22, 2025
0876e86
Merge branch 'main' into xls-94d
ckeshava Sep 25, 2025
0e07910
Merge branch 'main' into xls-94d
ckeshava Sep 29, 2025
02d4a96
simplify Github Actions steps
ckeshava Sep 29, 2025
d6ec04a
fix: rectify the syntax error in bash script
ckeshava Sep 29, 2025
bda0c2e
additional comments for MPToken transaction flags
ckeshava Sep 30, 2025
cbdcbc3
Additional validation on sfMutableFlags field for MPTokenIssuance(Cre…
ckeshava Sep 30, 2025
565402b
Rename ledger flags corresponding to rippled commit: 8e4fda160d9fb66d…
ckeshava Sep 30, 2025
747bfd2
Merge branch 'main' into xls-94d
ckeshava Oct 6, 2025
ce16616
address Phu comment: Introduce distinct MutableFlags interface
ckeshava Oct 6, 2025
42049ac
address Phu comment: refactor MutableFlags in MPTokenIssuanceSet tran…
ckeshava Oct 6, 2025
13f9ec9
Additional validations+tests for MPTokenIssuanceCreate transaction
ckeshava Oct 7, 2025
7260f2f
Additional validations and tests for MPTokenIssuanceSet txn
ckeshava Oct 7, 2025
0f3ae2f
Merge branch 'main' into xls-94d
ckeshava Oct 16, 2025
9a6c46c
feat: Add MPT Metadata validation check in MPTokenIssuanceSet transac…
ckeshava Oct 17, 2025
4a3a978
add docstring for mutable flags field
ckeshava Oct 30, 2025
0c228cd
[docs] add docstring to explain the stature of DomainID in MPTokenIss…
ckeshava Oct 30, 2025
020b895
Merge branch 'main' into xls-94d
ckeshava Oct 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .ci-config/rippled.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ Batch
PermissionedDEX
TokenEscrow
SingleAssetVault
DynamicMPT

# This section can be used to simulate various FeeSettings scenarios for rippled node in standalone mode
[voting]
Expand Down
34 changes: 32 additions & 2 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,11 @@ jobs:
fetch-depth: 0

- name: Run docker in background
id: run-docker
run: |
docker run --detach --rm -p 6006:6006 --volume "${{ github.workspace }}/.ci-config/":"/etc/opt/ripple/" --name rippled-service --health-cmd="rippled server_info || exit 1" --health-interval=5s --health-retries=10 --health-timeout=2s --env GITHUB_ACTIONS=true --env CI=true --entrypoint bash ${{ env.RIPPLED_DOCKER_IMAGE }} -c "rippled -a"
CONTAINER_ID=$(docker ps -aqf "name=rippled-service")
echo "docker-container-id=$CONTAINER_ID" >> $GITHUB_OUTPUT

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
Expand Down Expand Up @@ -154,11 +157,23 @@ jobs:

- run: npm run build

- name: Check if Docker container is running
id: check-docker-container
run: |
if ! docker ps | grep -q rippled-service; then
echo "rippled-service Docker container is not running"
echo "docker-container-running=false" >> $GITHUB_OUTPUT
else
echo "docker-container-running=true" >> $GITHUB_OUTPUT
fi
docker inspect ${{ steps.run-docker.outputs.docker-container-id }}

- name: Run integration test
if: steps.check-docker-container.outputs.docker-container-running == 'true'
run: npm run test:integration

- name: Stop docker container
if: always()
if: steps.check-docker-container.outputs.docker-container-running == 'true'
run: docker stop rippled-service

browser:
Expand All @@ -181,8 +196,11 @@ jobs:
node-version: ${{ matrix.node-version }}

- name: Run docker in background
id: run-docker
run: |
docker run --detach --rm -p 6006:6006 --volume "${{ github.workspace }}/.ci-config/":"/etc/opt/ripple/" --name rippled-service --health-cmd="rippled server_info || exit 1" --health-interval=5s --health-retries=10 --health-timeout=2s --env GITHUB_ACTIONS=true --env CI=true --entrypoint bash ${{ env.RIPPLED_DOCKER_IMAGE }} -c "rippled -a"
CONTAINER_ID=$(docker ps -aqf "name=rippled-service")
echo "docker-container-id=$CONTAINER_ID" >> $GITHUB_OUTPUT

- name: Setup npm version 10
run: |
Expand All @@ -208,11 +226,23 @@ jobs:

- run: npm run build

- name: Check if Docker container is running
id: check-docker-container
run: |
if ! docker ps | grep -q rippled-service; then
echo "rippled-service Docker container is not running"
echo "docker-container-running=false" >> $GITHUB_OUTPUT
else
echo "docker-container-running=true" >> $GITHUB_OUTPUT
fi
docker inspect ${{ steps.run-docker.outputs.docker-container-id }}

- name: Run integration test
if: steps.check-docker-container.outputs.docker-container-running == 'true'
run: npm run test:browser

- name: Stop docker container
if: always()
if: steps.check-docker-container.outputs.docker-container-running == 'true'
run: docker stop rippled-service

generate-documentation:
Expand Down
10 changes: 10 additions & 0 deletions packages/ripple-binary-codec/src/enums/definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,16 @@
"type": "UInt32"
}
],
[
"MutableFlags",
{
"isSerialized": true,
"isSigningField": true,
"isVLEncoded": false,
"nth": 53,
"type": "UInt32"
}
],
[
"IndexNext",
{
Expand Down
3 changes: 3 additions & 0 deletions packages/xrpl/HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xr

## Unreleased

### Added
* Support for `Dynamic MPT` (XLS-94D)

## 4.4.1 (2025-08-29)

### Fixed
Expand Down
2 changes: 2 additions & 0 deletions packages/xrpl/src/models/ledger/LedgerEntry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import DirectoryNode from './DirectoryNode'
import Escrow from './Escrow'
import FeeSettings from './FeeSettings'
import LedgerHashes from './LedgerHashes'
import { MPTokenIssuance } from './MPTokenIssuance'
import NegativeUNL from './NegativeUNL'
import Offer from './Offer'
import Oracle from './Oracle'
Expand Down Expand Up @@ -46,6 +47,7 @@ type LedgerEntry =
| Vault
| XChainOwnedClaimID
| XChainOwnedCreateAccountClaimID
| MPTokenIssuance

type LedgerEntryFilter =
| 'account'
Expand Down
88 changes: 88 additions & 0 deletions packages/xrpl/src/models/ledger/MPTokenIssuance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,92 @@ export interface MPTokenIssuance extends BaseLedgerEntry, HasPreviousTxnID {
MPTokenMetadata?: string
OwnerNode?: string
LockedAmount?: string
DomainID?: string
MutableFlags: number
}

export interface MPTokenIssuanceFlagsInterface {
lsfMPTLocked?: boolean
lsfMPTCanLock?: boolean
lsfMPTRequireAuth?: boolean
lsfMPTCanEscrow?: boolean
lsfMPTCanTrade?: boolean
lsfMPTCanTransfer?: boolean
lsfMPTCanClawback?: boolean

/**
* Indicates flag lsfMPTCanLock can be changed
*/
lmfMPTCanMutateCanLock?: boolean
/**
* Indicates flag lsfMPTRequireAuth can be changed
*/
lmfMPTCanMutateRequireAuth?: boolean
/**
* Indicates flag lsfMPTCanEscrow can be changed
*/
lmfMPTCanMutateCanEscrow?: boolean
/**
* Indicates flag lsfMPTCanTrade can be changed
*/
lmfMPTCanMutateCanTrade?: boolean
/**
* Indicates flag lsfMPTCanTransfer can be changed
*/
lmfMPTCanMutateCanTransfer?: boolean
/**
* Indicates flag lsfMPTCanClawback can be changed
*/
lmfMPTCanMutateCanClawback?: boolean
/**
* Allows field MPTokenMetadata to be modified
*/
lmfMPTCanMutateMetadata?: boolean
/**
* Allows field TransferFee to be modified
*/
lmfMPTCanMutateTransferFee?: boolean
}

export enum MPTokenIssuanceFlags {
lsfMPTLocked = 0x00000001,
lsfMPTCanLock = 0x00000002,
lsfMPTRequireAuth = 0x00000004,
lsfMPTCanEscrow = 0x00000008,
lsfMPTCanTrade = 0x00000010,
lsfMPTCanTransfer = 0x00000020,
lsfMPTCanClawback = 0x00000040,

/**
* Indicates flag lsfMPTCanLock can be changed
*/
lmfMPTCanMutateCanLock = 0x00000002,
/**
* Indicates flag lsfMPTRequireAuth can be changed
*/
lmfMPTCanMutateRequireAuth = 0x00000004,
/**
* Indicates flag lsfMPTCanEscrow can be changed
*/
lmfMPTCanMutateCanEscrow = 0x00000008,
/**
* Indicates flag lsfMPTCanTrade can be changed
*/
lmfMPTCanMutateCanTrade = 0x00000010,
/**
* Indicates flag lsfMPTCanTransfer can be changed
*/
lmfMPTCanMutateCanTransfer = 0x00000020,
/**
* Indicates flag lsfMPTCanClawback can be changed
*/
lmfMPTCanMutateCanClawback = 0x00000040,
/**
* Allows field MPTokenMetadata to be modified
*/
lmfMPTCanMutateMetadata = 0x00010000,
/**
* Allows field TransferFee to be modified
*/
lmfMPTCanMutateTransferFee = 0x00020000,
}
22 changes: 21 additions & 1 deletion packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type { TransactionMetadataBase } from './metadata'

// 2^63 - 1
const MAX_AMT = '9223372036854775807'
const MAX_TRANSFER_FEE = 50000
export const MAX_TRANSFER_FEE = 50000

/**
* Transaction Flags for an MPTokenIssuanceCreate Transaction.
Expand Down Expand Up @@ -53,6 +53,15 @@ export enum MPTokenIssuanceCreateFlags {
* to clawback value from individual holders.
*/
tfMPTCanClawback = 0x00000040,

tmfMPTCanMutateCanLock = 0x00000002,
tmfMPTCanMutateRequireAuth = 0x00000004,
tmfMPTCanMutateCanEscrow = 0x00000008,
tmfMPTCanMutateCanTrade = 0x00000010,
tmfMPTCanMutateCanTransfer = 0x00000020,
tmfMPTCanMutateCanClawback = 0x00000040,
tmfMPTCanMutateMetadata = 0x00010000,
tmfMPTCanMutateTransferFee = 0x00020000,
}

/**
Expand All @@ -69,6 +78,15 @@ export interface MPTokenIssuanceCreateFlagsInterface
tfMPTCanTrade?: boolean
tfMPTCanTransfer?: boolean
tfMPTCanClawback?: boolean

tmfMPTCanMutateCanLock?: boolean
Copy link
Collaborator

Choose a reason for hiding this comment

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

These flags are only available for MutableFlags field. Should it be separated into its own interface, similar to what we did with SetFlag options in AccountSet?

Copy link
Collaborator Author

@ckeshava ckeshava Sep 25, 2025

Choose a reason for hiding this comment

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

  1. The flags associated with Dynamic MPTs have tmf... in their prefix. This is used to indicate transaction-mutable-flag. This difference in names (tf... versus tmf...) should help users differentiate between the intent behind the flags.
  2. If we use a separate interface for these flags, it could potentially cause confusion. The xrpl.org documentation (and the rippled cpp code, other programming language clients) organize these flags under the MPTokenIssuanceCreate transaction's flags. This change would have been more impactful if it was done at the XLS level, instead of only xrpl.js deviating from the specification.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The xrpl.org documentation (and the rippled cpp code, other programming language clients) organize these flags under the MPTokenIssuanceCreate transaction's flags

Is the xrpl.org documentation updated already?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, the XLS specification is a good source of info for unreleased amendments. Usually, you can find the pre-release documentation for amendments on https://opensource.ripple.com/ as well, however LendingProtocol docs have not been published yet. You can look at pre-release docs for other amendments on that website.

Copy link
Collaborator

Choose a reason for hiding this comment

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

We were separating the flags that can be set with Flags and SetFlags for AccountSet transactions:
https://github.com/XRPLF/xrpl.js/blob/main/packages/xrpl/src/models/transactions/accountSet.ts
I think it's clearer that way, and also allows users to distinguish which flags they can set with Flags and MutableFlags. With this setup user can set a mutable flag with Flags field and there will be no warning, so I think it's more confusing

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@pdp2121 ok. I have introduced separate interface and enum for the Mutable Flags: ce16616

tmfMPTCanMutateRequireAuth?: boolean
tmfMPTCanMutateCanEscrow?: boolean
tmfMPTCanMutateCanTrade?: boolean
tmfMPTCanMutateCanTransfer?: boolean
tmfMPTCanMutateCanClawback?: boolean
tmfMPTCanMutateMetadata?: boolean
tmfMPTCanMutateTransferFee?: boolean
}

/**
Expand Down Expand Up @@ -120,6 +138,7 @@ export interface MPTokenIssuanceCreate extends BaseTransaction {
MPTokenMetadata?: string

Flags?: number | MPTokenIssuanceCreateFlagsInterface
Copy link
Collaborator

Choose a reason for hiding this comment

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

Flags cannot accept the mutable flags so the above change will be needed

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

code has been changed in ce16616

MutableFlags?: number
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you add docstring for this?

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 added a recent commit to fix this. However, I could not find the documentation for the domain_id field on the xrpl.org website ://

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Update: I have added a docstring for the DomainID field as well, based on my understanding of the topic. I could not find any other documentation to that effect. Commit: 0c228cd

}

export interface MPTokenIssuanceCreateMetadata extends TransactionMetadataBase {
Expand All @@ -141,6 +160,7 @@ export function validateMPTokenIssuanceCreate(
validateOptionalField(tx, 'MPTokenMetadata', isString)
validateOptionalField(tx, 'TransferFee', isNumber)
validateOptionalField(tx, 'AssetScale', isNumber)
validateOptionalField(tx, 'MutableFlags', isNumber)

if (
typeof tx.MPTokenMetadata === 'string' &&
Expand Down
Loading
Loading