Welcome to Part 6 of my Lightning Anchor Fee Outputs Series
In the previous articles, we built the entire backend for a Lightning powered CPFP fee bumping service. From Bitcoin RPC integration, to LND invoice creation, to broadcasting the child transaction.
In this final part, I will walk you through the frontend and show you exactly how to use the service end to end.
What the Service Does
When a Bitcoin transaction gets stuck in the mempool due to low fees, you can use Child-Pays-For-Parent (CPFP) to accelerate/unstuck it. Our service uses the anchor output as the input for a child transaction that pays a higher fee. You pay for this service via a Lightning invoice, and the service broadcasts the fee-bumping transaction on your behalf.
Prerequisites
Before using the frontend, make sure the following are running:
- Docker containers:
bitcoin-regtest,lnd-alice,postgres-db,redis-cache - Backend server on port 3000 (
npm run devin/backend) - Frontend on port 5173 (
npm run devin/frontend)
# Start all Docker services
cd backend
docker compose up -d
# Terminal 1: Start backend
cd backend && npm run dev
# Terminal 2: Start frontend
cd frontend && npm run dev
Step 1: The Status Dashboard
When you open the app at http://localhost:5173 and click on Get Started, the first thing you'll notice on the right side is the Status Dashboard.
After the backend syncs to the regtest blockchain, the dashboard shows:
- Block Height — the current regtest block height, confirming Bitcoin Core is synced
-
Network —
regtestfor local development -
Mempool Monitor — shows
Inactiveuntil a transaction is submitted
If Block Height shows a number (861 in our case), your backend is successfully connected to the regtest blockchain network.
If it shows an error, check that your backend is running.
Step 2: Creating a Test Transaction
Before using the fee bumper, you need a stuck transaction to work with. In regtest, we create one manually:
First, get the service wallet address:
SERVICE_ADDR=$(curl -s http://localhost:3000/api/v1/bitcoin/wallet-address | jq -r '.data.address')
echo "Service wallet address: $SERVICE_ADDR"
Then send 330 sats to it and capture the TXID:
TXID=$(docker compose exec bitcoin bitcoin-cli -regtest \
-rpcuser=bitcoinrpc -rpcpassword=changeme \
-rpcwallet=testwallet sendtoaddress $SERVICE_ADDR 0.00000330)
echo "TXID: $TXID"
Expected output
Copy the TXID(Transaction Id) as you'll need it in the next step. My TXID in this case is 59224b8385c5dd882f0a1f48b11e05fbe0e9fdab414344f8fd5f725b6571661a
Step 3: Estimating the Fee
Paste your TXID into the Transaction ID field. Set the Anchor Output Index (usually 0) and choose a Target Fee Rate.
Three fee rate presets are available:
| Preset | Rate | Use case |
|---|---|---|
| Low | 1 sat/vB | Non-urgent, patient |
| Medium | 10 sat/vB | Standard confirmation |
| High | 50 sat/vB | Urgent, next block |
Click Estimate Cost. The Fee Estimation panel below will populate with:
- Child Fee Needed — the fee the child transaction must pay
- Total Fee Needed — child fee plus the service fee
- Parent Fee Rate — what the stuck transaction is currently paying
- Feasibility indicator — confirms the anchor output can cover the bump
Feasible vs Non-Feasible Transactions
The 330-sat anchor feasible badge tells you whether the service can actually bump your transaction.
Feasible (green badge) means the anchor output in your transaction is a valid 330-satoshi output that the service can spend as the CPFP child input. The child transaction can pay enough to bring the combined package fee rate up to your target. You can proceed to generate an invoice and broadcast.
Not feasible (red badge) means one of the following is true:
- The output at the specified index is not a 330-satoshi anchor output
- The parent transaction's fee rate is already at or above your target. There is nothing to bump
- The TXID does not exist in the mempool or the local blockchain
If you see a non-feasible result, double-check that you are using the correct Anchor Output Index — try 0, 1, or 2 depending on which output in the transaction is the anchor. Also confirm the transaction is genuinely stuck by checking its current fee rate against your target..
Step 4: Generating the Lightning Invoice
Once the estimate looks good, scroll down and click Generate Invoice. The backend calls LND via gRPC to create a Lightning invoice for the exact fee amount.
The Lightning Invoice panel appears with:
- A QR code you can scan with any Lightning wallet
- The amount in satoshis
- The payment hash for tracking
- A Copy Invoice button to copy the raw
lnbc...invoice string
In production, your user scans this QR code with their Lightning wallet and pays. In regtest, you can pay it programmatically:
# Pay the invoice from a second LND node (if you have one set up)
docker compose exec lnd lncli --network=regtest payinvoice <INVOICE_STRING>
Expected output:
The error self-payments not allowed means you're trying to pay an invoice from the same LND node that created it. You can't pay yourself on Lightning.
Coming Up Next
In the next article, we step out of regtest and into the real Bitcoin network, mainnet.
To continue from here on mainnet, we'll need to:
- Spin up a Lightning node connected to the live Bitcoin network
- Migrate the project configuration from regtest to mainnet
By doing this, we'll be able to handle real invoices paid by real wallets
Part 7: Going Live — Migrating to Mainnet →
(Link will be updated when the article is published)
What We Built Across This Series
Over six parts, we've gone from understanding what anchor outputs are to building and using a fully functional fee bumping service:
- Parts 1–2: What anchor outputs are and why they exist in Lightning commitment transactions
- Part 3: Setting up the backend, Bitcoin RPC integration, and Docker environment
- Part 4: Integrating LND for Lightning invoice creation and payment verification
- Part 5: Building the CPFP transaction constructor and broadcast endpoint
- Part 6 (this article): Walking through the React frontend and completing the end-to-end flow
The full source code is on GitHub. If you found this series useful, feel free to connect on LinkedIn or follow along on Dev.to.







Top comments (0)