Okay, first off - if you're in a rush to bundle transactions on Solana without burning SOL on tips, hit up Bundlr's sponsored mode. It covers your fees upfront. Why? Because normal bundles eat ~0.000005 SOL per tx plus tips, but sponsored? Zero from your pocket. I usually flip this on for testing so I don't drip feed airdrops constantly.
The thing is, Bundlr isn't Jito - it's a layer 2 bundler that uploads data off chain then bundles it atomically on Solana. Perfect for NFTs, big payloads, or when you need guaranteed order without MEV drama.
Bundlr lets you bundle multiple txs into one atomic shot on Solana. Think Jito but with data bundling superpowers - upload files, metadata, whatever, then land it all or nothing. Fees? Around 0.3% on USDC/USDT deposits, gas ~0.000005 SOL per bundle tx. Honest.
In my experience, it's a game changer for dApps handling user uploads. No more failed partial bundles screwing your UX. Why does this matter? Solana's fast, but without bundles, txs can reorder or drop. Bundlr fixes that.
| Bundlr | Jito | |
|---|---|---|
| Focus | Data + tx bundling | Pure tx sequencing |
| Fees | 0.3% + tiny SOL | Tips ~0.001 SOL |
| Best For | NFTs, big data | Arbitrage, DEX |
| Sponsored? | Yes | No |
See? Bundlr's your friend for heavy lifts.
Look, before Bundlr, you need Solana basics. Don't skip this or you'll rage quit.
sh -c "$(curl -sSfL https://release.solana.com/stable/install)". Restart terminal, check with solana --version.curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh.solana keygen new --outfile ~/.config/solana/id.json. Set it: solana config set --keypair ~/.config/solana/id.json.solana config set --url https://api.devnet.solana.com.solana airdrop 2. Check: solana balance.Stuck? Source your shell: source ~/.bashrc or whatever. Common issue - path not set. I forget half the time.
Now you're cooking. Wallet ready?
So, Bundlr's SDK is JS first. Makes sense for web devs. Fire up a folder.
mkdir bundlr solana fun && cd bundlr solana funnpm init -ynpm i @bundlr network/client @solana/web3.js bs58That's it. No Rust hassle unless you're program deep. In my experience, JS gets you 80% there faster.
What's next? Fund it.
Bundlr needs funds for bundling. Use USDC or SOL. Devnet's free ish.
await bundlrClient.fund(1000000) - that's ~0.001 SOL in lamports. Or USDC via their API.await bundlrClient.getLoadedBalance().Potential issue: Low funds? Bundles fail silently. Always check first. Sponsored mode? Pass sponsored: true in options - covers ~0.3% fee.
Okay, code time. Here's your starter script - save as index.js.
const { Bundlr} = require('@bundlr network/client');
const { SolanaWeb3 } = require('@solana/web3.js');
const fs = require('fs');
const BS58 = require('bs58'); async function main() { const keypair = SolanaWeb3.Keypair.fromSecretKey(BS58.decode(fs.readFileSync('your.json', 'utf8'))); const bundlr = new Bundlr('https://devnet.bundlr.network', 'solana', keypair, {providerUrl: 'https://api.devnet.solana.com'}); console.log('Balance:', await bundlr.utils.getLoadedBalance()); if ((await bundlr.utils.getLoadedBalance()).lte(0)) { await bundlr.fund(1000000); // 0.001 SOL } console.log('Ready to bundle!');
} main();
Run node index.js. Boom. Funded.
Now the fun. Bundles shine with data. Say you're dropping NFT metadata.
First, prep data. Random JSON file - echo '{"name": "My Bundled NFT"}' > metadata.json.
Add this after funding:
const data = fs.readFileSync('metadata.json');
const tx = await bundlr.createTransaction(data, { tags: [{ name: 'Content Type', value: 'application/json' }] });
await tx.sign();
const result = await tx.upload();
console.log('Bundle ID:', result.id);
Short? Yeah. But it bundles your data atomically with Solana tx. Verify on Bundlr explorer: devnet.bundlr.network/{id}.
Why tags? Makes it queryable later. I usually tag everything - 'app id', 'user pubkey', whatever.
Runs into "insufficient funds"? Double your fund amount. Network clogged? Wait 10s, retry. Devnet's flaky sometimes.
Sound familiar? Happened to me first try.
One tx? Boring. Bundle five like Jito pros.
Extend the script. Create tx array:
const transactions = [];
for (let i = 0; i < 5; i++) { const data = Buffer.from(Tx ${i} data); const tx = bundlr.createTransaction(data, { tags: [{ name: 'tx index', value: i.toString() }] }); await tx.sign(); transactions.push(tx);
} const bundle = await bundlr.bundle(transactions);
const bundleResult = await bundlr.sendBundle(bundle);
console.log('Bundle landed:', bundleResult.id);
~0.000005 SOL gas per tx in bundle. Atomic - all or none. Perfect for DEX swaps or mints.
Potential gotcha: Signer mismatch. Ensure your keypair matches CLI. Export from CLI: solana keygen pubkey and match.
In my experience, test on devnet 10x before mainnet. Fees jump to real SOL.
JS app? Easy peasy. New React: npx create react app bundlr dapp && cd bundlr dapp && npm i @bundlr network/client @solana/web3.js @solana/wallet adapter react.
Wrap with wallet adapter. Then button handler:
const uploadBundle = async () => { const bundlr = new Bundlr(..wallet.publicKey..); // fund if needed const data = new TextEncoder().encode('Hello bundle!'); const tx = bundlr.createTransaction(data); await tx.sign(wallet.signTransaction.bind(wallet)); const res = await tx.upload(); alert(Bundled! ${res.id});
};
Hook to Phantom/Backpack. Users sign - no seed exposure. Why does this matter? UX gold.
Three paragraphs here 'cause steps vary. First, context provider like Solana's. Second, wallet connect button. Third, upload on click. No lists. Keeps it chill.
Common issue: Wallet not connected? Check if (!wallet.connected) return;. I add that everywhere.
await bundlr.fund(5000000, { currency: 'usdc' });. Cheaper for big bundles.new Bundlr(url, 'solana', keypair, { sponsored: true });. Bundlr pays - you pay later via app logic.await tx.simulate();. Catches errors pre upload.await bundlr.api.get('/tx/{id}');.Fees breakdown: SOL direct ~0.000005/tx, USDC 0.3%. Pick based on volatility.
Honestly, sponsored's my go to for prod. Users hate micro fees.
Wanna go Rust? Create program that calls Bundlr off chain.
cargo new bundlr program --lib && cd bundlr programsolana program = "1.18", borsh = "0.10"Build: cargo build bpf. Deploy: solana program deploy target/deploy/bundlr_program.so.
Then client bundles instruction to your program ID. Note the ID post deploy - it's your handle.
Stuck on BPF errors? Update Rust: rustup update. Old versions hate Solana.
Now, interact: Bundle tx calling your program + data upload. Atomic mint or whatever.
Don't mainnet blind. Devnet explorer: explorer.solana.com/?cluster=devnet. Search bundle IDs.
Logs: solana logs {programId}. Bundlr specific? Their dashboard.
Issues I hit:
{tip: 10000}.Pretty much covers 90%. Rest is network mood swings.
Mainnet switch: solana config set --url https://api.mainnet beta.solana.com. Bundlr URL too: node1.bundlr.network.
Monitor: Use QuickNode or Helius RPC for faster confirms. ~$50/mo scales fine.
In my experience, batch user actions into bundles. Cuts costs 5x. Questions? Like, how much for 100tx bundle? ~0.0005 SOL total.
That's your guide. Go build. Hit snags? Tweak and retry - Solana's forgiving on devnet.