MPTokenIssuance Fields & Flags Analysis for TapMint
Analysis Date
2024-01-XX
Overview
This document analyzes how we address each MPTokenIssuance field and flag in our TapMint process, and provides recommendations for fields we're not currently using.
MPTokenIssuance Fields
✅ Issuer (Required)
Status: ✅ IMPLEMENTED
- Our Implementation:
Account: vaultWallet.address - Location:
src/server/api/root.ts:2116 - Details: We use the vault wallet as the issuer for all TapMint tokens
- Recommendation: ✅ Correct - This is the right approach for centralized minting
⚠️ AssetScale (Required, Default: 0)
Status: ⚠️ NOT EXPLICITLY SET (Uses Default)
- Our Implementation: Not set, defaults to 0
- Current Behavior: Tokens cannot be subdivided (1 unit = 1 token)
- Recommendation:
- ✅ Keep default (0) for TapMint - These are 1/1 master tokens, no subdivision needed
- ⚠️ Consider documenting this - Add comment explaining why we use default
- 💡 Future consideration: If we ever mint fractional tokens, we'd need to set this (e.g., 2 for cents, 6 for micro-units)
✅ MaximumAmount (Optional)
Status: ✅ IMPLEMENTED
- Our Implementation:
MaximumAmount: "1" - Location:
src/server/api/root.ts:2117 - Details: We cap each issuance at 1 token (1/1 master token)
- Recommendation: ✅ Correct - Perfect for unique NFT-like tokens
ℹ️ OutstandingAmount (Required, Auto-managed)
Status: ℹ️ AUTO-MANAGED BY XRPL
- Our Implementation: Not set manually, managed by XRPL
- Details: XRPL automatically tracks this as tokens are issued/transferred
- Recommendation: ✅ No action needed - XRPL handles this automatically
ℹ️ LockedAmount (Optional, Auto-managed)
Status: ℹ️ AUTO-MANAGED BY XRPL (Requires TokenEscrow Amendment)
- Our Implementation: Not set manually, managed by XRPL
- Details:
- Currently tracked automatically when tokens are in escrow
- TokenEscrow amendment is "Open for Voting: 38.24%" (not yet active)
- Recommendation:
- ✅ No action needed - XRPL handles this automatically
- 💡 Future consideration: Once TokenEscrow amendment passes, this will be more relevant
✅ TransferFee (Required, Default: 0)
Status: ✅ IMPLEMENTED
- Our Implementation:
TransferFee: 0 - Location:
src/server/api/root.ts:2119 - Details:
- We set transfer fee to 0 (no fee on secondary sales)
- Valid range: 0-50,000 (0% to 50%)
- Value is in tenths of a basis point (1 = 0.001%)
- Recommendation:
- ✅ Keep at 0 for TapMint - These are user-owned tokens, no fee needed
- 💡 Future consideration: If we want to monetize secondary sales, we could set a fee (e.g., 100 = 0.01%, 1000 = 0.1%)
✅ MPTokenMetadata (Required, Max 1024 bytes)
Status: ✅ IMPLEMENTED
- Our Implementation:
MPTokenMetadata: convertStringToHex(JSON.stringify(onChainMetadata))- Limited to 8 top-level fields for XLS-89d compliance
- Location:
src/server/api/root.ts:2072
- Current Fields (8 total):
ticker(t) - Required - Uppercase, max 6 chars, A-Z and 0-9 onlyname(n) - Required - Display name from metadata or asset_nameicon(i) - Required - URI to token iconasset_class(ac) - Required -"gaming"for Mintlings,"rwa"for CardLayer/LegacyLayer,"other"for LayerLockissuer_name(in) - Required - App name (Mintlings, CardLayer, LegacyLayer, LayerApp)uris(us) - Optional - Array with view page URL:["https://liquiditylayer.io/view/${uuid}"]desc(d) - Optional - Description:"Protected by LayerLock"additional_info(ai) - Optional - Object:{ "nfc_uuid": "..." }
- Removed Fields:
minted_via- Removed (not needed on-chain)minted_at- Removed (not needed on-chain)image- Removed (redundant withicon)nfc_uuid- Moved toadditional_infoobject
- Recommendation: ✅ Correct - We're compliant with XLS-89d standard, using 8/9 available fields
ℹ️ OwnerNode (Required, Auto-managed)
Status: ℹ️ AUTO-MANAGED BY XRPL
- Our Implementation: Not set manually, managed by XRPL
- Details: XRPL automatically sets this for directory pagination
- Recommendation: ✅ No action needed - XRPL handles this automatically
ℹ️ PreviousTxnID (Required, Auto-managed)
Status: ℹ️ AUTO-MANAGED BY XRPL
- Our Implementation: Not set manually, managed by XRPL
- Details: XRPL automatically tracks the last transaction that modified this entry
- Recommendation: ✅ No action needed - XRPL handles this automatically
ℹ️ PreviousTxnLgrSeq (Required, Auto-managed)
Status: ℹ️ AUTO-MANAGED BY XRPL
- Our Implementation: Not set manually, managed by XRPL
- Details: XRPL automatically tracks the ledger sequence of the last modification
- Recommendation: ✅ No action needed - XRPL handles this automatically
ℹ️ Sequence (Required, Auto-managed)
Status: ℹ️ AUTO-MANAGED BY XRPL
- Our Implementation: Not set manually, managed by XRPL
- Details: XRPL automatically uses the transaction sequence number
- Recommendation: ✅ No action needed - XRPL handles this automatically
MPTokenIssuance Flags
❌ lsfMPTLocked (0x00000001 = 1)
Status: ❌ NOT USED
- Description: If set, indicates that all balances are locked
- Our Implementation: Not set
- Recommendation:
- ❌ Don't use for TapMint - This would lock all tokens, preventing transfers
- 💡 Use case: Only for emergency situations or regulatory compliance
❌ lsfMPTCanLock (0x00000002 = 2)
Status: ❌ NOT USED
- Description: If set, indicates that the issuer can lock an individual balance or all balances
- Our Implementation: Not set
- Recommendation:
- ❌ Don't use for TapMint - Users own their tokens, we shouldn't be able to lock them
- 💡 Use case: For regulatory compliance or fraud prevention (but not appropriate for user-owned tokens)
❌ lsfMPTRequireAuth (0x00000004 = 4)
Status: ❌ NOT USED
- Description: If set, indicates that individual holders must be authorized
- Our Implementation: Not set
- Current Behavior: Tokens can be held by any account without authorization
- Recommendation:
- ⚠️ Consider using this - Would require authorization before receiving tokens
- Pros:
- Prevents unauthorized accounts from receiving tokens
- Better control over token distribution
- Can enable/disable specific accounts
- Cons:
- Adds complexity (requires MPTokenAuthorize transaction)
- Currently we authorize escrow wallet, but not end users
- 💡 Recommendation:
- For TapMint: ❌ Don't use - Users should be able to receive tokens freely
- For future use cases: ✅ Consider - If we want to whitelist specific accounts
✅ lsfMPTCanEscrow (0x00000008 = 8)
Status: ✅ FIXED
- Description: If set, indicates that individual holders can place their balances into an escrow
- Our Implementation: We use
Flags: 32 | 16 | 8 - Fix Applied: Changed from
64to8to match official documentation - Current Behavior:
- Using correct flag value
8for CanEscrow - Escrow functionality should now work correctly
- Using correct flag value
- Recommendation: ✅ Correct - Now using the correct flag value per official docs
✅ lsfMPTCanTrade (0x00000010 = 16)
Status: ✅ IMPLEMENTED
- Description: If set, indicates that individual holders can trade their balances using the XRP Ledger DEX or AMM
- Our Implementation:
Flags: 32 | 16 | 64(we use16) - Location:
src/server/api/root.ts:2120 - Recommendation: ✅ Correct - Allows trading on DEX/AMM
✅ lsfMPTCanTransfer (0x00000020 = 32)
Status: ✅ IMPLEMENTED
- Description: If set, indicates that tokens held by non-issuers can be transferred to other accounts
- Our Implementation:
Flags: 32 | 16 | 64(we use32) - Location:
src/server/api/root.ts:2120 - Recommendation: ✅ Correct - Essential for user-owned tokens
❌ lsfMPTCanClawback (0x00000040 = 64)
Status: ✅ FIXED - NOT ENABLED
- Description: If set, indicates that the issuer may use the Clawback transaction to claw back value from individual holders
- Our Implementation: We do NOT use this flag (correctly disabled)
- Fix Applied: Removed
64from flags, now using8for CanEscrow instead - Current Behavior:
- Clawback is NOT enabled (correct behavior)
- Users own their tokens, issuer cannot take them back
- Recommendation: ✅ Correct - We intentionally don't enable clawback for user-owned tokens
Summary of Issues Found
✅ Fixed Issues
- Flag value corrected: Changed CanEscrow from
64to8to match official documentation- Fix Applied: Changed
Flags: 32 | 16 | 64toFlags: 32 | 16 | 8 - Impact:
- CanEscrow now uses correct flag value (8)
- CanClawback is no longer accidentally enabled
- Escrow functionality should now work correctly
- Location:
src/server/api/root.ts:2122(TapMint) andsrc/server/api/root.ts:358(Playground)
- Fix Applied: Changed
⚠️ Minor Issues
- AssetScale not documented: We use default (0) but don't explain why
- Fix: Add comment explaining this is intentional for 1/1 tokens
✅ Correctly Implemented
- Issuer (vault wallet)
- MaximumAmount (1)
- TransferFee (0)
- MPTokenMetadata (9 fields, XLS-89d compliant)
- CanTransfer (32)
- CanTrade (16)
Recommended Flag Configuration for TapMint
Current Implementation (Fixed):
Flags: 32 | 16 | 8 // CanTransfer | CanTrade | CanEscrow
Breakdown (Official Docs):
32(0x20) = lsfMPTCanTransfer ✅16(0x10) = lsfMPTCanTrade ✅8(0x08) = lsfMPTCanEscrow ✅ (according to official docs)64(0x40) = lsfMPTCanClawback ❌ (according to official docs)
Flags we intentionally don't use:
1(lsfMPTLocked) - Would lock all tokens2(lsfMPTCanLock) - Would allow issuer to lock user tokens4(lsfMPTRequireAuth) - Would require authorization (users should receive freely)64(lsfMPTCanClawback) - Would allow issuer to take tokens back (if official docs are correct)
✅ Note: Flag values have been corrected to match official XRPL documentation. CanEscrow is now 8 (not 64), and CanClawback is 64 (not enabled).
Action Items
-
✅ COMPLETED: Fixed flag values to match official documentation
- Changed CanEscrow from
64to8 - Removed accidental CanClawback enablement
- Updated both TapMint and Playground mint flows
- Location:
src/server/api/root.ts:2122(TapMint) andsrc/server/api/root.ts:358(Playground)
- Changed CanEscrow from
-
⚠️ MEDIUM PRIORITY: Add documentation comment for AssetScale
- Explain why we use default (0) for 1/1 tokens
- Location:
src/server/api/root.ts:2117(near MaximumAmount)
-
✅ LOW PRIORITY: Consider adding flag validation
- Add a check to ensure we're not accidentally enabling unwanted flags
- Add constants for flag values to avoid magic numbers
- Location: Create
src/lib/xrpl-mpt-flags.tsor similar
-
📋 TODO - FUTURE: Implement SecureJSON for metadata signing/validation
- Status: Not currently implemented
- Current State: We use
MPTokenMetadata(hex-encoded JSON) but don't sign it - What is SecureJSON: Signed and base64-encoded JSON for tamper-proof metadata
- Reference:
nfc-dev/securejson.pyhas a Python implementation - Considerations:
- Would add cryptographic signing to metadata
- Could be used for cross-chain bridging (mentioned in UI)
- Would require key management infrastructure
- May not be a standard XRPL field (needs research)
- Priority: Low - not blocking current functionality
- Location: Would need to be added to
src/server/api/root.tsminting functions
