Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to watch for transactions for an address in Bitcoinj (java)?

My goal is to watch a public bitcoin address and print to the console whenever money is sent to that address. That's all. I'm taking an address previously generated in Bitcoin Core, for now.

I'm doing the following:

 NetworkParameters params = MainNetParams.get();
 Wallet wallet = Wallet.loadFromFile(file);
 BlockStore blockStore = new MemoryBlockStore(params);
 BlockChain chain = new BlockChain(params, wallet, blockStore);

 PeerGroup peerGroup = new PeerGroup(params, chain);
 peerGroup.addPeerDiscovery(new DnsDiscovery(params));
 peerGroup.setUseLocalhostPeerWhenPossible(true);
 peerGroup.startAsync();

 Address add = new Address(params, "1NpxxxxxxxxxxxxxxxaSC4");
 wallet.addWatchedAddress(add);

 wallet.addEventListener(new AbstractWalletEventListener() {
        @Override
        public synchronized void onCoinsReceived(Wallet w, Transaction tx, Coin prevBalance, Coin newBalance) {
            System.out.println("[main]: COINS RECIEVED!"); 
            System.out.println("\nReceived tx " + tx.getHashAsString());
            System.out.println(tx.toString());
        }
    });

 System.out.println("\nDone!\n");
 System.out.println(wallet.toString());

I have a feeling that I'm not handling the AbstractWalletEventListener correctly. When I send money to the address, I don't get the text I expect to see in the console. Instead, I just see the continuous stream of "peer announced new transaction" from the [NioClientManager] from the peerGroup.startAsync() method.

What am I doing wrong and how can I correct it? I've spent way more time than I should have on something that seems like it should be such a simple task.

PS. The file I'm calling for "loadFromFile" is just a blank, default wallet file generated by bitcoinj. Nothing special about it.

Edit: Also, I'm not looking to see the total balance of the wallet. I only want to know when -new- transactions come in. Old ones are irrelevant in my program.

like image 593
Coty Avatar asked Jan 01 '15 00:01

Coty


1 Answers

I finally figured it out. Took me long enough. Instead of doing this manually and stuff, I decided to just use the wallet app kit. Here's my final code to do what I was trying to do (removed public key and files).

final NetworkParameters params = MainNetParams.get();

try{

    //initialize files and stuff here

    WalletAppKit kit = new WalletAppKit(params, wakfile, "_wak"); 
    kit.setAutoSave(true); 
    kit.connectToLocalHost(); 
    kit.startAsync(); 
    kit.awaitRunning();
    kit.peerGroup().addPeerDiscovery(new DnsDiscovery(params)); 
    kit.wallet().addWatchedAddress(new Address(params, "1NxxxxxxxxxxxxxxxxC4"));
    kit.wallet().addEventListener(new AbstractWalletEventListener() {
        @Override
        public synchronized void onCoinsReceived(Wallet w, Transaction tx, Coin prevBalance, Coin newBalance) {
            System.out.println("[main]: COINS RECIEVED!"); 
            System.out.println("\nReceived tx " + tx.getHashAsString());
            System.out.println(tx.toString());
        }
    });
} catch (IOException e) {
    e.printStackTrace();
} catch (AddressFormatException e) {
    e.printStackTrace();
}

Why this works and what I posted doesn't, I'm still not entirely sure. I must be missing something. If you come by this post and know what I did wrong up above; please let me know. It'd still be useful for future reference.

like image 155
Coty Avatar answered Nov 04 '22 10:11

Coty