Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
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
*/
lsfMPTCanMutateCanLock?: boolean
/**
* Indicates flag lsfMPTRequireAuth can be changed
*/
lsfMPTCanMutateRequireAuth?: boolean
/**
* Indicates flag lsfMPTCanEscrow can be changed
*/
lsfMPTCanMutateCanEscrow?: boolean
/**
* Indicates flag lsfMPTCanTrade can be changed
*/
lsfMPTCanMutateCanTrade?: boolean
/**
* Indicates flag lsfMPTCanTransfer can be changed
*/
lsfMPTCanMutateCanTransfer?: boolean
/**
* Indicates flag lsfMPTCanClawback can be changed
*/
lsfMPTCanMutateCanClawback?: boolean
/**
* Allows field MPTokenMetadata to be modified
*/
lsfMPTCanMutateMetadata?: boolean
/**
* Allows field TransferFee to be modified
*/
lsfMPTCanMutateTransferFee?: boolean
}

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

/**
* Indicates flag lsfMPTCanLock can be changed
*/
lsfMPTCanMutateCanLock = 0x00000002,
/**
* Indicates flag lsfMPTRequireAuth can be changed
*/
lsfMPTCanMutateRequireAuth = 0x00000004,
/**
* Indicates flag lsfMPTCanEscrow can be changed
*/
lsfMPTCanMutateCanEscrow = 0x00000008,
/**
* Indicates flag lsfMPTCanTrade can be changed
*/
lsfMPTCanMutateCanTrade = 0x00000010,
/**
* Indicates flag lsfMPTCanTransfer can be changed
*/
lsfMPTCanMutateCanTransfer = 0x00000020,
/**
* Indicates flag lsfMPTCanClawback can be changed
*/
lsfMPTCanMutateCanClawback = 0x00000040,
/**
* Allows field MPTokenMetadata to be modified
*/
lsfMPTCanMutateMetadata = 0x00010000,
/**
* Allows field TransferFee to be modified
*/
lsfMPTCanMutateTransferFee = 0x00020000,
}
19 changes: 19 additions & 0 deletions packages/xrpl/src/models/transactions/MPTokenIssuanceCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ export enum MPTokenIssuanceCreateFlags {
* to clawback value from individual holders.
*/
tfMPTCanClawback = 0x00000040,

tfMPTCanMutateCanLock = 0x00000002,
tfMPTCanMutateRequireAuth = 0x00000004,
tfMPTCanMutateCanEscrow = 0x00000008,
tfMPTCanMutateCanTrade = 0x00000010,
tfMPTCanMutateCanTransfer = 0x00000020,
tfMPTCanMutateCanClawback = 0x00000040,
tfMPTCanMutateMetadata = 0x00010000,
tfMPTCanMutateTransferFee = 0x00020000,
}

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

tfMPTCanMutateCanLock?: boolean
tfMPTCanMutateRequireAuth?: boolean
tfMPTCanMutateCanEscrow?: boolean
tfMPTCanMutateCanTrade?: boolean
tfMPTCanMutateCanTransfer?: boolean
tfMPTCanMutateCanClawback?: boolean
tfMPTCanMutateMetadata?: boolean
tfMPTCanMutateTransferFee?: 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 Down
102 changes: 102 additions & 0 deletions packages/xrpl/src/models/transactions/MPTokenIssuanceSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,55 @@ export enum MPTokenIssuanceSetFlags {
* If set, indicates that issuer unlocks the MPT
*/
tfMPTUnlock = 0x00000002,
// The below flags are used in the MutableFlags field
/*
** Sets the lsfMPTCanLock flag. Enables the token to be locked both individually and globally.
*/
tfMPTSetCanLock = 0x00000001,
/*
** Clears the lsfMPTCanLock flag. Disables both individual and global locking of the token.
*/
tfMPTClearCanLock = 0x00000002,
/*
** Sets the lsfMPTRequireAuth flag. Requires individual holders to be authorized.
*/
tfMPTSetRequireAuth = 0x00000004,
/*
** Clears the lsfMPTRequireAuth flag. Holders are not required to be authorized.
*/
tfMPTClearRequireAuth = 0x00000008,
/*
** Sets the lsfMPTCanEscrow flag. Allows holders to place balances into escrow.
*/
tfMPTSetCanEscrow = 0x00000010,
/*
** Clears the lsfMPTCanEscrow flag. Disallows holders from placing balances into escrow.
*/
tfMPTClearCanEscrow = 0x00000020,
/*
** Sets the lsfMPTCanTrade flag. Allows holders to trade balances on the XRPL DEX.
*/
tfMPTSetCanTrade = 0x00000040,
/*
** Clears the lsfMPTCanTrade flag. Disallows holders from trading balances on the XRPL DEX.
*/
tfMPTClearCanTrade = 0x00000080,
/*
** Sets the lsfMPTCanTransfer flag. Allows tokens to be transferred to non-issuer accounts.
*/
tfMPTSetCanTransfer = 0x00000100,
/*
** Clears the lsfMPTCanTransfer flag. Disallows transfers to non-issuer accounts.
*/
tfMPTClearCanTransfer = 0x00000200,
/*
** Sets the lsfMPTCanClawback flag. Enables the issuer to claw back tokens via Clawback or AMMClawback transactions.
*/
tfMPTSetCanClawback = 0x00000400,
/*
** Clears the lsfMPTCanClawback flag. The token can not be clawed back.
*/
tfMPTClearCanClawback = 0x00000800,
}

/**
Expand All @@ -37,6 +86,55 @@ export enum MPTokenIssuanceSetFlags {
export interface MPTokenIssuanceSetFlagsInterface extends GlobalFlagsInterface {
tfMPTLock?: boolean
tfMPTUnlock?: boolean
// The below flags are used in the MutableFlags field
Copy link
Collaborator

Choose a reason for hiding this comment

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

ditto

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

updated in 42049ac

/*
** Sets the lsfMPTCanLock flag. Enables the token to be locked both individually and globally.
*/
tfMPTSetCanLock?: boolean
/*
** Clears the lsfMPTCanLock flag. Disables both individual and global locking of the token.
*/
tfMPTClearCanLock?: boolean
/*
** Sets the lsfMPTRequireAuth flag. Requires individual holders to be authorized.
*/
tfMPTSetRequireAuth?: boolean
/*
** Clears the lsfMPTRequireAuth flag. Holders are not required to be authorized.
*/
tfMPTClearRequireAuth?: boolean
/*
** Sets the lsfMPTCanEscrow flag. Allows holders to place balances into escrow.
*/
tfMPTSetCanEscrow?: boolean
/*
** Clears the lsfMPTCanEscrow flag. Disallows holders from placing balances into escrow.
*/
tfMPTClearCanEscrow?: boolean
/*
** Sets the lsfMPTCanTrade flag. Allows holders to trade balances on the XRPL DEX.
*/
tfMPTSetCanTrade?: boolean
/*
** Clears the lsfMPTCanTrade flag. Disallows holders from trading balances on the XRPL DEX.
*/
tfMPTClearCanTrade?: boolean
/*
** Sets the lsfMPTCanTransfer flag. Allows tokens to be transferred to non-issuer accounts.
*/
tfMPTSetCanTransfer?: boolean
/*
** Clears the lsfMPTCanTransfer flag. Disallows transfers to non-issuer accounts.
*/
tfMPTClearCanTransfer?: boolean
/*
** Sets the lsfMPTCanClawback flag. Enables the issuer to claw back tokens via Clawback or AMMClawback transactions.
*/
tfMPTSetCanClawback?: boolean
/*
** Clears the lsfMPTCanClawback flag. The token can not be clawed back.
*/
tfMPTClearCanClawback?: boolean
}

/**
Expand All @@ -55,6 +153,10 @@ export interface MPTokenIssuanceSet extends BaseTransaction {
*/
Holder?: Account
Flags?: number | MPTokenIssuanceSetFlagsInterface

MPTokenMetadata?: string
TransferFee?: number
MutableFlags?: number
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,65 @@ describe('MPTokenIssuanceDestroy', function () {
},
TIMEOUT,
)

it(
'Test Mutability of Flags as per Dynamic MPT (XLS-94D) amendment',
async () => {
const createTx: MPTokenIssuanceCreate = {
TransactionType: 'MPTokenIssuanceCreate',
Account: testContext.wallet.classicAddress,
Flags: MPTokenIssuanceCreateFlags.tfMPTCanTransfer,
MutableFlags:
MPTokenIssuanceCreateFlags.tfMPTCanMutateTransferFee +
MPTokenIssuanceCreateFlags.tfMPTCanMutateCanTransfer,
}

const mptCreateRes = await testTransaction(
testContext.client,
createTx,
testContext.wallet,
)

const txHash = mptCreateRes.result.tx_json.hash

const txResponse = await testContext.client.request({
command: 'tx',
transaction: txHash,
})

const meta = txResponse.result
.meta as TransactionMetadata<MPTokenIssuanceCreate>

const mptID = meta.mpt_issuance_id

const setTransferFeeTx: MPTokenIssuanceSet = {
TransactionType: 'MPTokenIssuanceSet',
Account: testContext.wallet.classicAddress,
MPTokenIssuanceID: mptID!,
// set the transfer fee to a non-zero value
TransferFee: 200,
}

await testTransaction(
testContext.client,
setTransferFeeTx,
testContext.wallet,
)

// remove the ability to transfer the MPT
const clearTransferFlagTx: MPTokenIssuanceSet = {
TransactionType: 'MPTokenIssuanceSet',
Account: testContext.wallet.classicAddress,
MPTokenIssuanceID: mptID!,
MutableFlags: MPTokenIssuanceSetFlags.tfMPTClearCanTransfer,
}

await testTransaction(
testContext.client,
clearTransferFlagTx,
testContext.wallet,
)
},
TIMEOUT,
)
})
1 change: 1 addition & 0 deletions packages/xrpl/test/models/MPTokenIssuanceCreate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('MPTokenIssuanceCreate', function () {
AssetScale: 2,
TransferFee: 1,
Flags: MPTokenIssuanceCreateFlags.tfMPTCanTransfer,
MutableFlags: MPTokenIssuanceCreateFlags.tfMPTCanMutateTransferFee,
MPTokenMetadata: stringToHex(`{
"ticker": "TBILL",
"name": "T-Bill Yield Token",
Expand Down
7 changes: 7 additions & 0 deletions packages/xrpl/test/models/MPTokenIssuanceSet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ describe('MPTokenIssuanceSet', function () {
} as any

assertValid(validMPTokenIssuanceSet)

assertValid({
TransactionType: 'MPTokenIssuanceSet',
Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm',
MPTokenIssuanceID: TOKEN_ID,
MutableFlags: MPTokenIssuanceSetFlags.tfMPTClearCanTransfer,
} as any)
})

it(`throws w/ missing MPTokenIssuanceID`, function () {
Expand Down
Loading