diff --git a/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/IncognitocoinAddressValidator.java b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/IncognitocoinAddressValidator.java new file mode 100644 index 0000000..a4d6a67 --- /dev/null +++ b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/IncognitocoinAddressValidator.java @@ -0,0 +1,60 @@ +/************************************************************************************* + * Copyright (C) 2014 GENERAL BYTES s.r.o. All rights reserved. + * + * This software may be distributed and modified under the terms of the GNU + * General Public License version 2 (GPL2) as published by the Free Software + * Foundation and appearing in the file GPL2.TXT included in the packaging of + * this file. Please note that GPL2 Section 2[b] requires that all works based + * on this software must also be made publicly available under the terms of + * the GPL2 ("Copyleft"). + * + * Contact information + * ------------------- + * + * GENERAL BYTES s.r.o. + * Web : http://www.generalbytes.com + * + ************************************************************************************/ +package com.generalbytes.batm.server.extensions.extra.incognitocoin; + +import com.generalbytes.batm.server.coinutil.AddressFormatException; +import com.generalbytes.batm.server.coinutil.Base58; +import com.generalbytes.batm.server.extensions.ExtensionsUtil; +import com.generalbytes.batm.server.extensions.ICryptoAddressValidator; + +public class IncognitocoinAddressValidator implements ICryptoAddressValidator { + + @Override + public boolean isAddressValid(String address) { + boolean result = isIncognitocoinAddressValid(address); + if (!result) { + result = isPaperWalletSupported() && ExtensionsUtil.isValidEmailAddress(address); + } + return result; + } + + private boolean isIncognitocoinAddressValid(String address) { + if (address.startsWith("I")) { + try { + Base58.decodeToBigInteger(address); + Base58.decodeChecked(address); + } catch (AddressFormatException e) { + e.printStackTrace(); + return false; + } + return true; + }else{ + return false; + } + } + + @Override + public boolean isPaperWalletSupported() { + return false; + } + + @Override + public boolean mustBeBase58Address() { + return true; + } +} diff --git a/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/IncognitocoinExtension.java b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/IncognitocoinExtension.java new file mode 100644 index 0000000..bef4c9a --- /dev/null +++ b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/IncognitocoinExtension.java @@ -0,0 +1,118 @@ +/************************************************************************************* + * Copyright (C) 2014 GENERAL BYTES s.r.o. All rights reserved. + * + * This software may be distributed and modified under the terms of the GNU + * General Public License version 2 (GPL2) as published by the Free Software + * Foundation and appearing in the file GPL2.TXT included in the packaging of + * this file. Please note that GPL2 Section 2[b] requires that all works based + * on this software must also be made publicly available under the terms of + * the GPL2 ("Copyleft"). + * + * Contact information + * ------------------- + * + * GENERAL BYTES s.r.o. + * Web : http://www.generalbytes.com + * + ************************************************************************************/ +package com.generalbytes.batm.server.extensions.extra.incognitocoin; + +import com.generalbytes.batm.server.extensions.*; +import com.generalbytes.batm.server.extensions.extra.incognitocoin.sources.FixPriceRateSource; +import com.generalbytes.batm.server.extensions.extra.incognitocoin.sources.IncognitocoinTickerRateSource; +import com.generalbytes.batm.server.extensions.extra.incognitocoin.wallets.incognitocoind.IncognitocoindRPCWallet; + +import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Set; +import java.util.StringTokenizer; + +public class IncognitocoinExtension implements IExtension{ + @Override + public String getName() { + return "BATM Incognitocoin extension"; + } + + @Override + public IExchange createExchange(String exchangeLogin) { + return null; + } + + @Override + public IWallet createWallet(String walletLogin) { + if (walletLogin !=null && !walletLogin.trim().isEmpty()) { + StringTokenizer st = new StringTokenizer(walletLogin,":"); + String walletType = st.nextToken(); + + if ("incognitocoind".equalsIgnoreCase(walletType)) { + //"incognitocoind:protocol:user:password:ip:port:accountname" + + String protocol = st.nextToken(); + String username = st.nextToken(); + String password = st.nextToken(); + String hostname = st.nextToken(); + String port = st.nextToken(); + String accountName =""; + if (st.hasMoreTokens()) { + accountName = st.nextToken(); + } + + + if (protocol != null && username != null && password != null && hostname !=null && port != null && accountName != null) { + String rpcURL = protocol +"://" + username +":" + password + "@" + hostname +":" + port; + return new IncognitocoindRPCWallet(rpcURL,accountName); + } + } + } + return null; + } + + @Override + public ICryptoAddressValidator createAddressValidator(String cryptoCurrency) { + if (ICurrencies.ICG.equalsIgnoreCase(cryptoCurrency)) { + return new IncognitocoinAddressValidator(); + } + return null; + } + + @Override + public IPaperWalletGenerator createPaperWalletGenerator(String cryptoCurrency) { + return null; + } + + @Override + public IRateSource createRateSource(String sourceLogin) { + if (sourceLogin != null && !sourceLogin.trim().isEmpty()) { + StringTokenizer st = new StringTokenizer(sourceLogin,":"); + String exchangeType = st.nextToken(); + + if ("incognitocointicker".equalsIgnoreCase(exchangeType)) { + return new IncognitocoinTickerRateSource(); + }else if ("icgfix".equalsIgnoreCase(exchangeType)) { + BigDecimal rate = BigDecimal.ZERO; + if (st.hasMoreTokens()) { + try { + rate = new BigDecimal(st.nextToken()); + } catch (Throwable e) { + } + } + return new FixPriceRateSource(rate); + } + + } + return null; + } + + @Override + public IPaymentProcessor createPaymentProcessor(String paymentProcessorLogin) { + return null; //no payment processors available + } + + @Override + public Set getSupportedCryptoCurrencies() { + Set result = new HashSet(); + result.add(ICurrencies.ICG); + return result; + } + +} diff --git a/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/sources/FixPriceRateSource.java b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/sources/FixPriceRateSource.java new file mode 100644 index 0000000..0f8ffc7 --- /dev/null +++ b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/sources/FixPriceRateSource.java @@ -0,0 +1,43 @@ +package com.generalbytes.batm.server.extensions.extra.incognitocoin.sources; + +import com.generalbytes.batm.server.extensions.ICurrencies; +import com.generalbytes.batm.server.extensions.IRateSource; + +import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Set; + +/** + * Created by b00lean on 7/31/14. + */ +public class FixPriceRateSource implements IRateSource { + private BigDecimal rate = BigDecimal.ZERO; + + public FixPriceRateSource(BigDecimal rate) { + this.rate = rate; + } + + @Override + public Set getCryptoCurrencies() { + Set result = new HashSet(); + result.add(ICurrencies.ICG); + return result; + } + + @Override + public BigDecimal getExchangeRateLast(String cryptoCurrency, String fiatCurrency) { + if (ICurrencies.ICG.equalsIgnoreCase(cryptoCurrency)) { + return rate; + } + return null; + } + + @Override + public Set getFiatCurrencies() { + Set result = new HashSet(); + result.add(ICurrencies.USD); + result.add(ICurrencies.EUR); + return result; + } + +} diff --git a/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/sources/IIncognitocoinTickerRateAPI.java b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/sources/IIncognitocoinTickerRateAPI.java new file mode 100644 index 0000000..ba815e4 --- /dev/null +++ b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/sources/IIncognitocoinTickerRateAPI.java @@ -0,0 +1,31 @@ +/************************************************************************************* + * Copyright (C) 2014 GENERAL BYTES s.r.o. All rights reserved. + * + * This software may be distributed and modified under the terms of the GNU + * General Public License version 2 (GPL2) as published by the Free Software + * Foundation and appearing in the file GPL2.TXT included in the packaging of + * this file. Please note that GPL2 Section 2[b] requires that all works based + * on this software must also be made publicly available under the terms of + * the GPL2 ("Copyleft"). + * + * Contact information + * ------------------- + * + * GENERAL BYTES s.r.o. + * Web : http://www.generalbytes.com + * + ************************************************************************************/ +package com.generalbytes.batm.server.extensions.extra.incognitocoin.sources; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +@Path("/") +@Produces(MediaType.APPLICATION_JSON) +public interface IIncognitocoinTickerRateAPI { + @GET + @Path("getticker?market=BTC-ICG") + IncognitocoinTickerResponse getTicker(); +} diff --git a/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/sources/IncognitocoinTickerRateSource.java b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/sources/IncognitocoinTickerRateSource.java new file mode 100644 index 0000000..265f2a3 --- /dev/null +++ b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/sources/IncognitocoinTickerRateSource.java @@ -0,0 +1,119 @@ +/************************************************************************************* + * Copyright (C) 2014 GENERAL BYTES s.r.o. All rights reserved. + * + * This software may be distributed and modified under the terms of the GNU + * General Public License version 2 (GPL2) as published by the Free Software + * Foundation and appearing in the file GPL2.TXT included in the packaging of + * this file. Please note that GPL2 Section 2[b] requires that all works based + * on this software must also be made publicly available under the terms of + * the GPL2 ("Copyleft"). + * + * Contact information + * ------------------- + * + * GENERAL BYTES s.r.o. + * Web : http://www.generalbytes.com + * + ************************************************************************************/ +package com.generalbytes.batm.server.extensions.extra.incognitocoin.sources; + +import com.generalbytes.batm.server.extensions.ICurrencies; +import com.generalbytes.batm.server.extensions.IRateSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import si.mazi.rescu.RestProxyFactory; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +public class IncognitocoinTickerRateSource implements IRateSource{ + private static final Logger log = LoggerFactory.getLogger(IncognitocoinTickerRateSource.class); + + private static HashMap rateAmounts = new HashMap(); + private static HashMap rateTimes = new HashMap(); + private static final long MAXIMUM_ALLOWED_TIME_OFFSET = 30 * 1000; //30sec + + private IIncognitocoinTickerRateAPI api; + + public IncognitocoinTickerRateSource() { + api = RestProxyFactory.createProxy(IIncognitocoinTickerRateAPI.class, "https://bittrex.com/api/v1.1/public"); + } + + @Override + public BigDecimal getExchangeRateLast(String cryptoCurrency, String fiatCurrency) { + if (!(ICurrencies.ICG.equalsIgnoreCase(cryptoCurrency))) { + return null; + } + if (!(ICurrencies.USD.equalsIgnoreCase(fiatCurrency) || ICurrencies.EUR.equalsIgnoreCase(fiatCurrency))) { + return null; + } + + String key = cryptoCurrency +"_" + fiatCurrency; + synchronized (rateAmounts) { + long now = System.currentTimeMillis(); + BigDecimal amount = rateAmounts.get(key); + if (amount == null) { + BigDecimal result = getExchangeRateLastSync(cryptoCurrency, fiatCurrency); + log.debug("Called MaxTicker exchange for rate: " + key + " = " + result); + rateAmounts.put(key,result); + rateTimes.put(key,now+MAXIMUM_ALLOWED_TIME_OFFSET); + return result; + }else { + Long expirationTime = rateTimes.get(key); + if (expirationTime > now) { + return rateAmounts.get(key); + }else{ + //do the job; + BigDecimal result = getExchangeRateLastSync(cryptoCurrency, fiatCurrency); + log.debug("Called MaxTicker exchange for rate: " + key + " = " + result); + rateAmounts.put(key,result); + rateTimes.put(key,now+MAXIMUM_ALLOWED_TIME_OFFSET); + return result; + } + } + } + + } + + private BigDecimal getExchangeRateLastSync(String cryptoCurrency, String fiatCurrency) { + if (!(ICurrencies.ICG.equalsIgnoreCase(cryptoCurrency))) { + return null; + } + if (!(ICurrencies.USD.equalsIgnoreCase(fiatCurrency) || ICurrencies.EUR.equalsIgnoreCase(fiatCurrency))) { + return null; + } + IncognitocoinTickerResponse ticker = api.getTicker(); + if (ticker != null) { + if (ICurrencies.USD.equalsIgnoreCase(fiatCurrency)){ + return ticker.getMpusd(); + }else if (ICurrencies.USD.equalsIgnoreCase(fiatCurrency)){ + return ticker.getBtceuro(); + } + return null; + } + return null; + } + + @Override + public Set getCryptoCurrencies() { + Set result = new HashSet(); + result.add(ICurrencies.ICG); + return result; + } + + @Override + public Set getFiatCurrencies() { + Set result = new HashSet(); + result.add(ICurrencies.USD); + result.add(ICurrencies.EUR); + return result; + } + + public static void main(String[] args) { + IncognitocoinTickerRateSource rs = new IncognitocoinTickerRateSource(); + BigDecimal exchangeRateLast = rs.getExchangeRateLast(ICurrencies.ICG, ICurrencies.USD); + System.out.println("exchangeRateLast = " + exchangeRateLast); + } +} diff --git a/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/sources/IncognitocoinTickerResponse.java b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/sources/IncognitocoinTickerResponse.java new file mode 100644 index 0000000..cc3d167 --- /dev/null +++ b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/sources/IncognitocoinTickerResponse.java @@ -0,0 +1,104 @@ +/************************************************************************************* + * Copyright (C) 2014 GENERAL BYTES s.r.o. All rights reserved. + * + * This software may be distributed and modified under the terms of the GNU + * General Public License version 2 (GPL2) as published by the Free Software + * Foundation and appearing in the file GPL2.TXT included in the packaging of + * this file. Please note that GPL2 Section 2[b] requires that all works based + * on this software must also be made publicly available under the terms of + * the GPL2 ("Copyleft"). + * + * Contact information + * ------------------- + * + * GENERAL BYTES s.r.o. + * Web : http://www.generalbytes.com + * + ************************************************************************************/ +package com.generalbytes.batm.server.extensions.extra.incognitocoin.sources; + +import java.math.BigDecimal; + +public class IncognitocoinTickerResponse { + private BigDecimal btcusd; + private BigDecimal btceuro; + private BigDecimal btcgbp; + private BigDecimal btccny; + private BigDecimal mpbtc; + private BigDecimal mpusd; + private BigDecimal mpeuro; + private BigDecimal mpgbp; + private BigDecimal mpcny; + + public BigDecimal getBtcusd() { + return btcusd; + } + + public void setBtcusd(BigDecimal btcusd) { + this.btcusd = btcusd; + } + + public BigDecimal getBtceuro() { + return btceuro; + } + + public void setBtceuro(BigDecimal btceuro) { + this.btceuro = btceuro; + } + + public BigDecimal getBtcgbp() { + return btcgbp; + } + + public void setBtcgbp(BigDecimal btcgbp) { + this.btcgbp = btcgbp; + } + + public BigDecimal getBtccny() { + return btccny; + } + + public void setBtccny(BigDecimal btccny) { + this.btccny = btccny; + } + + public BigDecimal getMpbtc() { + return mpbtc; + } + + public void setMpbtc(BigDecimal mpbtc) { + this.mpbtc = mpbtc; + } + + public BigDecimal getMpusd() { + return mpusd; + } + + public void setMpusd(BigDecimal mpusd) { + this.mpusd = mpusd; + } + + public BigDecimal getMpeuro() { + return mpeuro; + } + + public void setMpeuro(BigDecimal mpeuro) { + this.mpeuro = mpeuro; + } + + public BigDecimal getMpgbp() { + return mpgbp; + } + + public void setMpgbp(BigDecimal mpgbp) { + this.mpgbp = mpgbp; + } + + public BigDecimal getMpcny() { + return mpcny; + } + + public void setMpcny(BigDecimal mpcny) { + this.mpcny = mpcny; + } +} diff --git a/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/wallets/incognitocoind/IncognitocoindRPCWallet.java b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/wallets/incognitocoind/IncognitocoindRPCWallet.java new file mode 100644 index 0000000..a4c817a --- /dev/null +++ b/server_extensions_extra/src/com/generalbytes/batm/server/extensions/extra/incognitocoin/wallets/incognitocoind/IncognitocoindRPCWallet.java @@ -0,0 +1,120 @@ +/************************************************************************************* + * Copyright (C) 2014 GENERAL BYTES s.r.o. All rights reserved. + * + * This software may be distributed and modified under the terms of the GNU + * General Public License version 2 (GPL2) as published by the Free Software + * Foundation and appearing in the file GPL2.TXT included in the packaging of + * this file. Please note that GPL2 Section 2[b] requires that all works based + * on this software must also be made publicly available under the terms of + * the GPL2 ("Copyleft"). + * + * Contact information + * ------------------- + * + * GENERAL BYTES s.r.o. + * Web : http://www.generalbytes.com + * + ************************************************************************************/ +package com.generalbytes.batm.server.extensions.extra.incognitocoin.wallets.incognitocoind; + +import com.azazar.bitcoin.jsonrpcclient.BitcoinException; +import com.azazar.bitcoin.jsonrpcclient.BitcoinJSONRPCClient; +import com.generalbytes.batm.server.extensions.ICurrencies; +import com.generalbytes.batm.server.extensions.IWallet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigDecimal; +import java.net.MalformedURLException; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class IncognitocoindRPCWallet implements IWallet{ + private static final Logger log = LoggerFactory.getLogger(IncognitocoindRPCWallet.class); + private static final String CRYPTO_CURRENCY = ICurrencies.ICG; + + public IncognitocoindRPCWallet(String rpcURL, String accountName) { + this.rpcURL = rpcURL; + this.accountName = accountName; + } + + private String rpcURL; + private String accountName; + + @Override + public Set getCryptoCurrencies() { + Set result = new HashSet(); + result.add(CRYPTO_CURRENCY); + return result; + + } + + @Override + public String getPreferredCryptoCurrency() { + return CRYPTO_CURRENCY; + } + + @Override + public String sendCoins(String destinationAddress, BigDecimal amount, String cryptoCurrency) { + if (!CRYPTO_CURRENCY.equalsIgnoreCase(cryptoCurrency)) { + log.error("Incognitocoind wallet error: unknown cryptocurrency."); + return null; + } + + log.info("Incognitocoind sending coins from " + accountName + " to: " + destinationAddress + " " + amount); + try { + String result = getClient(rpcURL).sendFrom(accountName, destinationAddress,amount.doubleValue()); + log.debug("result = " + result); + return result; + } catch (BitcoinException e) { + e.printStackTrace(); + return null; + } + } + + @Override + public String getCryptoAddress(String cryptoCurrency) { + if (!CRYPTO_CURRENCY.equalsIgnoreCase(cryptoCurrency)) { + log.error("Incognitocoind wallet error: unknown cryptocurrency."); + return null; + } + + try { + List addressesByAccount = getClient(rpcURL).getAddressesByAccount(accountName); + if (addressesByAccount == null || addressesByAccount.size() == 0) { + return null; + }else{ + return addressesByAccount.get(0); + } + } catch (BitcoinException e) { + e.printStackTrace(); + return null; + } + } + + @Override + public BigDecimal getCryptoBalance(String cryptoCurrency) { + if (!CRYPTO_CURRENCY.equalsIgnoreCase(cryptoCurrency)) { + log.error("Incognitocoind wallet error: unknown cryptocurrency: " + cryptoCurrency); + return null; + } + try { + double balance = getClient(rpcURL).getBalance(accountName); + return new BigDecimal(balance); + } catch (BitcoinException e) { + e.printStackTrace(); + return null; + } + } + + private BitcoinJSONRPCClient getClient(String rpcURL) { + try { + return new BitcoinJSONRPCClient(rpcURL); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return null; + } + +}