Partner – Orkes – NPI EA (cat=Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag=Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Partner – LambdaTest – NPI EA (cat=Testing)
announcement - icon

Browser testing is essential if you have a website or web applications that users interact with. Manual testing can be very helpful to an extent, but given the multiple browsers available, not to mention versions and operating system, testing everything manually becomes time-consuming and repetitive.

To help automate this process, Selenium is a popular choice for developers, as an open-source tool with a large and active community. What's more, we can further scale our automation testing by running on theLambdaTest cloud-based testing platform.

Read more through our step-by-step tutorial on how to set up Selenium tests with Java and run them on LambdaTest:

>> Automated Browser Testing With Selenium

Partner – Orkes – NPI EA (cat=Java)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

1. Overview

Cryptocurrency is a secure and decentralized value store. It adopts a peer-to-peer (P2P) network for propagation and verification of transactions.

BitcoinJ is a Java library that simplifies the process of creating Bitcoin applications that enable users to perform cryptocurrency transactions seamlessly.

In this tutorial, we’ll explore BitcoinJ by delving into its key features and components. Also, we’ll explore how to create a wallet, fund the wallet, and send some coins to another wallet.

2. What Is BitcoinJ?

BitcoinJ is a Java library to simplify the process of creating Bitcoin applications.  It provides tools to create and manage Bitcoin wallets, send and receive transactions, and integrate with Bitcoin’s main network mainnet, testnet, and regtest networks.

Also, it provides Simplified Payment Verification (SPV) to interact with the Bitcoin network without downloading the whole blockchain.

3. Features of BitcoinJ

BitcoinJ allows us to easily create Bitcoin wallets, including generating addresses, managing private and public keys, and handling seed phrases for wallet recovery.

Furthermore, it provides functionality for sending and receiving Bitcoin transactions, enabling us to build an application that can handle Bitcoin transfers.

Additionally, it supports integration with the Bitcoin main network (mainnet) where real-world Bitcoin transactions occur. Also, it supports the testnet and regtest network for testing and prototyping.

Finally, it allows event listeners to respond to various events, such as incoming transactions or changes in the blockchain.

4. Basic Setup

To start interacting with the library, let’s add bitcoinj-core dependency to the pom.xml:

<dependency>
    <groupId>org.bitcoinj</groupId>
    <artifactId>bitcoinj-core</artifactId>
    <version>0.17-alpha4</version>
</dependency>

This dependency provides the Wallet and WalletKitApp classes to create a Bitcoin wallet.

Also, let’s add the slf4j-api and slf4j-simple  dependencies for logging:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>2.1.0-alpha1</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>2.1.0-alpha1</version>
</dependency>

These dependencies are essential to log the activities of the application.

5. The Wallet Class

The wallet is an important component in cryptocurrency because it provides functionality to manage transactions. The BitcoinJ library provides the Wallet and WalletKitApp classes to create a wallet.

5.1. Creating Wallet

Before creating a wallet, we need to define the network the wallet interacts with.

BitcoinJ supports three types of networks – mainnet for production, testnest for testing, and regtest for local regression testing.

Let’s create the NetworkParameters object to connect to a test network:

 NetworkParameters params = TestNet3Params.get();

Next, let’s create a Wallet instance that accepts the NetworkParameters as a parameter:

void createWallet() throws IOException {
    Wallet wallet = Wallet.createDeterministic(params, Script.ScriptType.P2PKH);
    File walletFile = new File("baeldung.dat");
    wallet.saveToFile(walletFile);
}

In the method above, we create a Wallet that interacts with the test network. We use the P2PKH script type that represents a Pay-to-Pubkey-Hash address, which is a common type of Bitcoin address. Finally, we save the wallet as baeldung.dat.

Notably, the wallet address, seed phrase, and public and private keys are generated while creating the wallet.

5.2. Retrieving Wallet Details

After creating a wallet, we can retrieve essential details like the address, public key, private key, and the seed phrase:

Wallet loadWallet() throws IOException, UnreadableWalletException {
    File walletFile = new File("baeldung.dat");
    Wallet wallet = Wallet.loadFromFile(walletFile);
    logger.info("Address: " + wallet.currentReceiveAddress().toString());
    logger.info("Seed Phrase: " + wallet.getKeyChainSeed().getMnemonicString());
    logger.info("Balance: " + wallet.getBalance().toFriendlyString());
    logger.info("Public Key: " + wallet.findKeyFromAddress(wallet.currentReceiveAddress()).getPublicKeyAsHex());
    logger.info("Private Key: " + wallet.findKeyFromAddress(wallet.currentReceiveAddress()).getPrivateKeyAsHex());
    return wallet;
}

Here, we load the wallet from the baeldung.dat file by invoking the loadFromFile() method on the Wallet instance. Then, we log the address, seed phrase, and balance of the wallet to the console.

Additionally, we log the public and private keys to the console.

5.3. Recovering Wallet

In case where we lose access to the wallet file but have the seed phrase, we can recover the wallet using the seed phrase:

Wallet loadUsingSeed(String seedWord) throws UnreadableWalletException {
    DeterministicSeed seed = new DeterministicSeed(seedWord, null, "", Utils.currentTimeSeconds());
    return Wallet.fromSeed(params, seed);
}

In the code above, we create a DeterministicSeed object that accepts the seed phrases and time as arguments. Then we call the Wallet.fromSeed() method, passing params and seed as arguments. This creates a new Wallet instance from the provided seed phrase and network parameter.

5.4. Securing Wallet

We need to keep the private key and seed phrase private from unauthorized access. Gaining access to the private key can allow attackers to access our wallets and spend the available funds.

BitcoinJ provides the encrypt() method to set a password for our wallet:

// ...
wallet.encrypt("password");
wallet.saveToFile(walletFile);
// ...

Here, we invoke the encrypt() method on the Wallet object. It accepts the intended password as an argument. With the wallet encrypted, no one can access the private key without decrypting the wallet first:

// ...
Wallet wallet = Wallet.loadFromFile(walletFile);
wallet.decrypt("password");
// ...

Here, we decrypt the wallet with the password we used to encrypt it. Notably, it’s important to keep the wallet file, seed phrase, and private key from external sources.

5.5. Connecting to a Peer Group

Currently, our wallet is in isolation and isn’t aware of transactions because it’s not in synchronization with the blockchain. We need to connect to a peer group network:

void connectWalletToPeer() throws BlockStoreException, UnreadableWalletException, IOException {
    Wallet wallet = loadWallet();
    BlockStore blockStore = new MemoryBlockStore(params);
    BlockChain chain = new BlockChain(params, wallet, blockStore);
    PeerGroup peerGroup = new PeerGroup(params, chain);
    peerGroup.addPeerDiscovery(new DnsDiscovery(params));
    peerGroup.addWallet(wallet);
    peerGroup.start();
    peerGroup.downloadBlockChain();
}

Here, we first load the wallet and then create a BlockStore instance which stores the blockchain in memory. Also, we create a BlockChain instance, which manages the data structure behind Bitcoin.

Finally, we create a PeerGroup instance to establish network connections. These classes are necessary to interact with testnet and synchronize our wallet with the network.

However, downloading the whole blockchain may be resource-intensive. Hence, WalletKitApp class uses SPV by default to simplify this process.

6. The WalletKitApp Class

BitcoinJ provides the WalletKitApp class which simplifies the process of setting up a wallet. The class abstracts away creating BlockStore, BlockChain and PeerGroup instances, making it easier to work with the Bitcoin network.

Let’s create a wallet using the WalletKitApp and log the wallet details after creation:

NetworkParameters params = TestNet3Params.get();

WalletAppKit kit = new WalletAppKit(params, new File("."), "baeldungkit") {
    @Override
    protected void onSetupCompleted() {
        logger.info("Wallet created and loaded successfully.");
        logger.info("Receive address: " + wallet().currentReceiveAddress());
        logger.info("Seed Phrase: " + wallet().getKeyChainSeed());
        logger.info("Balance: " + wallet().getBalance().toFriendlyString());
        logger.info("Public Key: " + wallet().findKeyFromAddress(wallet().currentReceiveAddress())
          .getPublicKeyAsHex());
        logger.info("Private Key: " + wallet().findKeyFromAddress(wallet().currentReceiveAddress())
          .getPrivateKeyAsHex());
        wallet().encrypt("password");
    }
};
kit.startAsync();
kit.awaitRunning();
kit.setAutoSave(true);;

Here, we set up a new wallet with testnet parameters and we specify the directory to store the wallet data. We start the WalletAppKit object asynchronously. We enable auto-save to locally store the latest wallet information.

Here’s the wallet details:

[ STARTING] INFO com.baeldung.bitcoinj.Kit - Wallet created and loaded successfully.
[ STARTING] INFO com.baeldung.bitcoinj.Kit - Receive address: moqVLcdRFjyXehgRAK5bJBK6rDN2vq14Wc
[ STARTING] INFO com.baeldung.bitcoinj.Kit - Seed Phrase: DeterministicSeed{unencrypted}
[ STARTING] INFO com.baeldung.bitcoinj.Kit - Balance: 0

The wallet currently has zero Bitcoin.

6.1. Adding an Event Listener

We can add an event listener to the wallet to respond to various events, such as incoming transactions:

kit.wallet()
  .addCoinsReceivedEventListener((wallet, tx, prevBalance, newBalance) -> {
      logger.info("Received tx for " + tx.getValueSentToMe(wallet));
      logger.info("New balance: " + newBalance.toFriendlyString());
  });

The event listener above logs incoming transactions with transaction ID and the amount received.

Moreover, let’s add an event listener to log the current wallet balance when we send a coin to another wallet:

kit.wallet()
  .addCoinsSentEventListener((wallet, tx, prevBalance, newBalance) -> logger.info("new balance: " + newBalance.toFriendlyString()));

The code above listens to an event to send coins out of the wallet and log the new balance.

6.2. Receiving Bitcoin

Let’s fund our wallet by requesting test bitcoins from a Bitcoin testnet faucet:

test bitcoin from test faucet

In the image above, we sent 0.0001238 bitcoins to our wallet address. However, this undergoes some confirmation before our wallet receives it. Notably, our application must be running to be in sync with the test blockchain.

Next, let’s verify the transaction on a blockchain explorer like BlockCypher:

sending history on block cypher

Finally, let’s re-execute our program and check the log for the received coin:

balance when received

The wallet balance is now updated to reflect the received Bitcoin.

6.3. Sending Bitcoin

We can easily send a Bitcoin to another address by creating a Coin instance and specifying the amount to send:

String receiveAddress = "n1vb1YZXyMQxvEjkc53VULi5KTiRtcAA9G";
Coin value = Coin.valueOf(200);
final Coin amountToSend = value.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
final Wallet.SendResult sendResult = kit.wallet()
  .sendCoins(kit.peerGroup(), Address.fromString(params, receiveAddress), amountToSend);

In the code above, we specify the address to send 200 satoshi. Also, we subtract the transaction fee for the miner. Finally, we call sendCoins(), which initiates the process of transferring the coin.

7. Conclusion

In this article, we learned how to use the BitcoinJ library by interacting with a Bitcoin test network. We discussed key features such as wallet management, transaction handling, network integration, and event handling.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

Partner – Orkes – NPI EA (cat = Spring)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag = Microservices)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

Course – LS – NPI (cat=Java)
announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)