public interface BtcdClient {
	
	String addMultiSigAddress(Integer minSignatures, List<String> addresses) 
			throws BitcoindException, CommunicationException;

	String addMultiSigAddress(Integer minSignatures, List<String> addresses, String account) 
			throws BitcoindException, CommunicationException;

	void addNode(String node, String command) throws BitcoindException, CommunicationException;

	void backupWallet(String filePath) throws BitcoindException, CommunicationException;

	MultiSigAddress createMultiSig(Integer minSignatures, List<String> addresses) 
			throws BitcoindException, CommunicationException;

	String createRawTransaction(List<OutputOverview> outputs, Map<String, BigDecimal> toAddresses) 
			throws BitcoindException, CommunicationException;

	RawTransactionOverview decodeRawTransaction(String hexTransaction) throws BitcoindException, 
			CommunicationException;

	RedeemScript decodeScript(String hexRedeemScript) throws BitcoindException, 
			CommunicationException;

	String dumpPrivKey(String address) throws BitcoindException, CommunicationException;

	void dumpWallet(String filePath) throws BitcoindException, CommunicationException;

	String encryptWallet(String passphrase) throws BitcoindException, CommunicationException;

	BigDecimal estimateFee(Integer maxBlocks) throws BitcoindException, CommunicationException;

	BigDecimal estimatePriority(Integer maxBlocks) throws BitcoindException, CommunicationException;

	String getAccount(String address) throws BitcoindException, CommunicationException;

	String getAccountAddress(String account) throws BitcoindException, CommunicationException;

	List<AddedNode> getAddedNodeInfo(Boolean withDetails) throws BitcoindException, 
			CommunicationException;

	List<AddedNode> getAddedNodeInfo(Boolean withDetails, String node) throws BitcoindException, 
			CommunicationException;

	List<String> getAddressesByAccount(String account) throws BitcoindException, 
			CommunicationException;

	BigDecimal getBalance() throws BitcoindException, CommunicationException;

	BigDecimal getBalance(String account) throws BitcoindException, CommunicationException;

	BigDecimal getBalance(String account, Integer confirmations) throws BitcoindException, 
			CommunicationException;

	BigDecimal getBalance(String account, Integer confirmations, Boolean withWatchOnly) 
			throws BitcoindException, CommunicationException;

	String getBestBlockHash() throws BitcoindException, CommunicationException;

	Block getBlock(String headerHash) throws BitcoindException, CommunicationException;

	Object getBlock(String headerHash, Boolean isDecoded) throws BitcoindException, 
			CommunicationException;

	BlockChainInfo getBlockChainInfo() throws BitcoindException, CommunicationException;

	Integer getBlockCount() throws BitcoindException, CommunicationException;

	String getBlockHash(Integer blockHeight) throws BitcoindException, CommunicationException;

	List<Tip> getChainTips() throws BitcoindException, CommunicationException;

	Integer getConnectionCount() throws BitcoindException, CommunicationException;

	BigDecimal getDifficulty() throws BitcoindException, CommunicationException;

	Boolean getGenerate() throws BitcoindException, CommunicationException;

	Long getHashesPerSec() throws BitcoindException, CommunicationException;

	Info getInfo() throws BitcoindException, CommunicationException;

	MemPoolInfo getMemPoolInfo() throws BitcoindException, CommunicationException;

	MiningInfo getMiningInfo() throws BitcoindException, CommunicationException;

	NetworkTotals getNetTotals() throws BitcoindException, CommunicationException;

	BigInteger getNetworkHashPs() throws BitcoindException, CommunicationException;

	BigInteger getNetworkHashPs(Integer blocks) throws BitcoindException, CommunicationException;

	BigInteger getNetworkHashPs(Integer blocks, Integer blockHeight) throws BitcoindException, 
			CommunicationException;

	NetworkInfo getNetworkInfo() throws BitcoindException, CommunicationException;

	String getNewAddress() throws BitcoindException, CommunicationException;

	String getNewAddress(String account) throws BitcoindException, CommunicationException;

	List<PeerNode> getPeerInfo() throws BitcoindException, CommunicationException;

	String getRawChangeAddress() throws BitcoindException, CommunicationException;

	List<String> getRawMemPool() throws BitcoindException, CommunicationException;

	List<? extends Object> getRawMemPool(Boolean isDetailed) throws BitcoindException, 
			CommunicationException;

	String getRawTransaction(String txId) throws BitcoindException, CommunicationException;

	Object getRawTransaction(String txId, Integer verbosity) throws BitcoindException, 
			CommunicationException;

	BigDecimal getReceivedByAccount(String account) throws BitcoindException, 
			CommunicationException;

	BigDecimal getReceivedByAccount(String account, Integer confirmations) throws BitcoindException, 
			CommunicationException;

	BigDecimal getReceivedByAddress(String address) throws BitcoindException, CommunicationException;

	BigDecimal getReceivedByAddress(String address, Integer confirmations) throws BitcoindException,
			CommunicationException;

	Transaction getTransaction(String txId) throws BitcoindException, CommunicationException;

	Transaction getTransaction(String txId, Boolean withWatchOnly) throws BitcoindException, 
			CommunicationException;

	TxOutSetInfo getTxOutSetInfo() throws BitcoindException, CommunicationException;

	BigDecimal getUnconfirmedBalance() throws BitcoindException, CommunicationException;

	WalletInfo getWalletInfo() throws BitcoindException, CommunicationException;

	String help() throws BitcoindException, CommunicationException;

	String help(String command) throws BitcoindException, CommunicationException;

	void importAddress(String address) throws BitcoindException, CommunicationException;

	void importAddress(String address, String account) throws BitcoindException, 
			CommunicationException;

	void importAddress(String address, String account, Boolean withRescan) throws BitcoindException,
			CommunicationException;

	void importPrivKey(String privateKey) throws BitcoindException, CommunicationException;

	void importPrivKey(String privateKey, String account) throws BitcoindException, 
			CommunicationException;

	void importPrivKey(String privateKey, String account, Boolean withRescan) 
			throws BitcoindException, CommunicationException;

	void importWallet(String filePath) throws BitcoindException, CommunicationException;

	void keyPoolRefill() throws BitcoindException, CommunicationException;

	void keyPoolRefill(Integer keypoolSize) throws BitcoindException, CommunicationException;

	Map<String, BigDecimal> listAccounts() throws BitcoindException, CommunicationException;

	Map<String, BigDecimal> listAccounts(Integer confirmations) throws BitcoindException, 
			CommunicationException;

	Map<String, BigDecimal> listAccounts(Integer confirmations, Boolean withWatchOnly) 
			throws BitcoindException, CommunicationException;

	List<List<AddressOverview>> listAddressGroupings() throws BitcoindException, 
			CommunicationException;

	List<OutputOverview> listLockUnspent() throws BitcoindException, CommunicationException;

	List<Account> listReceivedByAccount() throws BitcoindException, CommunicationException;

	List<Account> listReceivedByAccount(Integer confirmations) throws BitcoindException, 
			CommunicationException;

	List<Account> listReceivedByAccount(Integer confirmations, Boolean withUnused) 
			throws BitcoindException, CommunicationException;

	List<Account> listReceivedByAccount(Integer confirmations, Boolean withUnused, 
			Boolean withWatchOnly) throws BitcoindException, CommunicationException;

	List<Address> listReceivedByAddress() throws BitcoindException, CommunicationException;

	List<Address> listReceivedByAddress(Integer confirmations) throws BitcoindException, 
			CommunicationException;

	List<Address> listReceivedByAddress(Integer confirmations, Boolean withUnused) 
			throws BitcoindException, CommunicationException;

	List<Address> listReceivedByAddress(Integer confirmations, Boolean withUnused,
			Boolean withWatchOnly) throws BitcoindException, CommunicationException;

	SinceBlock listSinceBlock() throws BitcoindException, CommunicationException;

	SinceBlock listSinceBlock(String headerHash) throws BitcoindException, CommunicationException;

	SinceBlock listSinceBlock(String headerHash, Integer confirmations) throws BitcoindException, 
			CommunicationException;

	SinceBlock listSinceBlock(String headerHash, Integer confirmations, Boolean withWatchOnly) 
			throws BitcoindException, CommunicationException;

	List<Payment> listTransactions() throws BitcoindException, CommunicationException;

	List<Payment> listTransactions(String account) throws BitcoindException, CommunicationException;

	List<Payment> listTransactions(String account, Integer count) throws BitcoindException, 
			CommunicationException;

	List<Payment> listTransactions(String account, Integer count, Integer offset) 
			throws BitcoindException, CommunicationException;

	List<Payment> listTransactions(String account, Integer count, Integer offset, 
			Boolean withWatchOnly) throws BitcoindException, CommunicationException;

	List<Output> listUnspent() throws BitcoindException, CommunicationException;

	List<Output> listUnspent(Integer minConfirmations) throws BitcoindException, 
			CommunicationException;

	List<Output> listUnspent(Integer minConfirmations, Integer maxConfirmations) 
			throws BitcoindException, CommunicationException;

	List<Output> listUnspent(Integer minConfirmations, Integer maxConfirmations, 
			List<String> addresses) throws BitcoindException, CommunicationException;

	Boolean lockUnspent(Boolean isUnlocked) throws BitcoindException, CommunicationException;

	Boolean lockUnspent(Boolean isUnlocked, List<OutputOverview> outputs) throws BitcoindException,
			CommunicationException;

	Boolean move(String fromAccount, String toAccount, BigDecimal amount) throws BitcoindException, 
			CommunicationException;

	Boolean move(String fromAccount, String toAccount, BigDecimal amount, Integer dummy, 
			String comment) throws BitcoindException, CommunicationException;

	void ping() throws BitcoindException, CommunicationException;

	Boolean prioritiseTransaction(String txId, BigDecimal deltaPriority, Long deltaFee) 
			throws BitcoindException, CommunicationException;

	String sendFrom(String fromAccount, String toAddress, BigDecimal amount) 
			throws BitcoindException, CommunicationException;

	String sendFrom(String fromAccount, String toAddress, BigDecimal amount, Integer confirmations) 
			throws BitcoindException, CommunicationException;

	String sendFrom(String fromAccount, String toAddress, BigDecimal amount, Integer confirmations,
			String comment) throws BitcoindException, CommunicationException;

	String sendFrom(String fromAccount, String toAddress, BigDecimal amount, Integer confirmations,
			String comment, String commentTo) throws BitcoindException, CommunicationException;

	String sendMany(String fromAccount, Map<String, BigDecimal> toAddresses) 
			throws BitcoindException, CommunicationException;

	String sendMany(String fromAccount, Map<String, BigDecimal> toAddresses, Integer confirmations) 
			throws BitcoindException, CommunicationException;

	String sendMany(String fromAccount, Map<String, BigDecimal> toAddresses, Integer confirmations, 
			String comment) throws BitcoindException, CommunicationException;

	String sendRawTransaction(String hexTransaction) throws BitcoindException, 
			CommunicationException;

	String sendRawTransaction(String hexTransaction, Boolean withHighFees) throws BitcoindException, 
			CommunicationException;

	String sendToAddress(String toAddress, BigDecimal amount) throws BitcoindException, 
			CommunicationException;

	String sendToAddress(String toAddress, BigDecimal amount, String comment) 
			throws BitcoindException, CommunicationException;

	String sendToAddress(String toAddress, BigDecimal amount, String comment, String commentTo) 
			throws BitcoindException, CommunicationException;

	void setAccount(String address, String account) throws BitcoindException, 
			CommunicationException;

	void setGenerate(Boolean isGenerate) throws BitcoindException, CommunicationException;

	void setGenerate(Boolean isGenerate, Integer processors) throws BitcoindException, 
			CommunicationException;

	Boolean setTxFee(BigDecimal txFee) throws BitcoindException, CommunicationException;

	String signMessage(String address, String message) throws BitcoindException, 
			CommunicationException;

	SignatureResult signRawTransaction(String hexTransaction) throws BitcoindException, 
			CommunicationException;

	SignatureResult signRawTransaction(String hexTransaction, List<Output> outputs) 
			throws BitcoindException, CommunicationException;

	SignatureResult signRawTransaction(String hexTransaction, List<Output> outputs, 
			List<String> privateKeys) throws BitcoindException, CommunicationException;

	SignatureResult signRawTransaction(String hexTransaction, List<Output> outputs, 
			List<String> privateKeys, String sigHashType) throws BitcoindException, 
			CommunicationException;

	String stop() throws BitcoindException, CommunicationException;

	String submitBlock(String block) throws BitcoindException, CommunicationException;

	String submitBlock(String block, Map<String, Object> extraParameters) throws BitcoindException, 
			CommunicationException;

	AddressInfo validateAddress(String address) throws BitcoindException, CommunicationException;

	Boolean verifyChain() throws BitcoindException, CommunicationException;

	Boolean verifyChain(Integer checkLevel) throws BitcoindException, CommunicationException;

	Boolean verifyChain(Integer checkLevel, Integer blocks) throws BitcoindException, 
			CommunicationException;

	Boolean verifyMessage(String address, String signature, String message) 
			throws BitcoindException, CommunicationException;

	void walletLock() throws BitcoindException, CommunicationException;

	void walletPassphrase(String passphrase, Integer authTimeout) throws BitcoindException, 
			CommunicationException;

	void walletPassphraseChange(String curPassphrase, String newPassphrase) 
			throws BitcoindException, CommunicationException;

	Properties getNodeConfig();

	String getNodeVersion();

	void close();
} public interface BtcdDaemon {
	
	void addAlertListener(AlertListener listener);
	
	int countAlertListeners();
	
	void removeAlertListener(AlertListener listener);
	
	void removeAlertListeners();
	
	void addBlockListener(BlockListener listener);
	
	int countBlockListeners();
	
	void removeBlockListener(BlockListener listener);
	
	void removeBlockListeners();
	
	void addWalletListener(WalletListener listener);
	
	int countWalletListeners();
	
	void removeWalletListener(WalletListener listener);
	
	void removeWalletListeners();
	
	boolean isMonitoring(Notifications notificationType);
	
	boolean isMonitoringAny();
	
	boolean isMonitoringAll();
	
	Properties getNodeConfig();
	
	void shutdown();
} @Getter
@ToString
@AllArgsConstructor
public enum Notifications {

	ALERT,
	BLOCK,
	WALLET;
} public abstract class AlertListener {

	private static final Logger LOG = LoggerFactory.getLogger(AlertListener.class);

	@Getter
	private Observer observer;


	public AlertListener() {
		observer = new Observer() {
			@Override
			public void update(Observable monitor, Object cause) {
				String alert = (String)cause;
				LOG.trace("-- update(..): forwarding incoming 'ALERT' notification to "
						+ "'alertReceived(..)'");
				alertReceived(alert);
			}
		};
	}

	public void alertReceived(String alert) {}
} public abstract class BlockListener {

	private static final Logger LOG = LoggerFactory.getLogger(BlockListener.class);

	@Getter
	private Observer observer;


	public BlockListener() {
		observer = new Observer() {
			@Override
			public void update(Observable monitor, Object cause) {
				Block block = (Block)cause;
				LOG.trace("-- update(..): forwarding incoming 'BLOCK' notification to "
						+ "'blockDetected(..)'");
				blockDetected(block);
			}
		};
	}

	public void blockDetected(Block block) {}
} public abstract class WalletListener {

	private static final Logger LOG = LoggerFactory.getLogger(WalletListener.class);

	@Getter
	private Observer observer;


	public WalletListener() {
		observer = new Observer() {
			@Override
			public void update(Observable monitor, Object cause) {
				Transaction transaction = (Transaction)cause;
				LOG.trace("-- update(..): forwarding incoming 'WALLET' notification to "
						+ "'walletChanged(..)'");
				walletChanged(transaction);
			}
		};
	}

	public void walletChanged(Transaction transaction) {}
} @Data
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Block extends Entity {

	private String hash;
	private Integer confirmations;
	private Integer size;
	private Integer height;
	private Integer version;
	@JsonProperty("merkleroot")
	private String merkleRoot;
	private List<String> tx;
	private Long time;
	private Long nonce;
	private String bits;
	@Setter(AccessLevel.NONE)
	private BigDecimal difficulty;
	@JsonProperty("chainwork")
	private String chainWork;
	@JsonProperty("previousblockhash")
	private String previousBlockHash;
	@JsonProperty("nextblockhash")
	private String nextBlockHash;


	public Block(String hash, Integer confirmations, Integer size, Integer height, Integer version,
			String merkleRoot, List<String> tx, Long time, Long nonce, String bits, 
			BigDecimal difficulty, String chainWork, String previousBlockHash, String nextBlockHash) {
		setHash(hash);
		setConfirmations(confirmations);
		setSize(size);
		setHeight(height);
		setVersion(version);
		setMerkleRoot(merkleRoot);
		setTx(tx);
		setTime(time);
		setNonce(nonce);
		setBits(bits);
		setDifficulty(difficulty);
		setChainWork(chainWork);
		setPreviousBlockHash(previousBlockHash);
		setNextBlockHash(nextBlockHash);
	}

	public void setDifficulty(BigDecimal difficulty) {
		this.difficulty = difficulty.setScale(Defaults.DECIMAL_SCALE, Defaults.ROUNDING_MODE);
	}
} @Data
@NoArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Transaction extends Entity {

	@Setter(AccessLevel.NONE)
	private BigDecimal amount;
	@Setter(AccessLevel.NONE)
	private BigDecimal fee;
	private Integer confirmations;
	private Boolean generated;
	@JsonProperty("blockhash")
	private String blockHash;
	@JsonProperty("blockindex")
	private Integer blockIndex;
	@JsonProperty("blocktime")
	private Long blockTime;
	@JsonProperty("txid")
	private String txId;
	@JsonProperty("walletconflicts")
	private List<String> walletConflicts;
	private Long time;
	@JsonProperty("timereceived")
	private Long timeReceived;
	private String comment;
	private String to;
	private List<PaymentOverview> details;
	private String hex;


	public Transaction(BigDecimal amount, BigDecimal fee, Integer confirmations, Boolean generated, 
			String blockHash, Integer blockIndex, Long blockTime, String txId, 
			List<String> walletConflicts, Long time, Long timeReceived, String comment, String to, 
			List<PaymentOverview> details, String hex) {
		setAmount(amount);
		setFee(fee);
		setConfirmations(confirmations);
		setGenerated(generated);
		setBlockHash(blockHash);
		setBlockIndex(blockIndex);
		setBlockTime(blockTime);
		setTxId(txId);
		setWalletConflicts(walletConflicts);
		setTime(time);
		setTimeReceived(timeReceived);
		setComment(comment);
		setTo(to);
		setDetails(details);
		setHex(hex);
	}

	public void setAmount(BigDecimal amount) {
		this.amount = amount.setScale(Defaults.DECIMAL_SCALE, Defaults.ROUNDING_MODE);
	}

	public void setFee(BigDecimal fee) {
		this.fee = fee.setScale(Defaults.DECIMAL_SCALE, Defaults.ROUNDING_MODE);
	}
} @NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class OutputUtils {

	private static final int LINE_SEPARATOR_LENGTH = 89;
	
	
	public static void printResult(String methodName, String[] paramNames, Object[] paramValues,
			Object result) {
		List<Object> printables = new ArrayList<Object>();
		printables.add(methodName);
		if (!(paramNames == null || paramValues == null)) {
			printables.addAll(CollectionUtils.mergeInterlaced(Arrays.asList(paramNames), 
					Arrays.asList(paramValues)));
		}
		printables.add(result);
		System.out.printf("'bitcoind' response for JSON-RPC API call '%s(" + StringUtils.repeat(
				"%s=%s, ", (printables.size() - 2)/2).replaceAll(", $", "") + ")' was: '%s'\n", 
				printables.toArray());
	}
	
	public static void printSeparator() {
		printSeparator(LINE_SEPARATOR_LENGTH);
	}
	
	public static void printSeparator(int length) {
		System.out.println(StringUtils.repeat('-', length));
	}
} @NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ResourceUtils {
	
	public static CloseableHttpClient getHttpProvider() {
		PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
		CloseableHttpClient httpProvider = HttpClients.custom().setConnectionManager(connManager)
				.build();
		return httpProvider;
	}
	
	public static BtcdClient getBtcdProvider() throws BitcoindException, CommunicationException, 
			IOException {
		return new BtcdClientImpl(getHttpProvider(), getNodeConfig());
	}
	
	public static Properties getNodeConfig() throws IOException {
		Properties nodeConfig = new Properties();
		InputStream inputStream = new BufferedInputStream(new FileInputStream(
				"src/main/resources/node_config.properties"));
		nodeConfig.load(inputStream);
		inputStream.close();
		return nodeConfig;
	}
}
import com.neemre.btcdcli4j.core.client.BtcdClient;
import com.neemre.btcdcli4j.daemon.BtcdDaemon;
import com.neemre.btcdcli4j.daemon.Notifications;
import com.neemre.btcdcli4j.daemon.event.AlertListener;
import com.neemre.btcdcli4j.daemon.event.BlockListener;
import com.neemre.btcdcli4j.daemon.event.WalletListener;
import com.neemre.btcdcli4j.core.domain.Block;
import com.neemre.btcdcli4j.core.domain.Transaction;
import com.neemre.btcdcli4j.examples.util.OutputUtils;
import com.neemre.btcdcli4j.examples.util.ResourceUtils;
package com.neemre.btcdcli4j.examples.daemon;


/**An example demonstrating the use of <i>bitcoind</i>'s 'callback-via-shell-command' notification 
 * API via RPC-capable {@code BtcdDaemon} instances.*/
public class RpcCapableDaemon {

	public static void main(String[] args) throws Exception {
		BtcdClient btcdProvider = ResourceUtils.getBtcdProvider();
		BtcdDaemon daemon = new VerboseBtcdDaemonImpl(btcdProvider);