Add Batch transactions tutorials

This commit is contained in:
Maria Shodunke
2025-10-28 12:42:15 +00:00
parent 192db8ff89
commit 42baf87d3b
3 changed files with 116 additions and 54 deletions

View File

@@ -5,76 +5,75 @@
* to create a single-account batch transaction.
*/
import xrpl from "xrpl";
import { BatchFlags } from "xrpl/dist/npm/models/transactions/batch.js";
import xrpl from "xrpl"
import { BatchFlags } from "xrpl/dist/npm/models/transactions/batch.js"
const client = new xrpl.Client("wss://s.devnet.rippletest.net:51233");
await client.connect();
const client = new xrpl.Client("wss://s.devnet.rippletest.net:51233/")
await client.connect()
// Create and fund the sender wallet
console.log("Funding new sender wallet from faucet...");
const { wallet } = await client.fundWallet();
console.log(`Wallet created: ${wallet.classicAddress}`);
// Create and fund recipient wallet
console.log("\nFunding new recipient wallet from faucet...");
const feeRecipient = (await client.fundWallet()).wallet;
console.log(`Fee Recipient: ${feeRecipient.classicAddress}`);
console.log("Funding new sender wallet from faucet...")
const { wallet: sender } = await client.fundWallet()
console.log(`Sender account: ${sender.address}`)
// Create and fund the receiver wallet
console.log("\nFunding new receiver wallet from faucet...")
const { wallet: receiver } = await client.fundWallet()
console.log(`Receiver account: ${receiver.address}`)
// Create inner transactions --------------------------------------------
// REQUIRED: Inner transactions MUST have the tfInnerBatchTxn flag (0x40000000)
// autofill() will automatically add Fee: "0" and SigningPubKey: ""
// REQUIRED: Inner transactions MUST have the tfInnerBatchTxn flag (0x40000000).
// "autofill" will automatically add Fee: "0" and SigningPubKey: "".
// Transaction 1: Create DEX offer (sell 100 XRP for 100 USD)
// Transaction 1: Create DEX offer
const offerCreate = {
TransactionType: "OfferCreate",
Account: wallet.address,
Account: sender.address,
TakerPays: {
currency: "USD",
issuer: "rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc",
value: "100"
currency: "TST",
issuer: "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd",
value: "25"
},
TakerGets: xrpl.xrpToDrops(25 * 10 * 1.16),
// 25 TST * 10 XRP per TST * 15% financial exchange (FX) cost
TakerGets: xrpl.xrpToDrops(25 * 10 * 1.15),
Flags: 0x40000000, // tfInnerBatchTxn - THIS IS REQUIRED
};
}
// Transaction 2: Pay platform fee (10 XRP)
// Transaction 2: Pay platform fee
const payment = {
TransactionType: "Payment",
Account: wallet.classicAddress,
Destination: feeRecipient.classicAddress,
Amount: xrpl.xrpToDrops(5), // 5 XRP
Flags: 0x40000000,
};
Account: sender.address,
Destination: receiver.address,
Amount: xrpl.xrpToDrops(2), // 2 XRP
Flags: 0x40000000, // tfInnerBatchTxn - THIS IS REQUIRED
}
// Send Batch transaction --------------------------------------------
const batchTx = {
TransactionType: "Batch",
Account: wallet.classicAddress,
Account: sender.address,
Flags: BatchFlags.tfAllOrNothing, // tfAllOrNothing: All inner transactions succeed or all fail
RawTransactions: [{ RawTransaction: offerCreate }, { RawTransaction: payment }],
};
xrpl.validate(batchTx);
}
// Validate the transaction structure before submitting
xrpl.validate(batchTx)
// Sign, submit, and wait for validation in one call
console.log(
"\nSigning and submitting batch transaction:\n",
JSON.stringify(batchTx, null, 2)
);
console.log("\nSigning and submitting batch transaction:\n", JSON.stringify(batchTx, null, 2))
const submitResponse = await client.submitAndWait(batchTx, {
wallet: wallet,
wallet: sender,
autofill: true, // Autofill handles Fee, Sequence, LastLedgerSequence, etc.
});
})
// Check transaction results and disconnect --------------------------------
if (submitResponse.result.meta.TransactionResult !== "tesSUCCESS") {
const resultCode = response.result.meta.TransactionResult;
console.warn(`Transaction failed with result code ${resultCode}.`);
process.exit(1);
const resultCode = submitResponse.result.meta.TransactionResult
console.warn(`\nTransaction failed with result code ${resultCode}`)
process.exit(1)
}
console.log("\nBatch transaction submitted successfully:");
console.log(JSON.stringify(submitResponse.result, null, 2));
console.log("\nBatch transaction submitted successfully!")
console.log("\nResult:\n", JSON.stringify(submitResponse.result, null, 2))
console.log(`\nTransaction URL:\nhttps://devnet.xrpl.org/transactions/${submitResponse.result.hash}`)
await client.disconnect();
await client.disconnect()

View File

@@ -7,3 +7,4 @@ labels:
- Batch
- Transactions
---
# Send a Multi-Account Batch Transaction

View File

@@ -11,23 +11,21 @@ labels:
# 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 and send a batch transaction from a single account, and how to configure the batch transaction so that either all inner transactions succeed or none are submitted.
The example in this tutorial demonstrates a scenario where an account creates a DEX offer and pays a platform fee all in one batch transaction, ensuring the platform gets paid if and only if the offer is created.
This tutorial shows you how to create and send a batch transaction from a single account, and how to configure the batch transaction so that either all inner transactions succeed or they all fail.
## Goals
By the end of this tutorial, you will be able to:
- Create a batch transaction with multiple inner transactions from a single account.
- Configure the batch transaction to ensure atomicity, so that either all inner transactions succeed or none are submitted.
- 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 XRPL Ledger.
- Have an XRP Ledger client library set up in your development environment:
- 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: [xrpl.js](https://github.com/XRPLF/xrpl.js)
- Python: [xrpl-py](https://github.com/XRPLF/xrpl-py)
@@ -37,6 +35,8 @@ You can find the complete source code for this tutorial's examples in the [code
## Steps
The example in this tutorial demonstrates a scenario where an account creates a DEX offer and pays a platform fee all in one batch transaction, ensuring the platform gets paid if and only if the offer is created.
### 1. Install dependencies
{% tabs %}
@@ -58,7 +58,7 @@ pip install xrpl-py
{% /tab %}
{% /tabs %}
## Set up client and accounts
### 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 transaction **sender**, and a second account to **receive** the platform fee.
@@ -71,20 +71,82 @@ To get started, import the client library and instantiate a client to connect to
{% /tab %}
{% /tabs %}
## Prepare inner transactions
### 3. Prepare inner transactions
Next, prepare the inner transactions that will be included in the batch. The following code shows the two inner transactions we want to send: one for the DEX UI offer, and another for the platform fee.
Next, prepare the inner transactions that will be included in the batch. The following code shows the two inner transactions we want to send: one for the DEX offer, and another for the platform fee.
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/singleAccountBatch.js" language="js" from="// Transaction 1:" to="// Send Batch transaction" /%}
{% code-snippet file="/_code-samples/batch/js/singleAccountBatch.js" language="js" from="// Create inner transactions" to="// Send Batch transaction" /%}
{% /tab %}
{% tab label="Python" %}
{% /tab %}
{% /tabs %}
In the code above we prepare the [OfferCreate transaction][] transaction which creates a DEX offer to sell 100 USD for XRP, and the [Payment transaction][] which sends 5 XRP to the platform fee recipient.
The [OfferCreate transaction][] creates a DEX offer to buy TST using XRP, and the [Payment transaction][] sends 2 XRP to the platform fee recipient. Both transactions must include the `tfInnerBatchTxn` (0x40000000) flag to indicate that they are inner transactions of a batch.
The `Fee` and `SigningPubKey` fields are omitted as the client library's _autofill_ functionality automatically populates these when submitting the batch transaction.
{% admonition type="info" name="Note" %}
The autofill functionality automatically adds `Fee: "0"` and `SigningPubKey: ""` when it detects the `tfInnerBatchTxn` flag. You typically don't need to set these manually, but if you do, ensure `Fee` is `"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` field, which is set to `tfAllOrNothing` (0x00010000) to ensure that either all inner transactions succeed or none are submitted. See [Batch Flags](../../../../references/protocol/transactions/types/batch.md#batch-flags) for other options. |
| 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. |
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/singleAccountBatch.js" language="js" from="// Send Batch transaction" before="// Sign, submit" /%}
{% /tab %}
{% tab label="Python" %}
{% /tab %}
{% /tabs %}
### 5. Sign and submit batch transaction
Now, sign and submit the batch transaction:
{% tabs %}
{% tab label="Javascript" %}
{% code-snippet file="/_code-samples/batch/js/singleAccountBatch.js" language="js" from="// Sign, submit" before="// Check transaction" /%}
{% /tab %}
{% tab label="Python" %}
{% /tab %}
{% /tabs %}
Because we set `autofill` to `true`, the client library automatically fills in any missing fields, like the `Fee` and `SigningPubKey`, before signing and submitting the transaction.
### 6. Check transaction result
Finally, 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 transaction" /%}
{% /tab %}
{% tab label="Python" %}
{% /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" /%}