mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-21 04:05:49 +00:00
Compare commits
3 Commits
add-batch-
...
issue-mpto
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b67931baa | ||
|
|
003927517f | ||
|
|
9c8c231900 |
@@ -9,8 +9,135 @@ npm i
|
||||
node issue-mpt-with-metadata.js
|
||||
```
|
||||
|
||||
The script should output a validated transaction and end with a line such as the following:
|
||||
The script should output a validated transaction and decoded metadata, similar to the following:
|
||||
|
||||
```text
|
||||
MPToken created successfully with issuance ID 005073C721E14A7613BAAF5E0B1A253459832FF8D0D81278.
|
||||
```sh
|
||||
=== Funding new wallet from faucet...===
|
||||
Issuer address: r9fhoyac7uUM9XZFDJV9wXQ4pcJb6UDpJM
|
||||
|
||||
=== Encoding metadata...===
|
||||
Encoded mpt_metadata_hex: 7B226163223A22727761222C226169223A7B226375736970223A22393132373936525830222C22696E7465726573745F72617465223A22352E303025222C22696E7465726573745F74797065223A227661726961626C65222C226D617475726974795F64617465223A22323034352D30362D3330222C227969656C645F736F75726365223A22552E532E2054726561737572792042696C6C73227D2C226173223A227472656173757279222C2264223A2241207969656C642D62656172696E6720737461626C65636F696E206261636B65642062792073686F72742D7465726D20552E532E205472656173757269657320616E64206D6F6E6579206D61726B657420696E737472756D656E74732E222C2269223A2268747470733A2F2F6578616D706C652E6F72672F7462696C6C2D69636F6E2E706E67222C22696E223A224578616D706C65205969656C6420436F2E222C226E223A22542D42696C6C205969656C6420546F6B656E222C2274223A225442494C4C222C227573223A5B7B2263223A2277656273697465222C2274223A2250726F647563742050616765222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F7462696C6C227D2C7B2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F646F6373227D5D7D
|
||||
|
||||
=== Sending MPTokenIssuanceCreate transaction...===
|
||||
{
|
||||
"TransactionType": "MPTokenIssuanceCreate",
|
||||
"Account": "r9fhoyac7uUM9XZFDJV9wXQ4pcJb6UDpJM",
|
||||
"AssetScale": 4,
|
||||
"MaximumAmount": "50000000",
|
||||
"TransferFee": 0,
|
||||
"Flags": 48,
|
||||
"MPTokenMetadata": "7B226163223A22727761222C226169223A7B226375736970223A22393132373936525830222C22696E7465726573745F72617465223A22352E303025222C22696E7465726573745F74797065223A227661726961626C65222C226D617475726974795F64617465223A22323034352D30362D3330222C227969656C645F736F75726365223A22552E532E2054726561737572792042696C6C73227D2C226173223A227472656173757279222C2264223A2241207969656C642D62656172696E6720737461626C65636F696E206261636B65642062792073686F72742D7465726D20552E532E205472656173757269657320616E64206D6F6E6579206D61726B657420696E737472756D656E74732E222C2269223A2268747470733A2F2F6578616D706C652E6F72672F7462696C6C2D69636F6E2E706E67222C22696E223A224578616D706C65205969656C6420436F2E222C226E223A22542D42696C6C205969656C6420546F6B656E222C2274223A225442494C4C222C227573223A5B7B2263223A2277656273697465222C2274223A2250726F647563742050616765222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F7462696C6C227D2C7B2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F646F6373227D5D7D"
|
||||
}
|
||||
|
||||
=== Checking MPTokenIssuanceCreate results... ===
|
||||
{
|
||||
"close_time_iso": "2025-11-20T18:13:30Z",
|
||||
"ctid": "C0148E8700000002",
|
||||
"hash": "555FAFDB99B239567FDF30DDF22BA3B30F8E70D8D06833B1270AC600E1575948",
|
||||
"ledger_hash": "A7010A2025989778420280F7F96B10F5D3C879E049BE5DA12500FFBB90D162C5",
|
||||
"ledger_index": 1347207,
|
||||
"meta": {
|
||||
"AffectedNodes": [
|
||||
{
|
||||
"CreatedNode": {
|
||||
"LedgerEntryType": "DirectoryNode",
|
||||
"LedgerIndex": "33468621DEF32177E84C1EBC2C457C908567E245622CBDE03185C4ABC83B7F9D",
|
||||
"NewFields": {
|
||||
"Owner": "r9fhoyac7uUM9XZFDJV9wXQ4pcJb6UDpJM",
|
||||
"RootIndex": "33468621DEF32177E84C1EBC2C457C908567E245622CBDE03185C4ABC83B7F9D"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"CreatedNode": {
|
||||
"LedgerEntryType": "MPTokenIssuance",
|
||||
"LedgerIndex": "6567EE49937AADAB4FC4D5DDBD6A4A6E179E0E5A9DF2FC7ED8B41B807F0DDBF2",
|
||||
"NewFields": {
|
||||
"AssetScale": 4,
|
||||
"Flags": 48,
|
||||
"Issuer": "r9fhoyac7uUM9XZFDJV9wXQ4pcJb6UDpJM",
|
||||
"MPTokenMetadata": "7B226163223A22727761222C226169223A7B226375736970223A22393132373936525830222C22696E7465726573745F72617465223A22352E303025222C22696E7465726573745F74797065223A227661726961626C65222C226D617475726974795F64617465223A22323034352D30362D3330222C227969656C645F736F75726365223A22552E532E2054726561737572792042696C6C73227D2C226173223A227472656173757279222C2264223A2241207969656C642D62656172696E6720737461626C65636F696E206261636B65642062792073686F72742D7465726D20552E532E205472656173757269657320616E64206D6F6E6579206D61726B657420696E737472756D656E74732E222C2269223A2268747470733A2F2F6578616D706C652E6F72672F7462696C6C2D69636F6E2E706E67222C22696E223A224578616D706C65205969656C6420436F2E222C226E223A22542D42696C6C205969656C6420546F6B656E222C2274223A225442494C4C222C227573223A5B7B2263223A2277656273697465222C2274223A2250726F647563742050616765222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F7462696C6C227D2C7B2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F646F6373227D5D7D",
|
||||
"MaximumAmount": "50000000",
|
||||
"Sequence": 1347205
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ModifiedNode": {
|
||||
"FinalFields": {
|
||||
"Account": "r9fhoyac7uUM9XZFDJV9wXQ4pcJb6UDpJM",
|
||||
"Balance": "99999999",
|
||||
"Flags": 0,
|
||||
"OwnerCount": 1,
|
||||
"Sequence": 1347206
|
||||
},
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"LedgerIndex": "AB5FC35110CED5BFD2CEA3E37B41E43CC4BBAF89AE66BA85942E04CBC38550FB",
|
||||
"PreviousFields": {
|
||||
"Balance": "100000000",
|
||||
"OwnerCount": 0,
|
||||
"Sequence": 1347205
|
||||
},
|
||||
"PreviousTxnID": "1CDF420134492607EC54838F91FA06A655E07DD296ED69CC7172C1AC356BF22B",
|
||||
"PreviousTxnLgrSeq": 1347205
|
||||
}
|
||||
}
|
||||
],
|
||||
"TransactionIndex": 0,
|
||||
"TransactionResult": "tesSUCCESS",
|
||||
"mpt_issuance_id": "00148E8558E6AEAA301085FBFD01D615F059A7CCE6E38296"
|
||||
},
|
||||
"tx_json": {
|
||||
"Account": "r9fhoyac7uUM9XZFDJV9wXQ4pcJb6UDpJM",
|
||||
"AssetScale": 4,
|
||||
"Fee": "1",
|
||||
"Flags": 48,
|
||||
"LastLedgerSequence": 1347225,
|
||||
"MPTokenMetadata": "7B226163223A22727761222C226169223A7B226375736970223A22393132373936525830222C22696E7465726573745F72617465223A22352E303025222C22696E7465726573745F74797065223A227661726961626C65222C226D617475726974795F64617465223A22323034352D30362D3330222C227969656C645F736F75726365223A22552E532E2054726561737572792042696C6C73227D2C226173223A227472656173757279222C2264223A2241207969656C642D62656172696E6720737461626C65636F696E206261636B65642062792073686F72742D7465726D20552E532E205472656173757269657320616E64206D6F6E6579206D61726B657420696E737472756D656E74732E222C2269223A2268747470733A2F2F6578616D706C652E6F72672F7462696C6C2D69636F6E2E706E67222C22696E223A224578616D706C65205969656C6420436F2E222C226E223A22542D42696C6C205969656C6420546F6B656E222C2274223A225442494C4C222C227573223A5B7B2263223A2277656273697465222C2274223A2250726F647563742050616765222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F7462696C6C227D2C7B2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F646F6373227D5D7D",
|
||||
"MaximumAmount": "50000000",
|
||||
"Sequence": 1347205,
|
||||
"SigningPubKey": "ED1EC65DB85E686A55F8FD9BC6E405E8F2F8EA5E1712AED64E28C97350EB4EF6E7",
|
||||
"TransactionType": "MPTokenIssuanceCreate",
|
||||
"TransferFee": 0,
|
||||
"TxnSignature": "3A671905D57342F051E3BF057CCF65B0D94114C04D255D4AE3CEE01C2D0B368118E94011CEB27EC9BB447D3498B24B750F2691B4D7AB71F82626BC6F49465806",
|
||||
"ctid": "C0148E8700000002",
|
||||
"date": 816977610,
|
||||
"ledger_index": 1347207
|
||||
},
|
||||
"validated": true
|
||||
}
|
||||
|
||||
- MPToken created successfully with issuance ID: 00148E8558E6AEAA301085FBFD01D615F059A7CCE6E38296
|
||||
- Explorer URL: https://devnet.xrpl.org/mpt/00148E8558E6AEAA301085FBFD01D615F059A7CCE6E38296
|
||||
|
||||
=== Confirming MPT Issuance metadata in the validated ledger... ===
|
||||
Decoded MPT metadata:
|
||||
{
|
||||
asset_class: 'rwa',
|
||||
additional_info: {
|
||||
cusip: '912796RX0',
|
||||
interest_rate: '5.00%',
|
||||
interest_type: 'variable',
|
||||
maturity_date: '2045-06-30',
|
||||
yield_source: 'U.S. Treasury Bills'
|
||||
},
|
||||
asset_subclass: 'treasury',
|
||||
desc: 'A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.',
|
||||
icon: 'https://example.org/tbill-icon.png',
|
||||
issuer_name: 'Example Yield Co.',
|
||||
name: 'T-Bill Yield Token',
|
||||
ticker: 'TBILL',
|
||||
uris: [
|
||||
{
|
||||
category: 'website',
|
||||
title: 'Product Page',
|
||||
uri: 'https://exampleyield.co/tbill'
|
||||
},
|
||||
{
|
||||
category: 'docs',
|
||||
title: 'Yield Token Docs',
|
||||
uri: 'https://exampleyield.co/docs'
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,85 +1,108 @@
|
||||
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()
|
||||
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: {
|
||||
interest_rate: '5.00%',
|
||||
interest_type: 'variable',
|
||||
yield_source: 'U.S. Treasury Bills',
|
||||
maturity_date: '2045-06-30',
|
||||
cusip: '912796RX0'
|
||||
}
|
||||
}
|
||||
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))
|
||||
// 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 = {
|
||||
TransactionType: 'MPTokenIssuanceCreate',
|
||||
Account: wallet.address,
|
||||
TransactionType: "MPTokenIssuanceCreate",
|
||||
Account: issuer.address,
|
||||
AssetScale: 4,
|
||||
MaximumAmount: '50000000',
|
||||
MaximumAmount: "50000000",
|
||||
TransferFee: 0,
|
||||
Flags: MPTokenIssuanceCreateFlags.tfMPTCanTransfer |
|
||||
MPTokenIssuanceCreateFlags.tfMPTCanTrade,
|
||||
MPTokenMetadata: mpt_metadata_hex
|
||||
Flags:
|
||||
MPTokenIssuanceCreateFlags.tfMPTCanTransfer |
|
||||
MPTokenIssuanceCreateFlags.tfMPTCanTrade,
|
||||
MPTokenMetadata: mpt_metadata_hex,
|
||||
};
|
||||
|
||||
// Sign and submit the transaction
|
||||
console.log("\n=== Sending MPTokenIssuanceCreate transaction...===");
|
||||
console.log(JSON.stringify(mpt_issuance_create, null, 2));
|
||||
const submit_response = await client.submitAndWait(mpt_issuance_create, {
|
||||
wallet: issuer,
|
||||
autofill: true,
|
||||
});
|
||||
|
||||
// Check transaction results
|
||||
console.log("\n=== Checking MPTokenIssuanceCreate results... ===");
|
||||
console.log(JSON.stringify(submit_response.result, null, 2));
|
||||
if (submit_response.result.meta.TransactionResult !== "tesSUCCESS") {
|
||||
const result_code = submit_response.result.meta.TransactionResult;
|
||||
console.warn(`Transaction failed with result code ${result_code}.`);
|
||||
await client.disconnect();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 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}.`)
|
||||
const issuance_id = submit_response.result.meta.mpt_issuance_id;
|
||||
console.log(
|
||||
`\n- MPToken created successfully with issuance ID: ${issuance_id}`
|
||||
);
|
||||
// View the MPT issuance on the XRPL Explorer
|
||||
console.log(`- 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"
|
||||
})
|
||||
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)
|
||||
// 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 = decodeMPTokenMetadata(metadata_blob);
|
||||
console.log("Decoded MPT metadata:\n", decoded_metadata);
|
||||
|
||||
|
||||
client.disconnect()
|
||||
// Disconnect from the client
|
||||
await client.disconnect();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"xrpl": "^4.4.0"
|
||||
"xrpl": "^4.4.3"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,137 @@ 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:
|
||||
The script should output a validated transaction and decoded metadata, similar to the following:
|
||||
|
||||
```text
|
||||
MPToken created successfully with issuance ID 0050773D6B8DF8C6BEA497016C8679728A217DE1C4D50AC5.
|
||||
```sh
|
||||
=== Funding new wallet from faucet... ===
|
||||
Attempting to fund address rN1vQBHqgbfXjeAfYVUVpQXMyyZYjAnQkS
|
||||
Faucet fund successful.
|
||||
|
||||
=== Encoding metadata...===
|
||||
Encoded mpt_metadata_hex: 7B226163223A22727761222C226169223A7B226375736970223A22393132373936525830222C22696E7465726573745F72617465223A22352E303025222C22696E7465726573745F74797065223A227661726961626C65222C226D617475726974795F64617465223A22323034352D30362D3330222C227969656C645F736F75726365223A22552E532E2054726561737572792042696C6C73227D2C226173223A227472656173757279222C2264223A2241207969656C642D62656172696E6720737461626C65636F696E206261636B65642062792073686F72742D7465726D20552E532E205472656173757269657320616E64206D6F6E6579206D61726B657420696E737472756D656E74732E222C2269223A2268747470733A2F2F6578616D706C652E6F72672F7462696C6C2D69636F6E2E706E67222C22696E223A224578616D706C65205969656C6420436F2E222C226E223A22542D42696C6C205969656C6420546F6B656E222C2274223A225442494C4C222C227573223A5B7B2263223A2277656273697465222C2274223A2250726F647563742050616765222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F7462696C6C227D2C7B2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F646F6373227D5D7D
|
||||
|
||||
=== Sending MPTokenIssuanceCreate transaction...===
|
||||
{
|
||||
"Account": "rN1vQBHqgbfXjeAfYVUVpQXMyyZYjAnQkS",
|
||||
"TransactionType": "MPTokenIssuanceCreate",
|
||||
"Flags": 48,
|
||||
"SigningPubKey": "",
|
||||
"AssetScale": 4,
|
||||
"MaximumAmount": "50000000",
|
||||
"TransferFee": 0,
|
||||
"MPTokenMetadata": "7B226163223A22727761222C226169223A7B226375736970223A22393132373936525830222C22696E7465726573745F72617465223A22352E303025222C22696E7465726573745F74797065223A227661726961626C65222C226D617475726974795F64617465223A22323034352D30362D3330222C227969656C645F736F75726365223A22552E532E2054726561737572792042696C6C73227D2C226173223A227472656173757279222C2264223A2241207969656C642D62656172696E6720737461626C65636F696E206261636B65642062792073686F72742D7465726D20552E532E205472656173757269657320616E64206D6F6E6579206D61726B657420696E737472756D656E74732E222C2269223A2268747470733A2F2F6578616D706C652E6F72672F7462696C6C2D69636F6E2E706E67222C22696E223A224578616D706C65205969656C6420436F2E222C226E223A22542D42696C6C205969656C6420546F6B656E222C2274223A225442494C4C222C227573223A5B7B2263223A2277656273697465222C2274223A2250726F647563742050616765222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F7462696C6C227D2C7B2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F646F6373227D5D7D"
|
||||
}
|
||||
|
||||
=== Checking MPTokenIssuanceCreate results... ===
|
||||
{
|
||||
"close_time_iso": "2025-11-20T18:21:12Z",
|
||||
"ctid": "C0148F2200000002",
|
||||
"hash": "47D87C3C93C80F2158CE5A688C63386E939BC77CFF4F5B62F84775A97EF991AE",
|
||||
"ledger_hash": "663C9D10B10586009F5C17B4A9A98220ECB00AF64A248A71ECF970D3E7D206F4",
|
||||
"ledger_index": 1347362,
|
||||
"meta": {
|
||||
"AffectedNodes": [
|
||||
{
|
||||
"ModifiedNode": {
|
||||
"FinalFields": {
|
||||
"Account": "rN1vQBHqgbfXjeAfYVUVpQXMyyZYjAnQkS",
|
||||
"Balance": "99999999",
|
||||
"Flags": 0,
|
||||
"OwnerCount": 1,
|
||||
"Sequence": 1347360
|
||||
},
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"LedgerIndex": "0B10E7C08910B27DE817A935972FBD91B57E6177627FDA78C9C75CD83D32D973",
|
||||
"PreviousFields": {
|
||||
"Balance": "100000000",
|
||||
"OwnerCount": 0,
|
||||
"Sequence": 1347359
|
||||
},
|
||||
"PreviousTxnID": "2166929BBF80BEAA631AB4FBE6864E03CD669D4AFEE6559BA6AB850602A9151A",
|
||||
"PreviousTxnLgrSeq": 1347359
|
||||
}
|
||||
},
|
||||
{
|
||||
"CreatedNode": {
|
||||
"LedgerEntryType": "DirectoryNode",
|
||||
"LedgerIndex": "5D2D7A2717A4ECF4C865A6F80E0C2C228409B27CE948307F3ED01213C9906AC4",
|
||||
"NewFields": {
|
||||
"Owner": "rN1vQBHqgbfXjeAfYVUVpQXMyyZYjAnQkS",
|
||||
"RootIndex": "5D2D7A2717A4ECF4C865A6F80E0C2C228409B27CE948307F3ED01213C9906AC4"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"CreatedNode": {
|
||||
"LedgerEntryType": "MPTokenIssuance",
|
||||
"LedgerIndex": "886355A55396B5511A96BCA43E73E3DEDC2875776EC307252157142B1D36B852",
|
||||
"NewFields": {
|
||||
"AssetScale": 4,
|
||||
"Flags": 48,
|
||||
"Issuer": "rN1vQBHqgbfXjeAfYVUVpQXMyyZYjAnQkS",
|
||||
"MPTokenMetadata": "7B226163223A22727761222C226169223A7B226375736970223A22393132373936525830222C22696E7465726573745F72617465223A22352E303025222C22696E7465726573745F74797065223A227661726961626C65222C226D617475726974795F64617465223A22323034352D30362D3330222C227969656C645F736F75726365223A22552E532E2054726561737572792042696C6C73227D2C226173223A227472656173757279222C2264223A2241207969656C642D62656172696E6720737461626C65636F696E206261636B65642062792073686F72742D7465726D20552E532E205472656173757269657320616E64206D6F6E6579206D61726B657420696E737472756D656E74732E222C2269223A2268747470733A2F2F6578616D706C652E6F72672F7462696C6C2D69636F6E2E706E67222C22696E223A224578616D706C65205969656C6420436F2E222C226E223A22542D42696C6C205969656C6420546F6B656E222C2274223A225442494C4C222C227573223A5B7B2263223A2277656273697465222C2274223A2250726F647563742050616765222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F7462696C6C227D2C7B2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F646F6373227D5D7D",
|
||||
"MaximumAmount": "50000000",
|
||||
"Sequence": 1347359
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"TransactionIndex": 0,
|
||||
"TransactionResult": "tesSUCCESS",
|
||||
"mpt_issuance_id": "00148F1F983B024FB54CE16CBC7F788C2F71AC9728355EFC"
|
||||
},
|
||||
"tx_json": {
|
||||
"Account": "rN1vQBHqgbfXjeAfYVUVpQXMyyZYjAnQkS",
|
||||
"AssetScale": 4,
|
||||
"Fee": "1",
|
||||
"Flags": 48,
|
||||
"LastLedgerSequence": 1347380,
|
||||
"MPTokenMetadata": "7B226163223A22727761222C226169223A7B226375736970223A22393132373936525830222C22696E7465726573745F72617465223A22352E303025222C22696E7465726573745F74797065223A227661726961626C65222C226D617475726974795F64617465223A22323034352D30362D3330222C227969656C645F736F75726365223A22552E532E2054726561737572792042696C6C73227D2C226173223A227472656173757279222C2264223A2241207969656C642D62656172696E6720737461626C65636F696E206261636B65642062792073686F72742D7465726D20552E532E205472656173757269657320616E64206D6F6E6579206D61726B657420696E737472756D656E74732E222C2269223A2268747470733A2F2F6578616D706C652E6F72672F7462696C6C2D69636F6E2E706E67222C22696E223A224578616D706C65205969656C6420436F2E222C226E223A22542D42696C6C205969656C6420546F6B656E222C2274223A225442494C4C222C227573223A5B7B2263223A2277656273697465222C2274223A2250726F647563742050616765222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F7462696C6C227D2C7B2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373222C2275223A2268747470733A2F2F6578616D706C657969656C642E636F2F646F6373227D5D7D",
|
||||
"MaximumAmount": "50000000",
|
||||
"Sequence": 1347359,
|
||||
"SigningPubKey": "ED0BFB56FB91211F7DCB245C3863958B8FF5A5BAC4B7293E598C7B4D34265EF0A9",
|
||||
"TransactionType": "MPTokenIssuanceCreate",
|
||||
"TransferFee": 0,
|
||||
"TxnSignature": "4710CCD303902101E6A009E8D459774D1FA9C59E20816588B9248883FF6A37DD8670C1C6EEED1DE5B363A15C88FCA40C1E74319886F3DB8278A63CF0B88CDC0A",
|
||||
"ctid": "C0148F2200000002",
|
||||
"date": 816978072,
|
||||
"ledger_index": 1347362
|
||||
},
|
||||
"validated": true
|
||||
}
|
||||
|
||||
- MPToken created successfully with issuance ID: 00148F1F983B024FB54CE16CBC7F788C2F71AC9728355EFC
|
||||
- Explorer URL: https://devnet.xrpl.org/mpt/00148F1F983B024FB54CE16CBC7F788C2F71AC9728355EFC
|
||||
|
||||
=== Confirming MPT Issuance metadata in the validated ledger... ===
|
||||
Decoded MPT metadata:
|
||||
{
|
||||
"asset_class": "rwa",
|
||||
"additional_info": {
|
||||
"cusip": "912796RX0",
|
||||
"interest_rate": "5.00%",
|
||||
"interest_type": "variable",
|
||||
"maturity_date": "2045-06-30",
|
||||
"yield_source": "U.S. Treasury Bills"
|
||||
},
|
||||
"asset_subclass": "treasury",
|
||||
"desc": "A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.",
|
||||
"icon": "https://example.org/tbill-icon.png",
|
||||
"issuer_name": "Example Yield Co.",
|
||||
"name": "T-Bill Yield Token",
|
||||
"ticker": "TBILL",
|
||||
"uris": [
|
||||
{
|
||||
"category": "website",
|
||||
"title": "Product Page",
|
||||
"uri": "https://exampleyield.co/tbill"
|
||||
},
|
||||
{
|
||||
"category": "docs",
|
||||
"title": "Yield Token Docs",
|
||||
"uri": "https://exampleyield.co/docs"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import json
|
||||
from xrpl.utils import str_to_hex, hex_to_str
|
||||
from xrpl.utils import encode_mptoken_metadata, decode_mptoken_metadata
|
||||
from xrpl.clients import JsonRpcClient
|
||||
from xrpl.wallet import generate_faucet_wallet
|
||||
from xrpl.transaction import submit_and_wait
|
||||
@@ -7,31 +7,31 @@ from xrpl.models import LedgerEntry, MPTokenIssuanceCreate, MPTokenIssuanceCreat
|
||||
|
||||
# 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)
|
||||
print("=== Funding new wallet from faucet... ===")
|
||||
issuer = generate_faucet_wallet(client, debug=True)
|
||||
|
||||
# Define metadata as JSON
|
||||
# Define metadata as JSON
|
||||
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": "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": "exampleyield.co/tbill",
|
||||
"c": "website",
|
||||
"t": "Product Page"
|
||||
"uri": "https://exampleyield.co/tbill",
|
||||
"category": "website",
|
||||
"title": "Product Page"
|
||||
},
|
||||
{
|
||||
"u": "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",
|
||||
@@ -40,13 +40,17 @@ mpt_metadata = {
|
||||
}
|
||||
}
|
||||
|
||||
# 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)
|
||||
# Encode the metadata.
|
||||
# The encode_mptoken_metadata 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
|
||||
print("\n=== Encoding metadata...===")
|
||||
mpt_metadata_hex = encode_mptoken_metadata(mpt_metadata)
|
||||
print("Encoded mpt_metadata_hex:", mpt_metadata_hex)
|
||||
|
||||
# Define the transaction, including other MPT parameters
|
||||
mpt_issuance_create = MPTokenIssuanceCreate(
|
||||
account=wallet.address,
|
||||
account=issuer.address,
|
||||
asset_scale=4,
|
||||
maximum_amount="50000000",
|
||||
transfer_fee=0,
|
||||
@@ -55,28 +59,33 @@ mpt_issuance_create = MPTokenIssuanceCreate(
|
||||
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))
|
||||
# Sign and submit the transaction
|
||||
print("\n=== Sending MPTokenIssuanceCreate transaction...===")
|
||||
print(json.dumps(mpt_issuance_create.to_xrpl(), indent=2))
|
||||
response = submit_and_wait(mpt_issuance_create, client, issuer, autofill=True)
|
||||
|
||||
# Check transaction results
|
||||
print("\n=== Checking MPTokenIssuanceCreate results... ===")
|
||||
print(json.dumps(response.result, indent=2))
|
||||
result_code = response.result["meta"]["TransactionResult"]
|
||||
if result_code != "tesSUCCESS":
|
||||
print(f"Transaction failed with result code {result_code}")
|
||||
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}")
|
||||
print(f"\n- MPToken created successfully with issuance ID: {issuance_id}")
|
||||
print(f"- Explorer URL: https://devnet.xrpl.org/mpt/{issuance_id}")
|
||||
|
||||
# Look up MPT Issuance entry in the validated ledger
|
||||
print("Confirming MPT Issuance metadata in the validated ledger.")
|
||||
print("\n=== Confirming MPT Issuance metadata in the validated ledger... ===")
|
||||
ledger_entry_response = client.request(LedgerEntry(
|
||||
mpt_issuance=issuance_id,
|
||||
ledger_index="validated"
|
||||
))
|
||||
|
||||
# Decode the metadata
|
||||
# Decode the metadata.
|
||||
# The decode_mptoken_metadata 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.
|
||||
metadata_blob = ledger_entry_response.result["node"]["MPTokenMetadata"]
|
||||
decoded_metadata = json.loads(hex_to_str(metadata_blob))
|
||||
print("Decoded metadata:", decoded_metadata)
|
||||
decoded_metadata = decode_mptoken_metadata(metadata_blob)
|
||||
print("Decoded MPT metadata:\n", json.dumps(decoded_metadata, indent=2))
|
||||
|
||||
@@ -1 +1 @@
|
||||
xrpl-py==4.3.0
|
||||
xrpl-py==4.3.1
|
||||
|
||||
@@ -169,7 +169,6 @@ A transaction is considered successful if it receives a `tesSUCCESS` result.
|
||||
|
||||
| Error Code | Description |
|
||||
|:--------------------------|:--------------------------------------------------|
|
||||
| `temARRAY_EMPTY` | The batch transaction contains zero or one inner transaction. You must submit at least two inner transactions. |
|
||||
| `temINVALID_INNER_BATCH` | An inner transaction is malformed. |
|
||||
| `temSEQ_AND_TICKET` | The transaction contains both a `TicketSequence` field and a non-zero `Sequence` value. A transaction can't include both fields, but must have at least one. |
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ This example assumes that the issuer of the token is the signer of the transacti
|
||||
"AssetScale": 4,
|
||||
"TransferFee": 0,
|
||||
"MaximumAmount": "50000000",
|
||||
"Flags": 83659,
|
||||
"MPTokenMetadata": "7B2274223A225442494C4C222C226E223A22542D42696C6C205969656C6420546F6B656E222C2264223A2241207969656C642D62656172696E6720737461626C65636F696E206261636B65642062792073686F72742D7465726D20552E532E205472656173757269657320616E64206D6F6E6579206D61726B657420696E737472756D656E74732E222C2269223A226578616D706C652E6F72672F7462696C6C2D69636F6E2E706E67222C226163223A22727761222C226173223A227472656173757279222C22696E223A224578616D706C65205969656C6420436F2E222C227573223A5B7B2275223A226578616D706C657969656C642E636F2F7462696C6C222C2263223A2277656273697465222C2274223A2250726F647563742050616765227D2C7B2275223A226578616D706C657969656C642E636F2F646F6373222C2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373227D5D2C226169223A7B22696E7465726573745F72617465223A22352E303025222C22696E7465726573745F74797065223A227661726961626C65222C227969656C645F736F75726365223A22552E532E2054726561737572792042696C6C73222C226D617475726974795F64617465223A22323034352D30362D3330222C226375736970223A22393132373936525830227D7D",
|
||||
"Fee": "12",
|
||||
"Flags": 122,
|
||||
|
||||
221
docs/tutorials/how-tos/use-tokens/issue-a-multi-purpose-token.md
Normal file
221
docs/tutorials/how-tos/use-tokens/issue-a-multi-purpose-token.md
Normal file
@@ -0,0 +1,221 @@
|
||||
---
|
||||
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 MPToken on the XRP Ledger.
|
||||
- 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.
|
||||
- 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.
|
||||
- **Python** with the [xrpl-py library](https://github.com/XRPLF/xrpl-py). See [Get Started Using Python](../../python/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
|
||||
|
||||
The example in this tutorial demonstrates how to issue a sample [US Treasury bill (T-bill)](https://www.treasurydirect.gov/research-center/history-of-marketable-securities/bills/t-bills-indepth/) as an MPT on the XRP Ledger.
|
||||
|
||||
### 1. Install dependencies
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="Javascript" %}
|
||||
From the code sample folder, use npm to install dependencies:
|
||||
|
||||
```bash
|
||||
npm install xrpl
|
||||
```
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
From the code sample folder, install dependencies using pip:
|
||||
|
||||
```bash
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
{% /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 %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/py/issue-mpt-with-metadata.py" language="py" before="# Define metadata as JSON" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
### 3. Define and encode MPT metadata
|
||||
|
||||
The metadata you provide is what distinguishes your token from other MPTs. Define the JSON metadata as shown in the following code snippet:
|
||||
|
||||
{% 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 %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/py/issue-mpt-with-metadata.py" language="py" from="# Define metadata as JSON" before="# Encode the metadata" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
The metadata schema defined in XLS-89 supports both long field names (`ticker`, `name`, `desc`) and compact short keys (`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 JSON, the **encoding utility function** automatically shortens them to their compact key equivalents before encoding. Similarly, when decoding, the **decoding utility function** converts the short keys back to their respective long names.
|
||||
|
||||
To encode the metadata:
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="Javascript" %}
|
||||
{% 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 %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/py/issue-mpt-with-metadata.py" language="py" from="# Encode the metadata" before="# Define the transaction" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
{% admonition type="warning" name="Warning" %}
|
||||
The encoding function will raise an error if the input is not a valid JSON object.
|
||||
{% /admonition %}
|
||||
|
||||
### 4. Prepare the MPTokenIssuanceCreate transaction
|
||||
|
||||
To issue the MPT, create an `MPTokenIssuanceCreate` transaction object. Specify the issuer, asset scale, maximum amount, flags, and the encoded metadata.
|
||||
|
||||
| Field | Description |
|
||||
|:------------------- |:------ |
|
||||
| `TransactionType` | The type of transaction, in this case `MPTokenIssuanceCreate`. |
|
||||
| `Account` | The wallet address of the account that is issuing the MPT, in this case the `issuer`. |
|
||||
| `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 set token permissions. For this example the **Can Transfer** and **Can Trade** flags are enabled. See [MPTokenIssuanceCreate Flags](../../../references/protocol/transactions/types/mptokenissuancecreate.md#mptokenissuancecreate-flags) for all available flags. |
|
||||
| `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="// Sign and submit the transaction" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/py/issue-mpt-with-metadata.py" language="py" from="# Define the transaction" before="# Sign and submit the transaction" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
### 5. Submit MPTokenIssuanceCreate transaction
|
||||
|
||||
Sign and submit the `MPTokenIssuanceCreate` transaction to the ledger.
|
||||
|
||||
{% tabs %}
|
||||
|
||||
{% tab label="Javascript" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/js/issue-mpt-with-metadata.js" language="js" from="// Sign and submit the transaction" before="// Check transaction results" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/py/issue-mpt-with-metadata.py" language="py" from="# Sign and submit the transaction" before="# Check transaction results" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
Some important considerations about token metadata when you submit the transaction:
|
||||
|
||||
- If you provide metadata that exceeds the 1024-byte limit, the transaction will fail with an error.
|
||||
|
||||
- If the metadata does not conform to the XLS-89 standards, the transaction stills succeeds, but your token may not be compatible with wallets and applications that expect valid MPT metadata.
|
||||
|
||||
The SDK libraries provide a warning to help you diagnose why your metadata is not compliant. For example, you might see a warning like the following:
|
||||
|
||||
```sh
|
||||
MPTokenMetadata is not properly formatted as JSON as per the XLS-89d standard.
|
||||
While adherence to this standard is not mandatory, such non-compliant MPToken's
|
||||
might not be discoverable by Explorers and Indexers in the XRPL ecosystem.
|
||||
- ticker/t: should have uppercase letters (A-Z) and digits (0-9) only. Max 6 characters recommended.
|
||||
- name/n: should be a non-empty string.
|
||||
- icon/i: should be a non-empty string.
|
||||
- asset_class/ac: should be one of rwa, memes, wrapped, gaming, defi, other.
|
||||
```
|
||||
|
||||
### 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 %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/py/issue-mpt-with-metadata.py" language="py" from="# Check transaction results" before="# Look up MPT Issuance entry" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
A `tesSUCCESS` result indicates that the transaction is successful and the token has been created.
|
||||
|
||||
### 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 %}
|
||||
|
||||
{% tab label="Python" %}
|
||||
{% code-snippet file="/_code-samples/issue-mpt-with-metadata/py/issue-mpt-with-metadata.py" language="py" from="# Look up MPT Issuance entry" /%}
|
||||
{% /tab %}
|
||||
|
||||
{% /tabs %}
|
||||
|
||||
The decoding utility function converts the metadata back to a JSON object and expands the compact key names back to their respective long names.
|
||||
|
||||
## See Also
|
||||
|
||||
- **Concepts**:
|
||||
- [Multi-Purpose Tokens (MPT)](../../../concepts/tokens/fungible-tokens/multi-purpose-tokens.md)
|
||||
- **References**:
|
||||
- [MPTokenIssuance entry][]
|
||||
- [MPTokenIssuanceCreate transaction][]
|
||||
|
||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
||||
@@ -322,6 +322,7 @@
|
||||
expanded: false
|
||||
items:
|
||||
- page: docs/tutorials/how-tos/use-tokens/issue-a-fungible-token.md
|
||||
- page: docs/tutorials/how-tos/use-tokens/issue-a-multi-purpose-token.md
|
||||
- page: docs/tutorials/how-tos/use-tokens/trade-in-the-decentralized-exchange.md
|
||||
- page: docs/tutorials/how-tos/use-tokens/enable-no-freeze.md
|
||||
- page: docs/tutorials/how-tos/use-tokens/enact-global-freeze.md
|
||||
|
||||
Reference in New Issue
Block a user