package org.multibit.mbm.core.bitcoin.service; import com.google.bitcoin.core.Address; import com.google.bitcoin.core.ScriptException; import com.google.bitcoin.core.Transaction; import com.google.bitcoin.core.TransactionOutput; import com.google.common.collect.Maps; import org.springframework.stereotype.Component; import java.awt.image.BufferedImage; import java.util.List; import java.util.Map; /** * <p> * Service to provide integration testing of BitcoinService to Controllers. This * implementation is for integration testing and does not actually talk to the * Bitcoin network. * </p> * <ul> * <li>Next available address from the address bucket.</li> * <li>Registration of addresses for notification of relevant Transactions</li> * </p> * * TODO Need a complete re-implementation of this * * @since 0.0.1 */ @Component public class CallBackBitcoinService implements BitcoinService { private static final int NO_ADDRESS_GOT_YET = -1; /** * the List of Bitcoin addresses available for use */ private List<Address> addressBucket; /** * the index of the last address that was given out */ private int lastAddressIndex=NO_ADDRESS_GOT_YET; /** * Map of addresses to address listeners */ private Map<Address, AddressListener> addressToAddressListenerMap= Maps.newHashMap();; public CallBackBitcoinService() { } public String getNextAddress(Long id) { // if no addresses available return null; if (addressBucket == null || lastAddressIndex >= addressBucket.size() - 1) { return null; } else { lastAddressIndex++; return addressBucket.get(lastAddressIndex).toString(); } } // Set up methods public List<Address> getAddressBucket() { return addressBucket; } @Override public BufferedImage createSwatch(String address, String label, String amount) { //return swatchGenerator.generateBitcoinSwatch(address, amount, label); return null; } @Override public void setAddressBucket(List<Address> addressBucket) { this.addressBucket = addressBucket; } /** * notify any address listeners of any of the addresses which receive bitcoin * in the transaction * * @param transaction * @param isPending * true = transaction is a pending transaction i.e zero confirms * false = transaction is a confirmed transaction */ public void notifyAddressListenersOfTransaction(Transaction transaction, boolean isPending) { if (transaction != null) { List<TransactionOutput> transactionOutputs = transaction.getOutputs(); if (transactionOutputs != null) { for (TransactionOutput transactionOutput : transactionOutputs) { try { Address loopAddress = transactionOutput.getScriptPubKey() .getToAddress(); AddressListener addressListener = addressToAddressListenerMap .get(loopAddress); if (addressListener != null) { // notify listener if (isPending) { addressListener .onPendingCoinsReceived(loopAddress, transaction); } else { addressListener.onCoinsReceived(loopAddress, transaction); } } } catch (ScriptException e) { e.printStackTrace(); } } } } } }