The process is pretty straight forward.
I'll list down the steps with code.
Set up your development environment:
- Make sure to have latest node installed. https://nodejs.org/
- Install the AvalancheJS library: Run npm install --save avalanche in your terminal.
Create a new JavaScript file (e.g., bulk_transaction.js) and import the required libraries:
const { Avalanche, BinTools, BN, Buffer, utils } = require("avalanche");
const { AVMAPI, KeyChain } = require("avalanche/dist/apis/avm");
const { UnixNow } = utils;
- Connect to the Avalanche network (mainnet or testnet):
const networkID = 5; // Use 1 for mainnet, 5 for testnet (Fuji)
const avalanche = new Avalanche("api.avax-test.network", 443, "https", networkID);
const avm = avalanche.XChain(); // Connect to the X-Chain
- Configure the wallets and addresses for the sender and recipients:
const mnemonic = "your-mnemonic-phrase-here"; // Replace with your mnemonic phrase
const keychain = avm.keyChain();
keychain.importKey(mnemonic);
const senderAddress = keychain.getAddressStrings()[0];
const recipients = [
{ address: "X-avax1...", amount: 1000 }, // Replace with the recipient's address and desired amount
// Add more recipients as needed
];
- Create, sign, and broadcast the transaction:
async function sendBulkTransaction() {
// Fetch the UTXOs for the sender
const { utxos } = await avm.getUTXOs(senderAddress);
const inputs = [];
const outputs = [];
const binTools = BinTools.getInstance();
// Fetch the assetID for the USDC on Avalanche
const usdcAssetIDBuf = await avm.getAssetID("USDC");
const usdcAssetID = binTools.cb58Encode(usdcAssetIDBuf);
// Iterate through the UTXOs and create the inputs and outputs
for (const utxo of utxos.getAllUTXOs()) {
const assetID = binTools.cb58Encode(utxo.getAssetID());
const output = utxo.getOutput();
const amount = output.getAmount().clone();
const locktime = output.getLocktime();
const threshold = output.getThreshold();
const addresses = output.getAddresses();
if (usdcAssetID === assetID) {
const input = utxo.getInput();
inputs.push(input);
const change = new utils.Output(amount, locktime, threshold, addresses);
outputs.push(change);
}
}
// Create the outputs for the recipients
recipients.forEach(({ address, amount }) => {
const recipientOutput = new utils.Output(
new BN(amount),
0,
1,
[avm.parseAddress(address)]
);
outputs.push(recipientOutput);
});
// Build, sign, and send the transaction
const unsignedTx = await avm.buildUnsignedTransaction(
new UnixNow().getValue(),
new BN(0),
senderAddress,
usdcAssetIDBuf,
inputs,
outputs
);
const signedTx = unsignedTx.sign(keychain);
const txid = await avm.sendTx(signedTx);
console.log(`Transaction submitted! TXID: ${txid}`);
}
sendBulkTransaction()
.then(() => console.log("Bulk transaction completed."))
.catch((error) => console.error("Error during the transaction:", error));
This code snippet completes the transaction by signing and sending it. If everything is set up correctly, you should see the transaction ID in the console output after running the script.
To test the transaction on the testnet, make sure you have set the networkID to 5 (for Fuji testnet) in the code, as shown in Step 3. The example above is set up to connect to the Fuji testnet by default.
To run the script, navigate to the folder containing your bulk_transaction.js file and execute the following command in the terminal:
node bulk_transaction.js
Remember to replace the mnemonic, sender address, and recipient addresses with your own. Also, ensure that you have enough USDC and AVAX (for the transaction fees) in the sender's address before attempting the transaction.