Compare commits

...

52 Commits

Author SHA1 Message Date
oeggert
a5475869c5 Update docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-12-19 14:53:17 -08:00
oeggert
053c4bb5a2 Update docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-12-19 14:52:05 -08:00
oeggert
9ceb186fb4 Update docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-12-19 14:51:50 -08:00
oeggert
18542eb915 Update docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-12-19 14:51:03 -08:00
oeggert
d8655b4a0c Update docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-12-19 14:50:52 -08:00
Oliver Eggert
3b276c6f19 update error messages 2025-12-17 21:56:34 -08:00
Oliver Eggert
898e698bec alphabetize entries 2025-12-17 21:14:02 -08:00
Oliver Eggert
e5049e53f9 add xchainownedcreateaccountclaimid entry 2025-12-17 20:54:00 -08:00
Oliver Eggert
afd636e69d add xchainownedclaimid entry 2025-12-17 18:50:58 -08:00
Oliver Eggert
a5b914caee remove unnecessary index field from bridge table 2025-12-17 18:06:00 -08:00
Oliver Eggert
df7cd95784 fix bridge entry 2025-12-17 17:53:43 -08:00
Oliver Eggert
5a9357553c add signerlist entry 2025-12-17 12:37:03 -08:00
Oliver Eggert
21d27c36bb add permissioneddomain entry 2025-12-17 12:20:39 -08:00
Oliver Eggert
d153a017b2 remove oracle not enabled status 2025-12-17 10:21:25 -08:00
Oliver Eggert
20a873ae55 fix credential entry and add example 2025-12-17 10:19:43 -08:00
Oliver Eggert
e54a5a4ea6 add negativeunl entry 2025-12-16 21:12:51 -08:00
Oliver Eggert
8f05a58f12 add nftokenoffer 2025-12-10 16:38:06 -08:00
Oliver Eggert
d8849f03f9 update amendments, feesettings, and ledgerhash to mainnet queries 2025-12-10 14:57:05 -08:00
Oliver Eggert
4b8b714e5b add amendments, did, fee, and hashes options 2025-12-10 14:24:50 -08:00
Maria Shodunke
898d067c02 Merge pull request #3386 from XRPLF/issue-mptoken-tutorial
Add tutorial for issuing an MPT (Javascript and Python)
2025-12-10 10:47:25 +00:00
oeggert
acc02da22e Merge pull request #3374 from XRPLF/rippled-3.0.0
3.0 Release Doc Updates
2025-12-09 23:29:43 -08:00
oeggert
ea16168700 Merge pull request #3407 from XRPLF/release-notes-3.0
Release notes 3.0
2025-12-09 16:38:59 -08:00
Oliver Eggert
ddafea0fe0 update date 2025-12-09 16:32:14 -08:00
oeggert
5d4904cfd6 Merge pull request #3377 from XRPLF/update-amendments-3.0
update known amendment page
2025-12-09 16:29:30 -08:00
Oliver Eggert
5e02c839ea update hash links and commit 2025-12-09 16:21:44 -08:00
Oliver Eggert
a44713a903 fix grammar 2025-12-09 15:03:09 -08:00
Oliver Eggert
3be9307845 add reviewer suggestions 2025-12-09 15:01:04 -08:00
oeggert
e197e4e034 Merge pull request #3414 from XRPLF/ledger-entry-update
add breaking change for ledger_entry
2025-12-09 13:46:51 -08:00
Oliver Eggert
337a576d2d add ammclawbackrounding 2025-12-09 12:10:12 -08:00
Oliver Eggert
1534ecfa26 add breaking change 2025-12-09 12:04:05 -08:00
Oliver Eggert
9600871944 add breaking change info 2025-12-09 11:08:53 -08:00
Maria Shodunke
7f4004ec30 Merge pull request #3411 from XRPLF/dependabot/go_modules/_code-samples/use-tickets/go/golang.org/x/crypto-0.45.0
Bump golang.org/x/crypto from 0.35.0 to 0.45.0 in /_code-samples/use-tickets/go
2025-12-09 14:22:34 +00:00
dependabot[bot]
372a9128a1 Bump golang.org/x/crypto in /_code-samples/use-tickets/go
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.35.0 to 0.45.0.
- [Commits](https://github.com/golang/crypto/compare/v0.35.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.45.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-09 14:19:08 +00:00
Maria Shodunke
3a339849b3 Merge pull request #3402 from XRPLF/dependabot/go_modules/_code-samples/non-fungible-token/go/golang.org/x/crypto-0.45.0
Bump golang.org/x/crypto from 0.35.0 to 0.45.0 in /_code-samples/non-fungible-token/go
2025-12-09 14:18:12 +00:00
Maria Shodunke
8a4d1851db Fix mpt-generator html file and regenerate zip 2025-12-09 12:17:43 +00:00
Maria Shodunke
2faba938f7 Run standard command to fix JS code style 2025-12-09 12:13:00 +00:00
Maria Shodunke
7dadae868f Apply suggestions from code review
Co-authored-by: oeggert <117319296+oeggert@users.noreply.github.com>
2025-12-09 11:28:22 +00:00
oeggert
da422329f9 Update blog/2025/rippled-3.0.0.md
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
2025-12-08 14:11:03 -08:00
Oliver Eggert
fa40ba2b71 add fixincludekeyletfields 2025-12-05 14:13:27 -08:00
Oliver Eggert
506b1c7b21 add release notes 2025-12-05 13:42:51 -08:00
dependabot[bot]
8f21c5d402 Bump golang.org/x/crypto in /_code-samples/non-fungible-token/go
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.35.0 to 0.45.0.
- [Commits](https://github.com/golang/crypto/compare/v0.35.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.45.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-03 11:22:53 +00:00
Oliver Eggert
938a85eac0 add lending protocol amendment and reviewer suggestion 2025-12-02 14:15:38 -08:00
Oliver Eggert
ad280c2c1b initial release notes 2025-12-01 17:03:41 -08:00
Oliver Eggert
682389e4e7 update binary format for signed int 2025-11-25 15:16:36 -08:00
Oliver Eggert
5c467f1c9b initialize 3.0 doc branch 2025-11-25 15:16:36 -08:00
Oliver Eggert
104d07c6bf add fixMPTDeliveredAmount amendment info 2025-11-25 15:13:15 -08:00
Maria Shodunke
f290941300 Update MPT Generator use case page 2025-11-25 18:22:53 +00:00
Maria Shodunke
a71a3fca10 Add tutorial for issuing an MPT (Javascript and Python). 2025-11-21 13:43:33 +00:00
oeggert
427d0ce441 Update resources/known-amendments.md
Co-authored-by: Rome Reginelli <rome@ripple.com>
2025-11-10 20:35:08 -08:00
oeggert
6be3d0117a Update resources/known-amendments.md
Co-authored-by: Rome Reginelli <rome@ripple.com>
2025-11-10 20:34:59 -08:00
Oliver Eggert
ed4b18586b update known amendment page 2025-11-05 21:14:14 -08:00
Oliver Eggert
864c412305 initialize 3.0 doc branch 2025-11-04 13:28:58 -08:00
28 changed files with 2074 additions and 548 deletions

View File

@@ -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'
}
]
}
```

View File

@@ -1,35 +1,40 @@
import { stringToHex, hexToString } from '@xrplf/isomorphic/dist/utils/index.js'
import { MPTokenIssuanceCreateFlags, Client } from 'xrpl'
import {
MPTokenIssuanceCreateFlags,
Client,
encodeMPTokenMetadata,
decodeMPTokenMetadata
} from 'xrpl'
// Connect to network and get a wallet
const client = new Client('wss://s.devnet.rippletest.net:51233')
await client.connect()
console.log('Funding new wallet from faucet...')
const { wallet } = await client.fundWallet()
console.log('=== Funding new wallet from faucet...===')
const { wallet: issuer } = await client.fundWallet()
console.log(`Issuer address: ${issuer.address}`)
// Define metadata as JSON
const mpt_metadata = {
t: 'TBILL',
n: 'T-Bill Yield Token',
d: 'A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.',
i: 'https://example.org/tbill-icon.png',
ac: 'rwa',
as: 'treasury',
in: 'Example Yield Co.',
us: [
const mptMetadata = {
ticker: 'TBILL',
name: 'T-Bill Yield Token',
desc: 'A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.',
icon: 'https://example.org/tbill-icon.png',
asset_class: 'rwa',
asset_subclass: 'treasury',
issuer_name: 'Example Yield Co.',
uris: [
{
u: 'https://exampleyield.co/tbill',
c: 'website',
t: 'Product Page'
uri: 'https://exampleyield.co/tbill',
category: 'website',
title: 'Product Page'
},
{
u: 'https://exampleyield.co/docs',
c: 'docs',
t: 'Yield Token Docs'
uri: 'https://exampleyield.co/docs',
category: 'docs',
title: 'Yield Token Docs'
}
],
ai: {
additional_info: {
interest_rate: '5.00%',
interest_type: 'variable',
yield_source: 'U.S. Treasury Bills',
@@ -38,48 +43,67 @@ const mpt_metadata = {
}
}
// Convert JSON to a string (without excess whitespace), then string to hex
const mpt_metadata_hex = stringToHex(JSON.stringify(mpt_metadata))
// Encode the metadata.
// The encodeMPTokenMetadata function shortens standard MPTokenMetadata
// field names to a compact key, then converts the JSON metadata object into a
// 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 mptMetadataHex = encodeMPTokenMetadata(mptMetadata)
console.log('Encoded mptMetadataHex: ', mptMetadataHex)
// Define the transaction, including other MPT parameters
const mpt_issuance_create = {
const mptIssuanceCreate = {
TransactionType: 'MPTokenIssuanceCreate',
Account: wallet.address,
Account: issuer.address,
AssetScale: 4,
MaximumAmount: '50000000',
TransferFee: 0,
Flags: MPTokenIssuanceCreateFlags.tfMPTCanTransfer |
MPTokenIssuanceCreateFlags.tfMPTCanTrade,
MPTokenMetadata: mpt_metadata_hex
Flags:
MPTokenIssuanceCreateFlags.tfMPTCanTransfer |
MPTokenIssuanceCreateFlags.tfMPTCanTrade,
MPTokenMetadata: mptMetadataHex
}
// Prepare, sign, and submit the transaction
console.log('Sending MPTokenIssuanceCreate transaction...')
const submit_response = await client.submitAndWait(mpt_issuance_create, { wallet, autofill: true })
// Sign and submit the transaction
console.log('\n=== Sending MPTokenIssuanceCreate transaction...===')
console.log(JSON.stringify(mptIssuanceCreate, null, 2))
const submitResponse = await client.submitAndWait(mptIssuanceCreate, {
wallet: issuer,
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}.`)
// Check transaction results
console.log('\n=== Checking MPTokenIssuanceCreate results... ===')
console.log(JSON.stringify(submitResponse.result, null, 2))
if (submitResponse.result.meta.TransactionResult !== 'tesSUCCESS') {
const resultCode = submitResponse.result.meta.TransactionResult
console.warn(`Transaction failed with result code ${resultCode}.`)
await client.disconnect()
process.exit(1)
}
const issuance_id = submit_response.result.meta.mpt_issuance_id
console.log(`MPToken created successfully with issuance ID ${issuance_id}.`)
const issuanceId = submitResponse.result.meta.mpt_issuance_id
console.log(
`\n- MPToken created successfully with issuance ID: ${issuanceId}`
)
// View the MPT issuance on the XRPL Explorer
console.log(`- Explorer URL: https://devnet.xrpl.org/mpt/${issuanceId}`)
// Look up MPT Issuance entry in the validated ledger
console.log('Confirming MPT Issuance metadata in the validated ledger.')
const ledger_entry_response = await client.request({
"command": "ledger_entry",
"mpt_issuance": issuance_id,
"ledger_index": "validated"
console.log('\n=== Confirming MPT Issuance metadata in the validated ledger... ===')
const ledgerEntryResponse = await client.request({
command: 'ledger_entry',
mpt_issuance: issuanceId,
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 metadataBlob = ledgerEntryResponse.result.node.MPTokenMetadata
const decodedMetadata = decodeMPTokenMetadata(metadataBlob)
console.log('Decoded MPT metadata:\n', decodedMetadata)
client.disconnect()
// Disconnect from the client
await client.disconnect()

View File

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

View File

@@ -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"
}
]
}
```

View File

@@ -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,18 @@ 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 shortens standard MPTokenMetadata
# field names to a compact key, then converts the JSON metadata object into a
# 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 +60,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))

View File

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

View File

@@ -4,7 +4,7 @@
<title>MPT Generator</title>
<link href='https://fonts.googleapis.com/css?family=Work Sans' rel='stylesheet'>
<link href="modular-tutorials.css" rel="stylesheet">
<script src='https://unpkg.com/xrpl@4.1.0/build/xrpl-latest.js'></script>
<script src='https://unpkg.com/xrpl@4.4.3/build/xrpl-latest.js'></script>
<script src='mpt-generator.js'></script>
<script>
@@ -229,4 +229,4 @@
</form>
</body>
</html>
</html>

View File

@@ -83,7 +83,7 @@ async function sendTransaction() {
const my_wallet = xrpl.Wallet.fromSeed(seedField.value)
const client = new xrpl.Client(net)
await client.connect()
const metadataHexString = xrpl.convertStringToHex(metadataTextArea.value)
const metadataHexString = xrpl.encodeMPTokenMetadata(JSON.parse(metadataTextArea.value))
const transactionJson = {
"TransactionType": "MPTokenIssuanceCreate",
"Account": accountField.value,
@@ -108,4 +108,4 @@ async function sendTransaction() {
function gatherMptInfo() {
let mptInfo = accountNameField.value + "\n" + accountField.value + "\n" + seedField.value + "\n" + mptIssuanceIdField.value
resultField.value = mptInfo
}
}

View File

@@ -1,8 +1,6 @@
module github.com/XRPLF
go 1.23.0
toolchain go1.23.10
go 1.24.0
require github.com/Peersyst/xrpl-go v0.1.11
@@ -20,5 +18,5 @@ require (
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.35.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
)

View File

@@ -46,8 +46,8 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@@ -1,8 +1,6 @@
module github.com/XRPLF
go 1.23.0
toolchain go1.23.10
go 1.24.0
require github.com/Peersyst/xrpl-go v0.1.11
@@ -19,5 +17,5 @@ require (
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.35.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
)

View File

@@ -44,8 +44,8 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

227
blog/2025/rippled-3.0.0.md Normal file
View File

@@ -0,0 +1,227 @@
---
category: 2025
date: "2025-12-09"
template: '../../@theme/templates/blogpost'
seo:
title: Introducing XRP Ledger version 3.0.0
description: rippled version 3.0.0 is now available. This version introduces new amendments and bug fixes.
labels:
- rippled Release Notes
markdown:
editPage:
hide: true
---
# Introducing XRP Ledger version 3.0.0
Version 3.0.0 of `rippled`, the reference server implementation of the XRP Ledger protocol, is now available. This release introduces new amendments and bug fixes.
## Action Required
If you run an XRP Ledger server, upgrade to version 3.0.0 as soon as possible to ensure service continuity.
## Install / Upgrade
On supported platforms, see the [instructions on installing or updating `rippled`](../../docs/infrastructure/installation/index.md).
| Package | SHA-256 |
|:--------|:--------|
| [RPM for Red Hat / CentOS (x86-64)](https://repos.ripple.com/repos/rippled-rpm/stable/rippled-3.0.0-1.el9.x86_64.rpm) | `2e181c8e966e043e10e32f3b0e30184014b88c2b5b9513d07c0e13c605edf050` |
| [DEB for Ubuntu / Debian (x86-64)](https://repos.ripple.com/repos/rippled-deb/pool/stable/rippled_3.0.0-1_amd64.deb) | `efbce53f39e2d94d74c3cfdb049758f8826aa5e0a2a246cd9b19e9246e7b4172` |
For other platforms, please [build from source](https://github.com/XRPLF/rippled/blob/master/BUILD.md). The most recent commit in the git log should be the change setting the version:
```text
commit 7527e35379a78901320b17a9a26c618e4384b1f6
Author: Ed Hennis <ed@ripple.com>
Date: Tue Dec 9 12:11:16 2025 -0500
Set version to 3.0.0
```
## Full Changelog
### Amendments
- **fixTokenEscrowV1**: Fixes an accounting error in MPT escrows. Specifically, when an escrow unlocks MPTs that have a transfer fee, the system incorrectly reduces the MPT issuer's locked token balance by the gross amount (without fees) rather than the net amount (with fees). This leads to discrepancies in the token's total supply accounting. ([#5571](https://github.com/XRPLF/rippled/pull/5571))
- **fixIncludeKeyletFields**: Adds missing keylet fields to these ledger entries:
- `Sequence` to `Escrow` and `PayChannel`.
- `Owner` to `SignerList`.
- `OracleDocumentID` to `Oracle`. ([#5646](https://github.com/XRPLF/rippled/pull/5646))
- **fixPriceOracleOrder**: Fixes an issue where the order of asset pair data is different from when a price oracle is created versus when it is updated. ([#5485](https://github.com/XRPLF/rippled/pull/5485))
- **fixAMMClawbackRounding**: Fixes a rounding error that can occur in the `LPTokenBalance` of an AMM when performing an `AMMClawback` transaction. ([#5750](https://github.com/XRPLF/rippled/pull/5750))
- **fixMPTDeliveredAmount**: This amendment adds missing `DeliveredAmount` and `delivered_amount` metadata fields from direct MPT `Payment` transactions. ([#5569](https://github.com/XRPLF/rippled/pull/5569))
### Features
- Added `delivered_amount`, `nftoken_id`, `nftoken_ids`, `offer_id`, and `mpt_issuance_id` metadata fields to the `simulate` API method. ([#5754](https://github.com/XRPLF/rippled/pull/5754))
- Added `STInt32` as a new `SType` to support negative 32-bit integer fields. ([#5788](https://github.com/XRPLF/rippled/pull/5788))
### Breaking Changes
- Updated the `ledger_entry` API method to return an `invalidParams` error if you specify multiple entries. Previously, the method would return information for only one entry selected at random. This change enforces a single entry lookup per request. ([#5237](https://github.com/XRPLF/rippled/pull/5237))
### Bug Fixes
- Fixed consensus stall detection to not flag prematurely. ([#5658](https://github.com/XRPLF/rippled/pull/5658))
- Added additional logging to differentiate why peer connections were refused. ([#5690](https://github.com/XRPLF/rippled/pull/5690))
- Fixed a code coverage error. ([#5765](https://github.com/XRPLF/rippled/pull/5765))
- Raised severity of unexpected/invalid keys when handling UNL manifest from `INFO` to `WARN`. Also changed internal error code for invalid UNL manifest formats from `untrusted` to `invalid`. ([#5804](https://github.com/XRPLF/rippled/pull/5804))
- Fixed release build errors with GCC 15.2. ([#5864](https://github.com/XRPLF/rippled/pull/5864))
- Fixed JSON parsing of negative integers in `STNumber` and `STAmount`. ([#5990](https://github.com/XRPLF/rippled/pull/5990))
- Fixed HTTP header case sensitivity issue in `HttpClient.cpp`. ([#5767](https://github.com/XRPLF/rippled/pull/5767))
- Fixed transaction signature checking functions to accept only required parameters instead of full `PreclaimContext`. ([#5829](https://github.com/XRPLF/rippled/pull/5829))
- Fixed an issue where the `sfSubjectNode` wasn't populated by the `CredentialCreate` transaction for self-issued credentials. ([#5936](https://github.com/XRPLF/rippled/pull/5936))
- Fixed domain order books not populating during node startup. ([#5998](https://github.com/XRPLF/rippled/pull/5998))
### Refactors
- Decoupled net module from xrpld and moved RPC related classes to the rpc folder. ([#5477](https://github.com/XRPLF/rippled/pull/5477))
- Moved ledger component to `libxrpl` as part of modularization effort. ([#5493](https://github.com/XRPLF/rippled/pull/5493))
- Refactored code in preparation for `LendingProtocol`. ([#5590](https://github.com/XRPLF/rippled/pull/5590))
- Refactored `parseLeaf` to separate the handlers for `STI_UINT16` and `STI_UINT32` into separate helper functions. ([#5591](https://github.com/XRPLF/rippled/pull/5591))
- Restructured `Transactor::preflight` to remove boilerplate code in derived classes' implementations of `preflight`. ([#5592](https://github.com/XRPLF/rippled/pull/5592))
- Restructured `Transactor` signature checking code to be able to handle a `sigObject`, which may be the full transaction or a field containing a separate transaction. ([#5594](https://github.com/XRPLF/rippled/pull/5594))
- Revamped CI workflows to leverage new Docker images and improve testing automation. ([#5661](https://github.com/XRPLF/rippled/pull/5661))
- Cleaned up `CTID.h` code for improved readability and maintainability. ([#5681](https://github.com/XRPLF/rippled/pull/5681))
- Added support for extra transaction signature validation. ([#5851](https://github.com/XRPLF/rippled/pull/5851))
- Replaced JSON `LastLedgerSequence` with `last_ledger_seq` to make tests simpler and easier to read. ([#5884](https://github.com/XRPLF/rippled/pull/5884))
- Replaced `boost::lexical_cast<std::string>` with `to_string` in tests. ([#5883](https://github.com/XRPLF/rippled/pull/5883))
- Replaced tests that write out JSONs as strings instead of using the `Json::Value` library. ([#5886](https://github.com/XRPLF/rippled/pull/5886))
- Added a `paychan` namespace to the TestHelpers and implementation files, improving organization and clarity. ([#5840](https://github.com/XRPLF/rippled/pull/5840))
- Improved and refactored txset handling. ([#5951](https://github.com/XRPLF/rippled/pull/5951))
### Documentation
- Updated old links and descriptions in `README.md`. ([#4701](https://github.com/XRPLF/rippled/pull/4701))
- Added compiler warning for `std::counting_semaphore` usage. ([#5595](https://github.com/XRPLF/rippled/pull/5595))
- Removed redundant word in code comment. ([#5752](https://github.com/XRPLF/rippled/pull/5752))
- Added remote to `conan lock create` command. ([#5770](https://github.com/XRPLF/rippled/pull/5770))
- Fixed typo in JSON writer documentation. ([#5881](https://github.com/XRPLF/rippled/pull/5881))
- Fixed spelling issues across the codebase. ([#6002](https://github.com/XRPLF/rippled/pull/6002))
- Fixed typos in code comments. ([#6040](https://github.com/XRPLF/rippled/pull/6040))
- Removed accidental copyright notice from `NetworkOps_test.cpp`. ([#6066](https://github.com/XRPLF/rippled/pull/6066))
### Testing
- Migrated json unit tests to use doctest framework. ([#5533](https://github.com/XRPLF/rippled/pull/5533))
- Added basic tests for `STInteger` and `STParsedJSON`. ([#5726](https://github.com/XRPLF/rippled/pull/5726))
- Fixed test framework to handle null metadata for unvalidated transactions in `env.meta`. ([#5715](https://github.com/XRPLF/rippled/pull/5715))
- Added more comprehensive tests for the `FeeVote` module. ([#5746](https://github.com/XRPLF/rippled/pull/5746))
- Added additional tests for `simulate` RPC metadata. ([#5827](https://github.com/XRPLF/rippled/pull/5827))
- Updated unit test summary to count crashed tests as failures. ([#5924](https://github.com/XRPLF/rippled/pull/5924))
- Fixed CI to upload all test binaries. ([#5932](https://github.com/XRPLF/rippled/pull/5932))
### CI/Build
- Modified GitHub Actions jobs to use `>>` instead of `tee` for `${GITHUB_OUTPUT}` to prevent output overwriting. ([#5699](https://github.com/XRPLF/rippled/pull/5699))
- Fixed CI workflow issues and reduced separate OS jobs into one by using a strategy matrix. ([#5700](https://github.com/XRPLF/rippled/pull/5700))
- Fixed `build_only` conditional check to correctly determine whether to run tests. ([#5708](https://github.com/XRPLF/rippled/pull/5708))
- Updated `clang-format` and added `prettier` to the `pre-commit`. Also added proto file formatting. ([#5709](https://github.com/XRPLF/rippled/pull/5709))
- Reverted formatting changes to external files and added formatting for proto files. ([#5711](https://github.com/XRPLF/rippled/pull/5711))
- Fixed `notify-clio` job to skip when running in forks, and reordered config fields for better job name visibility. ([#5712](https://github.com/XRPLF/rippled/pull/5712))
- Added workaround for CI build errors on arm64 with Clang 20. ([#5717](https://github.com/XRPLF/rippled/pull/5717))
- Fixed file formatting in anticipation of enabling additional `clang-format-hooks`. ([#5718](https://github.com/XRPLF/rippled/pull/5718))
- Removed codecov token check to support tokenless uploads from forks. ([#5722](https://github.com/XRPLF/rippled/pull/5722))
- Reverted PR pipeline trigger rules to fix unintended job skipping behavior. ([#5727](https://github.com/XRPLF/rippled/pull/5727))
- Replaced `on: pull_request: paths` with `changed-files` action for better CI control. ([#5728](https://github.com/XRPLF/rippled/pull/5728))
- Added support for `merge_group` event in GitHub CI to enable merge queues. ([#5734](https://github.com/XRPLF/rippled/pull/5734))
- Added codecov token to the `on-trigger` workflow to enable report uploading. ([#5736](https://github.com/XRPLF/rippled/pull/5736))
- Modified CI test jobs to run if files changed or PR has "Ready to merge" label. ([#5739](https://github.com/XRPLF/rippled/pull/5739))
- Used `XRPLF/prepare-runner` action to fix `CONAN_HOME` issues on macOS. Also removed old CMake code. ([#5740](https://github.com/XRPLF/rippled/pull/5740))
- Removed extraneous `LCOV_EXCL_START` marker from coverage reporting. ([#5744](https://github.com/XRPLF/rippled/pull/5744))
- Added conan lockfile for better dependency management and reproducible builds. ([#5751](https://github.com/XRPLF/rippled/pull/5751))
- Updated pre-commit to manage tools on its own. ([#5753](https://github.com/XRPLF/rippled/pull/5753))
- Added required `disable_ccache` option to workflow. ([#5756](https://github.com/XRPLF/rippled/pull/5756))
- Fixed coverage parameter in Cmake file. ([#5760](https://github.com/XRPLF/rippled/pull/5760))
- Added additional info to `notify-clio` workflow. ([#5761](https://github.com/XRPLF/rippled/pull/5761))
- Implemented separate upload workflow. ([#5762](https://github.com/XRPLF/rippled/pull/5762))
- Added `cleanup-workspace` action to clean workspace before builds. ([#5763](https://github.com/XRPLF/rippled/pull/5763))
- Added `conan.lock` to workflow file checks. ([#5769](https://github.com/XRPLF/rippled/pull/5769))
- Removed extra @ symbol in `notify-clio.yml`. ([#5771](https://github.com/XRPLF/rippled/pull/5771))
- Fixed `pre-commit` workflows. ([#5772](https://github.com/XRPLF/rippled/pull/5772))
- Switched `on-trigger` workflow to minimal build to reduce the number of builds. ([#5773](https://github.com/XRPLF/rippled/pull/5773))
- Fixed `passed` jobs to properly pass if all its dependencies passed or were skipped. ([#5776](https://github.com/XRPLF/rippled/pull/5776))
- Added `should-run` filtering back to `build-test` and `notify-clio` workflows. ([#5777](https://github.com/XRPLF/rippled/pull/5777))
- Switched CI pipeline `bookworm:gcc-13` from arm64 to amd64 architecture. ([#5779](https://github.com/XRPLF/rippled/pull/5779))
- Updated to self-hosted Windows runners to shorten build times. ([#5780](https://github.com/XRPLF/rippled/pull/5780))
- Limited `upload-conan-deps` to 10 parallel instances when using `max-parallel`. ([#5781](https://github.com/XRPLF/rippled/pull/5781))
- Changed when `upload-conan-deps` workflows run to avoid unnecessary execution on PRs. ([#5782](https://github.com/XRPLF/rippled/pull/5782))
- Added missing dependencies to workflows. ([#5783](https://github.com/XRPLF/rippled/pull/5783))
- Updated to use default conan install without `--format json`. ([#5784](https://github.com/XRPLF/rippled/pull/5784))
- Fixed secrets and variables in `upload-conan-deps` workflow. ([#5785](https://github.com/XRPLF/rippled/pull/5785))
- Modified Clio notifications to only happen when a PR targets the release or master branch. ([#5794](https://github.com/XRPLF/rippled/pull/5794))
- Wrapped all GitHub CI conditionals in curly braces for consistency. ([#5796](https://github.com/XRPLF/rippled/pull/5796))
- Limited CI build and test parallelism to 10 concurrent jobs. ([#5799](https://github.com/XRPLF/rippled/pull/5799))
- Enabled building and testing all configurations for daily scheduled runs. ([#5801](https://github.com/XRPLF/rippled/pull/5801))
- Excluded unit tests from code coverage reporting. ([#5803](https://github.com/XRPLF/rippled/pull/5803))
- Pinned all CI Docker image tags to latest versions in the XRPLF/CI repo. ([#5813](https://github.com/XRPLF/rippled/pull/5813))
- Implemented separate upload workflow for artifacts during build and test phases. ([#5817](https://github.com/XRPLF/rippled/pull/5817))
- Renamed all reusable workflows to include "reusable" in their names for clarity. ([#5818](https://github.com/XRPLF/rippled/pull/5818))
- Set free-form CI inputs as environment variables to prevent injection attacks. ([#5822](https://github.com/XRPLF/rippled/pull/5822))
- Removed extraneous coverage warnings. ([#5838](https://github.com/XRPLF/rippled/pull/5838))
- Excluded `UNREACHABLE` blocks from codecov to improve coverage accuracy. ([#5846](https://github.com/XRPLF/rippled/pull/5846))
- Excluded old, unreachable transaction code from codecov for better coverage reporting. ([#5847](https://github.com/XRPLF/rippled/pull/5847))
- Updated CI strategy matrix to use new RHEL 9 and RHEL 10 Docker images. ([#5856](https://github.com/XRPLF/rippled/pull/5856))
- Fixed Windows build log size issue by setting log verbosity to quiet. ([#5865](https://github.com/XRPLF/rippled/pull/5865))
- Added support for CMake 4 without workarounds. ([#5866](https://github.com/XRPLF/rippled/pull/5866))
- Added wildcard to support triggering for release pipelines. ([#5879](https://github.com/XRPLF/rippled/pull/5879))
- Added support for RHEL 8. ([#5880](https://github.com/XRPLF/rippled/pull/5880))
- Updated pre-commit workflow to latest version. ([#5902](https://github.com/XRPLF/rippled/pull/5902))
- Updated the Docker image hashes for `tools-rippled`. ([#5896](https://github.com/XRPLF/rippled/pull/5896))
- Set fail-fast to false unless it is run by a merge group. ([#5897](https://github.com/XRPLF/rippled/pull/5897))
- Cleaned up Conan variables in CI. ([#5903](https://github.com/XRPLF/rippled/pull/5903))
- Set explicit timeouts for build and test jobs. ([#5912](https://github.com/XRPLF/rippled/pull/5912))
- Removed unnecessary `LCOV_EXCL_LINE` marker in `Escrow.cpp`. ([#5913](https://github.com/XRPLF/rippled/pull/5913))
- Updated `${{ env.ENVVAR }}` syntax to `${ENVVAR}` in GitHub Actions. ([#5923](https://github.com/XRPLF/rippled/pull/5923))
- Cleaned up build profile options. ([#5934](https://github.com/XRPLF/rippled/pull/5934))
- Added network info output to CI test job to help diagnose port exhaustion issues. ([#5938](https://github.com/XRPLF/rippled/pull/5938))
- Reduced the number of cores used to build and test by two. ([#5939](https://github.com/XRPLF/rippled/pull/5939))
- Updated pre-commit failure message. ([#5940](https://github.com/XRPLF/rippled/pull/5940))
- Fixed CI to only run .exe files during test phase on Windows. ([#5947](https://github.com/XRPLF/rippled/pull/5947))
- Changed the CI concurrency group for pushes to the `develop` branch to use the commit hash instead of the target branch. ([#5950](https://github.com/XRPLF/rippled/pull/5950))
- Changed Conan remote login to only occur when uploading packages. ([#5952](https://github.com/XRPLF/rippled/pull/5952))
- Updated CI to only upload codecov reports in the original repo, not in forks. ([#5953](https://github.com/XRPLF/rippled/pull/5953))
- Updated CI to use new `prepare-runner` action. ([#5970](https://github.com/XRPLF/rippled/pull/5970))
- Updated CI image hashes to use netstat. ([#5987](https://github.com/XRPLF/rippled/pull/5987))
- Made CMake improvements, including removing unused definitions, moving variable definitions, and updating the minimum GCC and Clang versions required. ([#6010](https://github.com/XRPLF/rippled/pull/6010))
- Unified build and test jobs into a single job and added `ctest` to coverage reporting. ([#6013](https://github.com/XRPLF/rippled/pull/6013))
- Moved running of unit tests out of coverage target. ([#6018](https://github.com/XRPLF/rippled/pull/6018))
- Updated Conan to version 2.22.2. ([#6019](https://github.com/XRPLF/rippled/pull/6019))
- Specified bash as default shell in workflows. ([#6021](https://github.com/XRPLF/rippled/pull/6021))
- Updated the `cleanup-workspace` action to its latest version to add support for Windows. ([#6024](https://github.com/XRPLF/rippled/pull/6024))
- Added new Debian Trixie CI images to build and test with. ([#6034](https://github.com/XRPLF/rippled/pull/6034))
- Changed strategy matrix check to filter out Clang 20+ on ARM. ([#6046](https://github.com/XRPLF/rippled/pull/6046))
- Updated CI to only upload artifacts in XRPLF repo. ([#6060](https://github.com/XRPLF/rippled/pull/6060))
- Removed missing commits check. ([#6077](https://github.com/XRPLF/rippled/pull/6077))
- Updated CI to trigger Clio pipeline on PRs targeting any `release` branches. ([#6080](https://github.com/XRPLF/rippled/pull/6080))
## Credits
The following GitHub users contributed to this release:
- RippleX Engineering
- RippleX Docs
- RippleX Product
- @dangell7
- @tequdev
- @tzchenxixi
- @wojake
## Bug Bounties and Responsible Disclosures
We welcome reviews of the `rippled` code and urge researchers to responsibly disclose any issues they may find.
To report a bug, please send a detailed report to: <bugs@xrpl.org>

View File

@@ -10,6 +10,7 @@
- group: '2025'
expanded: false
items:
- page: 2025/rippled-3.0.0.md
- page: 2025/rippled-2.6.2.md
- page: 2025/rippled-2.6.1.md
- page: 2025/vulnerabilitydisclosurereport-bug-sep2025.md

View File

@@ -32,8 +32,8 @@
[AccountSet transactions]: /docs/references/protocol/transactions/types/accountset.md
[AccountSet]: /docs/references/protocol/transactions/types/accountset.md
[Address]: /docs/references/protocol/data-types/basic-data-types.md#addresses
[Amendments entry]: /docs/concepts/networks-and-servers/amendments.md
[Amendments object]: /docs/concepts/networks-and-servers/amendments.md
[Amendments entry]: /docs/references/protocol/ledger-data/ledger-entry-types/amendments.md
[Amendments object]: /docs/references/protocol/ledger-data/ledger-entry-types/amendments.md
[Batch amendment]: /resources/known-amendments.md#batch
[Batch]: /docs/references/protocol/transactions/types/batch.md
[Batch transaction]: /docs/references/protocol/transactions/types/batch.md
@@ -135,6 +135,7 @@
[MPTokensV1 amendment]: /resources/known-amendments.md#mptokensv1
[MultiSign amendment]: /resources/known-amendments.md#multisign
[MultiSignReserve amendment]: /resources/known-amendments.md#multisignreserve
[NFT]: /docs/references/protocol/data-types/nftoken.md
[NFTokenAcceptOffer transaction]: /docs/references/protocol/transactions/types/nftokenacceptoffer.md
[NFTokenAcceptOffer transactions]: /docs/references/protocol/transactions/types/nftokenacceptoffer.md
[NFTokenAcceptOffer]: /docs/references/protocol/transactions/types/nftokenacceptoffer.md
@@ -155,6 +156,7 @@
[NFTokenPage entry]: /docs/references/protocol/ledger-data/ledger-entry-types/nftokenpage.md
[NFTokenPage object]: /docs/references/protocol/ledger-data/ledger-entry-types/nftokenpage.md
[NFToken]: /docs/references/protocol/data-types/nftoken.md
[Negative UNL]: /docs/concepts/consensus-protocol/negative-unl.md
[NegativeUNL amendment]: /resources/known-amendments.md#negativeunl
[NegativeUNL entry]: /docs/references/protocol/ledger-data/ledger-entry-types/negativeunl.md
[NegativeUNL object]: /docs/references/protocol/ledger-data/ledger-entry-types/negativeunl.md
@@ -309,6 +311,7 @@
[fee command]: /docs/references/http-websocket-apis/public-api-methods/server-info-methods/fee.md
[fee levels]: /docs/concepts/transactions/transaction-cost.md#fee-levels
[fee method]: /docs/references/http-websocket-apis/public-api-methods/server-info-methods/fee.md
[fee voting]: /docs/concepts/consensus-protocol/fee-voting.md
[fetch_info command]: /docs/references/http-websocket-apis/admin-api-methods/status-and-debugging-methods/fetch_info.md
[fetch_info method]: /docs/references/http-websocket-apis/admin-api-methods/status-and-debugging-methods/fetch_info.md
[fix1201 amendment]: /resources/known-amendments.md#fix1201
@@ -352,6 +355,7 @@
[json command]: /docs/references/http-websocket-apis/public-api-methods/utility-methods/json.md
[json method]: /docs/references/http-websocket-apis/public-api-methods/utility-methods/json.md
[ledger command]: /docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger.md
[ledger entry ID]: /docs/references/protocol/ledger-data/common-fields.md
[ledger format]: /docs/references/protocol/ledger-data/ledger-entry-types/index.md
[ledger index]: /docs/references/protocol/data-types/basic-data-types.md#ledger-index
[ledger method]: /docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger.md
@@ -404,6 +408,7 @@
[public servers]: /docs/tutorials/public-servers.md
[random command]: /docs/references/http-websocket-apis/public-api-methods/utility-methods/random.md
[random method]: /docs/references/http-websocket-apis/public-api-methods/utility-methods/random.md
[reserves]: /docs/concepts/accounts/reserves.md
[result code]: /docs/references/protocol/transactions/transaction-results/index.md
[ripple-lib]: https://github.com/XRPLF/xrpl.js
[ripple_path_find command]: /docs/references/http-websocket-apis/public-api-methods/path-and-order-book-methods/ripple_path_find.md

Binary file not shown.

Before

Width:  |  Height:  |  Size: 520 KiB

After

Width:  |  Height:  |  Size: 710 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 KiB

After

Width:  |  Height:  |  Size: 474 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 492 KiB

After

Width:  |  Height:  |  Size: 664 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 KiB

After

Width:  |  Height:  |  Size: 445 KiB

View File

@@ -189,6 +189,8 @@ Transactions and ledger entries may contain fields of any of the following types
| [UInt256][] | 5 | 256 | No | A 256-bit binary value. This usually represents the hash of a transaction, ledger version, or ledger entry. |
| [UInt384][] | 22 | 384 | No | **UNUSED.** A 384-bit binary value. |
| [UInt512][] | 23 | 512 | No | **UNUSED.** A 512-bit binary value. |
| [Int32][] | 10 | 32 | No | **UNUSED.** A 32-bit signed integer. |
| [Int64][] | 11 | 64 | No | **UNUSED.** A 64-bit signed integer. |
| [Vector256][] | 19 | Variable | Yes | A list of 256-bit binary values. This may be a list of ledger entries or other hash values. |
| [XChainBridge][] | 25 | Variable | No | A bridge between two blockchains, identified by the door accounts and issued assets on both chains. |
@@ -394,6 +396,21 @@ The types UInt96, UInt384, and UInt512 are currently defined but not used.
The `TransactionType` field is a special case. In JSON, this field is conventionally represented as a string with the name of the transaction type. In binary, this field is a UInt16. The `TRANSACTION_TYPES` object in the [definitions file](#definitions-file) maps these strings to the numeric values used in the binary format.
### Int Fields
[Int32]: #int-fields
[Int64]: #int-fields
The XRP Ledger supports signed 32-bit integers (Int32), which use standard big-endian binary signed integer representation with two's complement to handle negative values.
In JSON format, Int32 fields can be represented as:
- JSON numbers (for values within JavaScript's safe integer range).
- Strings containing decimal numbers.
Although the protocol supports the Int32 type, no fields currently use it. An Int64 type has also been defined, but is unsupported.
### Vector256 Fields
[Vector256]: #vector256-fields

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 MPT 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 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. This is because the 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` | Where to put the decimal place when displaying amounts of this MPT. This is set to `4` for this example. |
| `MaximumAmount` | The maximum supply of the token to be issued. |
| `TransferFee` | The transfer fee to charge for transferring the token. 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

@@ -9,7 +9,7 @@ labels:
_As a financial professional, I want to use multi-purpose tokens to create an asset-backed token in order to profit from resale transactions._
A multi-purpose token (MPT) is a compact and flexible object that offers the best aspects of fungible and non-fungible tokens. It is the next generation of tokenization on the XRPL. Notable features include:
A Multi-Purpose Token (MPT) is a compact and flexible object that offers the best aspects of fungible and non-fungible tokens. It is the next generation of tokenization on the XRPL. Notable features include:
- MPTs store metadata directly on the XRPL blockchain, with the option of linking to additional off-chain data. Once created, the metadata is immutable.
- MPTs can have a fixed token supply, with a cap on the maximum number of tokens.
@@ -17,10 +17,21 @@ A multi-purpose token (MPT) is a compact and flexible object that offers the bes
- MPTs can be non-transferable, for use cases such as airline credits.
- MPTs also allow advanced compliance features.
To learn more, see [Multi-purpose Tokens](../../concepts/tokens/fungible-tokens/multi-purpose-tokens.md).
{% amendment-disclaimer name="MPTokensV1" /%}
## Intended Audience
This page is written for product managers, business stakeholders, and non-technical users who want a high-level use case and an easy way to generate an MPT using the downloadable MPT Generator utility.
To learn about MPTs in general, go to the **Concept** page. For developer-focused content and code examples go to the **Tutorial**.
{% card-grid %}
{% xrpl-card title="Concept: MultiPurpose Tokens" body="Read the concept documentation to learn more about Multi-Purpose Tokens." href="docs/concepts/tokens/fungible-tokens/multi-purpose-tokens/" /%}
{% xrpl-card title="Tutorial: Issue a MultiPurpose Token" body="Stepbystep, handson tutorial to issue an MPT using the XRP Ledger SDKs." href="docs/tutorials/how-tos/use-tokens/issue-a-multi-purpose-token/" /%}
{% xrpl-card title="MPT Generator" body="Download the MPT Generator and learn how to create an asset-backed Treasury bill." href="#mpt-generator"/%}
{% /card-grid %}
## MPT Generator
![MPT Generator Utility](../../img/uc-mpt1-mpt-generator-empty-form.png)
@@ -364,6 +375,7 @@ A US Treasury bill (T-bill) is a short-term debt security issued by the US gover
You can use the Account Configurator to experiment with the settings for a T-bill issuing account in a sandbox environment. When you are satisfied with your configuration, you can create an account on XRPL Mainnet to begin trading.
To create a new MPT Issuer account:
- In the Account Configurator utility, choose ledger instance **Devnet**.
- Click **Get New Account**.
- Choose account configuration template **Issuer**.
@@ -424,20 +436,33 @@ The metadata you provide is what distinguishes your token from other MPTs. The f
```json
{
"Name": "US Treasury Bill Token",
"Identifier": "USTBT",
"Issuer": "US Treasury",
"IssueDate": "2024-03-25",
"MaturityDate": "2025-03-25",
"FaceValue": 1000,
"InterestRate": 2.5,
"InterestFrequency": "Quarterly",
"Collateral": "US Government",
"Jurisdiction": "United States",
"RegulatoryCompliance": "SEC Regulations",
"SecurityType": "Treasury Bill",
"ExternalUrl": "https://example.com/t-bill-token-metadata.json"
"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": [
{
"uri": "https://exampleyield.co/tbill",
"category": "website",
"title": "Product Page"
},
{
"uri": "https://exampleyield.co/docs",
"category": "docs",
"title": "Yield Token Docs"
}
],
"additional_info": {
"interest_rate": "5.00%",
"interest_type": "variable",
"yield_source": "U.S. Treasury Bills",
"maturity_date": "2045-06-30",
"cusip": "912796RX0"
}
}
```
Once you've set your preferred values, click **Generate Transaction** to see the transaction syntax for your settings. The `Flags` field displays the sum of the flags you've selected, and the `MPTokenMetadata` is converted to a hexidecimal string.
@@ -456,8 +481,9 @@ Click **Gather MPT Information** to copy the account information and MPT Issuanc
![Account and MPT ID in the result field.](../../img/uc-mpt1-t-bill-gather-mpt-info.png)
## See Also:
## See Also
- [Issue a Multi-Purpose Token (MPT)](../../tutorials/how-tos/use-tokens/issue-a-multi-purpose-token.md)
- [Sending MPTs](../../tutorials/javascript/send-payments/sending-mpts.md)
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -627,6 +627,17 @@
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - Amendments",
"description": "Returns the Amendments object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-amendments-entry",
"body": {
"id": "example_get_amendments",
"command": "ledger_entry",
"amendments": "7DB0788C020F02780A673DC74757F23823FA3014C1866E72CC4CD8B226CD6EF4",
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - AMM",
"description": "Returns a single Automated Market Maker object in its raw ledger format.",
@@ -649,18 +660,18 @@
{
"name": "ledger_entry - Bridge",
"description": "Returns a single Bridge object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-bridge-object",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-bridge-entry",
"status": "not_enabled",
"body": {
"id": "example_get_bridge",
"command": "ledger_entry",
"bridge_account": "rnQAXXWoFNN6PEqwqsdTngCtFPCrmfuqFJ",
"bridge_account": "rf7zCh1aPD2DpeJVo6keG5Cf1TVyAKMFpR",
"bridge": {
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"IssuingChainIssue": {
"currency": "XRP"
},
"LockingChainDoor": "rnQAXXWoFNN6PEqwqsdTngCtFPCrmfuqFJ",
"LockingChainDoor": "rf7zCh1aPD2DpeJVo6keG5Cf1TVyAKMFpR",
"LockingChainIssue": {
"currency": "XRP"
}
@@ -668,6 +679,57 @@
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - Check",
"description": "Returns a Check object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-check-object",
"body": {
"id": "example_get_check",
"command": "ledger_entry",
"check": "C4A46CCD8F096E994C4B0DEAB6CE98E722FC17D7944C28B95127C2659C47CBEB",
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - Credential",
"description": "Returns a Credential object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-credential-entry",
"body": {
"id": "example_get_credential",
"command": "ledger_entry",
"credential": {
"subject": "rNnsnWZCsakxyMz5GzFrbbMpUnSmiDeKTW",
"issuer": "rFtKiHYdvmAiVvxAr6U6TNjcPSrAeANQa",
"credential_type": "746573742D63726564656E7469616C"
},
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - DepositPreauth",
"description": "Returns a DepositPreauth object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-depositpreauth-object",
"body": {
"id": "example_get_deposit_preauth",
"command": "ledger_entry",
"deposit_preauth": {
"owner": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"authorized": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX"
},
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - DID",
"description": "Returns a single DID object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-did-entry",
"body": {
"id": "example_get_did",
"command": "ledger_entry",
"did": "rFtKiHYdvmAiVvxAr6U6TNjcPSrAeANQa",
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - DirectoryNode",
"description": "Returns a directory object in its raw ledger format.",
@@ -682,6 +744,88 @@
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - Escrow",
"description": "Returns an Escrow object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-escrow-object",
"body": {
"id": "example_get_escrow",
"command": "ledger_entry",
"escrow": {
"owner": "rL4fPHi2FWGwRGRQSH7gBcxkuo2b9NTjKK",
"seq": 126
},
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - FeeSettings",
"description": "Returns the FeeSettings object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-feesettings-entry",
"body": {
"id": "example_get_feesettings",
"command": "ledger_entry",
"fee": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A651",
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - LedgerHashes",
"description": "Returns the LedgerHashes object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-ledgerhashes-entry",
"body": {
"id": "example_get_ledgerhashes",
"command": "ledger_entry",
"hashes": "B4979A36CDC7F3D3D5C31A4EAE2AC7D7209DDA877588B9AFC66799692AB0D66B",
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - MPToken",
"description": "Returns an MPToken object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-mptoken-entry",
"body": {
"id": "example_get_mpt",
"command": "ledger_entry",
"mptoken": {
"mpt_issuance_id": "05EECEBE97A7D635DE2393068691A015FED5A89AD203F5AA",
"account":"rsNw23ygZatXv7h8QVSgAE4jktY2uW1iZP"
}
}
},
{
"name": "ledger_entry - MPTokenIssuance",
"description": "Returns an MPTokenIssuance object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-mptokenissuance-entry",
"body": {
"id": "example_get_mpt_issuance",
"command": "ledger_entry",
"mpt_issuance": "05EECEBE97A7D635DE2393068691A015FED5A89AD203F5AA",
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - NFTokenOffer",
"description": "Returns an NFTokenOffer object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-nftokenoffer-entry",
"body": {
"id": "example_get_nftokenoffer",
"command": "ledger_entry",
"nft_offer": "6C4FC85B1F64FF2E30C3F657E41E373E5C1AC007A6B4F936C43B2F38BD8FFC14",
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - NegativeUNL",
"description": "Returns the NegativeUNL object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-negativeunl-entry",
"body": {
"id": "example_get_negativeunl",
"command": "ledger_entry",
"nunl": "2E8A59AA9D3B5B186B0B9E0F62E6C02587CA74A4D778938E957B6357D364B244",
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - NFT Page",
"description": "Returns an NFT Page object in its raw ledger format.",
@@ -711,7 +855,6 @@
"name": "ledger_entry - Oracle",
"description": "Returns a single Oracle object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-oracle-object",
"status": "not_enabled",
"body": {
"id": "example_get_oracle",
"command": "ledger_entry",
@@ -722,6 +865,32 @@
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - PayChannel",
"description": "Returns a PayChannel object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-paychannel-object",
"body": {
"id": "example_get_paychannel",
"command": "ledger_entry",
"payment_channel": "C7F634794B79DB40E87179A9D1BF05D05797AE7E92DF8E93FD6656E8C4BE3AE7",
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - PermissionedDomain",
"description": "Returns a PermissionedDomain object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-permissioneddomain-entry",
"status": "not_enabled",
"body": {
"id": "example_get_permissioneddomain",
"command": "ledger_entry",
"permissioned_domain": {
"account": "rf7zCh1aPD2DpeJVo6keG5Cf1TVyAKMFpR",
"seq": 2093655
},
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - RippleState",
"description": "Returns a RippleState object in its raw ledger format.",
@@ -740,52 +909,13 @@
}
},
{
"name": "ledger_entry - Check",
"description": "Returns a Check object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-check-object",
"name": "ledger_entry - SignerList",
"description": "Returns a SignerList object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-signerlist-entry",
"body": {
"id": "example_get_check",
"id": "example_get_signerlist",
"command": "ledger_entry",
"check": "C4A46CCD8F096E994C4B0DEAB6CE98E722FC17D7944C28B95127C2659C47CBEB",
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - Escrow",
"description": "Returns an Escrow object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-escrow-object",
"body": {
"id": "example_get_escrow",
"command": "ledger_entry",
"escrow": {
"owner": "rL4fPHi2FWGwRGRQSH7gBcxkuo2b9NTjKK",
"seq": 126
},
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - PayChannel",
"description": "Returns a PayChannel object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-paychannel-object",
"body": {
"id": "example_get_paychannel",
"command": "ledger_entry",
"payment_channel": "C7F634794B79DB40E87179A9D1BF05D05797AE7E92DF8E93FD6656E8C4BE3AE7",
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - DepositPreauth",
"description": "Returns a DepositPreauth object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-depositpreauth-object",
"body": {
"id": "example_get_deposit_preauth",
"command": "ledger_entry",
"deposit_preauth": {
"owner": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"authorized": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX"
},
"signer_list": "A9C28A28B85CD533217F5C0A0C7767666B093FA58A0F2D80026FCC4CD932DDC7",
"ledger_index": "validated"
}
},
@@ -804,27 +934,47 @@
}
},
{
"name": "ledger_entry - MPTokenIssuance",
"description": "Returns an MPTokenIssuance object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-mpt-issuance-entry",
"name": "ledger_entry - XChainOwnedClaimID",
"description": "Returns a single XChainOwnedClaimID object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-xchainownedclaimid-entry",
"status": "not_enabled",
"body": {
"id": "example_get_mpt_issuance",
"id": "example_get_xchainownedclaimid",
"command": "ledger_entry",
"mpt_issuance": "05EECEBE97A7D635DE2393068691A015FED5A89AD203F5AA",
"xchain_owned_claim_id": {
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"IssuingChainIssue": {
"currency": "XRP"
},
"LockingChainDoor": "rf7zCh1aPD2DpeJVo6keG5Cf1TVyAKMFpR",
"LockingChainIssue": {
"currency": "XRP"
},
"xchain_owned_claim_id": 1
},
"ledger_index": "validated"
}
},
{
"name": "ledger_entry - MPToken",
"description": "Returns an MPToken object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-mptoken-entry",
"name": "ledger_entry - XChainOwnedCreateAccountClaimID",
"description": "Returns a single XChainOwnedCreateAccountClaimID object in its raw ledger format.",
"link": "/docs/references/http-websocket-apis/public-api-methods/ledger-methods/ledger_entry#get-xchainownedcreateaccountclaimid-entry",
"status": "not_enabled",
"body": {
"id": "example_get_mpt",
"id": "example_get_xchainownedcreateaccountclaimid",
"command": "ledger_entry",
"mptoken": {
"mpt_issuance_id": "05EECEBE97A7D635DE2393068691A015FED5A89AD203F5AA",
"account":"rsNw23ygZatXv7h8QVSgAE4jktY2uW1iZP"
}
"xchain_owned_create_account_claim_id": {
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"IssuingChainIssue": {
"currency": "XRP"
},
"LockingChainDoor": "rf7zCh1aPD2DpeJVo6keG5Cf1TVyAKMFpR",
"LockingChainIssue": {
"currency": "XRP"
},
"xchain_owned_create_account_claim_id": 1
},
"ledger_index": "validated"
}
}
]

View File

@@ -23,6 +23,7 @@ The following is a list of [amendments](../docs/concepts/networks-and-servers/am
|:----------------------------------|:------------------------------------------|:-------------------------------|
| [Hooks][] | {% badge %}In Development: TBD{% /badge %} | [XRPL Hooks](https://hooks.xrpl.org/) |
| [InvariantsV1_1][] | {% badge %}In Development: TBD{% /badge %} | |
| [LendingProtocol][] | {% badge %}In Development: TBD{% /badge %} | [Lending Protocol (Ripple Opensource)](https://opensource.ripple.com/docs/xls-66d-lending-protocol) |
| [SingleAssetVault][] | {% badge %}In Development: TBD{% /badge %} | [Single Asset Vault (Ripple Opensource)](https://opensource.ripple.com/docs/xls-65d-single-asset-vault) |
{% admonition type="success" name="Tip" %}
@@ -169,7 +170,7 @@ See [Clawback](../docs/concepts/tokens/fungible-tokens/clawing-back-tokens.md) f
| Amendment | Credentials |
|:-------------|:------------|
| Amendment ID | 1CB67D082CF7D9102412D34258CEDB400E659352D3B207348889297A6D90F5EF |
| Status | Open for Voting |
| Status | Enabled |
| Default Vote (Latest stable release) | No |
| Pre-amendment functionality retired? | No |
@@ -666,6 +667,19 @@ Fixes a bug that could cause an amendment to achieve a majority and later activa
Without this amendment, the minimum threshold for amendment activation is any value that rounds to 204/256 of trusted validators, which depends on the number of trusted validators at the time. For example, an amendment could activate with exactly 28 out of 36 validators (approximately 77.8%). With this amendment, the actual minimum number of validators needed is never less than 80% of trusted validators.
### fixAMMClawbackRounding
[fixAMMClawbackRounding]: #fixammclawbackrounding
| Amendment | fixAMMClawbackRounding |
|:-------------|:-------------------------|
| Amendment ID | 5E9586DB3D765B4C5794658FB6BB385071E9838DF4016027E6E26820C8526724 |
| Status | Open for Voting |
| Default Vote (Latest stable release) | No |
| Pre-amendment functionality retired? | No |
Fixes an accounting error that can occur when performing an `AMMClawback` transaction on the last LP token holder. Due to rounding errors, the `LPTokenBalance` of the AMM may not match the holder's trust line balance. This amendment adjusts the `LPTokenBalance` to match the trust line balance before the clawback, so invariant checks pass without errors.
### fixAMMOverflowOffer
[fixAMMOverflowOffer]: #fixammoverflowoffer
@@ -867,6 +881,26 @@ With this amendment enabled, if an LP token is associated with a liquidity pool
2. The holder can receive frozen LP tokens, but can't send them out (similar to frozen trust lines).
### fixIncludeKeyletFields
[fixIncludeKeyletFields]: #fixincludekeyletfields
| Amendment | fixIncludeKeyletFields |
|:-------------|:--------------------|
| Amendment ID | 6143A27B71F7DAF9330ECA7C5EC3D54C8083A4FDEF7016737EEC06AB61E82EE0 |
| Status | Open for Voting |
| Default Vote (Latest stable release) | No |
| Pre-amendment functionality retired? | No |
This amendment adds fields to ledger entries in cases where those fields are part of the identifying information that forms their ledger entry ID:
- Add a `Sequence` field to `Escrow` and `PayChannel` entries.
- Add an `Owner` field to `SignerList` entries.
- Add an `OracleDocumentID` field to `Oracle` entries.
Without this amendment, some ledger entries do not store all the data that was used to create their ledger entry ID. After this amendment is enabled, ledger entries of those types have those fields added when the ledger entry is created or modified. Ledger entries that were created before the amendment are not changed until a transaction modifies them.
The presence of a `Sequence` field on Escrow ledger entries is especially useful since you need that value to finish or cancel the escrow, and you otherwise might have to look up the sequence number of the transaction that created the escrow.
### fixInnerObjTemplate
[fixInnerObjTemplate]: #fixinnerobjtemplate
@@ -937,6 +971,19 @@ Without this fix, a user can unintentionally "black hole" their account by setti
With this amendment enabled, a SetRegularKey transaction cannot set the regular key to match the master key; such a transaction results in the transaction code `temBAD_REGKEY`. Additionally, this amendment changes the signature verification code so that accounts which _already_ have their regular key set to match their master key can send transactions successfully using the key pair.
### fixMPTDeliveredAmount
[fixMPTDeliveredAmount]: #fixmptdeliveredamount
| Amendment | fixMPTDeliveredAmount |
|:-------------|:----------------|
| Amendment ID | AB8D932A5F338903FE5BCBD80B611FFED70839ABA3170E9CE01D947C0EDEDCF2 |
| Status | Open for Voting |
| Default Vote (Latest stable release) | No |
| Pre-amendment functionality retired? | No |
This amendment adds missing `DeliveredAmount` and `delivered_amount` metadata fields from direct MPT `Payment` transactions. Without this amendment, direct MPT payments deliver the full amount but do not have the metadata fields to summarize how much was delivered.
### fixNFTokenDirV1
[fixNFTokenDirV1]: #fixnftokendirv1
@@ -1106,6 +1153,21 @@ Ledger entries that were created before this amendment was enabled will get the
Without this amendment, some types of ledger entries don't have those fields, which makes it harder to trace the history of modifications to those ledger entries.
### fixPriceOracleOrder
[fixPriceOracleOrder]: #fixpriceoracleorder
| Amendment | fixPriceOracleOrder |
|:-------------|:--------------------|
| Amendment ID | FF2D1E13CF6D22427111B967BD504917F63A900CECD320D6FD3AC9FA90344631 |
| Status | Open for Voting |
| Default Vote (Latest stable release) | No |
| Pre-amendment functionality retired? | No |
Fixes an issue where the order of asset pair data is different from when a price oracle is created versus when it is updated.
This amendment ensures asset pairs follow a canonical order at all times, so you can predictably look up asset prices.
### fixQualityUpperBound
[fixQualityUpperBound]: #fixqualityupperbound
@@ -1223,6 +1285,21 @@ Without this fix, the dry offer remains on the ledger and counts toward its owne
With this amendment enabled, the XRP Ledger removes these dry offers when they're matched in auto-bridging.
### fixTokenEscrowV1
[fixTokenEscrowV1]: #fixtokenescrowv1
| Amendment | fixTokenEscrowV1 |
|:-------------|:-----------------|
| Amendment ID | 32B8614321F7E070419115ABEAB1742EA20F3E3AF34432B5E2F474F8083260DC |
| Status | Open for Voting |
| Default Vote (Latest stable release) | No |
| Pre-amendment functionality retired? | No |
Fixes an accounting error in MPT escrows. Specifically, when an escrow unlocks MPTs that have a transfer fee, the system incorrectly reduces the MPT issuer's locked token balance by the gross amount (without fees) rather than the net amount (with fees). This leads to discrepancies in the token's total supply accounting.
This amendment ensures that when escrowed MPTs are unlocked, the issuer's locked amount is reduced by the net amount, and the total supply is reduced by the transfer fees.
### fixTrustLinesToSelf
[fixTrustLinesToSelf]: #fixtrustlinestoself
@@ -1293,7 +1370,7 @@ The Flow Engine also makes it easier to improve and expand the payment engine wi
| Amendment ID | 3012E8230864E95A58C60FD61430D7E1B4D3353195F2981DC12B0C7C0950FFAC |
| Status | Enabled |
| Default Vote (Latest stable release) | Yes |
| Pre-amendment functionality retired? | No |
| Pre-amendment functionality retired? | Yes |
Streamlines the offer crossing logic in the XRP Ledger's decentralized exchange. Uses the updated code from the [Flow](#flow) amendment to power offer crossing, so [OfferCreate transactions][] and [Payment transactions][] share more code. This has subtle differences in how offers are processed:
@@ -1386,6 +1463,21 @@ This amendment adds several new invariants to protect the ledger against bugs in
- When deleting an account, ensure that certain types of ledger entries are also deleted, including that account's `DirectoryNode`, `SignerList`, `NFTokenPage`, and `AMM` directories, if any, are deleted with it.
### LendingProtocol
[LendingProtocol]: #lendingprotocol
| Amendment | LendingProtocol |
|:-------------|:-----------------|
| Amendment ID | 565B90CA1AB2B9D42208ED10884188C64F9E19083DECB9634AAF06EB03299509 |
| Status | In Development |
| Default Vote (Latest stable release) | No |
| Pre-amendment functionality retired? | No |
The Lending Protocol enables on-chain, fixed-term, uncollateralized loans using pooled funds from a Single Asset Vault. This implementation relies on off-chain underwriting and risk management to assess the creditworthiness of borrowers, but offers configurable, peer-to-peer loans.
Specification: [XLS-66](https://github.com/Tapanito/XRPL-Standards/tree/xls-66-lending-protocol/XLS-0066d-lending-protocol).
### MPTokensV1
[MPTokensV1]: #mptokensv1

View File

@@ -327,6 +327,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