-
Notifications
You must be signed in to change notification settings - Fork 303
feat(statics): add XrpMptCoin class and token config for XRPL MPT #8856
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -137,6 +137,12 @@ export interface XrpCoinConstructorOptions extends AccountConstructorOptions { | |
| contractAddress: string; | ||
| } | ||
|
|
||
| export interface XrpMptCoinConstructorOptions extends AccountConstructorOptions { | ||
| mptIssuanceId: string; // 48-char hex MPTokenIssuanceID — stored as contractAddress | ||
| canTransfer: boolean; // immutable lsfMPTCanTransfer (0x0008) flag | ||
| assetScale: number; // immutable AssetScale from MPTokenIssuanceCreate | ||
| } | ||
|
|
||
| export interface SuiCoinConstructorOptions extends AccountConstructorOptions { | ||
| packageId: string; | ||
| module: string; | ||
|
|
@@ -607,6 +613,34 @@ export class XrpCoin extends AccountCoinToken { | |
| } | ||
| } | ||
|
|
||
| /** | ||
| * XRP Ledger Multi-Purpose Token (MPT) — MPTokensV1 amendment. | ||
| * Identified by a 48-char hex MPTokenIssuanceID stored as contractAddress. | ||
| * Uses account_objects (not account_lines). No issuer::currency pattern. | ||
| * Named xrp:<token_name> — same pattern as trust-line tokens. | ||
| */ | ||
| export class XrpMptCoin extends AccountCoinToken { | ||
| public readonly contractAddress: string; // MPTokenIssuanceID | ||
| public readonly canTransfer: boolean; // immutable — set at MPTokenIssuanceCreate | ||
|
|
||
| constructor(options: XrpMptCoinConstructorOptions) { | ||
| super({ ...options }); | ||
|
|
||
| if (!/^[0-9a-fA-F]{48}$/.test(options.mptIssuanceId)) { | ||
| throw new InvalidContractAddressError(options.name, options.mptIssuanceId); | ||
| } | ||
|
|
||
| if (!Number.isInteger(options.assetScale) || options.assetScale < 0 || options.assetScale > 255) { | ||
| throw new Error( | ||
| `invalid assetScale '${options.assetScale}' for coin '${options.name}': must be an integer between 0 and 255 (uint8)` | ||
| ); | ||
| } | ||
|
|
||
| this.contractAddress = options.mptIssuanceId; | ||
| this.canTransfer = options.canTransfer; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what about assetScale ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. assetScale is passed as decimalPlaces in the factory (decimalPlaces: assetScale), so super() stores it as the inherited this.decimalPlaces. Storing it twice would be redundant use coin.decimalPlaces at runtime.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will we check this canTrasfer before building the tx?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes WP will reads coin.canTransfer from statics as a pre-flight before building the tx. |
||
| } | ||
| } | ||
|
|
||
| export class SuiCoin extends AccountCoinToken { | ||
| public packageId: string; | ||
| public module: string; | ||
|
|
@@ -3313,6 +3347,85 @@ export function txrpToken( | |
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Factory function for mainnet XRP MPT token instances. | ||
| * | ||
| * @param id uuid v4 | ||
| * @param name unique identifier of the token, e.g. "xrp:my_mpt" | ||
| * @param fullName Complete human-readable name of the token | ||
| * @param mptIssuanceId 48-char hex MPTokenIssuanceID | ||
| * @param canTransfer immutable lsfMPTCanTransfer flag from MPTokenIssuanceCreate | ||
| * @param assetScale immutable display decimal places from MPTokenIssuanceCreate (also used as decimalPlaces) | ||
| * @param asset UnderlyingAsset enum value | ||
| * @param features Optional coin features | ||
| * @param network Optional network override (defaults to mainnet XRP) | ||
| */ | ||
| export function xrpMptToken( | ||
| id: string, | ||
| name: string, | ||
| fullName: string, | ||
| mptIssuanceId: string, | ||
| canTransfer: boolean, | ||
| assetScale: number, | ||
| asset: UnderlyingAsset, | ||
| features: CoinFeature[] = AccountCoin.DEFAULT_FEATURES, | ||
| prefix = '', | ||
| suffix: string = name.toUpperCase(), | ||
| network: AccountNetwork = Networks.main.xrp, | ||
| primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1 | ||
| ) { | ||
| return Object.freeze( | ||
| new XrpMptCoin({ | ||
| id, | ||
| name, | ||
| fullName, | ||
| network, | ||
| mptIssuanceId, | ||
| canTransfer, | ||
| assetScale, | ||
| prefix, | ||
| suffix, | ||
| features, | ||
| decimalPlaces: assetScale, // assetScale IS the display decimal places — same concept as decimalPlaces elsewhere | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dont we need any validation on assetScale? |
||
| asset, | ||
| isToken: true, | ||
| primaryKeyCurve, | ||
| baseUnit: BaseUnit.XRP, | ||
| }) | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Factory function for testnet XRP MPT token instances. | ||
| */ | ||
| export function txrpMptToken( | ||
| id: string, | ||
| name: string, | ||
| fullName: string, | ||
| mptIssuanceId: string, | ||
| canTransfer: boolean, | ||
| assetScale: number, | ||
| asset: UnderlyingAsset, | ||
| features: CoinFeature[] = AccountCoin.DEFAULT_FEATURES, | ||
| prefix = '', | ||
| suffix: string = name.toUpperCase(), | ||
| network: AccountNetwork = Networks.test.xrp | ||
| ) { | ||
| return xrpMptToken( | ||
| id, | ||
| name, | ||
| fullName, | ||
| mptIssuanceId, | ||
| canTransfer, | ||
| assetScale, | ||
| asset, | ||
| features, | ||
| prefix, | ||
| suffix, | ||
| network | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Factory function for sui token instances. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,9 @@ export { | |
| TaoCoin, | ||
| PolyxCoin, | ||
| XrpCoin, | ||
| XrpMptCoin, | ||
| xrpMptToken, | ||
| txrpMptToken, | ||
|
Comment on lines
+29
to
+30
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. follow the naming convention
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. XrpMptCoin follows the existing convention Erc20Coin, XrpCoin, SuiCoin are all tokens too. The separate class is needed so WP can route instanceof XrpMptCoin vs instanceof XrpCoin for MPT vs trust-line logic. |
||
| AptCoin, | ||
| AptNFTCollection, | ||
| Sip10Token, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we have any validation on the
mptIssuanceId?