Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions _code-samples/issue-mpt-with-metadata/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Issue an MPT with Metadata

Shows how to issue a Multi-Purpose Token (MPT) with metadata encoded according to the XLS-89 schema.
16 changes: 16 additions & 0 deletions _code-samples/issue-mpt-with-metadata/js/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Issue MPT with Metadata (JavaScript)

Creates a sample MPT issuance with metadata encoded as JSON according to the [XLS-89 standard](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0089-multi-purpose-token-metadata-schema).

Quick setup and usage:

```sh
npm i
node issue-mpt-with-metadata.js
```

The script should output a validated transaction and end with a line such as the following:

```text
MPToken created successfully with issuance ID 005073C721E14A7613BAAF5E0B1A253459832FF8D0D81278.
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { stringToHex, hexToString } from '@xrplf/isomorphic/dist/utils/index.js'
import { MPTokenIssuanceCreateFlags, Client } 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()

// Define metadata as JSON
const mpt_metadata = {
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.',
urls: [
{
url: 'https://exampleyield.co/tbill',
type: 'website',
title: 'Product Page'
},
{
url: 'https://exampleyield.co/docs',
type: 'docs',
title: 'Yield Token Docs'
}
],
additional_info: {
interest_rate: '5.00%',
interest_type: 'variable',
yield_source: 'U.S. Treasury Bills',
maturity_date: '2045-06-30',
cusip: '912796RX0'
}
}

// Convert JSON to a string (without excess whitespace), then string to hex
const mpt_metadata_hex = stringToHex(JSON.stringify(mpt_metadata))

// Define the transaction, including other MPT parameters
const mpt_issuance_create = {
TransactionType: 'MPTokenIssuanceCreate',
Account: wallet.address,
AssetScale: 4,
MaximumAmount: '50000000',
TransferFee: 0,
Flags: MPTokenIssuanceCreateFlags.tfMPTCanTransfer |
MPTokenIssuanceCreateFlags.tfMPTCanTrade,
MPTokenMetadata: mpt_metadata_hex
}

// Prepare, sign, and submit the transaction
console.log('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))
if (submit_response.result.meta.TransactionResult !== 'tesSUCCESS') {
const result_code = response.result.meta.TransactionResult
console.warn(`Transaction failed with result code ${result_code}.`)
process.exit(1)
}

const issuance_id = submit_response.result.meta.mpt_issuance_id
console.log(`MPToken created successfully with issuance ID ${issuance_id}.`)

// Look up MPT Issuance entry in the validated ledger
console.log('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
const metadata_blob = ledger_entry_response.result.node.MPTokenMetadata
const decoded_metadata = JSON.parse(hexToString(metadata_blob))
console.log('Decoded metadata:', decoded_metadata)


client.disconnect()
6 changes: 6 additions & 0 deletions _code-samples/issue-mpt-with-metadata/js/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"dependencies": {
"xrpl": "^4.4.0"
},
"type": "module"
}
18 changes: 18 additions & 0 deletions _code-samples/issue-mpt-with-metadata/py/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Issue MPT with Metadata (Python)

Creates a sample MPT issuance with metadata encoded as JSON according to the [XLS-89 standard](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0089-multi-purpose-token-metadata-schema).

Quick setup and usage:

```sh
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python issue-mpt-with-metadata.py
```

The script should output a validated transaction and end with a line such as the following:

```text
MPToken created successfully with issuance ID 0050773D6B8DF8C6BEA497016C8679728A217DE1C4D50AC5.
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import json
from xrpl.utils import str_to_hex, hex_to_str
from xrpl.clients import JsonRpcClient
from xrpl.wallet import generate_faucet_wallet
from xrpl.transaction import submit_and_wait
from xrpl.models import LedgerEntry, MPTokenIssuanceCreate, MPTokenIssuanceCreateFlag

# Set up client and get a wallet
client = JsonRpcClient("https://s.devnet.rippletest.net:51234")
print("Funding new wallet from faucet...")
wallet = generate_faucet_wallet(client, debug=True)

# Define metadata as JSON
mpt_metadata = {
"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.",
"urls": [
{
"url": "https://exampleyield.co/tbill",
"type": "website",
"title": "Product Page"
},
{
"url": "https://exampleyield.co/docs",
"type": "docs",
"title": "Yield Token Docs"
}
],
"additional_info": {
"interest_rate": "5.00%",
"interest_type": "variable",
"yield_source": "U.S. Treasury Bills",
"maturity_date": "2045-06-30",
"cusip": "912796RX0"
}
}

# Convert JSON to a string (without excess whitespace), then string to hex
mpt_metadata_string = json.dumps(mpt_metadata, separators=(',', ':'))
mpt_metadata_hex = str_to_hex(mpt_metadata_string)

# Define the transaction, including other MPT parameters
mpt_issuance_create = MPTokenIssuanceCreate(
account=wallet.address,
asset_scale=4,
maximum_amount="50000000",
transfer_fee=0,
flags=MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRANSFER |
MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRADE,
mptoken_metadata=mpt_metadata_hex
)

# Prepare, sign, and submit the transaction
print("Sending MPTokenIssuanceCreate transaction...")
response = submit_and_wait(mpt_issuance_create, client, wallet, autofill=True)
print(json.dumps(response.result, indent=2))

# Check transaction results
result_code = response.result["meta"]["TransactionResult"]
if result_code != "tesSUCCESS":
print(f"Transaction failed with result code {result_code}")
exit(1)

issuance_id = response.result["meta"]["mpt_issuance_id"]
print(f"MPToken successfully created with issuance ID {issuance_id}")

# Look up MPT Issuance entry in the validated ledger
print("Confirming MPT Issuance metadata in the validated ledger.")
ledger_entry_response = client.request(LedgerEntry(
mpt_issuance=issuance_id,
ledger_index="validated"
))

# Decode the metadata
metadata_blob = ledger_entry_response.result["node"]["MPTokenMetadata"]
decoded_metadata = json.loads(hex_to_str(metadata_blob))
print("Decoded metadata:", decoded_metadata)
1 change: 1 addition & 0 deletions _code-samples/issue-mpt-with-metadata/py/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
xrpl-py==4.3.0
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ _(Requires the [MPTokensV1 amendment][] {% not-enabled /%}.)_
"AssetScale": 2,
"MaximumAmount": "100000000",
"OutstandingAmount": "100",
"TransferFee": 50000,
"TransferFee": 50000,
"MPTokenMetadata": "7B227469636B6572223A20225442494C4C222C20226E616D65223A2022542D42696C6C205969656C6420546F6B656E222C202264657363223A202241207969656C642D62656172696E6720737461626C65636F696E206261636B65642062792073686F72742D7465726D20552E532E205472656173757269657320616E64206D6F6E6579206D61726B657420696E737472756D656E74732E222C202269636F6E223A202268747470733A2F2F6578616D706C652E6F72672F7462696C6C2D69636F6E2E706E67222C202261737365745F636C617373223A2022727761222C202261737365745F737562636C617373223A20227472656173757279222C20226973737565725F6E616D65223A20224578616D706C65205969656C6420436F2E222C202275726C73223A205B7B2275726C223A202268747470733A2F2F6578616D706C657969656C642E636F2F7462696C6C222C202274797065223A202277656273697465222C20227469746C65223A202250726F647563742050616765227D2C207B2275726C223A202268747470733A2F2F6578616D706C657969656C642E636F2F646F6373222C202274797065223A2022646F6373222C20227469746C65223A20225969656C6420546F6B656E20446F6373227D5D2C20226164646974696F6E616C5F696E666F223A207B22696E7465726573745F72617465223A2022352E303025222C2022696E7465726573745F74797065223A20227661726961626C65222C20227969656C645F736F75726365223A2022552E532E2054726561737572792042696C6C73222C20226D617475726974795F64617465223A2022323034352D30362D3330222C20226375736970223A2022393132373936525830227D7D",
"OwnerNode": "74"
}
```

{% admonition type="success" name="Tip" %}
By convention, the metadata should decode to JSON data describing what the MPT represents. The [XLS-89d specification](https://github.com/XRPLF/XRPL-Standards/pull/293) defines a recommended format for metadata. For example, the above `MPTokenMetadata` field encodes the sample JSON from the XLS-89d spec, as a UTF-8 string with minimal whitespace.
By convention, the metadata should decode to JSON data describing what the MPT represents. The [XLS-89 specification](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0089-multi-purpose-token-metadata-schema) defines a recommended format for metadata. The above `MPTokenMetadata` field encodes the sample JSON from the spec, as a UTF-8 string with minimal whitespace.
{% /admonition %}

## MPTokenIssuance Fields
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ This example assumes that the issuer of the token is the signer of the transacti
| `AssetScale` | Number | UInt8 | No | Where to put the decimal place when displaying amounts of this MPT. More formally, the asset scale is a non-negative integer (0, 1, 2, …) such that one standard unit equals 10^(-scale) of a corresponding fractional unit. For example, if a US Dollar Stablecoin has an asset scale of _2_, then 1 unit of that MPT would equal 0.01 US Dollars. This indicates to how many decimal places the MPT can be subdivided. If omitted, the default is 0, meaning that the MPT cannot be divided into smaller than 1 unit. |
| `TransferFee` | Number | UInt16 | No | The value specifies the fee to charged by the issuer for secondary sales of the Token, if such sales are allowed. Valid values for this field are between 0 and 50,000 inclusive, allowing transfer rates of between 0.000% and 50.000% in increments of 0.001. The field _must not_ be present if the tfMPTCanTransfer flag is not set. If it is, the transaction should fail and a fee should be claimed. |
| `MaximumAmount` | String - Number | UInt64 | No | The maximum asset amount of this token that can ever be issued, as a base-10 number encoded as a string. The current default maximum limit is 9,223,372,036,854,775,807 (2^63-1). _This limit may increase in the future. If an upper limit is required, you must specify this field._ |
| `MPTokenMetadata` | String - Hexadecimal | Blob | No | Arbitrary metadata about this issuance. The limit for this field is 1024 bytes. By convention, the metadata should decode to JSON data describing what the MPT represents. The [XLS-89d specification](https://github.com/XRPLF/XRPL-Standards/pull/293) defines a recommended format for metadata. |
| `MPTokenMetadata` | String - Hexadecimal | Blob | No | Arbitrary metadata about this issuance. The limit for this field is 1024 bytes. By convention, the metadata should decode to JSON data describing what the MPT represents. The [XLS-89 specification](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0089-multi-purpose-token-metadata-schema) defines a recommended format for metadata. |

{% admonition type="success" name="Tip" %}
For an example of how to encode metadata for the `MPTokenMetadata` field, see {% repo-link path="_code-samples/issue-mpt-with-metadata/" %}Code Sample: Issue MPT with Metadata{% /repo-link %}.
{% /admonition %}

## MPTokenIssuanceCreate Flags

Expand Down