Compare commits

..

23 Commits

Author SHA1 Message Date
Oliver Eggert
d1969d3919 remove rbac to enable anonymous mcp connections 2025-11-20 14:46:57 -08:00
oeggert
92230d702c Merge pull request #3385 from XRPLF/rippled-2.6.2
Rippled 2.6.2
2025-11-20 10:48:05 -08:00
oeggert
30c6a42519 Update blog/2025/rippled-2.6.2.md
Co-authored-by: Amarantha Kulkarni <amarantha-k@users.noreply.github.com>
2025-11-20 07:26:04 -08:00
oeggert
24a374e2bf Update blog/2025/rippled-2.6.2.md
Co-authored-by: Amarantha Kulkarni <amarantha-k@users.noreply.github.com>
2025-11-20 07:25:49 -08:00
Maria Shodunke
cac56c37f6 Merge pull request #3372 from XRPLF/batch-transactions-tutorial
Javascript: Batch transactions tutorial
2025-11-20 03:58:58 -08:00
Oliver Eggert
bd06feb49c remove sha512half script 2025-11-19 21:04:49 -08:00
Oliver Eggert
815df642e0 add commit message and download links 2025-11-19 21:02:28 -08:00
Oliver Eggert
6c64a1e449 update tecdir_full error messages 2025-11-19 15:44:05 -08:00
Oliver Eggert
9e343558cc update tec codes and release notes 2025-11-19 15:16:42 -08:00
Maria Shodunke
fb33561a98 Address review comments 2025-11-19 12:22:32 +00:00
Oliver Eggert
567d980713 update known amendments with fixdirectorylimit 2025-11-17 15:32:44 -08:00
Maria Shodunke
7f16532b07 Calculate inner transaction hash to verify success 2025-11-17 19:13:57 +00:00
Oliver Eggert
62759ec261 add 2.6.2 release notes 2025-11-14 13:21:30 -08:00
Rome Reginelli
003927517f Merge pull request #3379 from XRPLF/rr-mpt-dupe-flag
Remove duplicate flags field in sample JSON
2025-11-14 12:19:31 -08:00
Rome Reginelli
9c8c231900 Remove duplicate flags field in sample JSON 2025-11-11 15:53:25 -08:00
Maria Shodunke
382a10bda9 Add temARRAY_EMPTY error for Batch transaction 2025-11-06 16:52:31 +00:00
Maria Shodunke
d2cf306ec6 Mention minimum number of transactions required in a Batch 2025-11-06 12:15:58 +00:00
Maria Shodunke
3e41224ef0 Add Batch transactions tutorials 2025-11-06 10:28:01 +00:00
Maria Shodunke
01ed3055ec Merge pull request #3299 from XRPLF/python-get-started-code-walkthrough
Add Get Started Walkthrough for Python
2025-11-06 10:17:26 +00:00
Maria Shodunke
eb174b8700 Add review comments 2025-11-06 09:57:51 +00:00
Maria Shodunke
9e96d40799 Add Get Started Walkthrough for Python 2025-11-06 09:57:51 +00:00
Maria Shodunke
d6b55ab177 Merge pull request #3375 from XRPLF/build-fix
Fix for build failure
2025-11-06 09:31:21 +00:00
Maria Shodunke
d8b216bdd7 Fix for build failure 2025-11-05 14:43:17 +00:00
45 changed files with 1253 additions and 1469 deletions

View File

@@ -47,6 +47,7 @@ export function blogPosts() {
actions.createSharedData('blog-posts', { blogPosts: sortedPosts });
actions.addRouteSharedData('/blog/', 'blog-posts', 'blog-posts');
actions.addRouteSharedData('/ja/blog/', 'blog-posts', 'blog-posts');
actions.addRouteSharedData('/es-es/blog/', 'blog-posts', 'blog-posts');
} catch (e) {
console.log(e);
}

View File

@@ -44,6 +44,7 @@ export function codeSamples() {
});
actions.addRouteSharedData('/resources/code-samples/', 'code-samples', 'code-samples');
actions.addRouteSharedData('/ja/resources/code-samples/', 'code-samples', 'code-samples');
actions.addRouteSharedData('/es-es/resources/code-samples/', 'code-samples', 'code-samples');
} catch (e) {
console.log(e);
}

View File

@@ -1,4 +1,5 @@
# Batch
Code samples showing how to create and submit a [Batch transaction](../../docs/concepts/transactions/batch-transactions.md).
Both for simple and multi account batch transactions.
Code samples showing how to create and submit a [Batch transaction](https://xrpl.org/docs/concepts/transactions/batch-transactions).
Both for single and multi-account batch transactions.

View File

@@ -0,0 +1,301 @@
# Send a Batch Transaction
Code samples showing how to create and submit a [Batch transaction](https://xrpl.org/docs/concepts/transactions/batch-transactions) with Javascript.
Both for single and multi-account batch transactions.
## Single Account Batch Transaction
Quick setup and usage:
```sh
npm install xrpl
node singleAccountBatch.js
```
The script should output the following:
```sh
=== Funding new wallets from faucet... ===
Sender: rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim, Balance: 100 XRP
Wallet1: rGx6SACvYEvX8SRrvTPD91UhBmJ16pxL94, Balance: 100 XRP
Wallet2: r3qetgSfAtyCpGc4rvKNz4LX3F3urMSJJy, Balance: 100 XRP
=== Creating Batch transaction... ===
{
"TransactionType": "Batch",
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
"Flags": 65536,
"RawTransactions": [
{
"RawTransaction": {
"TransactionType": "Payment",
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
"Destination": "rGx6SACvYEvX8SRrvTPD91UhBmJ16pxL94",
"Amount": "2000000",
"Flags": 1073741824
}
},
{
"RawTransaction": {
"TransactionType": "Payment",
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
"Destination": "r3qetgSfAtyCpGc4rvKNz4LX3F3urMSJJy",
"Amount": "5000000",
"Flags": 1073741824
}
}
]
}
=== Submitting Batch transaction... ===
Batch transaction submitted successfully!
Result:
{
"close_time_iso": "2025-11-17T12:04:50Z",
"ctid": "C013313800030002",
"hash": "AE118213B0A183528418ABC5F14E3BFD6524020C5DB1C060157A0D3FDE15B900",
"ledger_hash": "621183809B68A794371C5EC6522105FF04E502C48EBDC8171B80224991E33394",
"ledger_index": 1257784,
"meta": {
"AffectedNodes": [
{
"ModifiedNode": {
"FinalFields": {
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
"Balance": "99999996",
"Flags": 0,
"OwnerCount": 0,
"Sequence": 1257779
},
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "42CC98AF0A28EDDDC7E359B5622CC5748BDE2A93E124AF5C32647ECA8F68D480",
"PreviousFields": {
"Balance": "100000000",
"Sequence": 1257778
},
"PreviousTxnID": "081C42DAE12001735AC4E9A7F027636DF612DB17B4BFA2333F4DB8EA0C9D1E9F",
"PreviousTxnLgrSeq": 1257778
}
}
],
"TransactionIndex": 3,
"TransactionResult": "tesSUCCESS"
},
"tx_json": {
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
"Fee": "4",
"Flags": 65536,
"LastLedgerSequence": 1257802,
"RawTransactions": [
{
"RawTransaction": {
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
"Amount": "2000000",
"Destination": "rGx6SACvYEvX8SRrvTPD91UhBmJ16pxL94",
"Fee": "0",
"Flags": 1073741824,
"Sequence": 1257779,
"SigningPubKey": "",
"TransactionType": "Payment"
}
},
{
"RawTransaction": {
"Account": "rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim",
"Amount": "5000000",
"Destination": "r3qetgSfAtyCpGc4rvKNz4LX3F3urMSJJy",
"Fee": "0",
"Flags": 1073741824,
"Sequence": 1257780,
"SigningPubKey": "",
"TransactionType": "Payment"
}
}
],
"Sequence": 1257778,
"SigningPubKey": "ED7031CA5BA4EC745610AB495F5053F318C119E87567BE485A494773AD8ED4FBCE",
"TransactionType": "Batch",
"TxnSignature": "0610A277086943BC462C1A5F85BEB667B62B4BDA59525138B6014101C08297897A73D3D2D247CB37A06E1EA36267C53A51C0FDF32F3D8E974029BEDC41105B07",
"ctid": "C013313800030002",
"date": 816696290,
"ledger_index": 1257784
},
"validated": true
}
Batch transaction URL:
https://devnet.xrpl.org/transactions/AE118213B0A183528418ABC5F14E3BFD6524020C5DB1C060157A0D3FDE15B900
=== Verifying inner transactions... ===
Transaction 1 hash: D18EA54D5653BBB5C87F116978822EAB7A26EDFB1D6C41910F36D7484D4890E3
- Status: tesSUCCESS (Ledger 1257784)
- Transaction URL: https://devnet.xrpl.org/transactions/D18EA54D5653BBB5C87F116978822EAB7A26EDFB1D6C41910F36D7484D4890E3
Transaction 2 hash: 5660DB400F08EE5543C54D4D65824A2142F9D5AC17294A4ABF654260F129B44E
- Status: tesSUCCESS (Ledger 1257784)
- Transaction URL: https://devnet.xrpl.org/transactions/5660DB400F08EE5543C54D4D65824A2142F9D5AC17294A4ABF654260F129B44E
=== Final balances ===
Sender: rP9EsVosrmx2HyrmLgWJpJacX5ZrVVQsim, Balance: 92.999996 XRP
Wallet1: rGx6SACvYEvX8SRrvTPD91UhBmJ16pxL94, Balance: 102 XRP
Wallet2: r3qetgSfAtyCpGc4rvKNz4LX3F3urMSJJy, Balance: 105 XRP
```
## Multi-Account Batch Transaction
```sh
npm install xrpl
node multiAccountBatch.js
```
The script should output the following:
```sh
=== Funding new wallets from faucet... ===
Alice: rHpve1GL2ZXUs3NB5iU91BrXBSwb5PbBrG, Balance: 100 XRP
Bob: r3ruQ92bqXwWxcR2w4cC1tW35og9h3UbBq, Balance: 100 XRP
Charlie: rsi5D9bkczpbGykPxoGNBVVmFFFXGwm3QA, Balance: 100 XRP
Third-party wallet: rfUpGXTzU3siTr4UovV6Wt86Vw3gQU4ttA, Balance: 100 XRP
=== Creating Batch transaction... ===
{
"TransactionType": "Batch",
"Account": "rfUpGXTzU3siTr4UovV6Wt86Vw3gQU4ttA",
"Flags": 65536,
"RawTransactions": [
{
"RawTransaction": {
"TransactionType": "Payment",
"Account": "rsi5D9bkczpbGykPxoGNBVVmFFFXGwm3QA",
"Destination": "rHpve1GL2ZXUs3NB5iU91BrXBSwb5PbBrG",
"Amount": "50000000",
"Flags": 1073741824
}
},
{
"RawTransaction": {
"TransactionType": "Payment",
"Account": "r3ruQ92bqXwWxcR2w4cC1tW35og9h3UbBq",
"Destination": "rHpve1GL2ZXUs3NB5iU91BrXBSwb5PbBrG",
"Amount": "50000000",
"Flags": 1073741824
}
}
]
}
=== Submitting Batch transaction... ===
Batch transaction submitted successfully!
Result:
{
"close_time_iso": "2025-11-17T12:08:31Z",
"ctid": "C013317600000002",
"hash": "1299D20C6B489DA5C632AE4DBE49475DBF42D9444C7E9C109CC9B8DD0FD55FEC",
"ledger_hash": "E45ECF69057084CD02BA49A17E4D0C9154D33A98BB3C95A11B2EB9BE18F32C9B",
"ledger_index": 1257846,
"meta": {
"AffectedNodes": [
{
"ModifiedNode": {
"FinalFields": {
"Account": "rfUpGXTzU3siTr4UovV6Wt86Vw3gQU4ttA",
"Balance": "99999994",
"Flags": 0,
"OwnerCount": 0,
"Sequence": 1257845
},
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "2D9E0A02007241C38A8DF679E7E62AA0B273E8B12A5430B7B9D99300424F0E1F",
"PreviousFields": {
"Balance": "100000000",
"Sequence": 1257844
},
"PreviousTxnID": "3153DE8DE922538A6BE54AA8F783CAD4B848A321AFF028D3E6DD0E80C4B9C237",
"PreviousTxnLgrSeq": 1257844
}
}
],
"TransactionIndex": 0,
"TransactionResult": "tesSUCCESS"
},
"tx_json": {
"Account": "rfUpGXTzU3siTr4UovV6Wt86Vw3gQU4ttA",
"BatchSigners": [
{
"BatchSigner": {
"Account": "rsi5D9bkczpbGykPxoGNBVVmFFFXGwm3QA",
"SigningPubKey": "EDEB88C2868BD25BF03DB26050E16579FA6F8F9E3FF3172E0DC3DCBDA5408572EB",
"TxnSignature": "9508568084596147CFDCFC18A62DC298A78AD1148BA4B0EB99BEE1CD37E5555FE3930810790D5708F9739B0E3F79772012C154CA33C2280BDD5B72473C17A607"
}
},
{
"BatchSigner": {
"Account": "r3ruQ92bqXwWxcR2w4cC1tW35og9h3UbBq",
"SigningPubKey": "ED82F98DA6A3FC3E88D2EE3A5469D92C7070513BEF4DEE75CAB0BDAA81E8AE378D",
"TxnSignature": "A482C8747F79857530474F1677599766C0BE283CB7E2A05AACF76E61BECCA16DCE3802D2D8244FBF4546A1C0E5EB70691255E3EFD2F8AC80B55357BDAB9ACD05"
}
}
],
"Fee": "6",
"Flags": 65536,
"LastLedgerSequence": 1257864,
"RawTransactions": [
{
"RawTransaction": {
"Account": "rsi5D9bkczpbGykPxoGNBVVmFFFXGwm3QA",
"Amount": "50000000",
"Destination": "rHpve1GL2ZXUs3NB5iU91BrXBSwb5PbBrG",
"Fee": "0",
"Flags": 1073741824,
"Sequence": 1257842,
"SigningPubKey": "",
"TransactionType": "Payment"
}
},
{
"RawTransaction": {
"Account": "r3ruQ92bqXwWxcR2w4cC1tW35og9h3UbBq",
"Amount": "50000000",
"Destination": "rHpve1GL2ZXUs3NB5iU91BrXBSwb5PbBrG",
"Fee": "0",
"Flags": 1073741824,
"Sequence": 1257841,
"SigningPubKey": "",
"TransactionType": "Payment"
}
}
],
"Sequence": 1257844,
"SigningPubKey": "ED22A32B61EDF083315515831723BC18F8311F03886BBA375DFF46335BB7A75F0B",
"TransactionType": "Batch",
"TxnSignature": "156791D2DBFAEFC9B0AC29F2D8D0CDB25E13F92E70E6D5414FE31BD8573CA23D3F62F8B34FC1F117BD556B25E4F748095A24C4342108AB32F1B2BAFBF1443501",
"ctid": "C013317600000002",
"date": 816696511,
"ledger_index": 1257846
},
"validated": true
}
Batch transaction URL:
https://devnet.xrpl.org/transactions/1299D20C6B489DA5C632AE4DBE49475DBF42D9444C7E9C109CC9B8DD0FD55FEC
=== Verifying inner transactions ===
Transaction 1 hash: 0F71979E3F641C980929F926640DCA886C30236ED0CD7C94B6CB36F0D42948AC
- Status: tesSUCCESS (Ledger 1257846)
- Transaction URL: https://devnet.xrpl.org/transactions/0F71979E3F641C980929F926640DCA886C30236ED0CD7C94B6CB36F0D42948AC
Transaction 2 hash: BC124CB29334AA1079139A9BE186B69A0AC467797F147754E2406714854D2A50
- Status: tesSUCCESS (Ledger 1257846)
- Transaction URL: https://devnet.xrpl.org/transactions/BC124CB29334AA1079139A9BE186B69A0AC467797F147754E2406714854D2A50
=== Final balances ===
Alice: rHpve1GL2ZXUs3NB5iU91BrXBSwb5PbBrG, Balance: 200 XRP
Bob: r3ruQ92bqXwWxcR2w4cC1tW35og9h3UbBq, Balance: 50 XRP
Charlie: rsi5D9bkczpbGykPxoGNBVVmFFFXGwm3QA, Balance: 50 XRP
Third-party wallet: rfUpGXTzU3siTr4UovV6Wt86Vw3gQU4ttA, Balance: 99.999994 XRP
```

View File

@@ -0,0 +1,143 @@
/**
* XRP Ledger Batch Transactions Tutorial
*
* This tutorial demonstrates how to use the Batch transaction feature (XLS-56)
* to perform a multi-account batch transaction.
* Concept doc: https://xrpl.org/docs/concepts/transactions/batch-transactions
* Reference doc: https://xrpl.org/docs/references/protocol/transactions/types/batch
*/
import xrpl from "xrpl"
const client = new xrpl.Client("wss://s.devnet.rippletest.net:51233/")
await client.connect()
// Create and fund wallets
console.log("=== Funding new wallets from faucet... ===");
const [
{ wallet: alice },
{ wallet: bob },
{ wallet: charlie },
{ wallet: thirdPartyWallet },
] = await Promise.all([
client.fundWallet(),
client.fundWallet(),
client.fundWallet(),
client.fundWallet(),
]);
console.log(`Alice: ${alice.address}, Balance: ${await client.getXrpBalance(alice.address)} XRP`)
console.log(`Bob: ${bob.address}, Balance: ${await client.getXrpBalance(bob.address)} XRP`)
console.log(`Charlie: ${charlie.address}, Balance: ${await client.getXrpBalance(charlie.address)} XRP`)
console.log(`Third-party wallet: ${thirdPartyWallet.address}, Balance: ${await client.getXrpBalance(thirdPartyWallet.address)} XRP`)
// Create inner transactions --------------------------------------------
// REQUIRED: Inner transactions MUST have the tfInnerBatchTxn flag (0x40000000).
// This marks them as part of a batch (requires Fee: 0 and empty SigningPubKey).
// Transaction 1: Charlie pays Alice
const charliePayment = {
TransactionType: "Payment",
Account: charlie.address,
Destination: alice.address,
Amount: xrpl.xrpToDrops(50),
Flags: xrpl.GlobalFlags.tfInnerBatchTxn // THIS IS REQUIRED
}
// Transaction 2: Bob pays Alice
const bobPayment = {
TransactionType: "Payment",
Account: bob.address,
Destination: alice.address,
Amount: xrpl.xrpToDrops(50),
Flags: xrpl.GlobalFlags.tfInnerBatchTxn // THIS IS REQUIRED
}
// Send Batch transaction --------------------------------------------
console.log("\n=== Creating Batch transaction... ===")
const batchTx = {
TransactionType: "Batch",
Account: thirdPartyWallet.address,
Flags: xrpl.BatchFlags.tfAllOrNothing, // tfAllOrNothing: All inner transactions must succeed
// Must include a minimum of 2 transactions and a maximum of 8 transactions.
RawTransactions: [
{ RawTransaction: charliePayment },
{ RawTransaction: bobPayment },
]
}
console.log(JSON.stringify(batchTx, null, 2))
// Validate the transaction structure
xrpl.validate(batchTx)
// Set the expected number of signers, which is 2 (Bob and Charlie) in this case, for this transaction.
// "autofill" will automatically add Fee: "0" and SigningPubKey: "" to inner transactions.
const autofilledBatchTx = await client.autofill(batchTx, 2)
// Gather batch signatures --------------------------------
// Each signer needs their own tx copy because signMultiBatch modifies the object.
// Charlie signs the Batch transaction
const charlieBatch = { ...autofilledBatchTx }
xrpl.signMultiBatch(charlie, charlieBatch)
// Bob signs the Batch transaction
const bobBatch = { ...autofilledBatchTx }
xrpl.signMultiBatch(bob, bobBatch)
// Combine inner transaction signatures.
// This returns a signed transaction blob (hex string) ready for submission.
const combinedSignedTx = xrpl.combineBatchSigners([charlieBatch, bobBatch])
// Submit the signed blob with the third-party's wallet
console.log("\n=== Submitting Batch transaction... ===")
const submitResponse = await client.submitAndWait(combinedSignedTx,
{ wallet: thirdPartyWallet }
)
// Check Batch transaction result --------------------------------
if (submitResponse.result.meta.TransactionResult !== "tesSUCCESS") {
const resultCode = submitResponse.result.meta.TransactionResult
console.warn(`\nTransaction failed with result code ${resultCode}`)
await client.disconnect()
process.exit(1)
}
console.log("\nBatch transaction submitted successfully!")
console.log("Result:\n", JSON.stringify(submitResponse.result, null, 2))
// View the transaction on the XRPL Explorer
console.log(`\nBatch transaction URL:\nhttps://devnet.xrpl.org/transactions/${submitResponse.result.hash}`)
// Calculate and verify inner transaction hashes --------------------------------------------
console.log("\n=== Verifying inner transactions ===")
const rawTransactions = submitResponse.result.tx_json.RawTransactions
let hasFailure = false
for (let i = 0; i < rawTransactions.length; i++) {
const innerTx = rawTransactions[i].RawTransaction
const hash = xrpl.hashes.hashSignedTx(innerTx)
console.log(`\nTransaction ${i + 1} hash: ${hash}`)
try {
const tx = await client.request({ command: 'tx', transaction: hash })
const status = tx.result.meta?.TransactionResult
console.log(` - Status: ${status} (Ledger ${tx.result.ledger_index})`)
console.log(` - Transaction URL: https://devnet.xrpl.org/transactions/${hash}`)
} catch (error) {
hasFailure = true
console.log(` - Transaction not found: ${error}`)
}
}
if (hasFailure) {
console.error("\n--- Error: One or more inner transactions failed. ---")
await client.disconnect()
process.exit(1)
}
// Verify balances after transaction
console.log("\n=== Final balances ===")
console.log(`Alice: ${alice.address}, Balance: ${await client.getXrpBalance(alice.address)} XRP`)
console.log(`Bob: ${bob.address}, Balance: ${await client.getXrpBalance(bob.address)} XRP`)
console.log(`Charlie: ${charlie.address}, Balance: ${await client.getXrpBalance(charlie.address)} XRP`)
console.log(`Third-party wallet: ${thirdPartyWallet.address}, Balance: ${await client.getXrpBalance(thirdPartyWallet.address)} XRP`)
await client.disconnect()

View File

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

View File

@@ -0,0 +1,120 @@
/**
* Single Account Batch Transaction Example
*
* This example demonstrates how to use the Batch transactions feature (XLS-56)
* to create a single-account batch transaction that sends payments
* to multiple destinations in one atomic operation.
* Concept doc: https://xrpl.org/docs/concepts/transactions/batch-transactions
* Reference doc: https://xrpl.org/docs/references/protocol/transactions/types/batch
*/
import xrpl from "xrpl"
const client = new xrpl.Client("wss://s.devnet.rippletest.net:51233/")
await client.connect()
// Create and fund wallets
console.log("=== Funding new wallets from faucet... ===");
const [{ wallet: sender }, { wallet: wallet1 }, { wallet: wallet2 }] =
await Promise.all([
client.fundWallet(),
client.fundWallet(),
client.fundWallet(),
]);
console.log(`Sender: ${sender.address}, Balance: ${await client.getXrpBalance(sender.address)} XRP`)
console.log(`Wallet1: ${wallet1.address}, Balance: ${await client.getXrpBalance(wallet1.address)} XRP`)
console.log(`Wallet2: ${wallet2.address}, Balance: ${await client.getXrpBalance(wallet2.address)} XRP`)
// Create inner transactions --------------------------------------------
// REQUIRED: Inner transactions MUST have the tfInnerBatchTxn flag (0x40000000).
// This marks them as part of a batch (requires Fee: 0 and empty SigningPubKey).
// Transaction 1
const payment1 = {
TransactionType: "Payment",
Account: sender.address,
Destination: wallet1.address,
Amount: xrpl.xrpToDrops(2),
Flags: xrpl.GlobalFlags.tfInnerBatchTxn // THIS IS REQUIRED
}
// Transaction 2
const payment2 = {
TransactionType: "Payment",
Account: sender.address,
Destination: wallet2.address,
Amount: xrpl.xrpToDrops(5),
Flags: xrpl.GlobalFlags.tfInnerBatchTxn // THIS IS REQUIRED
}
// Send Batch transaction --------------------------------------------
console.log("\n=== Creating Batch transaction... ===")
const batchTx = {
TransactionType: "Batch",
Account: sender.address,
Flags: xrpl.BatchFlags.tfAllOrNothing, // tfAllOrNothing: All inner transactions must succeed
// Must include a minimum of 2 transactions and a maximum of 8 transactions.
RawTransactions: [
{ RawTransaction: payment1 },
{ RawTransaction: payment2 }
]
}
console.log(JSON.stringify(batchTx, null, 2))
// Validate the transaction structure before submitting
xrpl.validate(batchTx)
// Submit and wait for validation
console.log("\n=== Submitting Batch transaction... ===")
const submitResponse = await client.submitAndWait(batchTx, {
wallet: sender,
// "autofill" will automatically add Fee: "0" and SigningPubKey: "" to inner transactions.
autofill: true
})
// Check Batch transaction result --------------------------------
if (submitResponse.result.meta.TransactionResult !== "tesSUCCESS") {
const resultCode = submitResponse.result.meta.TransactionResult
console.warn(`\nTransaction failed with result code ${resultCode}`)
await client.disconnect()
process.exit(1)
}
console.log("\nBatch transaction submitted successfully!")
console.log("Result:\n", JSON.stringify(submitResponse.result, null, 2))
// View the batch transaction on the XRPL Explorer
console.log(`\nBatch transaction URL:\nhttps://devnet.xrpl.org/transactions/${submitResponse.result.hash}`)
// Calculate and verify inner transaction hashes --------------------------------------------
console.log("\n=== Verifying inner transactions... ===")
const rawTransactions = submitResponse.result.tx_json.RawTransactions
let hasFailure = false
for (let i = 0; i < rawTransactions.length; i++) {
const innerTx = rawTransactions[i].RawTransaction
const hash = xrpl.hashes.hashSignedTx(innerTx)
console.log(`\nTransaction ${i + 1} hash: ${hash}`)
try {
const tx = await client.request({ command: 'tx', transaction: hash })
const status = tx.result.meta?.TransactionResult
console.log(` - Status: ${status} (Ledger ${tx.result.ledger_index})`)
console.log(` - Transaction URL: https://devnet.xrpl.org/transactions/${hash}`)
} catch (error) {
hasFailure = true
console.log(` - Transaction not found: ${error}`)
}
}
if (hasFailure) {
console.error("\n--- Error: One or more inner transactions failed. ---")
await client.disconnect()
process.exit(1)
}
// Verify balances after transaction
console.log("\n=== Final balances ===")
console.log(`Sender: ${sender.address}, Balance: ${await client.getXrpBalance(sender.address)} XRP`)
console.log(`Wallet1: ${wallet1.address}, Balance: ${await client.getXrpBalance(wallet1.address)} XRP`)
console.log(`Wallet2: ${wallet2.address}, Balance: ${await client.getXrpBalance(wallet2.address)} XRP`)
await client.disconnect()

View File

@@ -0,0 +1,62 @@
# Get Started Using Python Library
Connects to the XRP Ledger and gets account information using Python.
To download the source code, see [Get Started Using Python Library](http://xrpl.org/docs/tutorials/python/build-apps/get-started).
## Run the Code
Quick setup and usage:
```sh
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python ./get-acct-info.py
```
You should see output similar to the following:
```sh
Creating a new wallet and funding it with Testnet XRP...
Attempting to fund address ravbHNootpSNQkxyEFCWevSkHsFGDHfyop
Faucet fund successful.
Wallet: ravbHNootpSNQkxyEFCWevSkHsFGDHfyop
Account Testnet Explorer URL:
https://testnet.xrpl.org/accounts/ravbHNootpSNQkxyEFCWevSkHsFGDHfyop
Getting account info...
Response Status: ResponseStatus.SUCCESS
{
"account_data": {
"Account": "ravbHNootpSNQkxyEFCWevSkHsFGDHfyop",
"Balance": "100000000",
"Flags": 0,
"LedgerEntryType": "AccountRoot",
"OwnerCount": 0,
"PreviousTxnID": "3DACF2438AD39F294C4EFF6132D5D88BCB65D2F2261C7650F40AC1F6A54C83EA",
"PreviousTxnLgrSeq": 12039759,
"Sequence": 12039759,
"index": "148E6F4B8E4C14018D679A2526200C292BDBC5AB77611BC3AE0CB97CD2FB84E5"
},
"account_flags": {
"allowTrustLineClawback": false,
"defaultRipple": false,
"depositAuth": false,
"disableMasterKey": false,
"disallowIncomingCheck": false,
"disallowIncomingNFTokenOffer": false,
"disallowIncomingPayChan": false,
"disallowIncomingTrustline": false,
"disallowIncomingXRP": false,
"globalFreeze": false,
"noFreeze": false,
"passwordSpent": false,
"requireAuthorization": false,
"requireDestinationTag": false
},
"ledger_hash": "CA624D717C4FCDD03BAD8C193F374A77A14F7D2566354A4E9617A8DAD896DE71",
"ledger_index": 12039759,
"validated": true
}
```

View File

@@ -1,34 +1,39 @@
# @chunk {"steps": ["connect-tag"]}
# Define the network client
from xrpl.clients import JsonRpcClient
from xrpl.wallet import generate_faucet_wallet
from xrpl.core import addresscodec
from xrpl.models.requests.account_info import AccountInfo
import json
JSON_RPC_URL = "https://s.altnet.rippletest.net:51234/"
client = JsonRpcClient(JSON_RPC_URL)
# @chunk-end
# Create a wallet using the testnet faucet:
# @chunk {"steps": ["get-account-create-wallet-tag"]}
# Create a wallet using the Testnet faucet:
# https://xrpl.org/xrp-testnet-faucet.html
from xrpl.wallet import generate_faucet_wallet
print("\nCreating a new wallet and funding it with Testnet XRP...")
test_wallet = generate_faucet_wallet(client, debug=True)
# Create an account str from the wallet
test_account = test_wallet.address
# Derive an x-address from the classic address:
# https://xrpaddress.info/
from xrpl.core import addresscodec
test_xaddress = addresscodec.classic_address_to_xaddress(test_account, tag=12345, is_test_network=True)
print("\nClassic address:\n\n", test_account)
print("X-address:\n\n", test_xaddress)
test_account = test_wallet.classic_address
print(f"Wallet: {test_account}")
print(f"Account Testnet Explorer URL: ")
print(f" https://testnet.xrpl.org/accounts/{test_account}")
# @chunk-end
# @chunk {"steps": ["query-xrpl-tag"]}
# Look up info about your account
from xrpl.models.requests.account_info import AccountInfo
print("\nGetting account info...")
acct_info = AccountInfo(
account=test_account,
ledger_index="validated",
strict=True,
)
response = client.request(acct_info)
result = response.result
print("response.status: ", response.status)
import json
print("Response Status: ", response.status)
print(json.dumps(response.result, indent=4, sort_keys=True))
# @chunk-end

View File

@@ -0,0 +1 @@
xrpl-py==4.3.0

View File

@@ -0,0 +1,70 @@
---
category: 2025
date: "2025-11-19"
template: '../../@theme/templates/blogpost'
seo:
title: Introducing XRP Ledger version 2.6.2
description: rippled version 2.6.2 is now available. This version contains a new amendment and a critical bug fix.
labels:
- rippled Release Notes
markdown:
editPage:
hide: true
---
# Introducing XRP Ledger version 2.6.2
Version 2.6.2 of `rippled`, the reference server implementation of the XRP Ledger protocol, is now available. This release adds a new `fixDirectoryLimit` amendment and a critical bug fix.
## Action Required
If you run an XRP Ledger server, upgrade to version 2.6.2 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-2.6.2-1.el9.x86_64.rpm) | `e3b041906a75c3c52cc6423219d7ba9c199a5d736d2e3978a5ce0ac5ef693fdf` |
| [DEB for Ubuntu / Debian (x86-64)](https://repos.ripple.com/repos/rippled-deb/pool/stable/rippled_2.6.2-1_amd64.deb) | `0887b5a77c43c362ea7680b83df40b955a5748b712924acf2212b2de29e3373b` |
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 df24ee077438e03673a9c6661c41e8f070b90cd9
Author: Vladislav Vysokikh <vvysokikh@gmail.com>
Date: Tue Nov 18 09:28:59 2025 +0000
Version 2.6.2
```
## Full Changelog
### Amendments
The following amendment is open for voting with this release:
- **fixDirectoryLimit** - Removes directory page limits. Object reserve requirements provide enough incentive to avoid creating unnecessary objects on the XRP Ledger. ([#5935](https://github.com/XRPLF/rippled/pull/5935))
### Bug Fixes
- Fixed an assertion failure when all the inner transactions of a `Batch` transaction were invalid. ([#5670](https://github.com/XRPLF/rippled/pull/5670))
## Credits
The following GitHub users contributed to this release:
- RippleX Engineering
- RippleX Docs
- RippleX Product
## 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-2.6.2.md
- page: 2025/rippled-2.6.1.md
- page: 2025/vulnerabilitydisclosurereport-bug-sep2025.md
- page: 2025/devnet-reset-oct.md

View File

@@ -248,13 +248,6 @@
[UNLModify pseudo-transaction]: /docs/references/protocol/transactions/pseudo-transaction-types/unlmodify.md
[UNLModify pseudo-transactions]: /docs/references/protocol/transactions/pseudo-transaction-types/unlmodify.md
[UNLModify]: /docs/references/protocol/transactions/pseudo-transaction-types/unlmodify.md
[Vault entry]: /docs/references/protocol/ledger-data/ledger-entry-types/vault.md
[VaultCreate transaction]: /docs/references/protocol/transactions/types/vaultcreate.md
[VaultDelete transaction]: /docs/references/protocol/transactions/types/vaultdelete.md
[VaultDeposit transaction]: /docs/references/protocol/transactions/types/vaultdeposit.md
[VaultSet transaction]: /docs/references/protocol/transactions/types/vaultset.md
[VaultWithdraw transaction]: /docs/references/protocol/transactions/types/vaultwithdraw.md
[VaultClawback transaction]: /docs/references/protocol/transactions/types/vaultclawback.md
[XChainAddAccountCreateAttestation transaction]: /docs/references/protocol/transactions/types/xchainaddaccountcreateattestation.md
[XChainAddAccountCreateAttestation transactions]: /docs/references/protocol/transactions/types/xchainaddaccountcreateattestation.md
[XChainAddAccountCreateAttestation]: /docs/references/protocol/transactions/types/xchainaddaccountcreateattestation.md
@@ -454,7 +447,5 @@
[validator_list_sites method]: /docs/references/http-websocket-apis/admin-api-methods/status-and-debugging-methods/validator_list_sites.md
[validators command]: /docs/references/http-websocket-apis/admin-api-methods/status-and-debugging-methods/validators.md
[validators method]: /docs/references/http-websocket-apis/admin-api-methods/status-and-debugging-methods/validators.md
[vault_info command]: /docs/references/http-websocket-apis/public-api-methods/vault-methods/vault_info.md
[vault_info method]: /docs/references/http-websocket-apis/public-api-methods/vault-methods/vault_info.md
[wallet_propose command]: /docs/references/http-websocket-apis/admin-api-methods/key-generation-methods/wallet_propose.md
[wallet_propose method]: /docs/references/http-websocket-apis/admin-api-methods/key-generation-methods/wallet_propose.md

View File

@@ -1,33 +0,0 @@
---
seo:
description: A pseudo-account is a special type of XRPL account that holds assets on behalf of an on-chain protocol.
labels:
- Single Asset Vault
- AMM
- Lending Protocol
status: not_enabled
---
# Pseudo-Accounts
The XRP Ledger is an account-based blockchain where assets like XRP, trust line tokens, and Multi-Purpose Tokens (MPTs) are held by accounts, and are represented on-chain by an [AccountRoot](../../references/protocol/ledger-data/ledger-entry-types/accountroot) ledger entry. However, certain use cases require assets to be transferable to and from an object, which is why a pseudo-account is needed.
A pseudo-account is a special type of account that holds assets on behalf of an on-chain protocol. Use cases for pseudo-accounts include:
- **Automated Market Makers (AMM)**: The [XLS-30 amendment](../../../resources/known-amendments#amm) introduced pseudo-accounts for AMMs by adding the `AMMID` field to the `AccountRoot` ledger entry. This field links a pseudo-account to an AMM instance, allowing it to track XRP and token balances in the pool and issue `LPTokens` on behalf of the AMM instance.
- **Single Asset Vaults**: A single asset vault pseudo-account is used to store deposited funds and issue MPT shares. A new `VaultID` field is introduced in the `AccountRoot` ledger entry, which links the pseudo-account with the vault.
- **Lending Protocol**: The Lending Protocol also uses the single asset vault's pseudo-account, with each `LoanBroker` tracked in the pseudo-account's owner directory. The pseudo-account holds first-loss capital that protects vault depositors from loan defaults, as well as the loan funds themselves.
A pseudo-account has strict limitations. It cannot receive payments from other accounts, cannot send transactions since it has no signing authority, and exists solely to store or issue assets.
## Reserve Requirements
The cost of creating a pseudo-account depends on whether it is owned and controlled by another account:
- **Owned pseudo-accounts**: For objects like a `Vault` where a single account owns and controls the associated pseudo-account, the creation transaction increases the owner's XRP reserve by one [incremental owner reserve](../accounts/reserves#base-reserve-and-owner-reserve) (currently {% $env.PUBLIC_OWNER_RESERVE %}). This is in addition to any other reserve requirements of the transaction (for example, the Vault object itself).
- **Unowned pseudo-accounts**: For objects like an `AMM` that are not owned by any account, the creation transaction must charge a special, higher-than-normal transaction fee. This fee must be at least the value of one incremental owner reserve. This amount is burned, compensating for the permanent ledger space without tying the reserve to a specific owner.
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -1,251 +0,0 @@
---
seo:
description: A single asset vault aggregates assets from multiple depositors and makes them available to other on-chain protocols.
labels:
- Single Asset Vault
status: not_enabled
---
# Single Asset Vault
A single asset vault is an XRP Ledger primitive that aggregates assets from multiple depositors and makes them available to other on-chain protocols, such as the Lending Protocol. A vault asset can be [XRP](../../introduction/what-is-xrp.md), a [trust line token](../tokens/fungible-tokens/index.md), or an [MPT (Multi-Purpose Token)](../tokens/fungible-tokens/multi-purpose-tokens.md).
A Vault Owner account manages the vault and can create, update, or delete it as needed. When creating a vault, the Vault Owner can also specify whether shares are transferable or non-transferable. Non-transferable shares cannot be transferred to any other account, and can only be redeemed.
_(Requires the [SingleAssetVault amendment][] {% not-enabled /%}.)_
## Public vs. Private Vaults
A vault can be **public** or **private**, depending on the required level of access control.
In a public vault, anyone can deposit or redeem liquidity as long as they hold sufficient shares. In contrast, a private vault restricts access, allowing only depositors with the necessary [Credentials](../../concepts/decentralized-storage/credentials.md), managed through [Permissioned Domains](./decentralized-exchange/permissioned-domains.md), to deposit assets.
{% admonition type="warning" name="Warning" %}
If a depositor's credentials expire, they can no longer deposit assets in a private vault, but can always redeem their existing shares.
{% /admonition %}
To prevent the Vault Owner from locking funds away, any shareholder in a private vault can redeem their shares for assets.
Choosing between a public or private vault depends on your use case. For example, if depositor identity verification is required, use a private vault and issue credentials only to verified accounts.
## Vault Share Distribution and Redemption
Depositors can deposit assets to receive shares, which represent their proportional ownership of the vault, or redeem shares for assets.
[{% inline-svg file="../../img/single-asset-vault-img.svg" /%}](../../img/single-asset-vault-img.svg "Diagram: an example of an asset being deposited into the vault and shares being redeemed.")
Since the XRP Ledger is an account-based blockchain, all assets must be held by an account. A `Vault` ledger entry cannot hold assets directly, so a [pseudo-account](../accounts/pseudo-accounts.md) is created to hold assets on its behalf. This stand-alone account cannot receive funds or send transactions, and exists solely to store assets and issue shares.
Each share is represented on-chain as an MPT, issued by the vault's pseudo-account. Since MPTs can only exist as whole number units, the vault uses a `Scale` setting to convert fractional asset amounts into whole number shares.
The scale behavior varies based on the type of asset held by the vault:
- **XRP**: Uses a fixed scale that aligns with XRP's native structure, where one share represents one drop.
- **Trust Line Token**: Allows configurable precision (default preserves 6 decimal places).
- **MPT**: Uses a 1-to-1 relationship between MPT units and shares.
Depending on the connected protocol, vault shares may be yield-bearing, meaning shareholders could redeem shares for more or less liquidity than they originally deposited. This is because the total asset balance in the vault can grow or shrink over time, affecting the value of each share. However, the vault asset (e.g., USDC, XRP) does not generate yield on its own.
The value of each share depends on the total assets in the vault:
- If the vault earns yield over time, shares represent a larger claim, allowing depositors to redeem them for more assets.
- If the vault incurs losses, shares hold less value, resulting in lower redemptions.
A vault could generate yield through mechanisms like lending or staking, with yield paid in the same asset deposited. The specific logic for this depends on how the connected on-chain protocol generates yield. For example, if a vault is used by a lending protocol, it could earn yield from interest paid by borrowers.
### Exchange Algorithm
A single asset vault uses an **exchange algorithm** to define how assets convert into shares during deposits and how shares convert back into assets during redemptions.
A vault's total value can fluctuate due to factors like _unrealized losses_, which impact the exchange rate for deposits and redemptions. To ensure fairness, the algorithm adjusts the exchange rate dynamically, so depositors receive shares or redeem them for assets at a rate that accurately reflects the vaults true value.
#### Unrealized Loss
To prevent depositors from exploiting potential losses by redeeming shares early and shifting the full loss onto the remaining depositors, the vault tracks unrealized losses (or paper loss) using the `LossUnrealized` attribute in the `Vault` ledger entry.
Because the unrealized loss temporarily decreases the vault's value, a malicious depositor may take advantage of this by depositing assets at a lowered price and redeeming shares once the price increases.
For example, consider a vault with a total value of $1.0m and total shares of 1.0m. Let's assume the unrealized loss for the vault is $900k:
1. The new exchange rate is calculated as:
```js
// ExchangeRate = (AssetsTotal - LossUnrealized) / SharesTotal
exchangeRate = (1,000,000 - 900,000) / 1,000,000
```
The exchange rate value is now **0.1**.
2. After the unrealized loss is cleared, the new effective exchange rate would be:
```js
// ExchangeRate = AssetsTotal / SharesTotal
exchangeRate = 1,000,000 / 1,000,000
```
The exchange rate is now **1.0**.
A depositor could deposit $100k assets at a 0.1 exchange rate and get 1.0m shares. Once the unrealized loss is cleared, their shares would be worth $1.0m.
To mitigate this, the vault uses separate exchange rates for deposits and redemptions.
#### Exchange Rates
A single asset vault uses **two distinct exchange rates**:
- **Deposit Exchange Rate**: Protects new depositors from prior losses and ensures fair share allocation.
- **Withdrawal Exchange Rate**: Ensures all shareholders share losses proportionally. Whether redeeming shares or withdrawing assets, the vault always calculates payouts using the actual current value (total assets minus losses), so depositors get their fair share of what's actually in the vault.
- **Redemptions**: The vault burns shares so the depositor can receive proportional assets.
- **Withdrawals**: The vault determines the shares to burn based on the requested asset amount.
These exchange rates ensure fairness and prevent manipulation, maintaining the integrity of deposits and redemptions.
To understand how the exchange rates are applied, here are the key variables used in the calculations:
- `Γ_assets`: The total balance of assets held within the vault.
- `Γ_shares`: The total number of shares currently issued by the vault.
- `Δ_assets`: The amount of assets being deposited, withdrawn, or redeemed.
- `Δ_shares`: The number of shares being issued or burned.
- `l`: The vault's total unrealized loss.
- `σ`: The scaling factor (σ = 10<sup>Scale</sup>) used to convert fractional assets into whole number shares.
{% tabs %}
{% tab label="Deposit" %}
The vault computes the number of shares a depositor will receive as follows:
- **Initial Deposit (Empty Vault)**: For the first deposit into an empty vault, shares are calculated using the scaling factor to properly represent fractional assets as whole numbers.
```js
Δ_shares = Δ_assets * σ // σ = 10^Scale
```
- **Subsequent Deposits**: For all other deposits, shares are calculated proportionally. The resulting share value is rounded **down** to the nearest whole number.
```js
Δ_shares = (Δ_assets * Γ_shares) / Γ_assets
```
Because the share amount is rounded down, the actual assets taken from the depositor are recalculated. This ensures the depositor isn't overcharged and that new shares are valued against the vault's true value, accounting for any unrealized loss:
```js
Δ_assets = (Δ_shares * (Γ_assets - l)) / Γ_shares
```
After a successful deposit, the _total assets_ and _total shares_ values are updated like so:
```js
Γ_assets = Γ_assets + Δ_assets // New balance of assets in the vault.
Γ_shares = Γ_shares + Δ_shares // New share balance in the vault.
```
{% /tab %}
{% tab label="Redeem" %}
The vault computes the number of assets returned by burning shares as follows:
```js
Δ_assets = (Δ_shares * (Γ_assets - l)) / Γ_shares
```
After a successful redemption, the _total assets_ and _total shares_ values are updated like so:
```js
Γ_assets = Γ_assets - Δ_assets // New balance of assets in the vault.
Γ_shares = Γ_shares - Δ_shares // New share balance in the vault.
```
{% /tab %}
{% tab label="Withdraw" %}
When a depositor requests a specific asset amount, the vault uses a two-step process to determine the final payout:
1. The requested asset amount (`Δ_assets_requested`) is converted into shares.
```js
Δ_shares = (Δ_assets_requested * Γ_shares) / (Γ_assets - l)
```
The calculated share amount is rounded to the **nearest** whole number.
2. The rounded number of shares is used to calculate the final asset payout (`Δ_assets_out`), using the same logic as a redemption.
```js
Δ_assets_out = (Δ_shares * (Γ_assets - l)) / Γ_shares
```
Due to rounding in step 1, the final payout may differ slightly from the requested amount.
After a successful withdrawal, the _total asset_ and _total share_ values are updated like so:
```js
Γ_assets = Γ_assets - Δ_assets_out // New balance of assets in the vault.
Γ_shares = Γ_shares - Δ_shares // New share balance in the vault.
```
{% /tab %}
{% /tabs %}
### Can a Depositor Transfer Shares to Another Account?
Vault shares are a first-class asset, meaning that they can be transferred and used in other on-ledger protocols that support MPTs. However, the payee (or the receiver) must have permission to hold both the shares and the underlying asset.
For example, if a private vault holds USDC, the destination account must belong to the vaults Permissioned Domain and have permission to hold USDC. Any compliance mechanisms applied to USDC also apply to the shares. If the USDC issuer freezes the payees trust line, the payee cannot receive shares representing USDC.
{% admonition type="info" name="Note" %}
It is important to remember that a vault must be **configured** to allow share transfers, or this will not be possible.
{% /admonition %}
A depositor can transfer vault shares to another account by making a [Payment](../../references/protocol/transactions/types/payment) transaction. Nothing changes in the way the payment transaction is submitted for transferring vault shares. However, there are new failure scenarios to watch out for if the transaction fails:
- The vault is private and the payee lacks credentials in the vault's permissioned domain.
- The vault shares are configured as non-transferable.
- There is a global freeze (trust line tokens) or lock (MPTs) on the underlying asset.
- The underlying asset is an MPT and is locked for the payer, payee, or vault pseudo-account.
- The underlying asset is a trust line token and the trust line is frozen between the issuer and the payer, payee, or vault pseudo-account.
If the transfer succeeds and the payee already holds vault shares, their balance increases. Otherwise, a new MPT entry is created for their account.
## Compliance
### Frozen Assets
The issuer of a vault asset can enact a [freeze](./fungible-tokens/freezes) for trust line tokens or [lock an MPT](./fungible-tokens/deep-freeze#how-does-mpt-freeze/lock-behavior-differ-from-iou). When a vault asset is frozen:
1. Withdrawals can only be made to the assets issuer.
2. The asset cannot be deposited into the vault.
3. Its corresponding shares also cannot be transferred.
### Clawback
An asset issuer can perform a [Clawback](../../use-cases/tokenization/stablecoin-issuer#clawback) on vault assets by forcing redemption of shares held by an account. This exchanges the holder's shares for the underlying assets, which are sent directly to the issuer. This mechanism allows asset issuers to recover their issued assets from vault depositors when necessary for fraud prevention or regulatory compliance.
## Why Use a Single Asset Vault?
With a single asset vault you don't have to manage liquidity at the protocol level. Instead, you can use the vault to handle deposits, redemptions, and asset tracking separately.
Vaults handle asset-to-share conversion, ensure accurate pricing, and eliminate the need to add custom logic to calculate exchange rates or account for unrealized losses.
Depending on the connected on-chain protocol, vaults can be applied to various use cases, such as:
- Lending markets
- Aggregators
- Yield-bearing tokens
- Asset management
The only supported use cases right now are _asset management_ and [_lending markets_](https://github.com/XRPLF/XRPL-Standards/discussions/190).
{% raw-partial file="/docs/_snippets/common-links.md" /%}
## See Also
- **Concepts:**
- [Credentials](../../concepts/decentralized-storage/credentials.md) - Define access requirements for private vaults.
- [Permissioned Domains](../tokens/decentralized-exchange/permissioned-domains.md) - Control access to private vaults.
- [Pseudo-Accounts](../accounts/pseudo-accounts.md) - Special accounts that hold assets on behalf of on-chain protocols.
- **References:**
- [Vault entry][] - Data structure on the ledger that records vault information.
- [VaultClawback transaction][] - Allow asset issuers to recover assets from the vault.
- [VaultCreate transaction][] - Create a new vault for aggregating assets.
- [VaultDelete transaction][] - Delete an existing vault entry.
- [VaultDeposit transaction][] - Add assets to a vault in exchange for shares.
- [VaultSet transaction][] - Update the configuration of an existing vault.
- [VaultWithdraw transaction][] - Redeem liquidity from a vault.
- [vault_info method][] - Retrieve information about a vault and its shares.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -115,11 +115,6 @@ Use these methods to perform convenient tasks, such as ping and random number ge
* **[`ping`](utility-methods/ping.md)** - Confirm connectivity with the server.
* **[`random`](utility-methods/random.md)** - Generate a random number.
## [Vault Methods](vault-methods/index.md)
Use these methods to retrieve vault information.
* **[`vault_info`](vault-methods/vault_info.md)** - Get information about a specific vault.
## Deprecated Methods

View File

@@ -984,54 +984,6 @@ rippled json ledger_entry '{ "mptoken": {"mpt_issuance_id": "000002DFA4D893CFBC4
-->
### Get Vault Entry
Retrieve a `Vault` object from the ledger. This is similar to the [vault_info method][], but the `ledger_entry` version returns only the ledger entry as stored.
_(Requires the [SingleAssetVault amendment][] {% not-enabled /%}.)_
| Field | Type | Description |
|:-------------|:-----------------|:----------------------|
| `vault` | String | The [ledger entry ID](../../../protocol/ledger-data/common-fields.md#ledger-entry-id) of a [Vault](../../../protocol/ledger-data/ledger-entry-types/vault.md) object to retrieve. |
{% tabs %}
{% tab label="WebSocket" %}
```json
{
"id": "example_get_vault_entry",
"command": "ledger_entry",
"vault": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166",
"ledger_index": "validated"
}
```
{% /tab %}
{% tab label="JSON-RPC" %}
```json
{
"method": "ledger_entry",
"params": [
{
"vault": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166",
"ledger_index": "validated"
}
]
}
```
{% /tab %}
{% tab label="Commandline" %}
```sh
rippled json ledger_entry '{ "vault": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166", "ledger_index": "validated" }'
```
{% /tab %}
{% /tabs %}
<!-- TODO: Add when deployed to Devnet/Testnet -->
<!-- {% try-it method="ledger_entry-single-asset-vault" server="testnet" /%} -->
## Response Format
The response follows the [standard format][], with a successful result containing the following fields:

View File

@@ -1,9 +0,0 @@
---
metadata:
indexPage: true
---
# Vault Methods
A `Vault` object in the XRP Ledger represents the state of a tokenized vault. Use these methods to interact with vaults.
{% child-pages /%}

View File

@@ -1,294 +0,0 @@
---
seo:
description: Retrieve information about a vault, its owner, available assets, and details on issued shares.
labels:
- Single Asset Vault
---
# vault_info
[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/rpc/handlers/VaultInfo.cpp "Source")
The `vault_info` command retrieves information about a vault, its owner, available assets, and details on issued shares. All information retrieved is relative to a particular version of the ledger. {% badge href="https://github.com/XRPLF/rippled/releases/tag/3.3.0" %}New in: rippled 3.3.0{% /badge %}
_(Requires the [SingleAssetVault amendment][] {% not-enabled /%})_
## Request Format
An example of the request format:
{% tabs %}
{% tab label="WebSocket" %}
```json
{
"command": "vault_info",
"vault_id": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166"
}
```
{% /tab %}
{% tab label="JSON-RPC" %}
```json
{
"method": "vault_info",
"params": [
{
"vault_id": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166"
}
]
}
```
{% /tab %}
{% tab label="Commandline" %}
```sh
#Syntax: vault_info [<vault_id>]
rippled vault_info 45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166
```
{% /tab %}
{% /tabs %}
<!-- TODO: Add this when available on Devnet -->
<!-- {% try-it method="vault_info" /%} -->
The request includes the following parameters:
| `Field` | Type | Description |
| :--------- | :----- | :----------------------------------------- |
| `vault_id` | String | The object ID of the Vault to be returned. |
| `owner` | String | The account address of the Vault Owner. |
| `seq` | Number | The transaction sequence number that created the vault. |
You can provide either the `vault_id`, or both `owner` and `seq` values in the request.
## Response Format
An example of a successful response:
{% tabs %}
{% tab label="WebSocket" %}
```json
{
"result": {
"ledger_current_index": 222403,
"validated": false,
"vault": {
"Account": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85",
"Asset": {
"currency": "USD",
"issuer": "rXJSJiZMxaLuH3kQBUV5DLipnYtrE6iVb"
},
"AssetsAvailable": "0",
"AssetsMaximum": "1000000",
"AssetsTotal": "0",
"Data": "5661756C74206D65746164617461",
"Flags": 0,
"LedgerEntryType": "Vault",
"LossUnrealized": "0",
"Owner": "rNGHoQwNG753zyfDrib4qDvvswbrtmV8Es",
"OwnerNode": "0",
"PreviousTxnID": "39CBBE3629AD9ADF9BA5CBAC5BF18665E785D0B199D2B2773A8A1EAA6CBC622B",
"PreviousTxnLgrSeq": 219033,
"Scale": 6,
"Sequence": 200370,
"ShareMPTID": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175",
"WithdrawalPolicy": 1,
"index": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166",
"shares": {
"AssetScale": 6,
"Flags": 56,
"Issuer": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85",
"LedgerEntryType": "MPTokenIssuance",
"MPTokenMetadata": "7B2274223A225473745368617265222C226E223A2254657374205661756C74205368617265222C2264223A22412074657374207661756C742073686172652E222C2269223A226578616D706C652E6F72672F73686172652D69636F6E2E706E67222C226163223A22727761222C226173223A22657175697479222C22696E223A224D53205465737420497373756572222C227573223A5B7B2275223A226578616D706C657969656C642E636F2F7473747368617265222C2263223A2277656273697465222C2274223A2250726F647563742050616765227D2C7B2275223A226578616D706C657969656C642E636F2F646F6373222C2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373227D5D2C226169223A7B22766F6C6174696C697479223A226C6F77227D7D",
"OutstandingAmount": "0",
"OwnerNode": "0",
"PreviousTxnID": "39CBBE3629AD9ADF9BA5CBAC5BF18665E785D0B199D2B2773A8A1EAA6CBC622B",
"PreviousTxnLgrSeq": 219033,
"Sequence": 1,
"index": "10D193CFF4619D2C7D552746A8C9F76AD6335E6D4452712CB39F8C7F096AE474",
"mpt_issuance_id": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175"
}
}
},
"status": "success",
"type": "response"
}
```
{% /tab %}
{% tab label="JSON-RPC" %}
```json
200 OK
{
"result": {
"ledger_current_index": 222403,
"status": "success",
"validated": false,
"vault": {
"Account": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85",
"Asset": {
"currency": "USD",
"issuer": "rXJSJiZMxaLuH3kQBUV5DLipnYtrE6iVb"
},
"AssetsAvailable": "0",
"AssetsMaximum": "1000000",
"AssetsTotal": "0",
"Data": "5661756C74206D65746164617461",
"Flags": 0,
"LedgerEntryType": "Vault",
"LossUnrealized": "0",
"Owner": "rNGHoQwNG753zyfDrib4qDvvswbrtmV8Es",
"OwnerNode": "0",
"PreviousTxnID": "39CBBE3629AD9ADF9BA5CBAC5BF18665E785D0B199D2B2773A8A1EAA6CBC622B",
"PreviousTxnLgrSeq": 219033,
"Scale": 6,
"Sequence": 200370,
"ShareMPTID": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175",
"WithdrawalPolicy": 1,
"index": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166",
"shares": {
"AssetScale": 6,
"Flags": 56,
"Issuer": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85",
"LedgerEntryType": "MPTokenIssuance",
"MPTokenMetadata": "7B2274223A225473745368617265222C226E223A2254657374205661756C74205368617265222C2264223A22412074657374207661756C742073686172652E222C2269223A226578616D706C652E6F72672F73686172652D69636F6E2E706E67222C226163223A22727761222C226173223A22657175697479222C22696E223A224D53205465737420497373756572222C227573223A5B7B2275223A226578616D706C657969656C642E636F2F7473747368617265222C2263223A2277656273697465222C2274223A2250726F647563742050616765227D2C7B2275223A226578616D706C657969656C642E636F2F646F6373222C2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373227D5D2C226169223A7B22766F6C6174696C697479223A226C6F77227D7D",
"OutstandingAmount": "0",
"OwnerNode": "0",
"PreviousTxnID": "39CBBE3629AD9ADF9BA5CBAC5BF18665E785D0B199D2B2773A8A1EAA6CBC622B",
"PreviousTxnLgrSeq": 219033,
"Sequence": 1,
"index": "10D193CFF4619D2C7D552746A8C9F76AD6335E6D4452712CB39F8C7F096AE474",
"mpt_issuance_id": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175"
}
}
}
}
```
{% /tab %}
{% tab label="Commandline" %}
```json
Loading: "/etc/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result": {
"ledger_current_index": 222403,
"validated": false,
"vault": {
"Account": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85",
"Asset": {
"currency": "USD",
"issuer": "rXJSJiZMxaLuH3kQBUV5DLipnYtrE6iVb"
},
"AssetsAvailable": "0",
"AssetsMaximum": "1000000",
"AssetsTotal": "0",
"Data": "5661756C74206D65746164617461",
"Flags": 0,
"LedgerEntryType": "Vault",
"LossUnrealized": "0",
"Owner": "rNGHoQwNG753zyfDrib4qDvvswbrtmV8Es",
"OwnerNode": "0",
"PreviousTxnID": "39CBBE3629AD9ADF9BA5CBAC5BF18665E785D0B199D2B2773A8A1EAA6CBC622B",
"PreviousTxnLgrSeq": 219033,
"Scale": 6,
"Sequence": 200370,
"ShareMPTID": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175",
"WithdrawalPolicy": 1,
"index": "45E6742527EDE6A2B537AE8A77B8D8CCFEFE115A22B3BF664A39407631F9A166",
"shares": {
"AssetScale": 6,
"Flags": 56,
"Issuer": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85",
"LedgerEntryType": "MPTokenIssuance",
"MPTokenMetadata": "7B2274223A225473745368617265222C226E223A2254657374205661756C74205368617265222C2264223A22412074657374207661756C742073686172652E222C2269223A226578616D706C652E6F72672F73686172652D69636F6E2E706E67222C226163223A22727761222C226173223A22657175697479222C22696E223A224D53205465737420497373756572222C227573223A5B7B2275223A226578616D706C657969656C642E636F2F7473747368617265222C2263223A2277656273697465222C2274223A2250726F647563742050616765227D2C7B2275223A226578616D706C657969656C642E636F2F646F6373222C2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373227D5D2C226169223A7B22766F6C6174696C697479223A226C6F77227D7D",
"OutstandingAmount": "0",
"OwnerNode": "0",
"PreviousTxnID": "39CBBE3629AD9ADF9BA5CBAC5BF18665E785D0B199D2B2773A8A1EAA6CBC622B",
"PreviousTxnLgrSeq": 219033,
"Sequence": 1,
"index": "10D193CFF4619D2C7D552746A8C9F76AD6335E6D4452712CB39F8C7F096AE474",
"mpt_issuance_id": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175"
}
}
},
"status": "success"
}
```
{% /tab %}
{% /tabs %}
The response follows the [standard format][], with a successful result containing following fields:
| `Field` | Type | Description |
| :--------------------- | :--------------- | :---------- |
| `ledger_hash` | [Hash][] | _(Omitted if `ledger_current_index` is provided instead)_ The identifying hash of the ledger version that was used when retrieving this data. |
| `ledger_current_index` | [Ledger Index][] | _(Omitted if `ledger_index` is provided instead)_ The [ledger index][] of the current in-progress ledger, which was used when retrieving this information. |
| `ledger_index` | [Ledger Index][] | _(Omitted if `ledger_current_index` is provided instead)_ The [ledger index][] of the ledger version used when retrieving this information. |
| `validated` | Boolean | True if this data is from a validated ledger version; if omitted or set to false, this data is not final. |
| `vault` | Object | The [**Vault Description Object**](#vault-description-object) that represents the current status of the vault. |
### Vault Description Object
The `vault` field is an object describing the current status of a Vault entry in the ledger, and contains the following fields:
| `Field` | Type | Description |
| :--------------------- | :------------------- | :---------- |
| `Account` | String - [Address][] | The address of the vault's pseudo-account. |
| `Asset` | Object | The [**Asset**](#asset-object) of the vault. An asset can be XRP, a trust line token, or an MPT. |
| `AssetsAvailable` | Number | The asset amount that is available in the vault. |
| `AssetsMaximum` | Number | The maximum asset amount that can be held in the vault. If set to 0, this indicates there is no cap. |
| `AssetsTotal` | Number | The total value of the vault. |
| `Flags` | String | Set of bit-flags for this ledger object. |
| `LossUnrealized` | Number | The potential loss amount that is not yet realized, expressed as the vault's asset. |
| `ShareMPTID` | String | The identifier of the share `MPTokenIssuance` object. |
| `WithdrawalPolicy` | String | Indicates the withdrawal strategy used by the vault. |
| `index` | String | The unique index of the vault ledger entry. |
| `shares` | Object | A [**Shares Object**](#shares-object) containing details about the vault's issued shares. |
| `Scale` | Number | Specifies decimal precision for share calculations. Assets are multiplied by 10<sup>Scale</sup > to convert fractional amounts into whole number shares. For example, with a `Scale` of `6`, depositing 20.3 units creates 20,300,000 shares (20.3 × 10<sup>Scale</sup >). For **trust line tokens** this can be configured at vault creation, and valid values are between 0-18, with the default being `6`. For **XRP** and **MPTs**, this is fixed at `0`. |
### Asset Object
The `asset` object contains the following nested fields:
| `Field` | Type | Description |
| :--------------------- | :------------------- | :---------- |
| `currency` | String | _(Omitted if the asset is an MPT)_ The currency code of the asset stored in the vault. |
| `issuer` | String - [Address][] | _(Omitted if the asset is XRP or an MPT)_ The address of the asset issuer. |
| `mpt_issuance_id` | String | _(Omitted if the asset is XRP or a trust line token)_ The identifier of the asset's `MPTokenIssuance` object. |
### Shares Object
The `shares` object contains the following nested fields:
| `Field` | Type | Description |
| :--------------------- | :--------------- | :---------- |
| `DomainID` | String | _(Omitted if the vault is public)_ The permissioned domain associated with the vault's shares. |
| `Flags` | Number | Set of bit-flags for this ledger object. |
| `Issuer` | String | The address issuing the shares. This is always the vault's pseudo-account. |
| `LedgerEntryType` | String | The ledger object type (i.e., `MPTokenIssuance`). |
| `OutstandingAmount` | String | The total outstanding shares issued. |
| `OwnerNode` | String | Identifies the page where this item is referenced in the owner's directory. |
| `PreviousTxnID` | String | Identifies the transaction ID that most recently modified this object. |
| `PreviousTxnLgrSeq` | Number | The sequence of the ledger that contains the transaction that most recently modified this object. |
| `Sequence` | Number | The transaction sequence number that created the shares. |
| `index` | String | The unique index of the shares ledger entry. |
| `mpt_issuance_id` | String | The identifier of the `MPTokenIssuance` object. This is always equal to the vault's `ShareMPTID`. |
| `AssetScale` | Number | The decimal precision for share calculations. |
## Possible Errors
- Any of the [universal error types][].
- `invalidParams` - One or more fields are specified incorrectly, or one or more required fields are missing.
## See Also
- [Vault entry][]
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -189,8 +189,6 @@ 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. |
@@ -396,21 +394,6 @@ 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

@@ -39,7 +39,7 @@ In addition to the [common fields](../common-fields.md), {% code-page-name /%} e
|:------------------------------|:----------|:------------------|:----------|:-------------|
| `Account` | String | AccountID | Yes | The identifying (classic) address of this [account](../../../../concepts/accounts/index.md). |
| `AccountTxnID` | String | UInt256 | No | The identifying hash of the transaction most recently sent by this account. This field must be enabled to use the [`AccountTxnID` transaction field](../../transactions/common-fields.md#accounttxnid). To enable it, send an [AccountSet transaction with the `asfAccountTxnID` flag enabled](../../transactions/types/accountset.md#accountset-flags). |
| `AMMID` | String | UInt256 | No | {% amendment-disclaimer name="AMM" /%} The ledger entry ID of the corresponding AMM ledger entry. Set during account creation; cannot be modified. If present, indicates that this is a special AMM [pseudo-account](../../../../concepts/accounts/pseudo-accounts.md) AccountRoot; always omitted on non-AMM accounts. |
| `AMMID` | String | UInt256 | No | {% amendment-disclaimer name="AMM" /%} The ledger entry ID of the corresponding AMM ledger entry. Set during account creation; cannot be modified. If present, indicates that this is a special AMM AccountRoot; always omitted on non-AMM accounts. |
| `Balance` | String | Amount | No | The account's current [XRP balance in drops][XRP, in drops], represented as a string. |
| `BurnedNFTokens` | Number | UInt32 | No | How many total of this account's issued [non-fungible tokens](../../../../concepts/tokens/nfts/index.md) have been burned. This number is always equal or less than `MintedNFTokens`. |
| `Domain` | String | Blob | No | A domain associated with this account. In JSON, this is the hexadecimal for the ASCII representation of the domain. [Cannot be more than 256 bytes in length.](https://github.com/XRPLF/rippled/blob/70d5c624e8cf732a362335642b2f5125ce4b43c1/include/xrpl/protocol/Protocol.h#L98) |
@@ -54,18 +54,15 @@ In addition to the [common fields](../common-fields.md), {% code-page-name /%} e
| `PreviousTxnLgrSeq` | Number | UInt32 | Yes |The [index of the ledger][Ledger Index] that contains the transaction that most recently modified this object. |
| `RegularKey` | String | AccountID | No | The address of a [key pair](../../../../concepts/accounts/cryptographic-keys.md) that can be used to sign transactions for this account instead of the master key. Use a [SetRegularKey transaction][] to change this value. |
| `Sequence` | Number | UInt32 | Yes | The [sequence number](../../data-types/basic-data-types.md#account-sequence) of the next valid transaction for this account. |
| `TicketCount` | Number | UInt32 | No | How many [Tickets](../../../../concepts/accounts/tickets.md) this account owns in the ledger. This is updated automatically to ensure that the account stays within the hard limit of 250 Tickets at a time. This field is omitted if the account has zero Tickets. _(Added by the [TicketBatch amendment][].)_ |
| `TickSize` | Number | UInt8 | No | How many significant digits to use for exchange rates of Offers involving currencies issued by this address. Valid values are `3` to `15`, inclusive. _(Added by the [TickSize amendment][].)_ |
| `TicketCount` | Number | UInt32 | No | How many [Tickets](../../../../concepts/accounts/tickets.md) this account owns in the ledger. This is updated automatically to ensure that the account stays within the hard limit of 250 Tickets at a time. This field is omitted if the account has zero Tickets. {% amendment-disclaimer name="TicketBatch" /%} |
| `TickSize` | Number | UInt8 | No | How many significant digits to use for exchange rates of Offers involving currencies issued by this address. Valid values are `3` to `15`, inclusive. {% amendment-disclaimer name="TickSize" /%} |
| `TransferRate` | Number | UInt32 | No | A [transfer fee](../../../../concepts/tokens/fungible-tokens/transfer-fees.md) to charge other users for sending currency issued by this account to each other. |
| `VaultID` | String | UInt256 | No | _(Requires the [SingleAssetVault amendment][] {% not-enabled /%}.)_ The ID of the `Vault` entry associated with this account. Set during account creation; cannot be modified. If present, indicates that this is a special Vault [pseudo-account](../../../../concepts/accounts/pseudo-accounts.md) AccountRoot; always omitted on non-Vault accounts. |
| `WalletLocator` | String | UInt256 | No | An arbitrary 256-bit value that users can set. |
| `WalletSize` | Number | UInt32 | No | Unused. (The code supports this field but there is no way to set it.) |
## Special AMM AccountRoot (Pseudo-Account)
## Special AMM AccountRoot Entries
{% amendment-disclaimer name="AMM" /%}
Automated Market Makers use an AccountRoot ledger entry (pseudo-account) to issue their LP Tokens and hold the assets in the AMM pool, and an [AMM ledger entry](amm.md) for tracking some of the details of the AMM. The address of an AMM's AccountRoot is randomized so that users cannot identify and fund the address in advance of the AMM being created. Unlike normal accounts, AMM AccountRoot objects are created with the following settings:
Automated Market Makers use an AccountRoot ledger entry to issue their LP Tokens and hold the assets in the AMM pool, and an [AMM ledger entry](amm.md) for tracking some of the details of the AMM. The address of an AMM's AccountRoot is randomized so that users cannot identify and fund the address in advance of the AMM being created. Unlike normal accounts, AMM AccountRoot objects are created with the following settings:
- `lsfDisableMaster` **enabled** and no means of authorizing transactions. This ensures no one can control the account directly, and it cannot send transactions.
- `lsfDepositAuth` **enabled** and no accounts preauthorized. This ensures that the only way to add money to the AMM Account is using the [AMMDeposit transaction][].
@@ -80,21 +77,7 @@ In addition, the following special rules apply to an AMM's AccountRoot entry:
Other than those exceptions, these accounts are like ordinary accounts; the LP Tokens they issue behave like other [tokens](../../../../concepts/tokens/index.md) except that those tokens can also be used in AMM-related transactions. You can check an AMM's balances and the history of transactions that affected it the same way you would with a regular account.
## Special Vault AccountRoot (Pseudo-Account)
_(Requires the [SingleAssetVault amendment][] {% not-enabled /%}.)_
Vaults use an AccountRoot ledger entry (pseudo-account) to issue their shares and hold the assets deposited into the vault, and a [Vault entry][] for tracking the vault's configuration and state. The address of a vault's AccountRoot is randomized so that users cannot identify and fund the address in advance of the vault being created. Unlike normal accounts, vault AccountRoot objects are created with the following settings:
- `lsfDisableMaster` **enabled** and no means of authorizing transactions. This ensures no one can control the account directly, and it cannot send transactions.
- `lsfDepositAuth` **enabled** and no accounts pre-authorized. This ensures that the only way to add money to the vault's AccountRoot is using the [VaultDeposit transaction][].
- `lsfDefaultRipple` **enabled**. This enables rippling for the vault's pseudo-account.
In addition, the following special rules apply to a Vault's AccountRoot entry:
- The vault owner account must pay one [incremental owner reserve](../../../../concepts/accounts/reserves#base-reserve-and-owner-reserve) (currently {% $env.PUBLIC_OWNER_RESERVE %}) when creating the vault to cover the pseudo-account.
- The `Sequence` number is always `0` and never changes, preventing the pseudo-account from submitting transactions.
- A pseudo-account is automatically deleted when the vault is deleted, and cannot exist independently of a Vault entry.
{% amendment-disclaimer name="AMM" /%}
## AccountRoot Flags
@@ -122,7 +105,7 @@ AccountRoot objects can have the following flags combined in the `Flags` field:
## {% $frontmatter.seo.title %} Reserve
The [reserve](../../../../concepts/accounts/reserves.md) for an AccountRoot entry is the base reserve, currently {% $env.PUBLIC_BASE_RESERVE %}, except in the case of a special AMM or Vault AccountRoot.
The [reserve](../../../../concepts/accounts/reserves.md) for an AccountRoot entry is the base reserve, currently {% $env.PUBLIC_BASE_RESERVE %}, except in the case of a special AMM AccountRoot.
This XRP cannot be sent to others but it can be burned as part of the [transaction cost][].
@@ -135,9 +118,6 @@ The ID of an AccountRoot entry is the [SHA-512Half][] of the following values, c
## See Also
- **Concepts:**
- [Pseudo-Accounts](../../../../concepts/accounts/pseudo-accounts.md)
- **Transactions:**
- [AccountSet transaction][]
- [AccountDelete transaction][]

View File

@@ -1,115 +0,0 @@
---
seo:
description: A Vault object defines the state of a tokenized vault.
labels:
- Vault
- Single Asset Vault
---
# Vault
[[Source]](https://github.com/XRPLF/rippled/blob/master/include/xrpl/protocol/detail/ledger_entries.macro#L484-L504 "Source")
A {% code-page-name /%} object defines the state of a tokenized vault. It contains key details such as available assets, shares, total value, and other relevant information. You can create a {% code-page-name /%} object with the [VaultCreate](../../transactions/types/vaultcreate.md) transaction.
The {% code-page-name /%} object is tracked in an [Owner Directory](../../../protocol/ledger-data/ledger-entry-types/directorynode) owned by the Vault Owner account.
Additionally, to facilitate `Vault` object lookup, the object is tracked in the owner directory of the vault's [pseudo-account](../../../../concepts/accounts/pseudo-accounts.md).
_(Requires the [SingleAssetVault amendment][] {% not-enabled /%})_
## Example Vault JSON
```json
{
"LedgerEntryType": "Vault",
"Account": "rwCNM7SeUHTajEBQDiNqxDG8p1Mreizw85",
"Asset": {
"currency": "USD",
"issuer": "rXJSJiZMxaLuH3kQBUV5DLipnYtrE6iVb"
},
"AssetsAvailable": "0",
"AssetsMaximum": "1000000",
"AssetsTotal": "0",
"Data": "5661756C74206D65746164617461",
"Flags": 0,
"LossUnrealized": "0",
"Owner": "rNGHoQwNG753zyfDrib4qDvvswbrtmV8Es",
"OwnerNode": "0",
"Scale": 6,
"Sequence": 200370,
"ShareMPTID": "0000000169F415C9F1AB6796AB9224CE635818AFD74F8175",
"WithdrawalPolicy": 1,
}
```
## {% $frontmatter.seo.title %} Fields
In addition to the [common ledger entry fields](../../../protocol/ledger-data/common-fields), {% code-page-name /%} {% code-page-name /%} entries have the following fields:
| Name | JSON Type | [Internal Type][] | Required? | Description |
| :------------------ | :------------ | :---------------- | :-------- | -----------------|
| `LedgerEntryType` | String | UInt16 | Yes | Ledger object type. The default value is `0x0081`. |
| `LedgerIndex` | String | UInt16 | Yes | The unique identifier of the ledger object. |
| `Flags` | String | UInt32 | Yes | Set of bit-flags for this ledger object. |
| `PreviousTxnID` | String | Hash256 | Yes | Identifies the transaction ID that most recently modified this object. |
| `PreviousTxnLgrSeq` | Number | UInt32 | Yes | The sequence of the ledger that contains the transaction that most recently modified this object. |
| `Sequence` | Number | UInt32 | Yes | The transaction sequence number that created the vault. |
| `OwnerNode` | Number | UInt64 | Yes | Identifies the page where this item is referenced in the owner's directory. |
| `Owner` | String | AccountID | Yes | The account address of the Vault Owner. |
| `Account` | String | AccountID | Yes | The address of the vault's pseudo-account. |
| `Data` | String | Blob | No | Arbitrary metadata about the vault. Limited to 256 bytes. |
| `Asset` | Object | Issue | Yes | The asset of the vault. The vault supports XRP, trust line tokens, and MPTs. |
| `AssetsTotal` | Number | Number | Yes | The total value of the vault. |
| `AssetsAvailable` | Number | Number | Yes | The asset amount that is available in the vault. |
| `AssetsMaximum` | Number | Number | No | The maximum asset amount that can be held in the vault. If set to 0, this indicates there is no cap. |
| `LossUnrealized` | Number | Number | Yes | The potential loss amount that is not yet realized, expressed as the vault's asset. Only a protocol connected to the vault can modify this attribute. |
| `ShareMPTID` | String | UInt192 | Yes | The identifier of the share `MPTokenIssuance` object. |
| `WithdrawalPolicy` | String | UInt8 | Yes | Indicates the withdrawal strategy used by the vault. |
| `Scale` | Number | UInt8 | No | Specifies decimal precision for share calculations. Assets are multiplied by 10<sup>Scale</sup > to convert fractional amounts into whole number shares. For example, with a `Scale` of `6`, depositing 20.3 units creates 20,300,000 shares (20.3 × 10<sup>Scale</sup >). For **trust line tokens** this can be configured at vault creation, and valid values are between 0-18, with the default being `6`. For **XRP** and **MPTs**, this is fixed at `0`. |
### Scaling Factor
The **`Scale`** field enables the vault to accurately represent fractional asset values using integer-only MPT shares, which prevents the loss of value from decimal truncation. It defines a scaling factor, calculated as 10<sup>Scale</sup>, that converts a decimal asset amount into a corresponding whole number of shares.
The scaling factor behavior varies by asset type:
- **Trust line token**: When a vault holds a trust line token, the `Scale` is configurable by the Vault Owner when creating the vault. The value can range from **0** to a maximum of **18**, with a default of **6**. This flexibility allows issuers to set a level of precision appropriate for their specific token.
- **XRP**: When a vault holds XRP, the `Scale` is fixed at **0**. This aligns with XRP's native structure, where one share represents one drop, and one XRP equals 1,000,000 drops. Therefore, a deposit of 10 XRP to an empty vault will result in the issuance of 10,000,000 shares.
- **MPT**: When a vault holds an MPT, its `Scale` is fixed at **0**. This creates a 1-to-1 relationship between deposited MPT units and the shares issued. For example, depositing 10 MPTs to an empty vault issues 10 shares. The value of a single MPT is determined at the issuer's discretion.
{% admonition type="warning" name="Warning" %}
If an MPT is set to represent a large value, the vault owner and the depositor must be cautious. Since only whole MPT units are used in calculations, any value that is not a multiple of a single MPT's value may be lost due to rounding during a transaction.
{% /admonition %}
## {% $frontmatter.seo.title %} Flags
{% code-page-name /%} entries can have the following flags:
| Flag Name | Flag Value | Description |
| :---------------- | :----------- | :---------------------------|
| `lsfVaultPrivate` | `0x00010000` | If set, indicates that the vault is private. This flag can only be set when _creating_ the vault. |
## Vault ID Format
The ID of a {% code-page-name /%} entry is the [SHA-512Half][] of the following values, concatenated in order:
- The {% code-page-name /%} space key `0x0056` (capital V).
- The [AccountID](../../../protocol/binary-format/#accountid-fields) of the account submitting the transaction (for example, the vault owner).
- The transaction `Sequence` number. If the transaction used a [Ticket](../../../../concepts/accounts/tickets), use the `TicketSequence` value.
## See Also
**API Methods**:
- [vault_info method][]
**Transactions**:
- [VaultClawback transaction][]
- [VaultCreate transaction][]
- [VaultDelete transaction][]
- [VaultDeposit transaction][]
- [VaultSet transaction][]
- [VaultWithdraw transaction][]
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -27,7 +27,7 @@ A transaction that fails with a `tec` code destroys the XRP paid as a [transacti
| `tecCANT_ACCEPT_OWN_NFTOKEN_OFFER` | 157 | The transaction tried to accept an offer that was placed by the same account to buy or sell a [non-fungible token](../../../../concepts/tokens/nfts/index.md). {% amendment-disclaimer name="NonFungibleTokensV1_1" /%} |
| `tecCLAIM` | 100 | Unspecified failure, with transaction cost destroyed. |
| `tecCRYPTOCONDITION_ERROR` | 146 | This [EscrowCreate][] or [EscrowFinish][] transaction contained a malformed or mismatched crypto-condition. |
| `tecDIR_FULL` | 121 | The transaction tried to add an object (such as a trust line, Check, Escrow, or Payment Channel) to an account's owner directory, but that account cannot own any more objects in the ledger. |
| `tecDIR_FULL` | 121 | The transaction tried to add an object (such as a trust line, Check, Escrow, or Payment Channel) to an account's owner directory, but that account cannot own any more objects in the ledger.<br>This error is effectively impossible to receive if {% amendment-disclaimer name="fixDirectoryLimit" compact=true /%} is enabled. |
| `tecDUPLICATE` | 149 | The transaction tried to create an object (such as a [DepositPreauth][] authorization) that already exists. |
| `tecDST_TAG_NEEDED` | 143 | The [Payment transaction][] omitted a [destination tag](../../../../concepts/transactions/source-and-destination-tags.md), but the destination account has the `lsfRequireDestTag` flag enabled. |
| `tecEMPTY_DID` | 187 | The transaction tried to create a [DID entry][] with no contents. A DID must not be empty. {% amendment-disclaimer name="DID" /%} |

View File

@@ -121,12 +121,12 @@ In this example, two users are atomically swapping their tokens: XRP for GKO.
| Field | JSON Type | [Internal Type][] | Required? | Description |
|:------------------|:----------|:------------------|:----------|:------------|
| `Flags` | Number | UInt32 | Yes | A bit-flag for this transaction. Exactly one must be specified to represent the batch mode of the transaction. See: [Batch Flags](#batch-flags). |
| `RawTransactions` | Array | Array | Yes | The list of transactions to apply. |
| `RawTransactions` | Array | Array | Yes | The list of transactions to apply. See [RawTransactions](#rawtransactions). |
| `BatchSigners` | Array | Array | No | The signatures authorizing a multi-account `Batch` transaction. |
### RawTransactions
`RawTransactions` contains the list of inner transactions to be applied. There can be up to 8 transactions included. These transactions can come from one account or multiple accounts.
`RawTransactions` contains the list of inner transactions to be applied. There must be a minimum of **2** transactions and a maximum of **8** transactions. These transactions can come from one account or multiple accounts.
Each inner transaction:
@@ -169,6 +169,7 @@ A transaction is considered successful if it receives a `tesSUCCESS` result.
| Error Code | Description |
|:--------------------------|:--------------------------------------------------|
| `temARRAY_EMPTY` | The batch transaction contains zero or one inner transaction. You must submit at least two inner transactions. |
| `temINVALID_INNER_BATCH` | An inner transaction is malformed. |
| `temSEQ_AND_TICKET` | The transaction contains both a `TicketSequence` field and a non-zero `Sequence` value. A transaction can't include both fields, but must have at least one. |

View File

@@ -40,14 +40,18 @@ Create an on-ledger [check](../../../../concepts/payment-types/checks.md), which
## Error Cases
- If the `Destination` account is blocking incoming Checks, the transaction fails with the result code `tecNO_PERMISSION`. {% amendment-disclaimer name="DisallowIncoming" /%}
- If the `Destination` is the sender of the transaction, the transaction fails with the result code `temREDUNDANT`.
- If the `Destination` [account](../../../../concepts/accounts/index.md) does not exist in the ledger, the transaction fails with the result code `tecNO_DST`.
- If the `Destination` account has the `RequireDest` flag enabled but the transaction does not include a `DestinationTag` field, the transaction fails with the result code `tecDST_TAG_NEEDED`.
- If `SendMax` specifies a token which is [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md), the transaction fails with the result `tecFROZEN`.
- If the `Expiration` of the transaction is in the past, the transaction fails with the result `tecEXPIRED`.
- If the sender does not have enough XRP to meet the [owner reserve](../../../../concepts/accounts/reserves.md#owner-reserves) after adding the Check, the transaction fails with the result `tecINSUFFICIENT_RESERVE`.
- If either the sender or the destination of the Check cannot own more objects in the ledger, the transaction fails with the result `tecDIR_FULL`.
Besides errors that can occur for all transactions, {% $frontmatter.seo.title %} transactions can result in the following [transaction result codes](../transaction-results/index.md):
| Error Code | Description |
|:-----------|:------------|
| `tecNO_PERMISSION` | The `Destination` account is blocking incoming Checks. {% amendment-disclaimer name="DisallowIncoming" /%} |
| `temREDUNDANT` | The `Destination` is the sender of the transaction. |
| `tecNO_DST` | The `Destination` [account](../../../../concepts/accounts/index.md) does not exist in the ledger. |
| `tecDST_TAG_NEEDED` | The `Destination` account has the `RequireDest` flag enabled but the transaction does not include a `DestinationTag` field. |
| `tecFROZEN` | `SendMax` specifies a token which is [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md). |
| `tecEXPIRED` | The `Expiration` of the transaction is in the past. |
| `tecINSUFFICIENT_RESERVE` | The sender does not have enough XRP to meet the [owner reserve](../../../../concepts/accounts/reserves.md#owner-reserves) after adding the Check. |
| `tecDIR_FULL` | Either the sender or the destination of the Check cannot own more objects in the ledger.<br>This error is effectively impossible to receive if {% amendment-disclaimer name="fixDirectoryLimit" compact=true /%} is enabled. |
## See Also

View File

@@ -65,7 +65,7 @@ Besides errors that can occur for all transactions, {% $frontmatter.seo.title %}
| Error Code | Description |
|:--------------------------|:------------|
| `tecDIR_FULL` | The sender owns too many items in the ledger already. |
| `tecDIR_FULL` | The sender owns too many items in the ledger already.<br>This error is effectively impossible to receive if {% amendment-disclaimer name="fixDirectoryLimit" compact=true /%} is enabled. |
| `tecINSUFFICIENT_RESERVE` | The sender does not have enough XRP to meet the [reserve requirement](/docs/concepts/accounts/reserves.md) of creating a new Delegate ledger entry. |
| `tecNO_PERMISSION` | At least one permission in the `Permissions` list is not delegatable. See [Permission Values](../../data-types/permission-values.md) for which permissions are not delegatable. |
| `tecNO_TARGET` | The account specified in the `Authorize` field does not exist in the ledger. |

View File

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

View File

@@ -56,7 +56,7 @@ Besides errors that can occur for all transactions, {% $frontmatter.seo.title %}
| `temDISABLED` | The [NonFungibleTokensV1 amendment][] is not enabled. |
| `temBAD_AMOUNT` | The `Amount` field is not valid. For example, the amount was zero for a buy offer, or the amount is denominated in fungible tokens but the `NFToken` has the [`lsfOnlyXRP` flag](../../data-types/nftoken.md#nftoken-flags) enabled. |
| `temBAD_EXPIRATION` | The specified `Expiration` time is invalid (for example, `0`). |
| `tecDIR_FULL` | The sender already owns too many objects in the ledger, or there are already too many offers to buy or sell this token. |
| `tecDIR_FULL` | The sender already owns too many objects in the ledger, or there are already too many offers to buy or sell this token.<br>This error is effectively impossible to receive if {% amendment-disclaimer name="fixDirectoryLimit" compact=true /%} is enabled. |
| `tecEXPIRED` | The specified `Expiration` time has already passed. |
| `tecFROZEN` | The `Amount` is denominated in fungible tokens, but one of the trust lines that would receive tokens from this offer is [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md). This could be the seller's trust line or the `NFToken`'s issuer's trust line (if the `NFToken` has a transfer fee). |
| `tecINSUFFICIENT_RESERVE` | The sender does not have enough XRP to meet the [reserve requirement](../../../../concepts/accounts/reserves.md) after placing this offer. |

View File

@@ -58,7 +58,7 @@ Transactions of the OfferCreate type support additional values in the [`Flags` f
| Error Code | Description |
|:-------------------------|:--------------------------------------------------|
| `tecDIR_FULL` | The owner owns too many items in the ledger, or the order book contains too many Offers at the same exchange rate already. |
| `tecDIR_FULL` | The owner owns too many items in the ledger, or the order book contains too many Offers at the same exchange rate already.<br>This error is effectively impossible to receive if {% amendment-disclaimer name="fixDirectoryLimit" compact=true /%} is enabled. |
| `tecEXPIRED` | The transaction specifies an `Expiration` time that has already passed. |
| `tecFROZEN` | The transaction involves a token on a [frozen](../../../../concepts/tokens/fungible-tokens/freezes.md) trust line (including local and global freezes). The `TakerPays` (buy amount) token has been deep-frozen by the issuer. |
| `tecINSUF_RESERVE_OFFER` | The owner does not have enough XRP to meet the reserve requirement of adding a new offer ledger entry, and the transaction did not convert any currency. (If the transaction successfully traded any amount, the transaction succeeds with the result code `tesSUCCESS`, but does not create an offer ledger entry for the remainder.) |

View File

@@ -55,7 +55,7 @@ Besides errors that can occur for all transactions, {% $frontmatter.seo.title %}
| Error Code | Description |
|:--------------------------|:------------|
| `tecDIR_FULL` | The transaction would create a new PermissionedDomain, but the sender's owner directory is full. |
| `tecDIR_FULL` | The transaction would create a new PermissionedDomain, but the sender's owner directory is full.<br>This error is effectively impossible to receive if {% amendment-disclaimer name="fixDirectoryLimit" compact=true /%} is enabled. |
| `tecINSUFFICIENT_RESERVE` | The transaction would create a new PermissionedDomain, but the sender does not have enough XRP to meet the increased owner reserve. |
| `tecNO_ENTRY` | The transaction attempted to modify a Domain that does not exist. Check the `DomainID` field of the transaction. |
| `tecNO_ISSUER` | At least one of the issuers specified in the `AcceptedCredentials` field is does not exist in the XRP Ledger. Check the `Issuer` field of each member of the array. |

View File

@@ -43,7 +43,7 @@ Besides errors that can occur for all transactions, {% $frontmatter.seo.title %}
| Error Code | Description |
|:--------------------------|:-------------------------------------------------|
| `temINVALID_COUNT` | The `TicketCount` field is invalid. It must be an integer from 1 to 250. |
| `tecDIR_FULL` | This transaction would cause the account to own more than the limit of 250 Tickets at a time, or more than the maximum number of ledger objects in general. |
| `tecDIR_FULL` | This transaction would cause the account to own more than the limit of 250 Tickets at a time, or more than the maximum number of ledger objects in general.<br>The maximum ledger objects error is effectively impossible to receive if {% amendment-disclaimer name="fixDirectoryLimit" compact=true /%} is enabled. |
| `tecINSUFFICIENT_RESERVE` | The sending account does not have enough XRP to meet the [owner reserve](../../../../concepts/accounts/reserves.md) of all the requested Tickets. |
## See Also

View File

@@ -1,70 +0,0 @@
---
seo:
description: Allows the issuer of a trust line token or MPT to claw back funds from the vault.
labels:
- Transactions
- Single Asset Vault
---
# VaultClawback
[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/VaultClawback.cpp "Source")
Performs a [Clawback](../../../../use-cases/tokenization/stablecoin-issuer#clawback) from the vault, exchanging the shares of an account for assets.
Under the hood, the transaction performs a [VaultWithdraw](./vaultwithdraw.md) on behalf of the account from which assets are clawed back, converting its shares into assets and transferring the funds to the assets issuing account. Because of this, {% code-page-name /%} must respect any applicable fees or penalties (e.g., unrealized loss).
{% admonition type="warning" name="Warning" %}
Clawbacks cannot be performed on native XRP.
{% /admonition %}
_(Requires the [SingleAssetVault amendment][] {% not-enabled /%})_
## Example {% $frontmatter.seo.title %} JSON
```json
{
"TransactionType": "VaultClawback",
"Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"Fee": "12",
"Flags": 0,
"LastLedgerSequence": 7108682,
"Sequence": 8,
"VaultID": "77D6234D074E505024D39C04C3F262997B773719AB29ACFA83119E4210328776",
"Holder": "ruazs5h1qEsqpke88pcqnaseXdm6od2xc",
"Amount" : "10000"
}
```
## {% $frontmatter.seo.title %} Fields
| Field Name | JSON Type | [Internal Type][] | Required? | Description |
| :--------- | :-------- | :---------------- | :-------- | :---------- |
| `VaultID` | String | Hash256 | Yes | The unique identifier of the vault from which assets are withdrawn. |
| `Holder` | String | AccountID | Yes | The unique identifier of the account from which to claw back the assets. |
| `Amount` | Number | Number | No | The asset amount to claw back. When this field is set to 0, the transaction claws back all funds, up to the total shares the `Holder` owns. |
If the requested amount exceeds the vaults available assets, the transaction claws back only up to the vault's `AssetsAvailable` balance. Otherwise, it retrieves the exact asset amount specified in the transaction.
## {% $frontmatter.seo.title %} Flags
There are no flags defined for {% code-page-name /%} transactions.
## Error Cases
Besides errors that can occur for all transactions, {% code-page-name /%} transactions can result in the following [transaction result codes](../../../protocol/transactions/transaction-results/index.md):
| Error Code | Description |
| :---------------------- | :---------- |
| `tecNO_ENTRY` | The `Vault` object with the specified `VaultID` does not exist on the ledger. |
| `tecNO_PERMISSION` | The transaction attempts to claw back XRP, or the asset is a trust line token or MPT and the transaction isn't submitted by the issuing account. |
| `tecWRONG_ASSET` | The asset in the transaction does not match the vault's asset type. |
| `tecINSUFFICIENT_FUNDS` | The `MPToken` object for the vault share of the `Holder` account does not exist, or the `MPToken.MPTAmount` is 0. |
| `temDISABLED` | The Single Asset Vault amendment is not enabled. |
| `temMALFORMED` | The transaction was not validly formatted. For example, if the `VaultID` is not provided. |
## See Also
- [Vault entry][]
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -1,99 +0,0 @@
---
seo:
description: Creates a new vault object in the ledger.
labels:
- Transactions
- Single Asset Vault
---
# VaultCreate
[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/VaultCreate.cpp "Source")
Creates a new `Vault` ledger entry, an `MPTokenIssuance` ledger entry for the vaults shares, and an `AccountRoot` for the vaults [pseudo-account](../../../../concepts/accounts/pseudo-accounts.md).
Only the Vault Owner can initiate this transaction.
{% admonition type="info" name="Note" %}
Currently, the same account that creates the vault must also create other protocols, though this may change in the future.
{% /admonition %}
_(Requires the [SingleAssetVault amendment][] {% not-enabled /%})_
## Example {% $frontmatter.seo.title %} JSON
```json
{
"TransactionType": "VaultCreate",
"Account": "rNGHoQwNG753zyfDrib4qDvvswbrtmV8Es",
"Asset": {
"currency": "USD",
"issuer": "rXJSJiZMxaLuH3kQBUV5DLipnYtrE6iVb"
},
"AssetsMaximum": "1000000",
"Data": "5661756C74206D65746164617461",
"Fee": "5000000",
"Flags": 0,
"MPTokenMetadata": "7B2274223A225473745368617265222C226E223A2254657374205661756C74205368617265222C2264223A22412074657374207661756C742073686172652E222C2269223A226578616D706C652E6F72672F73686172652D69636F6E2E706E67222C226163223A22727761222C226173223A22657175697479222C22696E223A224D53205465737420497373756572222C227573223A5B7B2275223A226578616D706C657969656C642E636F2F7473747368617265222C2263223A2277656273697465222C2274223A2250726F647563742050616765227D2C7B2275223A226578616D706C657969656C642E636F2F646F6373222C2263223A22646F6373222C2274223A225969656C6420546F6B656E20446F6373227D5D2C226169223A7B22766F6C6174696C697479223A226C6F77227D7D",
"Scale": 6,
"Sequence": 200370,
"WithdrawalPolicy": 1
}
```
## {% $frontmatter.seo.title %} Fields
In addition to the [common fields](../../../../references/protocol/transactions/common-fields#transaction-common-fields), {% code-page-name /%} transactions use the following fields:
| Field Name | JSON Type | [Internal Type][] | Required? |Description |
|:-------------------|:--------------|:------------------|:----------|:------------------|
| `Data` | String | Blob | No | Arbitrary vault metadata, in hex format, limited to 256 bytes. |
| `Asset` | Object | Issue | Yes | The asset to be held in the vault. This can be XRP, a trust line token, or an MPT. If the asset is a trust line token, the transaction creates a [trust line](../../../../concepts/tokens/fungible-tokens/trust-line-tokens.md#structure) between the vault's pseudo-account and the issuer of the asset. If the asset is an MPT, the transaction creates an `MPToken` object for the vault's pseudo-account. |
| `AssetsMaximum` | Number | UInt64 | No | The maximum asset amount that can be held in a vault. |
| `MPTokenMetadata` | String | Blob | No | Arbitrary metadata about the share `MPToken`, in hex format, limited to 1024 bytes. |
| `WithdrawalPolicy` | Number | UInt8 | No | Indicates the withdrawal strategy used by the vault. The default value is `0x0001`, mapped to the string `vaultStrategyFirstComeFirstServe`. See [WithdrawalPolicy](#withdrawalpolicy). |
| `DomainID` | String | Hash256 | No | The [PermissionedDomain](../../../../concepts/tokens/decentralized-exchange/permissioned-domains.md) object ID associated with the shares of this vault. If provided, the transaction creates a private vault, which restricts access to accounts with [credentials](../../../../concepts/decentralized-storage/credentials.md) in the specified Permissioned Domain. |
| `Scale` | Number | UInt8 | No | _(Trust line tokens only)_ Specifies decimal precision for share calculations. Assets are multiplied by 10<sup>Scale</sup > to convert fractional amounts into whole number shares. For example, with a `Scale` of `6`, depositing 20.3 units creates 20,300,000 shares (20.3 × 10<sup>Scale</sup >). For **trust line tokens** this can be configured at vault creation, and valid values are between 0-18, with the default being `6`. For **XRP** and **MPTs**, this is fixed at `0`.|
## {% $frontmatter.seo.title %} Flags
{% code-page-name /%} transactions support additional values in the `Flags` field, as follows:
| Flag Name | Value | Description |
| :---------------------------- | :------------| -------------------------|
| `tfVaultPrivate` | `0x00010000` | Indicates that the vault is private. This flag can only be set when _creating_ the vault. |
| `tfVaultShareNonTransferable` | `0x00020000` | Indicates the vault share is non-transferable. This flag can only be set when _creating_ the vault. |
## WithdrawalPolicy
A `WithdrawalPolicy` defines the strategy for processing withdrawal requests from a vault. This policy governs how liquidity is removed. Currently, only one strategy is supported:
| Policy Name | Value | Description |
| :--------------------------------- | :------- | -------------------------|
| `vaultStrategyFirstComeFirstServe` | `0x0001` | Requests are processed on a first-come, first-served basis. With this strategy, a depositor can redeem any amount of assets, provided they hold a sufficient number of shares. |
## Transaction Cost
Since the {% code-page-name /%} transaction creates a new `AccountRoot` object for a vaults pseudo-account, it incurs a higher than usual [transaction cost](../../../../concepts/transactions/transaction-cost) to deter ledger spam. Instead of the standard minimum of 0.00001 XRP, {% code-page-name /%} must destroy an [incremental owner reserve](../../../../concepts/accounts/reserves#base-reserve-and-owner-reserve), currently 0.2 XRP.
## Error Cases
Besides errors that can occur for all transactions, {% code-page-name /%} transactions can result in the following [transaction result codes](../transaction-results/index.md):
| Error Code | Description |
| :------------------------ | :----------------------------------|
| `tecNO_AUTH` | The asset is an MPT and the `lsfMPTCanTransfer` flag is not set in the `MPTokenIssuance` object, meaning the vault cannot be created with a non-transferable MPT. |
| `tecLOCKED` | The asset is an MPT and the `lsfMPTLocked` flag is set in the `MPTokenIssuance` object, meaning the asset is locked. |
| `tecFROZEN` | The issuer has frozen the asset to be held in the vault. |
| `tecOBJECT_NOT_FOUND` | A ledger entry specified in the transaction does not exist. For example, the provided `DomainID` does not exist. |
| `temMALFORMED` | The transaction was not validly formatted. For example, the `Data` field is larger than 256 bytes. |
| `tecINSUFFICIENT_RESERVE` | There is insufficient `AccountRoot.Balance` for the Owner Reserve. |
| `terNO_RIPPLE` | The issuer of the asset has not enabled the [Default Ripple flag](../../../../concepts/tokens/fungible-tokens/stablecoins/configuration#default-ripple). |
| `terNO_ACCOUNT` | The issuer account of the vault's asset does not exist. |
| `temDISABLED` | Either the Single Asset Vault amendment is not enabled, a `DomainID` is provided and the Permissioned Domains amendment is not enabled, or the MPTokensV1 amendment is not enabled. |
## See Also
- [Vault entry][]
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -1,59 +0,0 @@
---
seo:
description: Deletes an existing Vault object from the ledger.
labels:
- Transactions
- Single Asset Vault
---
# VaultDelete
[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/VaultDelete.cpp "Source")
Permanently deletes an existing `Vault` object from the ledger, removes all associated ledger entries, and frees up the reserve requirement for the Vault Owner.
Only the Vault Owner can initiate this transaction, and the vault must be completely empty before deletion.
_(Requires the [SingleAssetVault amendment][] {% not-enabled /%})_
## Example {% $frontmatter.seo.title %} JSON
```json
{
"TransactionType": "VaultDelete",
"Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"Fee": "12",
"Flags": 0,
"LastLedgerSequence": 7108682,
"Sequence": 8,
"VaultID": "77D6234D074E505024D39C04C3F262997B773719AB29ACFA83119E4210328776"
}
```
## {% $frontmatter.seo.title %} Fields
In addition to the [common fields](https://xrpl.org/docs/references/protocol/transactions/common-fields#transaction-common-fields), {% code-page-name /%} transactions use the following fields:
| Field Name | JSON Type | [Internal Type][] | Required? | Description |
| :----------------- | :-------- | :---------------- | :-------- | :------------|
| `VaultID` | String | Hash256 | Yes | The unique identifier of the vault that needs to be deleted. |
## {% $frontmatter.seo.title %} Flags
There are no flags defined for {% code-page-name /%} transactions.
## Error Cases
Besides errors that can occur for all transactions, VaultCreate transactions can result in the following [transaction result codes](../../../protocol/transactions/transaction-results/index.md):
| Error Code | Description |
| :------------------------ | :----------------------------------|
| `tecNO_ENTRY` | The `Vault` object with the provided `VaultID` does not exist on the ledger. |
| `tecNO_PERMISSION` | The account submitting the transaction is not the `Owner` of the vault. |
| `tecHAS_OBLIGATIONS` | The vault to be deleted is connected to objects that cannot be deleted in the ledger. For example, the owner directory of the vault's pseudo-account contains references to any objects other than the vault, shares, or assets. |
## See Also
- [Vault entry][]
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -1,95 +0,0 @@
---
seo:
description: Deposits a specified number of assets into a vault in exchange for shares.
labels:
- Transactions
- Single Asset Vault
---
# VaultDeposit
[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/VaultDeposit.cpp "Source")
Deposits a specified number of assets into a vault in exchange for shares.
For private vaults, the depositor must be authorized to interact with the vaults shares and have [Credentials](../../../../concepts/decentralized-storage/credentials.md) in the [Permissioned Domain](../../../../concepts/tokens/decentralized-exchange/permissioned-domains.md) of the share.
Public vaults require no authorization, and anyone can deposit as long as they meet the asset type requirement and have sufficient funds.
{% admonition type="warning" name="Warning" %}
A depositor cannot deposit assets into the vault if:
- The asset is frozen for the depositor.
- The trust line between the pseudo-account and the issuer is frozen, or the `MPToken` is locked.
- The vault is private and the depositor's credentials have expired.
{% /admonition %}
If successful, the transaction moves the assets from the depositor's account to the vault's pseudo-account, issues the corresponding vault shares, and updates the vaults balance.
_(Requires the [SingleAssetVault amendment][] {% not-enabled /%})_
## Example {% $frontmatter.seo.title %} JSON
```json
{
"TransactionType": "VaultDeposit",
"Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"Fee": "12",
"Flags": 0,
"LastLedgerSequence": 7108682,
"Sequence": 8,
"VaultID": "77D6234D074E505024D39C04C3F262997B773719AB29ACFA83119E4210328776",
"Amount" : {
"currency" : "TST",
"issuer" : "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd",
"value" : "2.5"
}
}
```
## {% $frontmatter.seo.title %} Fields
In addition to the [common fields](../../../protocol/transactions/common-fields#transaction-common-fields), {% code-page-name /%} transactions use the following fields:
| Field Name | JSON Type | [Internal Type][] | Required? | Description |
| :-----------------------| :------------ | :---------------- | :-------- | :-------------------|
| `VaultID` | String | Hash256 | Yes | The unique identifier of the vault to which the asset is deposited. |
| `Amount` | Object | Amount | Yes | The asset and quantity to be deposited into the vault.|
The deposited asset must match the vaults designated asset for the transaction to succeed. Depending on the asset type, the following changes occur:
- **XRP**: The vaults pseudo-account balance increases, and the depositors balance decreases.
- **Trust line token**: The [trust line](../../../../concepts/tokens/fungible-tokens/trust-line-tokens.md#structure) balance between the vault's pseudo-account and the asset issuer is adjusted.
- **MPT**: The `MPToken.MPTAmount` of both the depositor and the vault's pseudo-account is updated.
## {% $frontmatter.seo.title %} Flags
There are no flags defined for {% code-page-name /%} transactions.
## Transfer Fees
A single asset vault does not apply the [transfer fee](../../../../concepts/tokens/fungible-tokens/transfer-fees) to {% code-page-name /%} transactions. Additionally, whenever a protocol moves assets from or to a vault, the transfer fee isn't charged.
## Error Cases
Besides errors that can occur for all transactions, {% code-page-name /%} transactions can result in the following [transaction result codes](../../../protocol/transactions/transaction-results/index.md):
| Error Code | Description |
| :---------------------- | :----------------------------------|
| `tecNO_ENTRY` | The `Vault` object with the provided `VaultID` does not exist on the ledger. |
| `tecOBJECT_NOT_FOUND` | A ledger entry specified in the transaction does not exist. |
| `tecWRONG_ASSET` | The asset of the vault does not match the asset being deposited. |
| `tecINSUFFICIENT_FUNDS` | The depositor does not have sufficient funds to make a deposit. |
| `tecLIMIT_EXCEEDED` | Adding the provided `Amount` to the `AssetsTotal` exceeds the `AssetsMaximum` value. |
| `tecNO_AUTH` | Either the vault is private and the depositing account does not have credentials in the share's Permissioned Domain, or the asset is a non-transferable MPT. |
| `tecFROZEN` | Either the trust line between the issuer and the depositor is frozen, or the asset is globally frozen. |
| `tecLOCKED` | Either the MPT asset is locked for the depositor, or if the asset is globally locked. |
| `temMALFORMED` | The transaction was not validly formatted. For example, if the `VaultID` is not provided. |
| `temDISABLED` | The Single Asset Vault amendment is not enabled. |
| `temBAD_AMOUNT` | The `Amount` field of the transaction is invalid. |
## See Also
- [Vault entry][]
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -1,70 +0,0 @@
---
seo:
description: Modifies a single asset vault that you own.
labels:
- Transactions
- Single Asset Vault
---
# VaultSet
[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/VaultSet.cpp "Source")
Modifies a single asset vault that you own. This transaction allows the Vault Owner to update certain mutable fields, including vault metadata and the maximum asset amount.
{% admonition type="warning" name="Warning" %}
Once a vault is created, its public or private status is permanent and cannot be changed. The [tfVaultPrivate](../../ledger-data/ledger-entry-types/vault.md#vault-flags) flag determines this status, and once set, it cannot be updated.
{% /admonition %}
_(Requires the [SingleAssetVault amendment][] {% not-enabled /%})_
## Example {% $frontmatter.seo.title %} JSON
```json
{
"TransactionType": "VaultSet",
"Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
"Fee": "12",
"Flags": 0,
"LastLedgerSequence": 7108682,
"Sequence": 8,
"VaultID": "77D6234D074E505024D39C04C3F262997B773719AB29ACFA83119E4210328776",
"Data": "5468697320697320617262697472617279206D657461646174612061626F757420746865207661756C742E",
"AssetsMaximum": 5,
"DomainID": "77D6234D074E505024D39C04C3F262997B773719AB29ACFA83119E4210328776"
}
```
## {% $frontmatter.seo.title %} Fields
In addition to the [common fields](../../../protocol/transactions/common-fields#transaction-common-fields), {% code-page-name /%} transactions use the following fields:
| Field Name | JSON Type | [Internal Type][] | Required? | Description |
| :---------------- | :-------- | :---------------- | :-------- | :-------------------|
| `VaultID` | String | Hash256 | Yes | The unique identifier of the vault that needs to be updated. |
| `Data` | String | Blob | No | Arbitrary vault metadata, limited to 256 bytes. |
| `AssetsMaximum` | Number | Number | No | The maximum asset amount that can be held in a vault. The value cannot be lower than the current `AssetsTotal`, unless the value is 0. |
| `DomainID` | String | Hash256 | No | The [PermissionedDomain](../../../../concepts/tokens/decentralized-exchange/permissioned-domains.md) object ID associated with the shares of this vault. The `DomainID` is only required when updating a private vault. |
## {% $frontmatter.seo.title %} Flags
There are no flags defined for {% code-page-name /%} transactions.
## Error Cases
Besides errors that can occur for all transactions, {% code-page-name /%} transactions can result in the following [transaction result codes](../../../protocol/transactions/transaction-results/index.md):
| Error Code | Description |
| :-------------------- | :-------------------------------------|
| `tecNO_ENTRY` | The transaction attempted to modify a vault that does not exist. Check the `VaultID` field of the transaction. |
| `tecOBJECT_NOT_FOUND` | The `PermissionedDomain` object with the provided `DomainID` does not exist. |
| `tecNO_PERMISSION` | The account submitting the transaction is not the `Owner` of the vault, or is trying to set a `DomainID` for a public vault. |
| `temMALFORMED` | The transaction was not validly formatted. For example, the `Data` field is larger than 256 bytes. |
| `tecLIMIT_EXCEEDED` | The _new_ `AssetsMaximum` value is **lower** than the vault's _current_ `AssetsTotal`. |
| `temDISABLED` | Either the Single Asset Vault amendment is not enabled, or a `DomainID` is provided and the Permissioned Domains amendment is not enabled. |
## See Also
- [Vault entry][]
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -1,89 +0,0 @@
---
seo:
description: Redeem vault shares for assets.
labels:
- Transactions
- Single Asset Vault
---
# VaultWithdraw
[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/VaultWithdraw.cpp "Source")
Redeem vault shares for assets. The amount of assets received depends on the [exchange rate](../../../../concepts/tokens/single-asset-vault.md#exchange-algorithm), which adjusts based on the vaults total assets and any [unrealized losses](../../../../concepts/tokens/single-asset-vault.md#unrealized-loss).
{% admonition type="info" name="Note" %}
The `VaultWithdraw` transaction does not respect the Permissioned Domain rules. In other words, any account that holds the shares of the vault can redeem them. This is to avoid a situation where a depositor deposits assets to a private vault to then have their access revoked by invalidating their credentials, and thus losing access to their funds.
{% /admonition %}
A depositor cannot redeem liquidity if the trust line between the pseudo-account and the issuer of the vault asset is frozen, or the `MPToken` is locked.
_(Requires the [SingleAssetVault amendment][] {% not-enabled /%})_
## Example {% $frontmatter.seo.title %} JSON
```json
{
"TransactionType": "VaultWithdraw",
"Account": "rGFBE8WA2ZKfqGGB7CFkLusVt7hsVT4r8H",
"Amount": {
"mpt_issuance_id": "000000016E1417CA9DFD23400B05E43FDE5BB8D8FFA817CA",
"value": "5"
},
"Destination": "rGFBE8WA2ZKfqGGB7CFkLusVt7hsVT4r8H",
"Fee": "12",
"Flags": 0,
"Sequence": 200380,
"VaultID": "A7B7B3ED3F5BD8E58C9064278EB29519CD6475D87A4517707DE108E65AE9C08C",
}
```
## {% $frontmatter.seo.title %} Fields
In addition to the [common fields](../../../protocol/transactions/common-fields#transaction-common-fields), {% code-page-name /%} transactions use the following fields:
| Field Name | JSON Type | [Internal Type][] | Required? | Description |
| :-----------------------| :------------ | :---------------- | :-------- | :-------------------|
| `VaultID` | String | Hash256 | Yes | The unique identifier of the vault to which the assets are deposited. |
| `Amount` | Number | Amount | Yes | The exact amount of vault asset to withdraw or vault share to redeem. |
| `Destination` | String | AccountID | No | An account to receive the assets. This account must be able to receive the vault asset or the transaction fails. |
| `DestinationTag` | Number | UInt32 | No | Arbitrary tag identifying the reason for the withdrawal to the destination. |
There are two ways to specify the transaction `Amount` field:
<!-- Added extra column to avoid first column text from being automatically bolded -->
| |Specify Assets | Specify Shares |
|:--- |:-------------- |:--------------- |
| |<ul><li>If the `Amount` field specifies an **asset amount** (e.g., 100 XRP), the transaction burns the necessary number of shares to provide the requested amount.</li><li>If the vault has an **unrealized loss**, withdrawing the same amount of assets requires burning more shares.</li></ul> | <ul><li>If the `Amount` field specifies a **share amount** (e.g., 500 vault shares), the transaction converts those shares into the corresponding amount of assets.</li><li>If the vault has an **unrealized loss**, each share is worth less, meaning fewer assets are received.</li></ul> |
## {% $frontmatter.seo.title %} Flags
There are no flags defined for {% code-page-name /%} transactions.
## Transfer Fees
A single asset vault does not apply the [transfer fee](../../../../concepts/tokens/fungible-tokens/transfer-fees) to {% code-page-name /%} transactions. Additionally, whenever a protocol moves assets from or to a vault, the Transfer Fee must not be charged.
## Error Cases
Besides errors that can occur for all transactions, {% code-page-name /%} transactions can result in the following [transaction result codes](../../../protocol/transactions/transaction-results/index.md):
| Error Code | Description |
| :---------------------- | :----------------------------------|
| `tecNO_ENTRY` | The `Vault` object with the provided `VaultID` does not exist on the ledger. |
| `tecOBJECT_NOT_FOUND` | A ledger entry specified in the transaction does not exist. |
| `tecNO_PERMISSION` | The destination account specified does not have permission to receive the asset. |
| `tecWRONG_ASSET` | The unit of `Amount` is neither a share or asset of the vault. |
| `tecINSUFFICIENT_FUNDS` | There is insufficient liquidity in the vault to fill the request. |
| `tecFROZEN` | Either the trust line between the issuer and the destination account is frozen, or the asset is globally frozen. |
| `tecLOCKED` | The MPT asset is locked for the depositor, destination account, or if the asset is globally locked. |
| `temMALFORMED` | The transaction is not validly formatted. For example, the `VaultID` is not provided. |
| `temDISABLED` | The Single Asset Vault amendment is not enabled. |
| `temBAD_AMOUNT` | The `Amount` field of the transaction is invalid. For example, the provided amount is set to 0. |
| `tecNO_AUTH` | The asset is a non-transferable MPT. |
## See Also
- [Vault entry][]
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -0,0 +1,14 @@
---
seo:
description: Batch multiple transactions together and execute them as a single unit.
metadata:
indexPage: true
labels:
- Batch
- Transactions
---
# Use Batch Transactions
Batch multiple transactions together and execute them as a single unit.
{% child-pages /%}

View File

@@ -0,0 +1,172 @@
---
seo:
description: Send a Batch transaction containing transactions from multiple accounts.
metadata:
indexPage: true
labels:
- Batch
- Transactions
---
# Send a Multi-Account Batch Transaction
This tutorial shows you how to create a [Batch transaction][] containing transactions from multiple accounts, where each account must sign the `Batch` transaction. Any account, even one not involved in the inner transactions, can submit the batch.
## Goals
By the end of this tutorial, you will be able to:
- Create a `Batch` transaction with multiple inner transactions, signed by multiple accounts, and submitted by a third party account.
- Configure the `Batch` transaction to ensure atomicity, so that either all inner transactions succeed or they all fail.
## 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.
## Source Code
You can find the complete source code for this tutorial's examples in the [code samples section of this website's repository](https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/batch/).
## Steps
The example in this tutorial demonstrates a scenario where Bob and Charlie both owe Alice 50 XRP each, and a third-party (such as a payment processor) submits the `Batch` transaction atomically to ensure Alice is paid by both parties.
### 1. Install dependencies
{% tabs %}
{% tab label="Javascript" %}
From the code sample folder, use npm to install dependencies:
```bash
npm install xrpl
```
{% /tab %}
{% /tabs %}
### 2. Set up client and accounts
To get started, import the client library and instantiate a client to connect to the XRPL. Then, create the accounts for Alice, Bob, Charlie, and the third-party.
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/multiAccountBatch.js" language="js" from="import xrpl" before="// Create inner transactions" /%}
{% /tab %}
{% /tabs %}
### 3. Prepare inner transactions
Next, prepare the inner transactions that will be included in the batch.
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/multiAccountBatch.js" language="js" from="// Create inner transactions" to="// Send Batch transaction" /%}
{% /tab %}
{% /tabs %}
The first transaction sends a payment of 50 XRP from Charlie to Alice, and the second sends a payment of 50 XRP from Bob to Alice. Both transactions must include the `tfInnerBatchTxn` (0x40000000) flag to indicate that they are inner transactions of a batch.
Inner transactions must have a Fee of **0** and an empty string for the `SigningPubKey`. The outer `Batch` transaction handles the overall fee and signing for all inner transactions.
{% admonition type="info" name="Note" %}
The `Fee` and `SigningPubKey` fields are omitted as the client library's _autofill_ functionality automatically populates these when submitting the `Batch` transaction.
You typically don't need to set these manually, but if you do, ensure `Fee` is set to 0 and `SigningPubKey` is an empty string.
{% /admonition %}
### 4. Prepare Batch transaction
Create the `Batch` transaction and provide the inner transactions. The key fields to note are:
| Field | Value |
|:---------------- |:---------- |
| TransactionType | The type of transaction, in this case `Batch`.|
| Account | The wallet address of the account that is sending the `Batch` transaction. |
| Flags | The flags for the `Batch` transaction. For this example the transaction is configured with the `tfAllOrNothing` (0x00010000) flag to ensure that either all inner transactions succeed or they all fail atomically. See [Batch Flags](../../../references/protocol/transactions/types/batch.md#batch-flags) for other options. |
| RawTransactions | Contains the list of inner transactions to be applied. Must include a minimum of **2** transactions and a maximum of **8** transactions. These transactions can come from one account or multiple accounts. |
| BatchSigners | The list of signatures required for the `Batch` transaction. This is required because there are multiple accounts' transactions included in the batch. |
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/multiAccountBatch.js" language="js" from="// Send Batch transaction" before="// Gather batch signatures" /%}
{% /tab %}
{% /tabs %}
Because we used `autofill`, the client library automatically fills in any missing fields, like `Fee` and `SigningPubKey`. Additionally, we specify the expected number of signers (2 in this case).
### 5. Gather batch signatures
To add the `BatchSigners` field, you need to collect signatures from each account that's sending a transaction within the batch. In this case we need two signatures, one from Charlie and one from Bob. Each sender must sign the `Batch` transaction to authorize their payment.
{% tabs %}
{% tab label="Javascript" %}
The **xrpl.js** library provides a helper function, `signMultiBatch()`, to sign the `Batch` transaction for each account.
Then, to combine the signatures into a single signed `Batch` transaction, use the `combineBatchSigners()` utility function.
{% code-snippet file="/_code-samples/batch/js/multiAccountBatch.js" language="js" from="// Gather batch signatures" to="// Submit" /%}
{% /tab %}
{% /tabs %}
### 6. Submit Batch transaction
With all the required signatures gathered, the third-party wallet can now submit the `Batch` transaction.
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/multiAccountBatch.js" language="js" from="// Submit" before="// Check Batch transaction" /%}
{% /tab %}
{% /tabs %}
### 7. Check Batch transaction result
To check the result of the `Batch` transaction submission:
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/multiAccountBatch.js" language="js" from="// Check Batch transaction" before="// Calculate and verify" /%}
{% /tab %}
{% /tabs %}
The code checks for a `tesSUCCESS` result and displays the response details.
{% admonition type="warning" name="Warning" %}
A `tesSUCCESS` result indicates that the `Batch` transaction was processed successfully, but does not guarantee the inner transactions succeeded. For example, see the [following transaction on the XRPL Explorer](https://devnet.xrpl.org/transactions/20CFCE5CF75E93E6D1E9C1E42F8E8C8C4CB1786A65BE23D2EA77EAAB65A455C5/simple).
{% /admonition %}
Because the `Batch` transaction is configured with a `tfAllOrNothing` flag, if any inner transaction fails, **all** inner transactions wil fail, and only the `Batch` transaction fee is deducted from the **third-party wallet**.
### 8. Verify inner transactions
Since there is no way to check the status of inner transactions in the `Batch` transaction result, you need to calculate the inner transaction hashes and look them up on the ledger:
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/multiAccountBatch.js" language="js" from="// Calculate and verify" before="// Verify balances after transaction" /%}
{% /tab %}
{% /tabs %}
The code extracts the actual inner transactions from the batch response, calculates the hash of each inner transaction and looks up each transaction on the ledger using its hash.
### 9. Verify balances
You can also verify that the inner transactions executed successfully by checking the account balances to confirm the expected changes.
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/multiAccountBatch.js" language="js" from="// Verify balances after transaction" /%}
{% /tab %}
{% /tabs %}
## See Also
- **Concepts**:
- [Batch Transactions](../../../concepts/transactions/batch-transactions.md)
- **Tutorials**:
- [Send a Single Account Batch Transaction](send-a-single-account-batch-transaction.md)
- **References**:
- [Batch Transaction][]
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -0,0 +1,162 @@
---
seo:
description: Send a Batch transaction from a single account.
metadata:
indexPage: true
labels:
- Batch
- Transactions
---
# Send a Single Account Batch Transaction
A [Batch transaction][] allows you to group multiple transactions together and execute them as a single atomic operation.
This tutorial shows you how to create a `Batch` transaction where a single account submits multiple transactions that either all succeed together or all fail together.
## Goals
By the end of this tutorial, you will be able to:
- Create a `Batch` transaction with multiple inner transactions, signed and submitted by a single account.
- Configure the `Batch` transaction to ensure atomicity, so that either all inner transactions succeed or they all fail.
## 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.
## Source Code
You can find the complete source code for this tutorial's examples in the [code samples section of this website's repository](https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/batch/).
## Steps
The example in this tutorial demonstrates a scenario where an account sends multiple payments that must be processed atomically in one `Batch` transaction.
### 1. Install dependencies
{% tabs %}
{% tab label="Javascript" %}
From the code sample folder, use npm to install dependencies:
```bash
npm install xrpl
```
{% /tab %}
{% /tabs %}
### 2. Set up client and accounts
To get started, import the client library and instantiate a client to connect to the XRPL. For this tutorial you need a funded account for the `Batch` transaction **sender**, and two other accounts to **receive** the payments.
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/singleAccountBatch.js" language="js" from="import xrpl" before="// Create inner transactions" /%}
{% /tab %}
{% /tabs %}
### 3. Prepare inner transactions
Next, prepare the inner transactions that will be included in the batch.
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/singleAccountBatch.js" language="js" from="// Create inner transactions" to="// Send Batch transaction" /%}
{% /tab %}
{% /tabs %}
The first transaction sends a payment of 2 XRP from the sender to `wallet1`, and the second transaction sends 5 XRP from the sender to `wallet2`. Both transactions must include the `tfInnerBatchTxn` (0x40000000) flag to indicate that they are inner transactions of a batch.
Inner transactions must have a Fee of **0** and an empty string for the `SigningPubKey`. The outer `Batch` transaction handles the overall fee and signing for all inner transactions.
{% admonition type="info" name="Note" %}
The `Fee` and `SigningPubKey` fields are omitted as the client library's _autofill_ functionality automatically populates these when submitting the `Batch` transaction.
You typically don't need to set these manually, but if you do, ensure `Fee` is set to 0 and `SigningPubKey` is an empty string.
{% /admonition %}
### 4. Prepare Batch transaction
Create the `Batch` transaction and provide the inner transactions. The key fields to note are:
| Field | Value |
|:---------------- |:---------- |
| TransactionType | The type of transaction, in this case `Batch`.|
| Account | The wallet address of the account that is sending the `Batch` transaction. |
| Flags | The flags for the `Batch` transaction. For this example the transaction is configured with the `tfAllOrNothing` (0x00010000) flag to ensure that either all inner transactions succeed or they all fail atomically. See [Batch Flags](../../../references/protocol/transactions/types/batch.md#batch-flags) for other options. |
| RawTransactions | Contains the list of inner transactions to be applied. Must include a minimum of **2** transactions and a maximum of **8** transactions. These transactions can come from one account or multiple accounts. |
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/singleAccountBatch.js" language="js" from="// Send Batch transaction" before="// Submit" /%}
{% /tab %}
{% /tabs %}
### 5. Submit Batch transaction
Now the sender can submit the `Batch` transaction:
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/singleAccountBatch.js" language="js" from="// Submit" before="// Check Batch transaction" /%}
{% /tab %}
{% /tabs %}
Because `autofill` is set to `true`, the client library automatically fills in any missing fields, like the `Fee` and `SigningPubKey`, before submitting the batch.
### 6. Check Batch transaction result
To check the result of the `Batch` transaction submission:
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/singleAccountBatch.js" language="js" from="// Check Batch transaction" before="// Calculate and verify" /%}
{% /tab %}
{% /tabs %}
The code checks for a `tesSUCCESS` result and displays the response details.
{% admonition type="warning" name="Warning" %}
A `tesSUCCESS` result indicates that the `Batch` transaction was processed successfully, but does not guarantee the inner transactions succeeded.
For example, see the [following transaction on the XRPL Explorer](https://devnet.xrpl.org/transactions/20CFCE5CF75E93E6D1E9C1E42F8E8C8C4CB1786A65BE23D2EA77EAAB65A455C5/simple).
{% /admonition %}
Because the `Batch` transaction is configured with a `tfAllOrNothing` flag, if any inner transaction fails, **all** inner transactions wil fail, and only the `Batch` transaction fee is deducted from the **third-party wallet**.
### 7. Verify inner transactions
Since there is no way to check the status of inner transactions in the `Batch` transaction result, you need to calculate the inner transaction hashes and look them up on the ledger:
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/singleAccountBatch.js" language="js" from="// Calculate and verify" before="// Verify balances after transaction" /%}
{% /tab %}
{% /tabs %}
The code extracts the actual inner transactions from the batch response, calculates the hash of each inner transaction and looks up each transaction on the ledger using its hash.
### 8. Verify balances
You can also verify that the inner transactions executed successfully by checking the account balances to confirm the expected changes.
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/singleAccountBatch.js" language="js" from="// Verify balances after transaction" /%}
{% /tab %}
{% /tabs %}
## See Also
- **Concepts**:
- [Batch Transactions](../../../concepts/transactions/batch-transactions.md)
- **Tutorials**:
- [Send a Multi-Account Batch Transaction](send-a-multi-account-batch-transaction.md)
- **References**:
- [Batch Transaction][]
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -1,63 +1,97 @@
---
seo:
description: Build a Python app that interacts with the XRP Ledger.
top_nav_name: Python
top_nav_grouping: Get Started
labels:
- Development
---
{% code-walkthrough
filesets=[
{
"files": ["/_code-samples/get-started/py/get-acct-info.py"],
"downloadAssociatedFiles": ["/_code-samples/get-started/py/requirements.txt","/_code-samples/get-started/py/get-acct-info.py", "/_code-samples/get-started/py/README.md"]
}
]
%}
# Get Started Using Python Library
This tutorial walks you through the basics of building an XRP Ledger-connected application using [`xrpl-py`](https://github.com/XRPLF/xrpl-py), a pure [Python](https://www.python.org) library built to interact with the XRP Ledger using native Python models and methods.
This tutorial walks you through the basics of building an XRP Ledger-connected application using the [`xrpl-py`](https://github.com/XRPLF/xrpl-py) client library, a pure [Python](https://www.python.org) library built to interact with the XRP Ledger using native Python models and methods.
This tutorial is intended for beginners and should take no longer than 30 minutes to complete.
## Learning Goals
## Goals
In this tutorial, you'll learn:
* The basic building blocks of XRP Ledger-based applications.
* How to connect to the XRP Ledger using `xrpl-py`.
* How to get an account on the [Testnet](/resources/dev-tools/xrp-faucets) using `xrpl-py`.
* How to use the `xrpl-py` library to look up information about an account on the XRP Ledger.
* How to put these steps together to create a Python app.
- The basic building blocks of XRP Ledger-based applications.
- How to connect to the XRP Ledger using `xrpl-py`.
- How to get an account on the [Testnet](/resources/dev-tools/xrp-faucets) using `xrpl-py`.
- How to use the `xrpl-py` library to look up information about an account on the XRP Ledger.
- How to put these steps together to create a Python app.
## Requirements
## Prerequisites
The `xrpl-py` library supports [Python 3.7](https://www.python.org/downloads/) and later.
To complete this tutorial, you should meet the following guidelines:
- Have a basic understanding of Python.
- Have installed [Python 3.7](https://www.python.org/downloads/) or later.
## Installation
## Source Code
The [`xrpl-py` library](https://github.com/XRPLF/xrpl-py) is available on [PyPI](https://pypi.org/project/xrpl-py/). Install with `pip`: <!-- SPELLING_IGNORE: pypi -->
Click **Download** on the top right of the code preview panel to download the source code.
## Steps
```py
pip3 install xrpl-py
Follow the steps to create a simple application with `xrpl-py`.
{% step id="import-tag" %}
### 1. Install Dependencies
Start a new project by creating an empty folder, then move into that folder and set up a Python virtual environment with the necessary dependencies:
```sh
# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate
# Install the xrpl-py library
pip install xrpl-py
```
## Start Building
Alternatively, if you're using the downloaded source code, you can install all dependencies from the `requirements.txt` file:
When you're working with the XRP Ledger, there are a few things you'll need to manage, whether you're adding XRP to your [account](../../../concepts/accounts/index.md), integrating with the [decentralized exchange](../../../concepts/tokens/decentralized-exchange/index.md), or [issuing tokens](../../../concepts/tokens/index.md). This tutorial walks you through basic patterns common to getting started with all of these use cases and provides sample code for implementing them.
```sh
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
{% /step %}
Here are the basic steps you'll need to cover for almost any XRP Ledger project:
### 2. Connect to the XRP Ledger
1. [Connect to the XRP Ledger.](#1-connect-to-the-xrp-ledger)
1. [Get an account.](#2-get-account)
1. [Query the XRP Ledger.](#3-query-the-xrp-ledger)
{% step id="connect-tag" %}
#### Connect to the XRP Ledger Testnet
To make queries and submit transactions, you need to connect to the XRP Ledger. To do this with `xrpl-py`, use the [`xrp.clients` module](https://xrpl-py.readthedocs.io/en/latest/source/xrpl.clients.html).
### 1. Connect to the XRP Ledger
{% admonition type="info" name="Note" %}
The standard approach with `xrpl-py` is to use the JSON-RPC client. While a WebSocket client is available, it requires you to use `async`/`await` throughout your code. For most use cases, stick with JSON-RPC to avoid the complexity of asynchronous programming.
{% /admonition %}
To make queries and submit transactions, you need to connect to the XRP Ledger. To do this with `xrpl-py`, use the [`xrp.clients` module](https://xrpl-py.readthedocs.io/en/latest/source/xrpl.clients.html):
The sample code shows you how to connect to the Testnet, which is one of the available [parallel networks](../../../concepts/networks-and-servers/parallel-networks.md).
{% /step %}
{% code-snippet file="/_code-samples/get-started/py/get-acct-info.py" from="# Define the network client" before="# Create a wallet using the testnet faucet:" language="py" /%}
#### Connect to the production XRP Ledger
{% step id="connect-mainnet-tag"%}
#### Connect to the XRP Ledger Mainnet
The sample code in the previous section shows you how to connect to the Testnet, which is a [parallel network](../../../concepts/networks-and-servers/parallel-networks.md) for testing where the money has no real value. When you're ready to integrate with the production XRP Ledger, you'll need to connect to the Mainnet. You can do that in two ways:
* By [installing the core server](../../../infrastructure/installation/index.md) (`rippled`) and running a node yourself. The core server connects to the Mainnet by default, but you can [change the configuration to use Testnet or Devnet](../../../infrastructure/configuration/connect-your-rippled-to-the-xrp-test-net.md). [There are good reasons to run your own core server](../../../concepts/networks-and-servers/index.md#reasons-to-run-your-own-server). If you run your own server, you can connect to it like so:
- By [installing the core server](../../../infrastructure/installation/index.md) (`rippled`) and running a node yourself. The core server connects to the Mainnet by default, but you can [change the configuration to use Testnet or Devnet](../../../infrastructure/configuration/connect-your-rippled-to-the-xrp-test-net.md). [There are good reasons to run your own core server](../../../concepts/networks-and-servers/index.md#reasons-to-run-your-own-server). If you run your own server, you can connect to it like so:
```
```python
from xrpl.clients import JsonRpcClient
JSON_RPC_URL = "http://localhost:5005/"
client = JsonRpcClient(JSON_RPC_URL)
@@ -65,146 +99,115 @@ The sample code in the previous section shows you how to connect to the Testnet,
See the example [core server config file](https://github.com/XRPLF/rippled/blob/c0a0b79d2d483b318ce1d82e526bd53df83a4a2c/cfg/rippled-example.cfg#L1562) for more information about default values.
* By using one of the available [public servers][]:
- By using one of the available [public servers][]:
```
```python
from xrpl.clients import JsonRpcClient
JSON_RPC_URL = "https://s2.ripple.com:51234/"
client = JsonRpcClient(JSON_RPC_URL)
```
{% /step %}
### 2. Get account
{% step id="get-account-create-wallet-tag" %}
### 3. Get account
To store value and execute transactions on the XRP Ledger, you need an account: a [set of keys](../../../concepts/accounts/cryptographic-keys.md#key-components) and an [address](../../../concepts/accounts/addresses.md) that's been [funded with enough XRP](../../../concepts/accounts/index.md#creating-accounts) to meet the [account reserve](../../../concepts/accounts/reserves.md). The address is the identifier of your account and you use the [private key](../../../concepts/accounts/cryptographic-keys.md#private-key) to sign transactions that you submit to the XRP Ledger.
{% admonition type="success" name="Tip" %}
For testing and development purposes, you can use the [XRP Faucets](/resources/dev-tools/xrp-faucets) to generate keys and fund the account on the Testnet or Devnet. For production purposes, you should take care to store your keys and set up a [secure signing method](../../../concepts/transactions/secure-signing.md). Another difference in production is that XRP has real worth, so you can't get it for free from a faucet.
{% /admonition %}
To create and fund an account on the Testnet, `xrpl-py` provides the [`generate_faucet_wallet`](https://xrpl-py.readthedocs.io/en/latest/source/xrpl.wallet.html#xrpl.wallet.generate_faucet_wallet) method:
To create and fund an account on the Testnet, `xrpl-py` provides the [`generate_faucet_wallet`](https://xrpl-py.readthedocs.io/en/latest/source/xrpl.wallet.html#xrpl.wallet.generate_faucet_wallet) method. This method returns a [`Wallet` instance](https://xrpl-py.readthedocs.io/en/latest/source/xrpl.wallet.html#xrpl.wallet.Wallet).
{% /step %}
{% code-snippet file="/_code-samples/get-started/py/get-acct-info.py" from="# Create a wallet using the testnet faucet:" before="# Create an account str from the wallet" language="py" /%}
This method returns a [`Wallet` instance](https://xrpl-py.readthedocs.io/en/latest/source/xrpl.wallet.html#xrpl.wallet.Wallet):
```py
print(test_wallet)
# print output
public_key:: 022FA613294CD13FFEA759D0185007DBE763331910509EF8F1635B4F84FA08AEE3
private_key:: -HIDDEN-
classic_address: raaFKKmgf6CRZttTVABeTcsqzRQ51bNR6Q
```
#### Using the account
In this tutorial we only query details about the generated account from the XRP Ledger, but you can use the values in the `Wallet` instance to prepare, sign, and submit transactions with `xrpl-py`.
##### Prepare
To prepare the transaction:
{% code-snippet file="/_code-samples/get-started/py/prepare-payment.py" from="# Prepare payment" before="# print prepared payment" language="py" /%}
##### Sign and submit
To sign and submit the transaction:
{% code-snippet file="/_code-samples/get-started/py/prepare-payment.py" from="# Sign and submit the transaction" before="# Print tx response" language="py" /%}
##### Derive an X-address
You can use `xrpl-py`'s [`xrpl.core.addresscodec`](https://xrpl-py.readthedocs.io/en/latest/source/xrpl.core.addresscodec.html) module to derive an [X-address](https://xrpaddress.info/) from the `Wallet.address` field:
{% code-snippet file="/_code-samples/get-started/py/get-acct-info.py" from="# Derive an x-address from the classic address:" before="# Look up info about your account" language="py" /%}
The X-address format [packs the address and destination tag](https://github.com/XRPLF/XRPL-Standards/issues/6) into a more user-friendly value.
### 3. Query the XRP Ledger
{% step id="query-xrpl-tag" %}
### 4. Query the XRP Ledger
You can query the XRP Ledger to get information about [a specific account](../../../references/http-websocket-apis/public-api-methods/account-methods/index.md), [a specific transaction](../../../references/http-websocket-apis/public-api-methods/transaction-methods/tx.md), the state of a [current or a historical ledger](../../../references/http-websocket-apis/public-api-methods/ledger-methods/index.md), and [the XRP Ledger's decentralized exchange](../../../references/http-websocket-apis/public-api-methods/path-and-order-book-methods/index.md). You need to make these queries, among other reasons, to look up account info to follow best practices for [reliable transaction submission](../../../concepts/transactions/reliable-transaction-submission.md).
Here, we use `xrpl-py`'s [`xrpl.account`](https://xrpl-py.readthedocs.io/en/latest/source/xrpl.account.html) module to look up information about the [account we got](#2-get-account) in the previous step.
Use the [account_info method][] to look up information about the account you got in the previous step. Use a request model like `AccountInfo` to validate the request format and catch errors sooner.
{% /step %}
{% step id="run-app-tag" %}
### 5. Run the Application
{% code-snippet file="/_code-samples/get-started/py/get-acct-info.py" from="# Look up info about your account" language="py" /%}
### 4. Putting it all together
Using these building blocks, we can create a Python app that:
1. Gets an account on the Testnet.
2. Connects to the XRP Ledger.
3. Looks up and prints information about the account you created.
{% code-snippet file="/_code-samples/get-started/py/get-acct-info.py" language="python" /%}
To run the app, you can copy and paste the code into an editor or IDE and run it from there. Or you could download the file from the [XRP Ledger Dev Portal repo](https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/get-started/py) and run it locally:
Finally, in your terminal, run the application like so:
```sh
git clone git@github.com:XRPLF/xrpl-dev-portal.git
cd xrpl-dev-portal/_code-samples/get-started/py/get-acct-info.py
python3 get-acct-info.py
python get-acct-info.py
```
You should see output similar to this example:
```sh
Classic address:
Creating a new wallet and funding it with Testnet XRP...
Attempting to fund address ravbHNootpSNQkxyEFCWevSkHsFGDHfyop
Faucet fund successful.
Wallet: ravbHNootpSNQkxyEFCWevSkHsFGDHfyop
Account Testnet Explorer URL:
https://testnet.xrpl.org/accounts/ravbHNootpSNQkxyEFCWevSkHsFGDHfyop
rnQLnSEA1YFMABnCMrkMWFKxnqW6sQ8EWk
X-address:
T7dRN2ktZGYSTyEPWa9SyDevrwS5yDca4m7xfXTGM3bqff8
response.status: ResponseStatus.SUCCESS
Getting account info...
Response Status: ResponseStatus.SUCCESS
{
"account_data": {
"Account": "rnQLnSEA1YFMABnCMrkMWFKxnqW6sQ8EWk",
"Balance": "1000000000",
"Account": "ravbHNootpSNQkxyEFCWevSkHsFGDHfyop",
"Balance": "100000000",
"Flags": 0,
"LedgerEntryType": "AccountRoot",
"OwnerCount": 0,
"PreviousTxnID": "5A5203AFF41503539D11ADC41BE4185761C5B78B7ED382E6D001ADE83A59B8DC",
"PreviousTxnLgrSeq": 16126889,
"Sequence": 16126889,
"index": "CAD0F7EF3AB91DA7A952E09D4AF62C943FC1EEE41BE926D632DDB34CAA2E0E8F"
"PreviousTxnID": "3DACF2438AD39F294C4EFF6132D5D88BCB65D2F2261C7650F40AC1F6A54C83EA",
"PreviousTxnLgrSeq": 12039759,
"Sequence": 12039759,
"index": "148E6F4B8E4C14018D679A2526200C292BDBC5AB77611BC3AE0CB97CD2FB84E5"
},
"ledger_current_index": 16126890,
"queue_data": {
"txn_count": 0
"account_flags": {
"allowTrustLineClawback": false,
"defaultRipple": false,
"depositAuth": false,
"disableMasterKey": false,
"disallowIncomingCheck": false,
"disallowIncomingNFTokenOffer": false,
"disallowIncomingPayChan": false,
"disallowIncomingTrustline": false,
"disallowIncomingXRP": false,
"globalFreeze": false,
"noFreeze": false,
"passwordSpent": false,
"requireAuthorization": false,
"requireDestinationTag": false
},
"validated": false
"ledger_hash": "CA624D717C4FCDD03BAD8C193F374A77A14F7D2566354A4E9617A8DAD896DE71",
"ledger_index": 12039759,
"validated": true
}
```
#### Interpreting the response
The response fields that you want to inspect in most cases are:
* `account_data.Sequence` — This is the sequence number of the next valid transaction for the account. You need to specify the sequence number when you prepare transactions. With `xrpl-py`, you can use the [`get_next_valid_seq_number`](https://xrpl-py.readthedocs.io/en/latest/source/xrpl.account.html#xrpl.account.get_next_valid_seq_number) to get this automatically from the XRP Ledger. See an example of this usage in the project [README](https://github.com/XRPLF/xrpl-py#serialize-and-sign-transactions).
- `account_data.Balance` — This is the account's balance of [XRP, in drops][]. You can use this to confirm that you have enough XRP to send (if you're making a payment) and to meet the [current transaction cost](../../../concepts/transactions/transaction-cost.md#current-transaction-cost) for a given transaction.
* `account_data.Balance` — This is the account's balance of [XRP, in drops][]. You can use this to confirm that you have enough XRP to send (if you're making a payment) and to meet the [current transaction cost](../../../concepts/transactions/transaction-cost.md#current-transaction-cost) for a given transaction.
* `validated` — Indicates whether the returned data is from a [validated ledger](../../../concepts/ledgers/open-closed-validated-ledgers.md). When inspecting transactions, it's important to confirm that [the results are final](../../../concepts/transactions/finality-of-results/index.md) before further processing the transaction. If `validated` is `true` then you know for sure the results won't change. For more information about best practices for transaction processing, see [Reliable Transaction Submission](../../../concepts/transactions/reliable-transaction-submission.md).
- `validated` — Indicates whether the returned data is from a [validated ledger](../../../concepts/ledgers/open-closed-validated-ledgers.md). When inspecting transactions, it's important to confirm that [the results are final](../../../concepts/transactions/finality-of-results/index.md) before further processing the transaction. If `validated` is `true` then you know for sure the results won't change. For more information about best practices for transaction processing, see [Reliable Transaction Submission](../../../concepts/transactions/reliable-transaction-submission.md).
For a detailed description of every response field, see [account_info](../../../references/http-websocket-apis/public-api-methods/account-methods/account_info.md#response-format).
{% /step %}
## See Also
## Keep on building
Now that you know how to use `xrpl-py` to connect to the XRP Ledger, get an account, and look up information about it, you can also use `xrpl-py` to:
* [Send XRP](../../how-tos/send-xrp.md).
* [Set up secure signing](../../../concepts/transactions/secure-signing.md) for your account.
- **Concepts:**
- [XRP Ledger Overview](/about/)
- [Client Libraries](../../../references/client-libraries.md)
- **Tutorials:**
- [Send XRP](../../how-tos/send-xrp.md)
- [Issue a Fungible Token](../../how-tos/use-tokens/issue-a-fungible-token.md)
- [Set up Secure Signing](../../../concepts/transactions/secure-signing.md)
- **References:**
- [`xrpl-py` Reference](https://xrpl-py.readthedocs.io/en/latest/)
- [Public API Methods](../../../references/http-websocket-apis/public-api-methods/index.md)
- [API Conventions](../../../references/http-websocket-apis/api-conventions/index.md)
- [base58 Encodings](../../../references/protocol/data-types/base58-encodings.md)
- [Transaction Formats](../../../references/protocol/transactions/index.md)
{% raw-partial file="/docs/_snippets/common-links.md" /%}
{% /code-walkthrough %}

View File

@@ -42,9 +42,6 @@ metadataGlobs:
redocly_category: Community
seo:
siteUrl: https://xrpl.org/
rbac:
reunite:
xrpl-org-editors: maintain
analytics:
gtm:
includeInDevelopment: true

View File

@@ -742,6 +742,19 @@ Changes the way Checks transactions affect account metadata, so that Checks are
Without this amendment, Checks transactions ([CheckCreate][], [CheckCash][], and [CheckCancel][]) only update the account history of the sender. With this amendment, those transactions affect both the sending and receiving accounts. This amendment has no effect unless the [Checks amendment](#checks) is also enabled.
### fixDirectoryLimit
[fixDirectoryLimit]: #fixdirectorylimit
| Amendment | fixdirectorylimit |
|:-------------|:----------------------|
| Amendment ID | 41765F664A8D67FF03DDB1C1A893DE6273690BA340A6C2B07C8D29D0DD013D3A |
| Status | Open for Voting |
| Default Vote (Latest stable release) | No |
| Pre-amendment functionality retired? | No |
This amendment removes the directory page limit. Object reserve requirements provide enough incentive to avoid creating unnecessary objects on the XRP Ledger.
### fixDisallowIncomingV1
[fixDisallowIncomingV1]: #fixdisallowincomingv1
@@ -1678,7 +1691,8 @@ When this amendment is activated, the XRP Ledger will undergo a brief scheduled
Creates a structure for aggregating assets from multiple depositors. This is intended to be used with the proposed on-chain Lending Protocol.
Specification: [XLS-65](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0065-single-asset-vault).
Specification: [XLS-65](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0065d-single-asset-vault).
### SortedDirectories
[SortedDirectories]: #sorteddirectories

View File

@@ -155,7 +155,6 @@
- page: docs/concepts/tokens/decentralized-exchange/automated-market-makers.md
- page: docs/concepts/tokens/decentralized-exchange/permissioned-domains.md
- page: docs/concepts/tokens/decentralized-exchange/permissioned-dexes.md
- page: docs/concepts/tokens/single-asset-vault.md
- page: docs/concepts/accounts/index.md
expanded: false
items:
@@ -169,7 +168,6 @@
- page: docs/concepts/accounts/depositauth.md
- page: docs/concepts/accounts/tickets.md
- page: docs/concepts/accounts/permission-delegation.md
- page: docs/concepts/accounts/pseudo-accounts.md
- page: docs/concepts/xrpl-sidechains/index.md
expanded: false
items:
@@ -297,6 +295,11 @@
- page: docs/tutorials/how-tos/manage-account-settings/require-destination-tags.md
- page: docs/tutorials/how-tos/manage-account-settings/offline-account-setup.md
- page: docs/tutorials/how-tos/manage-account-settings/use-tickets.md
- page: docs/tutorials/how-tos/use-batch-transactions/index.md
expanded: false
items:
- page: docs/tutorials/how-tos/use-batch-transactions/send-a-single-account-batch-transaction.md
- page: docs/tutorials/how-tos/use-batch-transactions/send-a-multi-account-batch-transaction.md
- page: docs/tutorials/how-tos/use-specialized-payment-types/index.md
expanded: false
items:
@@ -383,7 +386,6 @@
- page: docs/references/protocol/ledger-data/ledger-entry-types/ripplestate.md
- page: docs/references/protocol/ledger-data/ledger-entry-types/signerlist.md
- page: docs/references/protocol/ledger-data/ledger-entry-types/ticket.md
- page: docs/references/protocol/ledger-data/ledger-entry-types/vault.md
- page: docs/references/protocol/ledger-data/ledger-entry-types/xchainownedclaimid.md
- page: docs/references/protocol/ledger-data/ledger-entry-types/xchainownedcreateaccountclaimid.md
- page: docs/references/protocol/transactions/index.md
@@ -442,12 +444,6 @@
- page: docs/references/protocol/transactions/types/signerlistset.md
- page: docs/references/protocol/transactions/types/ticketcreate.md
- page: docs/references/protocol/transactions/types/trustset.md
- page: docs/references/protocol/transactions/types/vaultclawback.md
- page: docs/references/protocol/transactions/types/vaultcreate.md
- page: docs/references/protocol/transactions/types/vaultdelete.md
- page: docs/references/protocol/transactions/types/vaultdeposit.md
- page: docs/references/protocol/transactions/types/vaultset.md
- page: docs/references/protocol/transactions/types/vaultwithdraw.md
- page: docs/references/protocol/transactions/types/xchainaccountcreatecommit.md
- page: docs/references/protocol/transactions/types/xchainaddaccountcreateattestation.md
- page: docs/references/protocol/transactions/types/xchainaddclaimattestation.md
@@ -592,12 +588,6 @@
- page: docs/references/http-websocket-apis/public-api-methods/utility-methods/json.md
- page: docs/references/http-websocket-apis/public-api-methods/utility-methods/ping.md
- page: docs/references/http-websocket-apis/public-api-methods/utility-methods/random.md
- page: docs/references/http-websocket-apis/public-api-methods/vault-methods/index.md
expanded: false
items:
- page: docs/references/http-websocket-apis/public-api-methods/vault-methods/vault_info.md
- page: docs/references/http-websocket-apis/admin-api-methods/index.md
expanded: false
items: