@@ -29,6 +29,15 @@ These are the transaction types available in the XRPL:
2929- [ DelegateSet] ( https://xrpl.org/docs/references/protocol/transactions/types/delegateset )
3030- [ DIDDelete] ( https://xrpl.org/docs/references/protocol/transactions/types/diddelete )
3131- [ DIDSet] ( https://xrpl.org/docs/references/protocol/transactions/types/didset )
32+ - [ LoanBrokerCoverClawback] ( https://xrpl.org/docs/references/protocol/transactions/types/loanbrokercoverclawback )
33+ - [ LoanBrokerCoverDeposit] ( https://xrpl.org/docs/references/protocol/transactions/types/loanbrokercoverdeposit )
34+ - [ LoanBrokerCoverWithdraw] ( https://xrpl.org/docs/references/protocol/transactions/types/loanbrokercoverwithdraw )
35+ - [ LoanBrokerDelete] ( https://xrpl.org/docs/references/protocol/transactions/types/loanbrokerdelete )
36+ - [ LoanBrokerSet] ( https://xrpl.org/docs/references/protocol/transactions/types/loanbrokerset )
37+ - [ LoanDelete] ( https://xrpl.org/docs/references/protocol/transactions/types/loandelete )
38+ - [ LoanManage] ( https://xrpl.org/docs/references/protocol/transactions/types/loanmanage )
39+ - [ LoanPay] ( https://xrpl.org/docs/references/protocol/transactions/types/loanpay )
40+ - [ LoanSet] ( https://xrpl.org/docs/references/protocol/transactions/types/loanset )
3241- [ EscrowCancel] ( https://xrpl.org/docs/references/protocol/transactions/types/escrowcancel )
3342- [ EscrowCreate] ( https://xrpl.org/docs/references/protocol/transactions/types/escrowcreate )
3443- [ EscrowFinish] ( https://xrpl.org/docs/references/protocol/transactions/types/escrowfinish )
@@ -65,6 +74,309 @@ These are the transaction types available in the XRPL:
6574- [ XChainCreateClaimID] ( https://xrpl.org/docs/references/protocol/transactions/types/xchaincreateclaimid )
6675- [ XChainModifyBridge] ( https://xrpl.org/docs/references/protocol/transactions/types/xchainmodifybridge )
6776
77+ ## MPTokenMetadata
78+
79+ The ` MPTokenMetadata ` type provides functionality to encode, decode, and validate metadata for Multi-Purpose Tokens (MPTs) as per the [ XLS-89 standard] ( https://xls.xrpl.org/xls/XLS-0089-multi-purpose-token-metadata-schema.html ) . This metadata includes information about the token such as ticker, name, description, icon, asset classification, and related URIs.
80+
81+ ### Overview
82+
83+ MPTokenMetadata is used in MPToken transactions (like ` MPTokenIssuanceCreate ` ) to provide structured metadata about tokens. The metadata is encoded as a hex string and must comply with the XLS-89 standard, which includes:
84+
85+ - Maximum size limit of 1024 bytes
86+ - Support for both long-form and compact-form JSON keys
87+ - Validation of required fields, field types, and allowed values
88+ - Alphabetical ordering of fields for consistent encoding
89+
90+ ### Types
91+
92+ #### ParsedMPTokenMetadata
93+
94+ The ` ParsedMPTokenMetadata ` struct represents the complete metadata structure for an MPToken. Fields are ordered alphabetically by JSON key for consistent encoding.
95+
96+ ``` go
97+ type ParsedMPTokenMetadata struct {
98+ // Top-level classification of token purpose (required)
99+ // Allowed values: "rwa", "memes", "wrapped", "gaming", "defi", "other"
100+ AssetClass string ` json:"ac"`
101+
102+ // Freeform field for key token details (optional)
103+ // Can be any valid JSON object or UTF-8 string
104+ AdditionalInfo any ` json:"ai,omitempty"`
105+
106+ // Optional subcategory of the asset class (optional, required if AssetClass is "rwa")
107+ // Allowed values: "stablecoin", "commodity", "real_estate", "private_credit", "equity", "treasury", "other"
108+ AssetSubclass *string ` json:"as,omitempty"`
109+
110+ // Short description of the token (optional)
111+ Desc *string ` json:"d,omitempty"`
112+
113+ // URI to the token icon (required)
114+ // Can be a hostname/path (HTTPS assumed) or full URI for other protocols (e.g., ipfs://)
115+ Icon string ` json:"i"`
116+
117+ // The name of the issuer account (required)
118+ IssuerName string ` json:"in"`
119+
120+ // Display name of the token (required)
121+ Name string ` json:"n"`
122+
123+ // Ticker symbol used to represent the token (required)
124+ // Uppercase letters (A-Z) and digits (0-9) only. Max 6 chars.
125+ Ticker string ` json:"t"`
126+
127+ // List of related URIs (optional)
128+ // Each URI object contains the link, its category, and a human-readable title
129+ URIs []ParsedMPTokenMetadataURI ` json:"us,omitempty"`
130+ }
131+ ```
132+
133+ ** Field Requirements:**
134+
135+ - ** Required fields** : ` Ticker ` , ` Name ` , ` Icon ` , ` AssetClass ` , ` IssuerName `
136+ - ** Conditional** : ` AssetSubclass ` is required when ` AssetClass ` is ` "rwa" `
137+ - ** Optional fields** : ` Desc ` , ` URIs ` , ` AdditionalInfo `
138+
139+ #### ParsedMPTokenMetadataURI
140+
141+ The ` ParsedMPTokenMetadataURI ` struct represents a URI entry within the metadata. Fields are ordered alphabetically by JSON key for consistent encoding.
142+
143+ ``` go
144+ type ParsedMPTokenMetadataURI struct {
145+ // The category of the link (required)
146+ // Allowed values: "website", "social", "docs", "other"
147+ Category string ` json:"c"`
148+
149+ // A human-readable label for the link (required)
150+ Title string ` json:"t"`
151+
152+ // URI to the related resource (required)
153+ // Can be a hostname/path (HTTPS assumed) or full URI for other protocols (e.g., ipfs://)
154+ URI string ` json:"u"`
155+ }
156+ ```
157+
158+ ### Functions
159+
160+ #### EncodeMPTokenMetadata
161+
162+ Encodes a ` ParsedMPTokenMetadata ` struct into a hex string compliant with XLS-89.
163+
164+ ``` go
165+ func EncodeMPTokenMetadata (meta ParsedMPTokenMetadata ) (string , error )
166+ ```
167+
168+ **Returns:**
169+ - `string`: The encoded hex string (uppercase)
170+ - `error`: An error if encoding fails
171+
172+ #### DecodeMPTokenMetadata
173+
174+ Decodes a hex string into a `ParsedMPTokenMetadata` struct. Handles input with either long-form or compact-form keys via custom `UnmarshalJSON` methods.
175+
176+ ```go
177+ func DecodeMPTokenMetadata(hexInput string) (ParsedMPTokenMetadata, error)
178+ ```
179+
180+ **Returns:**
181+ - `ParsedMPTokenMetadata`: The decoded metadata struct
182+ - `error`: An error if decoding fails (e.g., invalid hex, invalid JSON)
183+
184+ #### ValidateMPTokenMetadata
185+
186+ Validates MPToken metadata according to the XLS-89 standard. Checks for:
187+ - Valid hex string format
188+ - Maximum size limit (1024 bytes)
189+ - Valid JSON structure
190+ - Required fields presence
191+ - Field types and formats
192+ - Allowed values for enums
193+ - Field count limits
194+
195+ ```go
196+ func ValidateMPTokenMetadata(input string) error
197+ ```
198+
199+ **Returns:**
200+ - `error`: `nil` if valid, or `MPTokenMetadataValidationErrors` containing all validation errors
201+
202+ ### Constants
203+
204+ ```go
205+ // Maximum byte length for MPToken metadata (1024 bytes)
206+ const MaxMPTokenMetadataByteLength = 1024
207+
208+ // Allowed values for the asset class field
209+ var MPTokenMetadataAssetClasses = [6]string{" rwa" , " memes" , " wrapped" , " gaming" , " defi" , " other" }
210+
211+ // Allowed values for the asset subclass field
212+ var MPTokenMetadataAssetSubClasses = [7 ]string {" stablecoin" , " commodity" , " real_estate" , " private_credit" , " equity" , " treasury" , " other" }
213+
214+ // Allowed values for the URI category field
215+ var MPTokenMetadataURICategories = [4 ]string {" website" , " social" , " docs" , " other" }
216+ ```
217+
218+ ### Usage Examples
219+
220+ #### Creating and Encoding Metadata
221+
222+ ``` go
223+ package main
224+
225+ import (
226+ " fmt"
227+ " github.com/Peersyst/xrpl-go/xrpl/transaction/types"
228+ )
229+
230+ func main () {
231+ // Create metadata struct
232+ assetSubclass := " treasury"
233+ desc := " A yield-bearing stablecoin backed by short-term U.S. Treasuries."
234+
235+ metadata := types.ParsedMPTokenMetadata {
236+ Ticker: " TBILL" ,
237+ Name: " T-Bill Yield Token" ,
238+ Desc: &desc,
239+ Icon: " https://example.org/tbill-icon.png" ,
240+ AssetClass: " rwa" ,
241+ AssetSubclass: &assetSubclass,
242+ IssuerName: " Example Yield Co." ,
243+ URIs: []types.ParsedMPTokenMetadataURI {
244+ {
245+ URI: " https://exampleyield.co/tbill" ,
246+ Category: " website" ,
247+ Title: " Product Page" ,
248+ },
249+ {
250+ URI: " https://exampleyield.co/docs" ,
251+ Category: " docs" ,
252+ Title: " Yield Token Docs" ,
253+ },
254+ },
255+ AdditionalInfo: map [string ]any{
256+ " interest_rate" : " 5.00% " ,
257+ " maturity_date" : " 2045-06-30" ,
258+ },
259+ }
260+
261+ // Encode to hex string
262+ hexStr , err := types.EncodeMPTokenMetadata (metadata)
263+ if err != nil {
264+ panic (err)
265+ }
266+
267+ fmt.Printf (" Encoded metadata: %s \n " , hexStr)
268+ }
269+ ```
270+
271+ #### Decoding Metadata
272+
273+ ``` go
274+ package main
275+
276+ import (
277+ " fmt"
278+ " github.com/Peersyst/xrpl-go/xrpl/transaction/types"
279+ )
280+
281+ func main () {
282+ hexStr := " 7B226163223A22727761222C226173223A227472656173757279222C..."
283+
284+ // Decode from hex string
285+ metadata , err := types.DecodeMPTokenMetadata (hexStr)
286+ if err != nil {
287+ panic (err)
288+ }
289+
290+ fmt.Printf (" Ticker: %s \n " , metadata.Ticker )
291+ fmt.Printf (" Name: %s \n " , metadata.Name )
292+ fmt.Printf (" Asset Class: %s \n " , metadata.AssetClass )
293+ }
294+ ```
295+
296+ #### Validating Metadata
297+
298+ ``` go
299+ package main
300+
301+ import (
302+ " fmt"
303+ " github.com/Peersyst/xrpl-go/xrpl/transaction/types"
304+ )
305+
306+ func main () {
307+ hexStr := " 7B226163223A22727761222C226173223A227472656173757279222C..."
308+
309+ // Validate metadata
310+ err := types.ValidateMPTokenMetadata (hexStr)
311+ if err != nil {
312+ fmt.Printf (" Validation failed: %v \n " , err)
313+ return
314+ }
315+
316+ fmt.Println (" Metadata is valid!" )
317+ }
318+ ```
319+
320+ #### Using in MPTokenIssuanceCreate Transaction
321+
322+ ``` go
323+ package main
324+
325+ import (
326+ " github.com/Peersyst/xrpl-go/xrpl/transaction"
327+ " github.com/Peersyst/xrpl-go/xrpl/transaction/types"
328+ )
329+
330+ func main () {
331+ // Create and encode metadata
332+ metadata := types.ParsedMPTokenMetadata {
333+ Ticker: " TBILL" ,
334+ Name: " T-Bill Yield Token" ,
335+ Icon: " https://example.org/tbill-icon.png" ,
336+ AssetClass: " rwa" ,
337+ IssuerName: " Example Yield Co." ,
338+ }
339+
340+ hexStr , _ := types.EncodeMPTokenMetadata (metadata)
341+
342+ // Use in transaction
343+ tx := transaction.MPTokenIssuanceCreate {
344+ BaseTx: transaction.BaseTx {
345+ TransactionType: " MPTokenIssuanceCreate" ,
346+ Account: " rajgkBmMxmz161r8bWYH7CQAFZP5bA9oSG" ,
347+ },
348+ AssetScale: 2 ,
349+ TransferFee: 314 ,
350+ MaximumAmount: " 50000000" ,
351+ MPTokenMetadata: types.MPTokenMetadata (hexStr),
352+ }
353+
354+ // ... continue with transaction signing and submission
355+ }
356+ ```
357+
358+ ### JSON Key Formats
359+
360+ The implementation supports both long-form and compact-form JSON keys for backward compatibility and flexibility:
361+
362+ ** Long-form keys:**
363+ - ` ticker ` , ` name ` , ` desc ` , ` icon ` , ` asset_class ` , ` asset_subclass ` , ` issuer_name ` , ` uris ` , ` additional_info `
364+ - ` uri ` , ` category ` , ` title ` (for URI objects)
365+
366+ ** Compact-form keys:**
367+ - ` t ` , ` n ` , ` d ` , ` i ` , ` ac ` , ` as ` , ` in ` , ` us ` , ` ai `
368+ - ` u ` , ` c ` , ` t ` (for URI objects)
369+
370+ Both formats are accepted when decoding, but encoding always uses compact-form keys for consistency and size efficiency.
371+
372+ ### Import
373+
374+ To use MPTokenMetadata types and functions, import:
375+
376+ ``` go
377+ import " github.com/Peersyst/xrpl-go/xrpl/transaction/types"
378+ ```
379+
68380## Usage
69381
70382To use the ` transaction ` package, you need to import it in your project:
0 commit comments