Compare commits

..

3 Commits

Author SHA1 Message Date
Maria Shodunke
a71a3fca10 Add tutorial for issuing an MPT (Javascript and Python). 2025-11-21 13:43:33 +00:00
Rome Reginelli
003927517f Merge pull request #3379 from XRPLF/rr-mpt-dupe-flag
Remove duplicate flags field in sample JSON
2025-11-14 12:19:31 -08:00
Rome Reginelli
9c8c231900 Remove duplicate flags field in sample JSON 2025-11-11 15:53:25 -08:00
11 changed files with 641 additions and 128 deletions

View File

@@ -1,9 +1,7 @@
// @chunk {"steps": ["import-node-tag"]}
// Import the library // Import the library
import xrpl from "xrpl"
// @chunk-end
// @chunk {"steps": ["connect-tag"]} // @chunk {"steps": ["connect-tag"]}
import xrpl from "xrpl"
// Define the network client // Define the network client
const SERVER_URL = "wss://s.altnet.rippletest.net:51233/" const SERVER_URL = "wss://s.altnet.rippletest.net:51233/"
const client = new xrpl.Client(SERVER_URL) const client = new xrpl.Client(SERVER_URL)

View File

@@ -9,8 +9,135 @@ npm i
node issue-mpt-with-metadata.js 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 ```sh
MPToken created successfully with issuance ID 005073C721E14A7613BAAF5E0B1A253459832FF8D0D81278. === 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'
}
]
}
``` ```

View File

@@ -1,85 +1,108 @@
import { stringToHex, hexToString } from '@xrplf/isomorphic/dist/utils/index.js' import {
import { MPTokenIssuanceCreateFlags, Client } from 'xrpl' MPTokenIssuanceCreateFlags,
Client,
encodeMPTokenMetadata,
decodeMPTokenMetadata,
} from "xrpl";
// Connect to network and get a wallet // Connect to network and get a wallet
const client = new Client('wss://s.devnet.rippletest.net:51233') const client = new Client("wss://s.devnet.rippletest.net:51233");
await client.connect() await client.connect();
console.log('Funding new wallet from faucet...') console.log("=== Funding new wallet from faucet...===");
const { wallet } = await client.fundWallet() const { wallet: issuer } = await client.fundWallet();
console.log(`Issuer address: ${issuer.address}`);
// Define metadata as JSON // Define metadata as JSON
const mpt_metadata = { const mpt_metadata = {
t: 'TBILL', ticker: "TBILL",
n: 'T-Bill Yield Token', name: "T-Bill Yield Token",
d: 'A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.', desc: "A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.",
i: 'https://example.org/tbill-icon.png', icon: "https://example.org/tbill-icon.png",
ac: 'rwa', asset_class: "rwa",
as: 'treasury', asset_subclass: "treasury",
in: 'Example Yield Co.', issuer_name: "Example Yield Co.",
us: [ uris: [
{ {
u: 'https://exampleyield.co/tbill', uri: "https://exampleyield.co/tbill",
c: 'website', category: "website",
t: 'Product Page' title: "Product Page",
}, },
{ {
u: 'https://exampleyield.co/docs', uri: "https://exampleyield.co/docs",
c: 'docs', category: "docs",
t: 'Yield Token Docs' title: "Yield Token Docs",
} },
], ],
ai: { additional_info: {
interest_rate: '5.00%', interest_rate: "5.00%",
interest_type: 'variable', interest_type: "variable",
yield_source: 'U.S. Treasury Bills', yield_source: "U.S. Treasury Bills",
maturity_date: '2045-06-30', maturity_date: "2045-06-30",
cusip: '912796RX0' cusip: "912796RX0",
} },
} };
// Convert JSON to a string (without excess whitespace), then string to hex // Encode the metadata.
const mpt_metadata_hex = stringToHex(JSON.stringify(mpt_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 // Define the transaction, including other MPT parameters
const mpt_issuance_create = { const mpt_issuance_create = {
TransactionType: 'MPTokenIssuanceCreate', TransactionType: "MPTokenIssuanceCreate",
Account: wallet.address, Account: issuer.address,
AssetScale: 4, AssetScale: 4,
MaximumAmount: '50000000', MaximumAmount: "50000000",
TransferFee: 0, TransferFee: 0,
Flags: MPTokenIssuanceCreateFlags.tfMPTCanTransfer | Flags:
MPTokenIssuanceCreateFlags.tfMPTCanTrade, MPTokenIssuanceCreateFlags.tfMPTCanTransfer |
MPTokenMetadata: mpt_metadata_hex 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 const issuance_id = submit_response.result.meta.mpt_issuance_id;
console.log('Sending MPTokenIssuanceCreate transaction...') console.log(
const submit_response = await client.submitAndWait(mpt_issuance_create, { wallet, autofill: true }) `\n- MPToken created successfully with issuance ID: ${issuance_id}`
);
// Check transaction results and disconnect // View the MPT issuance on the XRPL Explorer
console.log(JSON.stringify(submit_response, null, 2)) console.log(`- Explorer URL: https://devnet.xrpl.org/mpt/${issuance_id}`);
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 // 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({ const ledger_entry_response = await client.request({
"command": "ledger_entry", command: "ledger_entry",
"mpt_issuance": issuance_id, mpt_issuance: issuance_id,
"ledger_index": "validated" ledger_index: "validated",
}) });
// Decode the metadata // Decode the metadata.
const metadata_blob = ledger_entry_response.result.node.MPTokenMetadata // The decodeMPTokenMetadata function takes a hex-encoded string representing MPT metadata,
const decoded_metadata = JSON.parse(hexToString(metadata_blob)) // decodes it to a JSON object, and expands any compact field names to their full forms.
console.log('Decoded metadata:', decoded_metadata) const metadata_blob = ledger_entry_response.result.node.MPTokenMetadata;
const decoded_metadata = decodeMPTokenMetadata(metadata_blob);
console.log("Decoded MPT metadata:\n", decoded_metadata);
// Disconnect from the client
client.disconnect() await client.disconnect();

View File

@@ -1,6 +1,6 @@
{ {
"dependencies": { "dependencies": {
"xrpl": "^4.4.0" "xrpl": "^4.4.3"
}, },
"type": "module" "type": "module"
} }

View File

@@ -11,8 +11,137 @@ pip install -r requirements.txt
python issue-mpt-with-metadata.py 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 ```sh
MPToken created successfully with issuance ID 0050773D6B8DF8C6BEA497016C8679728A217DE1C4D50AC5. === 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"
}
]
}
``` ```

View File

@@ -1,5 +1,5 @@
import json 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.clients import JsonRpcClient
from xrpl.wallet import generate_faucet_wallet from xrpl.wallet import generate_faucet_wallet
from xrpl.transaction import submit_and_wait 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 # Set up client and get a wallet
client = JsonRpcClient("https://s.devnet.rippletest.net:51234") client = JsonRpcClient("https://s.devnet.rippletest.net:51234")
print("Funding new wallet from faucet...") print("=== Funding new wallet from faucet... ===")
wallet = generate_faucet_wallet(client, debug=True) issuer = generate_faucet_wallet(client, debug=True)
# Define metadata as JSON # Define metadata as JSON
mpt_metadata = { mpt_metadata = {
"t": "TBILL", "ticker": "TBILL",
"n": "T-Bill Yield Token", "name": "T-Bill Yield Token",
"d": "A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.", "desc": "A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.",
"i": "example.org/tbill-icon.png", "icon": "https://example.org/tbill-icon.png",
"ac": "rwa", "asset_class": "rwa",
"as": "treasury", "asset_subclass": "treasury",
"in": "Example Yield Co.", "issuer_name": "Example Yield Co.",
"us": [ "uris": [
{ {
"u": "exampleyield.co/tbill", "uri": "https://exampleyield.co/tbill",
"c": "website", "category": "website",
"t": "Product Page" "title": "Product Page"
}, },
{ {
"u": "exampleyield.co/docs", "uri": "https://exampleyield.co/docs",
"c": "docs", "category": "docs",
"t": "Yield Token Docs" "title": "Yield Token Docs"
} }
], ],
"ai": { "additional_info": {
"interest_rate": "5.00%", "interest_rate": "5.00%",
"interest_type": "variable", "interest_type": "variable",
"yield_source": "U.S. Treasury Bills", "yield_source": "U.S. Treasury Bills",
@@ -40,13 +40,17 @@ mpt_metadata = {
} }
} }
# Convert JSON to a string (without excess whitespace), then string to hex # Encode the metadata.
mpt_metadata_string = json.dumps(mpt_metadata, separators=(',', ':')) # The encode_mptoken_metadata function converts the JSON metadata object into
mpt_metadata_hex = str_to_hex(mpt_metadata_string) # 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 # Define the transaction, including other MPT parameters
mpt_issuance_create = MPTokenIssuanceCreate( mpt_issuance_create = MPTokenIssuanceCreate(
account=wallet.address, account=issuer.address,
asset_scale=4, asset_scale=4,
maximum_amount="50000000", maximum_amount="50000000",
transfer_fee=0, transfer_fee=0,
@@ -55,28 +59,33 @@ mpt_issuance_create = MPTokenIssuanceCreate(
mptoken_metadata=mpt_metadata_hex mptoken_metadata=mpt_metadata_hex
) )
# Prepare, sign, and submit the transaction # Sign and submit the transaction
print("Sending MPTokenIssuanceCreate transaction...") print("\n=== Sending MPTokenIssuanceCreate transaction...===")
response = submit_and_wait(mpt_issuance_create, client, wallet, autofill=True) print(json.dumps(mpt_issuance_create.to_xrpl(), indent=2))
print(json.dumps(response.result, indent=2)) response = submit_and_wait(mpt_issuance_create, client, issuer, autofill=True)
# Check transaction results # Check transaction results
print("\n=== Checking MPTokenIssuanceCreate results... ===")
print(json.dumps(response.result, indent=2))
result_code = response.result["meta"]["TransactionResult"] result_code = response.result["meta"]["TransactionResult"]
if result_code != "tesSUCCESS": if result_code != "tesSUCCESS":
print(f"Transaction failed with result code {result_code}") print(f"Transaction failed with result code {result_code}.")
exit(1) exit(1)
issuance_id = response.result["meta"]["mpt_issuance_id"] 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 # 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( ledger_entry_response = client.request(LedgerEntry(
mpt_issuance=issuance_id, mpt_issuance=issuance_id,
ledger_index="validated" 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"] metadata_blob = ledger_entry_response.result["node"]["MPTokenMetadata"]
decoded_metadata = json.loads(hex_to_str(metadata_blob)) decoded_metadata = decode_mptoken_metadata(metadata_blob)
print("Decoded metadata:", decoded_metadata) print("Decoded MPT metadata:\n", json.dumps(decoded_metadata, indent=2))

View File

@@ -1 +1 @@
xrpl-py==4.3.0 xrpl-py==4.3.1

View File

@@ -24,7 +24,6 @@ This example assumes that the issuer of the token is the signer of the transacti
"AssetScale": 4, "AssetScale": 4,
"TransferFee": 0, "TransferFee": 0,
"MaximumAmount": "50000000", "MaximumAmount": "50000000",
"Flags": 83659,
"MPTokenMetadata": "7B2274223A225442494C4C222C226E223A22542D42696C6C205969656C6420546F6B656E222C2264223A2241207969656C642D62656172696E6720737461626C65636F696E206261636B65642062792073686F72742D7465726D20552E532E205472656173757269657320616E64206D6F6E6579206D61726B657420696E737472756D656E74732E222C2269223A226578616D706C652E6F72672F7462696C6C2D69636F6E2E706E67222C226163223A22727761222C226173223A227472656173757279222C22696E223A224578616D706C65205969656C6420436F2E222C227573223A5B7B2275223A226578616D706C657969656C642E636F2F7462696C6C222C2263223A2277656273697465222C2274223A2250726F647563742050616765227D2C7B2275223A226578616D706C657969656C642E636F2F646F6373222C2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373227D5D2C226169223A7B22696E7465726573745F72617465223A22352E303025222C22696E7465726573745F74797065223A227661726961626C65222C227969656C645F736F75726365223A22552E532E2054726561737572792042696C6C73222C226D617475726974795F64617465223A22323034352D30362D3330222C226375736970223A22393132373936525830227D7D", "MPTokenMetadata": "7B2274223A225442494C4C222C226E223A22542D42696C6C205969656C6420546F6B656E222C2264223A2241207969656C642D62656172696E6720737461626C65636F696E206261636B65642062792073686F72742D7465726D20552E532E205472656173757269657320616E64206D6F6E6579206D61726B657420696E737472756D656E74732E222C2269223A226578616D706C652E6F72672F7462696C6C2D69636F6E2E706E67222C226163223A22727761222C226173223A227472656173757279222C22696E223A224578616D706C65205969656C6420436F2E222C227573223A5B7B2275223A226578616D706C657969656C642E636F2F7462696C6C222C2263223A2277656273697465222C2274223A2250726F647563742050616765227D2C7B2275223A226578616D706C657969656C642E636F2F646F6373222C2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373227D5D2C226169223A7B22696E7465726573745F72617465223A22352E303025222C22696E7465726573745F74797065223A227661726961626C65222C227969656C645F736F75726365223A22552E532E2054726561737572792042696C6C73222C226D617475726974795F64617465223A22323034352D30362D3330222C226375736970223A22393132373936525830227D7D",
"Fee": "12", "Fee": "12",
"Flags": 122, "Flags": 122,

View File

@@ -0,0 +1,232 @@
---
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 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 and decode token metadata according to the XLS-89 standard.
## 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 account
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 %}
{% admonition type="info" name="Note" %}
The ledger entry that defines an MPT issuance counts as one object towards the issuer's [owner reserve](../../../concepts/accounts/reserves.md#owner-reserves), so the issuer needs to set aside **{% $env.PUBLIC_OWNER_RESERVE %}** per MPT issuance.
{% /admonition %}
### 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, its 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 raises an error if the input isn't a valid JSON object.
{% /admonition %}
### 4. Prepare the MPTokenIssuanceCreate transaction
To issue the MPT, create an `MPTokenIssuanceCreate` transaction object with the following fields:
| Field | Value |
|:------------------- |:------ |
| `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 (for example, `4` means amounts are divided by `10,000`). |
| `MaximumAmount` | The maximum supply of the token to be issued. |
| `TransferFee` | The transfer fee (if any) to charge for token transfers. In this example it is set to `0`. |
| `Flags` | Flags to set token permissions. For this example, the following flags are configured: <ul><li>**Can Transfer**: A holder can transfer the T-bill MPT to another account.</li><li>**Can Trade**: A holder can trade the T-bill MPT with another account.</li></ul>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
Some important considerations about token metadata when you submit the transaction:
- If you provide metadata that exceeds the 1024-byte limit, the transaction fails with an error.
- If the metadata does not conform to the XLS-89 standards, the transaction still 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 may not be compliant. For example:
```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.
```
Sign and submit the `MPTokenIssuanceCreate` transaction to the ledger.
{% admonition type="warning" name="Warning" %}
Once created, the MPT cannot be modified. Review all settings carefully before submitting the transaction. Mutable token properties are planned for a future XRPL amendment ([XLS-94](https://xls.xrpl.org/xls/XLS-0094-dynamic-MPT.html)).
{% /admonition %}
{% 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 %}
### 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][]
- [MPTokenIssuanceDestroy transaction][]
- [MPTokenIssuanceSet transaction][]
<!-- TODO: Add when the tutorial on sending MPTs is ready. -->
<!-- - **Tutorials**:
- [Send a Multi-Purpose Token (MPT)](./send-a-multi-purpose-token.md) -->
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -62,10 +62,10 @@ Click **Download** on the top right of the code preview panel to download the so
Follow the steps to create a simple application with `xrpl.js`. Follow the steps to create a simple application with `xrpl.js`.
<!-- Web steps -->
{% step id="import-web-tag" when={ "environment": "Web" } %}
### 1. Install Dependencies ### 1. Install Dependencies
<!-- Web steps -->
{% step id="import-web-tag" when={ "environment": "Web" } %}
To load `xrpl.js` into your project, add a `<script>` tag to your HTML. To load `xrpl.js` into your project, add a `<script>` tag to your HTML.
You can load the library from a CDN as in the example, or download a release and host it on your own website. You can load the library from a CDN as in the example, or download a release and host it on your own website.
@@ -74,8 +74,7 @@ This loads the module into the top level as `xrpl`.
{% /step %} {% /step %}
<!-- Node.js steps --> <!-- Node.js steps -->
{% step id="import-node-tag" when={ "environment": "Node" } %} {% step id="install-node-tag" when={ "environment": "Node" } %}
### 1. Install Dependencies
Start a new project by creating an empty folder, then move into that folder and use [NPM](https://www.npmjs.com/) to install the latest version of xrpl.js: Start a new project by creating an empty folder, then move into that folder and use [NPM](https://www.npmjs.com/) to install the latest version of xrpl.js:
@@ -95,7 +94,7 @@ Your `package.json` file should look something like this:
{% step id="connect-tag" %} {% step id="connect-tag" %}
#### Connect to the XRP Ledger Testnet #### Connect to the XRP Ledger Testnet
To make queries and submit transactions, you need to connect to the XRP Ledger. To do this with `xrpl.js`, you create an instance of the [`Client`](https://js.xrpl.org/classes/Client.html) class and use the [`connect()`](https://js.xrpl.org/classes/Client.html#connect) method. To make queries and submit transactions, you need to connect to the XRP Ledger. To do this with `xrpl.js`, you create an instance of the `Client` class and use the `connect()` method.
{% admonition type="success" name="Tip" %}Many network functions in `xrpl.js` use [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) to return values asynchronously. The code samples here use the [`async/await` pattern](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await) to wait for the actual result of the Promises.{% /admonition %} {% admonition type="success" name="Tip" %}Many network functions in `xrpl.js` use [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) to return values asynchronously. The code samples here use the [`async/await` pattern](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await) to wait for the actual result of the Promises.{% /admonition %}
@@ -131,48 +130,46 @@ The sample code shows you how to connect to the Testnet, which is one of the ava
{% step id="get-account-create-wallet-tag" %} {% step id="get-account-create-wallet-tag" %}
#### Create and Fund a Wallet #### Create and Fund a Wallet
The `xrpl.js` library has a [`Wallet`](https://js.xrpl.org/classes/Wallet.html) class for handling the keys and address of an XRP Ledger account. On Testnet, you can fund a new account as shown in the example. The `xrpl.js` library has a `Wallet` class for handling the keys and address of an XRP Ledger account. On Testnet, you can fund a new account as shown in the example.
{% /step %} {% /step %}
{% step id="get-account-create-wallet-b-tag" %} {% step id="get-account-create-wallet-b-tag" %}
#### (Optional) Generate a Wallet Only #### (Optional) Generate a Wallet Only
If you want to generate a wallet without funding it, you can create a new [`Wallet`](https://js.xrpl.org/classes/Wallet.html) instance. Keep in mind that you need to send XRP to the wallet for it to be a valid account on the ledger. If you want to generate a wallet without funding it, you can create a new `Wallet` instance. Keep in mind that you need to send XRP to the wallet for it to be a valid account on the ledger.
{% /step %} {% /step %}
{% step id="get-account-create-wallet-c-tag" %} {% step id="get-account-create-wallet-c-tag" %}
#### (Optional) Use Your Own Wallet Seed #### (Optional) Use Your Own Wallet Seed
To use an existing wallet seed encoded in [base58][], you can create a [`Wallet`](https://js.xrpl.org/classes/Wallet.html) instance from it. To use an existing wallet seed encoded in [base58][], you can create a `Wallet` instance from it.
{% /step %} {% /step %}
{% step id="query-xrpl-tag" %}
### 4. Query the XRP Ledger ### 4. Query the XRP Ledger
Use the Client's [`request()`](https://js.xrpl.org/classes/Client.html#request) method to access the XRP Ledger's [WebSocket API](../../../references/http-websocket-apis/api-conventions/request-formatting.md). {% step id="query-xrpl-tag" %}
Use the Client's `request()` method to access the XRP Ledger's [WebSocket API](../../../references/http-websocket-apis/api-conventions/request-formatting.md).
{% /step %} {% /step %}
{% step id="listen-for-events-tag" %}
### 5. Listen for Events ### 5. Listen for Events
You can set up handlers for various types of events in `xrpl.js`, such as whenever the XRP Ledger's [consensus process](../../../concepts/consensus-protocol/index.md) produces a new [ledger version](../../../concepts/ledgers/index.md). To do that, first call the [subscribe method][] to get the type of events you want, then attach an event handler using the [`on(eventType, callback)`](https://js.xrpl.org/classes/Client.html#on) method of the client. {% step id="listen-for-events-tag" %}
You can set up handlers for various types of events in `xrpl.js`, such as whenever the XRP Ledger's [consensus process](../../../concepts/consensus-protocol/index.md) produces a new [ledger version](../../../concepts/ledgers/index.md). To do that, first call the [subscribe method][] to get the type of events you want, then attach an event handler using the `on(eventType, callback)` method of the client.
{% /step %} {% /step %}
{% step id="disconnect-node-tag" when={ "environment": "Node" } %}
### 6. Disconnect ### 6. Disconnect
Call the [`disconnect()`](https://js.xrpl.org/classes/Client.html#disconnect) function so Node.js can end the process. The example code waits 10 seconds before disconnecting to allow time for the ledger event listener to receive and display events. {% step id="disconnect-node-tag" when={ "environment": "Node" } %}
Disconnect when done so Node.js can end the process. The example code waits 10 seconds before disconnecting to allow time for the ledger event listener to receive and display events.
{% /step %} {% /step %}
{% step id="disconnect-web-tag" when={ "environment": "Web" } %} {% step id="disconnect-web-tag" when={ "environment": "Web" } %}
### 6. Disconnect Disconnect from the ledger when done. The example code waits 10 seconds before disconnecting to allow time for the ledger event listener to receive and display events.
Call the [`disconnect()`](https://js.xrpl.org/classes/Client.html#disconnect) function to disconnect from the ledger when done. The example code waits 10 seconds before disconnecting to allow time for the ledger event listener to receive and display events.
{% /step %} {% /step %}
{% step id="run-app-node-tag" when={ "environment": "Node" } %}
### 7. Run the Application ### 7. Run the Application
{% step id="run-app-node-tag" when={ "environment": "Node" } %}
Finally, in your terminal, run the application like so: Finally, in your terminal, run the application like so:
```sh ```sh
@@ -240,8 +237,6 @@ Disconnected
{% /step %} {% /step %}
{% step id="run-app-web-tag" when={ "environment": "Web" } %} {% step id="run-app-web-tag" when={ "environment": "Web" } %}
### 7. Run the Application
Open the `index.html` file in a web browser. Open the `index.html` file in a web browser.
You should see output similar to the following: You should see output similar to the following:

View File

@@ -322,6 +322,7 @@
expanded: false expanded: false
items: items:
- page: docs/tutorials/how-tos/use-tokens/issue-a-fungible-token.md - 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/trade-in-the-decentralized-exchange.md
- page: docs/tutorials/how-tos/use-tokens/enable-no-freeze.md - page: docs/tutorials/how-tos/use-tokens/enable-no-freeze.md
- page: docs/tutorials/how-tos/use-tokens/enact-global-freeze.md - page: docs/tutorials/how-tos/use-tokens/enact-global-freeze.md