mirror of
				https://github.com/XRPLF/xrpl-dev-portal.git
				synced 2025-11-04 03:45:49 +00:00 
			
		
		
		
	Add Batch transactions tutorials
This commit is contained in:
		@@ -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.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										281
									
								
								_code-samples/batch/js/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								_code-samples/batch/js/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,281 @@
 | 
			
		||||
# 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: raNwujquxJ7QTLhfbkKN6sZa7RBPHV671e, Balance: 100 XRP
 | 
			
		||||
Wallet1: r4JMmKToZRMVT3mGWPnKHFEHsSMQEWigLC, Balance: 100 XRP
 | 
			
		||||
Wallet2: rKfPgHASYuttoF1HfU56V31WbJvZn3w8xn, Balance: 100 XRP
 | 
			
		||||
 | 
			
		||||
Creating batch transaction:
 | 
			
		||||
{
 | 
			
		||||
  "TransactionType": "Batch",
 | 
			
		||||
  "Account": "raNwujquxJ7QTLhfbkKN6sZa7RBPHV671e",
 | 
			
		||||
  "Flags": 65536,
 | 
			
		||||
  "RawTransactions": [
 | 
			
		||||
    {
 | 
			
		||||
      "RawTransaction": {
 | 
			
		||||
        "TransactionType": "Payment",
 | 
			
		||||
        "Account": "raNwujquxJ7QTLhfbkKN6sZa7RBPHV671e",
 | 
			
		||||
        "Destination": "r4JMmKToZRMVT3mGWPnKHFEHsSMQEWigLC",
 | 
			
		||||
        "Amount": "2000000",
 | 
			
		||||
        "Flags": 1073741824
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "RawTransaction": {
 | 
			
		||||
        "TransactionType": "Payment",
 | 
			
		||||
        "Account": "raNwujquxJ7QTLhfbkKN6sZa7RBPHV671e",
 | 
			
		||||
        "Destination": "rKfPgHASYuttoF1HfU56V31WbJvZn3w8xn",
 | 
			
		||||
        "Amount": "5000000",
 | 
			
		||||
        "Flags": 1073741824
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Submitting batch transaction...
 | 
			
		||||
 | 
			
		||||
Batch transaction submitted successfully!
 | 
			
		||||
Result:
 | 
			
		||||
 {
 | 
			
		||||
  "close_time_iso": "2025-11-03T14:16:21Z",
 | 
			
		||||
  "ctid": "C00D458B00020002",
 | 
			
		||||
  "hash": "A93D3C2BDB5D600E592B64B84E66D789237D029267129EBC659EE483E532DD95",
 | 
			
		||||
  "ledger_hash": "BE6B7C12E551305F09E942D6FA3FC8546F024AE5C53FC495DA6ABF78461E7019",
 | 
			
		||||
  "ledger_index": 869771,
 | 
			
		||||
  "meta": {
 | 
			
		||||
    "AffectedNodes": [
 | 
			
		||||
      {
 | 
			
		||||
        "ModifiedNode": {
 | 
			
		||||
          "FinalFields": {
 | 
			
		||||
            "Account": "raNwujquxJ7QTLhfbkKN6sZa7RBPHV671e",
 | 
			
		||||
            "Balance": "99999996",
 | 
			
		||||
            "Flags": 0,
 | 
			
		||||
            "OwnerCount": 0,
 | 
			
		||||
            "Sequence": 869767
 | 
			
		||||
          },
 | 
			
		||||
          "LedgerEntryType": "AccountRoot",
 | 
			
		||||
          "LedgerIndex": "6238B6901FEBD1492C03546C7965A01F184C4E37B696304B86F78F4ADB7831B1",
 | 
			
		||||
          "PreviousFields": {
 | 
			
		||||
            "Balance": "100000000",
 | 
			
		||||
            "Sequence": 869766
 | 
			
		||||
          },
 | 
			
		||||
          "PreviousTxnID": "559F102041D84FF9DA17483355C3C96A0F8923D9C9C7971BBB15C972DD1F37D6",
 | 
			
		||||
          "PreviousTxnLgrSeq": 869766
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "TransactionIndex": 2,
 | 
			
		||||
    "TransactionResult": "tesSUCCESS"
 | 
			
		||||
  },
 | 
			
		||||
  "tx_json": {
 | 
			
		||||
    "Account": "raNwujquxJ7QTLhfbkKN6sZa7RBPHV671e",
 | 
			
		||||
    "Fee": "4",
 | 
			
		||||
    "Flags": 65536,
 | 
			
		||||
    "LastLedgerSequence": 869789,
 | 
			
		||||
    "RawTransactions": [
 | 
			
		||||
      {
 | 
			
		||||
        "RawTransaction": {
 | 
			
		||||
          "Account": "raNwujquxJ7QTLhfbkKN6sZa7RBPHV671e",
 | 
			
		||||
          "Amount": "2000000",
 | 
			
		||||
          "Destination": "r4JMmKToZRMVT3mGWPnKHFEHsSMQEWigLC",
 | 
			
		||||
          "Fee": "0",
 | 
			
		||||
          "Flags": 1073741824,
 | 
			
		||||
          "Sequence": 869767,
 | 
			
		||||
          "SigningPubKey": "",
 | 
			
		||||
          "TransactionType": "Payment"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "RawTransaction": {
 | 
			
		||||
          "Account": "raNwujquxJ7QTLhfbkKN6sZa7RBPHV671e",
 | 
			
		||||
          "Amount": "5000000",
 | 
			
		||||
          "Destination": "rKfPgHASYuttoF1HfU56V31WbJvZn3w8xn",
 | 
			
		||||
          "Fee": "0",
 | 
			
		||||
          "Flags": 1073741824,
 | 
			
		||||
          "Sequence": 869768,
 | 
			
		||||
          "SigningPubKey": "",
 | 
			
		||||
          "TransactionType": "Payment"
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "Sequence": 869766,
 | 
			
		||||
    "SigningPubKey": "EDFECFB87A29F93E52BBA0BA5A14A59B520BB0E39F33943A2FDC1101D34349270D",
 | 
			
		||||
    "TransactionType": "Batch",
 | 
			
		||||
    "TxnSignature": "E08E300BDE1700C7CC27F3DA9B784907F637518E1C7E0978E57BFE5D1511A3B6A4269235FC2D9EAA550182A5F2B59415A442CE59555B9B9A0A79AB4030C9F701",
 | 
			
		||||
    "ctid": "C00D458B00020002",
 | 
			
		||||
    "date": 815494581,
 | 
			
		||||
    "ledger_index": 869771
 | 
			
		||||
  },
 | 
			
		||||
  "validated": true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Final balances after batch transaction:
 | 
			
		||||
Sender: raNwujquxJ7QTLhfbkKN6sZa7RBPHV671e, Balance: 92.999996 XRP
 | 
			
		||||
Wallet1: r4JMmKToZRMVT3mGWPnKHFEHsSMQEWigLC, Balance: 102 XRP
 | 
			
		||||
Wallet2: rKfPgHASYuttoF1HfU56V31WbJvZn3w8xn, Balance: 105 XRP
 | 
			
		||||
 | 
			
		||||
Transaction URL:
 | 
			
		||||
https://devnet.xrpl.org/transactions/A93D3C2BDB5D600E592B64B84E66D789237D029267129EBC659EE483E532DD95
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Multi-Account Batch Transaction
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
npm install xrpl
 | 
			
		||||
node multiAccountBatch.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The script should output the following:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
Funding new wallets from faucet...
 | 
			
		||||
Alice: rfCBfRGpcGJLwdbfz1M6HYoAL8nZyHRHHa, Balance: 100 XRP
 | 
			
		||||
Bob: rKPUDuS2jQNpAMhkNncqC9rKJDpL2gXDN7, Balance: 100 XRP
 | 
			
		||||
Charlie: rnz3Da7phfR6tgTZoPYF5psYTiHTshTB8K, Balance: 100 XRP
 | 
			
		||||
Third-party wallet: rU8LsCmVjSdf7hSmiGBtBDtt2WhHxp7Zpc, Balance: 100 XRP
 | 
			
		||||
 | 
			
		||||
Creating batch transaction:
 | 
			
		||||
{
 | 
			
		||||
  "TransactionType": "Batch",
 | 
			
		||||
  "Account": "rU8LsCmVjSdf7hSmiGBtBDtt2WhHxp7Zpc",
 | 
			
		||||
  "Flags": 65536,
 | 
			
		||||
  "RawTransactions": [
 | 
			
		||||
    {
 | 
			
		||||
      "RawTransaction": {
 | 
			
		||||
        "TransactionType": "Payment",
 | 
			
		||||
        "Account": "rnz3Da7phfR6tgTZoPYF5psYTiHTshTB8K",
 | 
			
		||||
        "Destination": "rfCBfRGpcGJLwdbfz1M6HYoAL8nZyHRHHa",
 | 
			
		||||
        "Amount": "50000000",
 | 
			
		||||
        "Flags": 1073741824
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "RawTransaction": {
 | 
			
		||||
        "TransactionType": "Payment",
 | 
			
		||||
        "Account": "rKPUDuS2jQNpAMhkNncqC9rKJDpL2gXDN7",
 | 
			
		||||
        "Destination": "rfCBfRGpcGJLwdbfz1M6HYoAL8nZyHRHHa",
 | 
			
		||||
        "Amount": "50000000",
 | 
			
		||||
        "Flags": 1073741824
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Submitting batch transaction...
 | 
			
		||||
 | 
			
		||||
Batch transaction submitted successfully!
 | 
			
		||||
Result:
 | 
			
		||||
 {
 | 
			
		||||
  "close_time_iso": "2025-11-03T14:15:00Z",
 | 
			
		||||
  "ctid": "C00D457000000002",
 | 
			
		||||
  "hash": "8CBCCD88B8ABC248797B84ABB92066961C1CB5FE75ACE2115ADCA6B74C85993A",
 | 
			
		||||
  "ledger_hash": "2217A0DBB38B870187B412533B939724095359A050B21E071A2A114BF57CFB60",
 | 
			
		||||
  "ledger_index": 869744,
 | 
			
		||||
  "meta": {
 | 
			
		||||
    "AffectedNodes": [
 | 
			
		||||
      {
 | 
			
		||||
        "ModifiedNode": {
 | 
			
		||||
          "FinalFields": {
 | 
			
		||||
            "Account": "rU8LsCmVjSdf7hSmiGBtBDtt2WhHxp7Zpc",
 | 
			
		||||
            "Balance": "99999994",
 | 
			
		||||
            "Flags": 0,
 | 
			
		||||
            "OwnerCount": 0,
 | 
			
		||||
            "Sequence": 869743
 | 
			
		||||
          },
 | 
			
		||||
          "LedgerEntryType": "AccountRoot",
 | 
			
		||||
          "LedgerIndex": "1E9BA043B9C6518582D0FF73A08DCD8B6958195735086CF7295E5EB6433FB453",
 | 
			
		||||
          "PreviousFields": {
 | 
			
		||||
            "Balance": "100000000",
 | 
			
		||||
            "Sequence": 869742
 | 
			
		||||
          },
 | 
			
		||||
          "PreviousTxnID": "F7019BC55D80438FDDB01C2549CCC3F7DAF9791F8645E0269D63979EAEC5BBA6",
 | 
			
		||||
          "PreviousTxnLgrSeq": 869742
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "TransactionIndex": 0,
 | 
			
		||||
    "TransactionResult": "tesSUCCESS"
 | 
			
		||||
  },
 | 
			
		||||
  "tx_json": {
 | 
			
		||||
    "Account": "rU8LsCmVjSdf7hSmiGBtBDtt2WhHxp7Zpc",
 | 
			
		||||
    "BatchSigners": [
 | 
			
		||||
      {
 | 
			
		||||
        "BatchSigner": {
 | 
			
		||||
          "Account": "rnz3Da7phfR6tgTZoPYF5psYTiHTshTB8K",
 | 
			
		||||
          "SigningPubKey": "EDC566D7DA8186BBD30DDAE1FB770FCE7F248949194E1A2E70B18CFA060B140B59",
 | 
			
		||||
          "TxnSignature": "31639BFA1359DD24345776EAEEACCF61C1CDC792988679263D113E80A22D837E20ACD2B25E482FCA769990C004D747836370C6BAD14524559639BBEBA5813002"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "BatchSigner": {
 | 
			
		||||
          "Account": "rKPUDuS2jQNpAMhkNncqC9rKJDpL2gXDN7",
 | 
			
		||||
          "SigningPubKey": "EDEF1966B325000407940E4C0792E3CCC3E27F51D132BDC53DCC2B1998E7C32A34",
 | 
			
		||||
          "TxnSignature": "6BF9860B0E2E134FB302329D711BAA7B6314395D39523982DBBC037E84FB17AB5E8E736DB3DB0019B4477686AF2D91E5D2B49409698A95219376B2E318D3E501"
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "Fee": "6",
 | 
			
		||||
    "Flags": 65536,
 | 
			
		||||
    "LastLedgerSequence": 869762,
 | 
			
		||||
    "RawTransactions": [
 | 
			
		||||
      {
 | 
			
		||||
        "RawTransaction": {
 | 
			
		||||
          "Account": "rnz3Da7phfR6tgTZoPYF5psYTiHTshTB8K",
 | 
			
		||||
          "Amount": "50000000",
 | 
			
		||||
          "Destination": "rfCBfRGpcGJLwdbfz1M6HYoAL8nZyHRHHa",
 | 
			
		||||
          "Fee": "0",
 | 
			
		||||
          "Flags": 1073741824,
 | 
			
		||||
          "Sequence": 869740,
 | 
			
		||||
          "SigningPubKey": "",
 | 
			
		||||
          "TransactionType": "Payment"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "RawTransaction": {
 | 
			
		||||
          "Account": "rKPUDuS2jQNpAMhkNncqC9rKJDpL2gXDN7",
 | 
			
		||||
          "Amount": "50000000",
 | 
			
		||||
          "Destination": "rfCBfRGpcGJLwdbfz1M6HYoAL8nZyHRHHa",
 | 
			
		||||
          "Fee": "0",
 | 
			
		||||
          "Flags": 1073741824,
 | 
			
		||||
          "Sequence": 869738,
 | 
			
		||||
          "SigningPubKey": "",
 | 
			
		||||
          "TransactionType": "Payment"
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "Sequence": 869742,
 | 
			
		||||
    "SigningPubKey": "ED2B56D6FB4E8C236A6B07E8D8AD9A4938606144E31779918F99525CA6B3C56664",
 | 
			
		||||
    "TransactionType": "Batch",
 | 
			
		||||
    "TxnSignature": "9C51C1F2CB0E8BCEA1FADD3992249DE72AC46FC86AB2FB023A597FBD5C4CCB3337967E9AAFFB5F1C0CBC91128F3FD194F78F207E461BE1FF906C496B94EC410E",
 | 
			
		||||
    "ctid": "C00D457000000002",
 | 
			
		||||
    "date": 815494500,
 | 
			
		||||
    "ledger_index": 869744
 | 
			
		||||
  },
 | 
			
		||||
  "validated": true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Final balances after batch transaction:
 | 
			
		||||
Alice: rfCBfRGpcGJLwdbfz1M6HYoAL8nZyHRHHa, Balance: 200 XRP
 | 
			
		||||
Bob: rKPUDuS2jQNpAMhkNncqC9rKJDpL2gXDN7, Balance: 50 XRP
 | 
			
		||||
Charlie: rnz3Da7phfR6tgTZoPYF5psYTiHTshTB8K, Balance: 50 XRP
 | 
			
		||||
Third-party wallet: rU8LsCmVjSdf7hSmiGBtBDtt2WhHxp7Zpc, Balance: 99.999994 XRP
 | 
			
		||||
 | 
			
		||||
Transaction URL:
 | 
			
		||||
https://devnet.xrpl.org/transactions/8CBCCD88B8ABC248797B84ABB92066961C1CB5FE75ACE2115ADCA6B74C85993A
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										110
									
								
								_code-samples/batch/js/multiAccountBatch.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								_code-samples/batch/js/multiAccountBatch.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
			
		||||
/**
 | 
			
		||||
 * XRP Ledger Batch Transactions Tutorial
 | 
			
		||||
 *
 | 
			
		||||
 * This tutorial demonstrates how to use the Batch transaction feature (XLS-56)
 | 
			
		||||
 * to perform a multi-account batch transaction.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
import xrpl from "xrpl"
 | 
			
		||||
import { BatchFlags } from 'xrpl/dist/npm/models/transactions/batch.js'
 | 
			
		||||
import { GlobalFlags } from 'xrpl/dist/npm/models/transactions/common.js'
 | 
			
		||||
import { signMultiBatch, combineBatchSigners } from 'xrpl/dist/npm/Wallet/batchSigner.js'
 | 
			
		||||
 | 
			
		||||
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 } = await client.fundWallet()
 | 
			
		||||
const { wallet: bob } = await client.fundWallet()
 | 
			
		||||
const { wallet: charlie } = await client.fundWallet()
 | 
			
		||||
const { wallet: thirdPartyWallet } = await 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 (allows 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: 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: GlobalFlags.tfInnerBatchTxn // THIS IS REQUIRED
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Send Batch transaction --------------------------------------------
 | 
			
		||||
console.log("\nCreating batch transaction:")
 | 
			
		||||
const batchTx = {
 | 
			
		||||
  TransactionType: "Batch",
 | 
			
		||||
  Account: thirdPartyWallet.address,
 | 
			
		||||
  Flags: BatchFlags.tfAllOrNothing, // tfAllOrNothing: All inner transactions must succeed
 | 
			
		||||
  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 for this transaction.
 | 
			
		||||
// "autofill" will automatically add Fee: "0" and SigningPubKey: "".
 | 
			
		||||
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 }
 | 
			
		||||
signMultiBatch(charlie, charlieBatch)
 | 
			
		||||
 | 
			
		||||
// Bob signs the Batch transaction
 | 
			
		||||
const bobBatch = { ...autofilledBatchTx }
 | 
			
		||||
signMultiBatch(bob, bobBatch)
 | 
			
		||||
 | 
			
		||||
// Combine inner transaction signatures.
 | 
			
		||||
// This returns a signed transaction blob (hex string) ready for submission.
 | 
			
		||||
const combinedSignedTx = combineBatchSigners([charlieBatch, bobBatch])
 | 
			
		||||
 | 
			
		||||
// Submit the signed blob with the third-party's wallet
 | 
			
		||||
console.log("\nSubmitting 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}`)
 | 
			
		||||
  process.exit(1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
console.log("\nBatch transaction submitted successfully!")
 | 
			
		||||
console.log("Result:\n", JSON.stringify(submitResponse.result, null, 2))
 | 
			
		||||
 | 
			
		||||
// Verify balances after transaction
 | 
			
		||||
console.log("\nFinal balances after batch transaction:")
 | 
			
		||||
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`)
 | 
			
		||||
 | 
			
		||||
// View the transaction on the XRPL Explorer 
 | 
			
		||||
console.log(`\nTransaction URL:\nhttps://devnet.xrpl.org/transactions/${submitResponse.result.hash}`)
 | 
			
		||||
 | 
			
		||||
await client.disconnect()
 | 
			
		||||
							
								
								
									
										6
									
								
								_code-samples/batch/js/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								_code-samples/batch/js/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "xrpl": "^4.4.2"
 | 
			
		||||
  },
 | 
			
		||||
  "type": "module"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								_code-samples/batch/js/singleAccountBatch.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								_code-samples/batch/js/singleAccountBatch.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
import xrpl from "xrpl"
 | 
			
		||||
import { BatchFlags } from 'xrpl/dist/npm/models/transactions/batch.js'
 | 
			
		||||
import { GlobalFlags } from 'xrpl/dist/npm/models/transactions/common.js'
 | 
			
		||||
 | 
			
		||||
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 } = await client.fundWallet()
 | 
			
		||||
const { wallet: wallet1 } = await client.fundWallet()
 | 
			
		||||
const { wallet: wallet2 } = await 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 (allows Fee: 0 and empty SigningPubKey).
 | 
			
		||||
 | 
			
		||||
// Transaction 1
 | 
			
		||||
const payment1 = {
 | 
			
		||||
  TransactionType: "Payment",
 | 
			
		||||
  Account: sender.address,
 | 
			
		||||
  Destination: wallet1.address,
 | 
			
		||||
  Amount: xrpl.xrpToDrops(2),
 | 
			
		||||
  Flags: GlobalFlags.tfInnerBatchTxn // THIS IS REQUIRED
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Transaction 2
 | 
			
		||||
const payment2 = {
 | 
			
		||||
  TransactionType: "Payment",
 | 
			
		||||
  Account: sender.address,
 | 
			
		||||
  Destination: wallet2.address,
 | 
			
		||||
  Amount: xrpl.xrpToDrops(5),
 | 
			
		||||
  Flags: GlobalFlags.tfInnerBatchTxn // THIS IS REQUIRED
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Send Batch transaction --------------------------------------------
 | 
			
		||||
console.log("\nCreating batch transaction:")
 | 
			
		||||
const batchTx = {
 | 
			
		||||
  TransactionType: "Batch",
 | 
			
		||||
  Account: sender.address,
 | 
			
		||||
  Flags: BatchFlags.tfAllOrNothing, // tfAllOrNothing: All inner transactions must succeed
 | 
			
		||||
  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("\nSubmitting batch transaction...")
 | 
			
		||||
const submitResponse = await client.submitAndWait(batchTx, {
 | 
			
		||||
  wallet: sender,
 | 
			
		||||
  // "autofill" will automatically add Fee: "0" and SigningPubKey: "".
 | 
			
		||||
  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}`)
 | 
			
		||||
  process.exit(1)
 | 
			
		||||
}
 | 
			
		||||
console.log("\nBatch transaction submitted successfully!")
 | 
			
		||||
console.log("Result:\n", JSON.stringify(submitResponse.result, null, 2))
 | 
			
		||||
 | 
			
		||||
// Verify balances after transaction
 | 
			
		||||
console.log("\nFinal balances after batch transaction:")
 | 
			
		||||
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`)
 | 
			
		||||
 | 
			
		||||
// View the transaction on the XRPL Explorer 
 | 
			
		||||
console.log(`\nTransaction URL:\nhttps://devnet.xrpl.org/transactions/${submitResponse.result.hash}`)
 | 
			
		||||
 | 
			
		||||
await client.disconnect()
 | 
			
		||||
							
								
								
									
										14
									
								
								docs/tutorials/how-tos/use-batch-transactions/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								docs/tutorials/how-tos/use-batch-transactions/index.md
									
									
									
									
									
										Normal 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 /%}
 | 
			
		||||
@@ -0,0 +1,158 @@
 | 
			
		||||
---
 | 
			
		||||
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. There can be up to **8** transactions included. 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 %}
 | 
			
		||||
 | 
			
		||||
### 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/multiAccountBatch.js" language="js" from="// Check Batch transaction" before="// Verify balances after transaction" /%}
 | 
			
		||||
{% /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 %}
 | 
			
		||||
 | 
			
		||||
To verify that the inner transactions have been successful, check 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 %}
 | 
			
		||||
 | 
			
		||||
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**.
 | 
			
		||||
 | 
			
		||||
## 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" /%}
 | 
			
		||||
@@ -0,0 +1,148 @@
 | 
			
		||||
---
 | 
			
		||||
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. 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="// 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="// Verify balances after transaction" /%}
 | 
			
		||||
{% /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 %}
 | 
			
		||||
 | 
			
		||||
To verify that the inner transactions have been successful, check 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 %}
 | 
			
		||||
 | 
			
		||||
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 **sender**.
 | 
			
		||||
 | 
			
		||||
## 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" /%}
 | 
			
		||||
@@ -295,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:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user