mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-20 03:35:51 +00:00
Compare commits
1 Commits
master
...
issue-mpto
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eec9c977fa |
@@ -1,35 +1,40 @@
|
||||
import { stringToHex, hexToString } from '@xrplf/isomorphic/dist/utils/index.js'
|
||||
import { MPTokenIssuanceCreateFlags, Client } from 'xrpl'
|
||||
import {
|
||||
MPTokenIssuanceCreateFlags,
|
||||
Client,
|
||||
encodeMPTokenMetadata,
|
||||
decodeMPTokenMetadata
|
||||
} from 'xrpl'
|
||||
|
||||
// Connect to network and get a wallet
|
||||
const client = new Client('wss://s.devnet.rippletest.net:51233')
|
||||
await client.connect()
|
||||
|
||||
console.log('Funding new wallet from faucet...')
|
||||
const { wallet } = await client.fundWallet()
|
||||
console.log('=== Funding new wallet from faucet...===')
|
||||
const { wallet: issuer } = await client.fundWallet()
|
||||
console.log(`Issuer address: ${issuer.address}`)
|
||||
|
||||
// Define metadata as JSON
|
||||
const mpt_metadata = {
|
||||
t: 'TBILL',
|
||||
n: 'T-Bill Yield Token',
|
||||
d: 'A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.',
|
||||
i: 'https://example.org/tbill-icon.png',
|
||||
ac: 'rwa',
|
||||
as: 'treasury',
|
||||
in: 'Example Yield Co.',
|
||||
us: [
|
||||
ticker: 'TBILL',
|
||||
name: 'T-Bill Yield Token',
|
||||
desc: 'A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.',
|
||||
icon: 'https://example.org/tbill-icon.png',
|
||||
asset_class: 'rwa',
|
||||
asset_subclass: 'treasury',
|
||||
issuer_name: 'Example Yield Co.',
|
||||
uris: [
|
||||
{
|
||||
u: 'https://exampleyield.co/tbill',
|
||||
c: 'website',
|
||||
t: 'Product Page'
|
||||
uri: 'https://exampleyield.co/tbill',
|
||||
category: 'website',
|
||||
title: 'Product Page'
|
||||
},
|
||||
{
|
||||
u: 'https://exampleyield.co/docs',
|
||||
c: 'docs',
|
||||
t: 'Yield Token Docs'
|
||||
uri: 'https://exampleyield.co/docs',
|
||||
category: 'docs',
|
||||
title: 'Yield Token Docs'
|
||||
}
|
||||
],
|
||||
ai: {
|
||||
additional_info: {
|
||||
interest_rate: '5.00%',
|
||||
interest_type: 'variable',
|
||||
yield_source: 'U.S. Treasury Bills',
|
||||
@@ -38,8 +43,13 @@ const mpt_metadata = {
|
||||
}
|
||||
}
|
||||
|
||||
// Convert JSON to a string (without excess whitespace), then string to hex
|
||||
const mpt_metadata_hex = stringToHex(JSON.stringify(mpt_metadata))
|
||||
// Encode the metadata.
|
||||
// The encodeMPTokenMetadata function converts the JSON metadata object into
|
||||
// a compact, hex-encoded string, following the XLS-89 standard.
|
||||
// https://xls.xrpl.org/xls/XLS-0089-multi-purpose-token-metadata-schema.html
|
||||
console.log('\n=== Encoding metadata...===')
|
||||
const mpt_metadata_hex = encodeMPTokenMetadata(mpt_metadata)
|
||||
console.log("Encoded mpt_metadata_hex:", mpt_metadata_hex)
|
||||
|
||||
// Define the transaction, including other MPT parameters
|
||||
const mpt_issuance_create = {
|
||||
@@ -54,32 +64,40 @@ const mpt_issuance_create = {
|
||||
}
|
||||
|
||||
// Prepare, sign, and submit the transaction
|
||||
console.log('Sending MPTokenIssuanceCreate transaction...')
|
||||
const submit_response = await client.submitAndWait(mpt_issuance_create, { wallet, autofill: true })
|
||||
console.log('\n=== Sending MPTokenIssuanceCreate transaction...===')
|
||||
const submit_response = await client.submitAndWait(mpt_issuance_create,
|
||||
{ wallet, autofill: true }
|
||||
)
|
||||
|
||||
// Check transaction results and disconnect
|
||||
console.log(JSON.stringify(submit_response, null, 2))
|
||||
// Check transaction results
|
||||
console.log('\n=== Checking MPTokenIssuanceCreate results...===')
|
||||
// console.log(JSON.stringify(submit_response, null, 2))
|
||||
if (submit_response.result.meta.TransactionResult !== 'tesSUCCESS') {
|
||||
const result_code = response.result.meta.TransactionResult
|
||||
const result_code = submit_response.result.meta.TransactionResult
|
||||
console.warn(`Transaction failed with result code ${result_code}.`)
|
||||
await client.disconnect()
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const issuance_id = submit_response.result.meta.mpt_issuance_id
|
||||
console.log(`MPToken created successfully with issuance ID ${issuance_id}.`)
|
||||
console.log(`- MPToken created successfully with issuance ID: ${issuance_id}`)
|
||||
// View the MPT issuance on the XRPL Explorer
|
||||
console.log(`\n- Explorer URL: https://devnet.xrpl.org/mpt/${issuance_id}`)
|
||||
|
||||
// Look up MPT Issuance entry in the validated ledger
|
||||
console.log('Confirming MPT Issuance metadata in the validated ledger.')
|
||||
console.log('\n=== Confirming MPT Issuance metadata in the validated ledger... ===')
|
||||
const ledger_entry_response = await client.request({
|
||||
"command": "ledger_entry",
|
||||
"mpt_issuance": issuance_id,
|
||||
"ledger_index": "validated"
|
||||
})
|
||||
|
||||
// Decode the metadata
|
||||
// Decode the metadata.
|
||||
// The decodeMPTokenMetadata function takes a hex-encoded string representing MPT metadata,
|
||||
// decodes it to a JSON object, and expands any compact field names to their full forms.
|
||||
const metadata_blob = ledger_entry_response.result.node.MPTokenMetadata
|
||||
const decoded_metadata = JSON.parse(hexToString(metadata_blob))
|
||||
console.log('Decoded metadata:', decoded_metadata)
|
||||
|
||||
const decoded_metadata = decodeMPTokenMetadata(metadata_blob)
|
||||
console.log('Decoded MPT metadata: ', decoded_metadata)
|
||||
|
||||
// Disconnect from the client
|
||||
client.disconnect()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"xrpl": "^4.4.0"
|
||||
"xrpl": "^4.4.3"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
xrpl-py==4.3.0
|
||||
xrpl-py==4.4.3
|
||||
|
||||
149
docs/tutorials/how-tos/use-tokens/issue-a-multi-purpose-token.md
Normal file
149
docs/tutorials/how-tos/use-tokens/issue-a-multi-purpose-token.md
Normal file
@@ -0,0 +1,149 @@
|
||||
---
|
||||
seo:
|
||||
description: Issue a Multi-Purpose Token (MPT) with arbitrary metadata on the XRP Ledger.
|
||||
metadata:
|
||||
indexPage: true
|
||||
labels:
|
||||
- Multi-Purpose Token
|
||||
- MPT
|
||||
- Token Issuance
|
||||
---
|
||||
# Issue a Multi-Purpose Token (MPT)
|
||||
|
||||
A [Multi-Purpose Token (MPT)](../../../concepts/tokens/fungible-tokens/multi-purpose-tokens.md) lets you to quickly access powerful, built-in tokenization features on the XRP Ledger with minimal code.
|
||||
|
||||
This tutorial shows you how to issue an MPT with on-chain metadata such as the token's ticker, name, or description, encoded according to the MPT [metadata schema](../../../concepts/tokens/fungible-tokens/multi-purpose-tokens.md#metadata-schema) defined in [XLS-89](https://xls.xrpl.org/xls/XLS-0089-multi-purpose-token-metadata-schema.html).
|
||||
|
||||
## Goals
|
||||
|
||||
By the end of this tutorial, you will be able to:
|
||||
|
||||
- Issue a new MPT using the `MPTokenIssuanceCreate` transaction.
|
||||
- Encode or decode token metadata following MPT standards best practices.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
To complete this tutorial, you should:
|
||||
|
||||
- Have a basic understanding of the XRP Ledger and token issuance.
|
||||
- Have an XRP Ledger client library set up in your development environment. This page provides examples for the following:
|
||||
- **JavaScript** with the [xrpl.js library](https://github.com/XRPLF/xrpl.js). See [Get Started Using JavaScript](../../javascript/build-apps/get-started.md) for setup steps.
|
||||
|
||||
## Source Code
|
||||
|
||||
You can find the complete source code for this tutorial's example in the [code samples section of this website's repository](https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/issue-mpt-with-metadata).
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Install dependencies
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="Javascript" %}
|
||||
From the code sample folder, use npm to install dependencies:
|
||||
|
||||
```bash
|
||||
npm install xrpl
|
||||
```
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
### 2. Set up client and fund issuer wallet
|
||||
|
||||
Import the client library, instantiate a client to connect to the XRPL, and fund a new wallet to act as the token issuer.
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="Javascript" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/js/issue-mpt-with-metadata.js" language="js" before="// Define metadata as JSON" /%}
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
### 3. Define and encode MPT metadata
|
||||
|
||||
Define your token's metadata as a JSON object:
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="Javascript" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/js/issue-mpt-with-metadata.js" language="js" from="// Define metadata as JSON" before="// Encode the metadata" /%}
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
The metadata schema supports both long field names (e.g., `ticker`, `name`, `desc`) and compact short keys (e.g., `t`, `n`, `d`). To save space on the ledger, it’s recommended to use short key names. The MPT metadata field has a 1024-byte limit, so using compact keys allows you to include more information.
|
||||
|
||||
The SDK libraries provide utility functions to encode or decode the metadata for you, so you don't have to. If long field names are provided in the metadata JSON, the _encoding_ utility function automatically shortens them to their compact key equivalents before encoding. Similarly, when decoding, the _decoding_ utility function converts the shorthands back to the respective long names.
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="Javascript" %}
|
||||
Use the `encodeMPTokenMetadata()` function to encode metadata with `xrpl.js`.
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/js/issue-mpt-with-metadata.js" language="js" from="// Encode the metadata" before="// Define the transaction" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% admonition type="warning" name="Warning" %}
|
||||
While the encoding utility formats the JSON for you correctly and replaces the full key names with shorthands, it does **not** validate the metadata content or size.
|
||||
{% /admonition %}
|
||||
|
||||
### 4. Prepare the MPTokenIssuanceCreate transaction
|
||||
|
||||
Create the transaction object, specifying the issuer, asset scale, maximum amount, transfer/trade flags, and the encoded metadata.
|
||||
|
||||
| Field | Value |
|
||||
|:------------------|:---------------------------------------------------------------------|
|
||||
| `TransactionType` | The type of transaction, in this case `MPTokenIssuanceCreate`. |
|
||||
| `Account` | The wallet address of the account that is issuing the MPT. |
|
||||
| `AssetScale` | The number of decimal places for the token. |
|
||||
| `MaximumAmount` | The maximum supply of the token to be issued. |
|
||||
| `TransferFee` | The transfer fee (if any) to charge for token transfers. |
|
||||
| `Flags` | Flags to control transfer/trade permissions. |
|
||||
| `MPTokenMetadata` | The hex-encoded metadata for the token. |
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="Javascript" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/js/issue-mpt-with-metadata.js" language="js" from="// Define the transaction" before="// Prepare, sign, and submit the transaction" /%}
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
### 5. Submit the transaction
|
||||
|
||||
Sign and submit the transaction, then wait for validation.
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="Javascript" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/js/issue-mpt-with-metadata.js" language="js" from="// Prepare, sign, and submit the transaction" before="// Check transaction results" /%}
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
### 6. Check transaction result
|
||||
|
||||
Verify that the transaction succeeded and retrieve the MPT issuance ID.
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="Javascript" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/js/issue-mpt-with-metadata.js" language="js" from="// Check transaction results" before="// Look up MPT Issuance entry" /%}
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
{% admonition type="info" name="Note" %}
|
||||
A `tesSUCCESS` result indicates that the MPT issuance transaction was processed successfully and the token was created.
|
||||
{% /admonition %}
|
||||
|
||||
### 7. Confirm MPT issuance and decode metadata
|
||||
|
||||
Look up the MPT issuance entry in the validated ledger and decode the metadata to verify it matches your original input.
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="Javascript" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/js/issue-mpt-with-metadata.js" language="js" from="// Look up MPT Issuance entry" /%}
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
The _decoding_ utility function converts the metadata shorthand key names back to the respective long names.
|
||||
|
||||
## See Also
|
||||
|
||||
- **Concepts**:
|
||||
- [Multi-Purpose Tokens (MPT)](../../../concepts/tokens/fungible-tokens/multi-purpose-tokens.md)
|
||||
- **References**:
|
||||
- [MPTokenIssuanceCreate Transaction](../../../references/protocol/transactions/types/mptokenissuancecreate.md)
|
||||
|
||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
||||
Reference in New Issue
Block a user