diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..571e10c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +tab_width = 4 +trim_trailing_whitespace = true +insert_final_newline = false diff --git a/.gitignore b/.gitignore index 85d5d7f..12eeb40 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ out/ target install-libs.sh .mvn-repo +..gitignore.swp .project .classpath .settings/ diff --git a/README.md b/README.md index a1f2f9f..fd098bc 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Here is the list of functionality that can be extended with extenstions API: Content ======= * **server_extensions_api** - contains extension api that all extensions use to extend BATM Server's functionality. -* **server_extensions_extra** - reference extension implementation that implements BTC, LTC, DASH,FLASH, DOGE, NLG, ICG, NBT, GRS and MAX coin support functionality. +* **server_extensions_extra** - reference extension implementation that implements BTC, LTC, DGB, DASH, FLASH, DOGE, NLG, ICG, NBT, GRS and MAX coin support functionality. * **server_extensions_test** - contains tester for testing the extensions without requirement of having a BATM server Note for developers diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a5fe1cb..91ca28c 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 43b9ff6..16d2805 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Feb 02 13:42:34 CET 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-all.zip diff --git a/server_extensions_api/build.gradle b/server_extensions_api/build.gradle index 7540019..c853918 100644 --- a/server_extensions_api/build.gradle +++ b/server_extensions_api/build.gradle @@ -8,6 +8,7 @@ version = projectVersion jar { baseName 'batm_server_extensions_api' + archiveName "${baseName}.${extension}" } distributions { @@ -25,20 +26,22 @@ dependencies { compile(group: 'com.sun.mail', name: 'javax.mail', version: '1.4.7') } -publishing { - repositories { - maven { - credentials { - username gbArtifactoryUser - password gbArtifactoryPassword +if (hasProperty('gbArtifactoryUser') && hasProperty('gbArtifactoryPassword') && hasProperty('gbArtifactoryUploadUrl')) { + publishing { + repositories { + maven { + credentials { + username gbArtifactoryUser + password gbArtifactoryPassword + } + url gbArtifactoryUploadUrl } - url gbArtifactoryUploadUrl } - } - publications { - mavenJava(MavenPublication) { - from components.java + publications { + mavenJava(MavenPublication) { + from components.java + } } } } \ No newline at end of file diff --git a/server_extensions_api/src/main/java/com/generalbytes/batm/server/extensions/Currencies.java b/server_extensions_api/src/main/java/com/generalbytes/batm/server/extensions/Currencies.java index 10255e1..1f3801d 100644 --- a/server_extensions_api/src/main/java/com/generalbytes/batm/server/extensions/Currencies.java +++ b/server_extensions_api/src/main/java/com/generalbytes/batm/server/extensions/Currencies.java @@ -31,8 +31,10 @@ public class Currencies { public static final String VIA = "VIA"; public static final String DEX = "DEX"; public static final String DASH = "DASH"; + public static final String DGB = "DGB"; public static final String DOGE = "DOGE"; public static final String FLASH = "FLASH";// FLASH Coin + public static final String FTO = "FTO"; public static final String MAX = "MAX"; public static final String LEO = "LEO"; public static final String NLG = "NLG"; @@ -75,6 +77,7 @@ public class Currencies { crypto.add(VIA); crypto.add(DEX); crypto.add(DASH); + crypto.add(DGB); crypto.add(DOGE); crypto.add(FLASH); crypto.add(MAX); diff --git a/server_extensions_extra/build.gradle b/server_extensions_extra/build.gradle index 7da0690..bc98d20 100644 --- a/server_extensions_extra/build.gradle +++ b/server_extensions_extra/build.gradle @@ -8,6 +8,7 @@ version = projectVersion jar { baseName 'batm_server_extensions_extra' + archiveName "${baseName}.${extension}" } configurations { @@ -22,13 +23,15 @@ artifacts { } dependencies { - compile project(':server_extensions_api'); + compile project(':server_extensions_api') compile(group: 'com.azazar', name: 'bitcoin-json-rpc-client', version: '1.0') compile(group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25') compile(group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25') compile(group: 'com.github.mmazi', name: 'rescu', version: '1.9.1') compile(group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0.1') compile(group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.8.0') + compile(group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.2') + compile(group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.8.2') compile(group: 'org.knowm.xchange', name: 'xchange-core', version: '4.2.1') compile(group: 'com.google.guava', name: 'guava', version: '18.0') compile(group: 'com.google.zxing', name: 'core', version: '2.3.0') @@ -49,20 +52,22 @@ distributions { } } -publishing { - repositories { - maven { - credentials { - username gbArtifactoryUser - password gbArtifactoryPassword +if (hasProperty('gbArtifactoryUser') && hasProperty('gbArtifactoryPassword') && hasProperty('gbArtifactoryUploadUrl')) { + publishing { + repositories { + maven { + credentials { + username gbArtifactoryUser + password gbArtifactoryPassword + } + url gbArtifactoryUploadUrl } - url gbArtifactoryUploadUrl } - } - publications { - mavenJava(MavenPublication) { - from components.java + publications { + mavenJava(MavenPublication) { + from components.java + } } } -} \ No newline at end of file +} diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/DigiByteAddressValidator.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/DigiByteAddressValidator.java new file mode 100644 index 0000000..f55acbc --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/DigiByteAddressValidator.java @@ -0,0 +1,64 @@ +/************************************************************************************* + * Copyright (C) 2014-2016 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.digibyte; + +import com.generalbytes.batm.server.coinutil.AddressFormatException; +import com.generalbytes.batm.server.coinutil.Base58; +import com.generalbytes.batm.server.extensions.ICryptoAddressValidator; + +public class DigiByteAddressValidator implements ICryptoAddressValidator { + + @Override + public boolean isAddressValid(String address) { + //For whatever reason this may occur, cover the case + String lowercase = address.toLowerCase(); + if (lowercase.startsWith("d") || lowercase.startsWith("3") || lowercase.startsWith("s")) { + char[] addressChars = address.toCharArray(); + //Check for invalid characters; ensure alphanumeric and no forbidden characters exist + for (char addressCharacter : addressChars) { + if (!(((addressCharacter >= '0' && addressCharacter <= '9') || + (addressCharacter >= 'a' && addressCharacter <= 'z') || + (addressCharacter >= 'A' && addressCharacter <= 'Z')) && + addressCharacter != 'l' && addressCharacter != 'I' && + addressCharacter != '0' && addressCharacter != 'O')) { + return false; + } + } + try { + Base58.decodeToBigInteger(address); + Base58.decodeChecked(address); + return true; + } catch (AddressFormatException e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + + @Override + public boolean isPaperWalletSupported() { + return false; + } + + @Override + public boolean mustBeBase58Address() { + return true; + } +} \ No newline at end of file diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/DigiByteExtension.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/DigiByteExtension.java new file mode 100644 index 0000000..bc20129 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/DigiByteExtension.java @@ -0,0 +1,143 @@ +/************************************************************************************* + * Copyright (C) 2014-2016 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.digibyte; + +import com.generalbytes.batm.server.extensions.Currencies; +import com.generalbytes.batm.server.extensions.ICryptoAddressValidator; +import com.generalbytes.batm.server.extensions.IExchange; +import com.generalbytes.batm.server.extensions.IExtension; +import com.generalbytes.batm.server.extensions.IPaperWalletGenerator; +import com.generalbytes.batm.server.extensions.IPaymentProcessor; +import com.generalbytes.batm.server.extensions.IRateSource; +import com.generalbytes.batm.server.extensions.IWallet; +import com.generalbytes.batm.server.extensions.extra.digibyte.sources.FixPriceRateSource; +import com.generalbytes.batm.server.extensions.extra.digibyte.sources.livecoin.LiveCoinRateSource; +import com.generalbytes.batm.server.extensions.extra.digibyte.wallets.digibyted.DigiByteRPCWallet; +import com.generalbytes.batm.server.extensions.watchlist.IWatchList; + +import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Set; +import java.util.StringTokenizer; + +public class DigiByteExtension implements IExtension { + + @Override + public String getName() { + return "BATM DigiByte extra extension"; + } + + @Override + public IExchange createExchange(String exchangeLogin) { + return null; + } + + @Override + public IPaymentProcessor createPaymentProcessor(String paymentProcessorLogin) { + return null; //no payment processors available + } + + @Override + public IWallet createWallet(String walletLogin) { + if (walletLogin != null && !walletLogin.trim().isEmpty()) { + StringTokenizer st = new StringTokenizer(walletLogin, ":"); + String walletType = st.nextToken(); + + if ("digibyted".equalsIgnoreCase(walletType)) { + //"digibyted: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 DigiByteRPCWallet(rpcURL, accountName); + } + } + } + return null; + } + + @Override + public ICryptoAddressValidator createAddressValidator(String cryptoCurrency) { + if (Currencies.DGB.equalsIgnoreCase(cryptoCurrency)) { + return new DigiByteAddressValidator(); + } + 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 ("digibytefix".equalsIgnoreCase(exchangeType)) { + BigDecimal rate = BigDecimal.ZERO; + if (st.hasMoreTokens()) { + try { + rate = new BigDecimal(st.nextToken()); + } catch (Throwable e) { + } + } + String preferedFiatCurrency = Currencies.USD; + if (st.hasMoreTokens()) { + preferedFiatCurrency = st.nextToken().toUpperCase(); + } + return new FixPriceRateSource(rate, preferedFiatCurrency); + } else if ("livecoin".equalsIgnoreCase(exchangeType)) { + String preferedFiatCurrency = Currencies.USD; + if (st.hasMoreTokens()) { + preferedFiatCurrency = st.nextToken().toUpperCase(); + } + return new LiveCoinRateSource(preferedFiatCurrency); + } + } + return null; + } + + @Override + public Set getSupportedCryptoCurrencies() { + Set result = new HashSet(); + result.add(Currencies.DGB); + return result; + } + + @Override + public Set getSupportedWatchListsNames() { + return null; + } + + @Override + public IWatchList getWatchList(String name) { + return null; + } +} \ No newline at end of file diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/sources/FixPriceRateSource.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/sources/FixPriceRateSource.java new file mode 100644 index 0000000..805baad --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/sources/FixPriceRateSource.java @@ -0,0 +1,61 @@ +package com.generalbytes.batm.server.extensions.extra.digibyte.sources; + +import com.generalbytes.batm.server.extensions.Currencies; +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; + + private String preferedFiatCurrency = Currencies.USD; + + public FixPriceRateSource(BigDecimal rate, String preferedFiatCurrency) { + this.rate = rate; + if (Currencies.EUR.equalsIgnoreCase(preferedFiatCurrency)) { + this.preferedFiatCurrency = Currencies.EUR; + } + if (Currencies.USD.equalsIgnoreCase(preferedFiatCurrency)) { + this.preferedFiatCurrency = Currencies.USD; + } + if (Currencies.CAD.equalsIgnoreCase(preferedFiatCurrency)) { + this.preferedFiatCurrency = Currencies.CAD; + } + } + + @Override + public Set getCryptoCurrencies() { + Set result = new HashSet(); + result.add(Currencies.DGB); + return result; + } + + @Override + public BigDecimal getExchangeRateLast(String cryptoCurrency, String fiatCurrency) { + if (Currencies.DGB.equalsIgnoreCase(cryptoCurrency)) { + return rate; + } + return null; + } + + @Override + public Set getFiatCurrencies() { + Set result = new HashSet(); + result.add(Currencies.CAD); + result.add(Currencies.USD); + result.add(Currencies.EUR); + return result; + } + + @Override + public String getPreferredFiatCurrency() { + return preferedFiatCurrency; + } + +} \ No newline at end of file diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/sources/livecoin/ILiveCoinAPI.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/sources/livecoin/ILiveCoinAPI.java new file mode 100644 index 0000000..1e19cd7 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/sources/livecoin/ILiveCoinAPI.java @@ -0,0 +1,16 @@ +package com.generalbytes.batm.server.extensions.extra.digibyte.sources.livecoin; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +@Path("/exchange") +@Produces(MediaType.APPLICATION_JSON) +public interface ILiveCoinAPI { + + @GET + @Path("/ticker?currencyPair={currencyPair}") + LiveCoinTicker getTicker(@PathParam("currencyPair") String currencyPair); +} diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/sources/livecoin/LiveCoinRateSource.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/sources/livecoin/LiveCoinRateSource.java new file mode 100644 index 0000000..96a79c3 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/sources/livecoin/LiveCoinRateSource.java @@ -0,0 +1,68 @@ +package com.generalbytes.batm.server.extensions.extra.digibyte.sources.livecoin; + +import com.generalbytes.batm.server.extensions.Currencies; +import com.generalbytes.batm.server.extensions.IRateSource; + +import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Set; + +import si.mazi.rescu.RestProxyFactory; + +public class LiveCoinRateSource implements IRateSource { + + private ILiveCoinAPI api; + + private String preferredFiatCurrency = Currencies.USD; + + public LiveCoinRateSource(String preferedFiatCurrency) { + if (Currencies.EUR.equalsIgnoreCase(preferedFiatCurrency)) { + this.preferredFiatCurrency = Currencies.EUR; + } + if (Currencies.USD.equalsIgnoreCase(preferedFiatCurrency)) { + this.preferredFiatCurrency = Currencies.USD; + } + api = RestProxyFactory.createProxy(ILiveCoinAPI.class, "https://api.livecoin.net"); + } + + + @Override + public Set getCryptoCurrencies() { + Set result = new HashSet(); + result.add(Currencies.DGB); + return result; + } + + @Override + public Set getFiatCurrencies() { + Set result = new HashSet(); + result.add(Currencies.USD); + result.add(Currencies.EUR); + return result; + } + + @Override + public BigDecimal getExchangeRateLast(String cryptoCurrency, String fiatCurrency) { + if (!getFiatCurrencies().contains(fiatCurrency) || !getCryptoCurrencies().contains(cryptoCurrency)) { + return null; + } + //Grab the last dgb rate in btc + LiveCoinTicker dgbBtc = api.getTicker(Currencies.DGB + "/" + Currencies.BTC); + + //Grab the last btc rate in the selected fiat currency + LiveCoinTicker btcFiat = api.getTicker(Currencies.BTC + "/" + fiatCurrency); + + BigDecimal lastDgbPriceInBtc = dgbBtc.getLast(); + BigDecimal lastBtcPriceInFiat = btcFiat.getLast(); + + //Multiply the last dgb/btc rate by the last btc/fiat rate to get the last dgb/fiat rate + BigDecimal lastDgbPriceInFiat = lastDgbPriceInBtc.multiply(lastBtcPriceInFiat); + + return lastDgbPriceInFiat; + } + + @Override + public String getPreferredFiatCurrency() { + return preferredFiatCurrency; + } +} \ No newline at end of file diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/sources/livecoin/LiveCoinTicker.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/sources/livecoin/LiveCoinTicker.java new file mode 100644 index 0000000..3cc6267 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/sources/livecoin/LiveCoinTicker.java @@ -0,0 +1,14 @@ +package com.generalbytes.batm.server.extensions.extra.digibyte.sources.livecoin; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.math.BigDecimal; + +public class LiveCoinTicker { + + @JsonProperty("last") + private BigDecimal last; + + public BigDecimal getLast() { + return last; + } +} \ No newline at end of file diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/wallets/digibyted/DigiByteRPCWallet.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/wallets/digibyted/DigiByteRPCWallet.java new file mode 100644 index 0000000..5d7246b --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/digibyte/wallets/digibyted/DigiByteRPCWallet.java @@ -0,0 +1,124 @@ +/************************************************************************************* + * Copyright (C) 2014-2016 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.digibyte.wallets.digibyted; + +import com.azazar.bitcoin.jsonrpcclient.BitcoinException; +import com.azazar.bitcoin.jsonrpcclient.BitcoinJSONRPCClient; +import com.generalbytes.batm.server.extensions.Currencies; +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 DigiByteRPCWallet implements IWallet { + + private static final Logger log = LoggerFactory.getLogger(DigiByteRPCWallet.class); + private static final String CRYPTO_CURRENCY = Currencies.DGB; + + public DigiByteRPCWallet(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, + String description) { + if (!CRYPTO_CURRENCY.equalsIgnoreCase(cryptoCurrency)) { + log.error("Digibyted wallet error: unknown cryptocurrency."); + return null; + } + + log.info("Digibyted 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("Digibyted 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("Digibyted wallet error: unknown cryptocurrency: " + cryptoCurrency); + return null; + } + try { + double balance = getClient(rpcURL).getBalance(accountName); + return BigDecimal.valueOf(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; + } +} \ No newline at end of file diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/FuturocoinAddressValidator.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/FuturocoinAddressValidator.java new file mode 100644 index 0000000..bf270d5 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/FuturocoinAddressValidator.java @@ -0,0 +1,34 @@ +package com.generalbytes.batm.server.extensions.extra.futurocoin; + +import com.generalbytes.batm.server.coinutil.AddressFormatException; +import com.generalbytes.batm.server.coinutil.Base58; +import com.generalbytes.batm.server.extensions.ICryptoAddressValidator; + +public class FuturocoinAddressValidator implements ICryptoAddressValidator { + + @Override + public boolean isAddressValid(String address) { + if (address.startsWith("F") || address.startsWith("6")) { + try { + Base58.decodeToBigInteger(address); + Base58.decodeChecked(address); + } catch (AddressFormatException e) { + e.printStackTrace(); + return false; + } + return true; + }else{ + return false; + } + } + + @Override + public boolean mustBeBase58Address() { + return true; + } + + @Override + public boolean isPaperWalletSupported() { + return false; + } +} diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/FuturocoinExtension.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/FuturocoinExtension.java new file mode 100644 index 0000000..14cca7b --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/FuturocoinExtension.java @@ -0,0 +1,130 @@ +/************************************************************************************* + * Copyright (C) 2014-2016 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.futurocoin; + +import com.generalbytes.batm.server.extensions.*; +import com.generalbytes.batm.server.extensions.extra.futurocoin.sources.FixPriceRateSource; +import com.generalbytes.batm.server.extensions.extra.futurocoin.sources.yobit.YobitRateSource; +import com.generalbytes.batm.server.extensions.extra.futurocoin.wallets.futurocoind.FuturocoinRPCWallet; +import com.generalbytes.batm.server.extensions.watchlist.IWatchList; + +import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Set; +import java.util.StringTokenizer; + +public class FuturocoinExtension implements IExtension{ + @Override + public String getName() { + return "BATM Futurocoin extra extension"; + } + + @Override + public IExchange createExchange(String exchangeLogin) { + return null; + } + + @Override + public IPaymentProcessor createPaymentProcessor(String paymentProcessorLogin) { + return null; //no payment processors available + } + + @Override + public IWallet createWallet(String walletLogin) { + if (walletLogin !=null && !walletLogin.trim().isEmpty()) { + StringTokenizer st = new StringTokenizer(walletLogin,":"); + String walletType = st.nextToken(); + + if ("futurocoind".equalsIgnoreCase(walletType)) { + 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 FuturocoinRPCWallet(rpcURL,accountName); + } + } + + } + return null; + } + + @Override + public ICryptoAddressValidator createAddressValidator(String cryptoCurrency) { + if (Currencies.FTO.equalsIgnoreCase(cryptoCurrency)) { + return new FuturocoinAddressValidator(); + } + 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 ("futurocoinfix".equalsIgnoreCase(exchangeType)) { + BigDecimal rate = BigDecimal.ZERO; + if (st.hasMoreTokens()) { + try { + rate = new BigDecimal(st.nextToken()); + } catch (Throwable e) { + } + } + String preferedFiatCurrency = Currencies.USD; + if (st.hasMoreTokens()) { + preferedFiatCurrency = st.nextToken().toUpperCase(); + } + return new FixPriceRateSource(rate, preferedFiatCurrency); + } else if ("yobit".equalsIgnoreCase(exchangeType)) { + return new YobitRateSource(); + } + } + return null; + } + + @Override + public Set getSupportedCryptoCurrencies() { + Set result = new HashSet(); + result.add(Currencies.FTO); + return result; + } + + @Override + public Set getSupportedWatchListsNames() { + return null; + } + + @Override + public IWatchList getWatchList(String name) { + return null; + } +} diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/FixPriceRateSource.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/FixPriceRateSource.java new file mode 100644 index 0000000..ca1eac6 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/FixPriceRateSource.java @@ -0,0 +1,50 @@ +package com.generalbytes.batm.server.extensions.extra.futurocoin.sources; + +import com.generalbytes.batm.server.extensions.Currencies; +import com.generalbytes.batm.server.extensions.IRateSource; + +import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Set; + +/** + * Created by woolly_sammoth on 11/12/14. + */ +public class FixPriceRateSource implements IRateSource { + private BigDecimal rate = BigDecimal.ZERO; + + private String preferedFiatCurrency = Currencies.USD; + + public FixPriceRateSource(BigDecimal rate, String preferedFiatCurrency) { + this.rate = rate; + if (Currencies.USD.equalsIgnoreCase(preferedFiatCurrency)) { + this.preferedFiatCurrency = Currencies.USD; + } + } + + @Override + public Set getCryptoCurrencies() { + Set result = new HashSet(); + result.add(Currencies.FTO); + return result; + } + + @Override + public BigDecimal getExchangeRateLast(String cryptoCurrency, String fiatCurrency) { + if (Currencies.FTO.equalsIgnoreCase(cryptoCurrency)) { + return rate; + } + return null; + } + + @Override + public Set getFiatCurrencies() { + Set result = new HashSet(); + result.add(Currencies.USD); + return result; + } + @Override + public String getPreferredFiatCurrency() { + return preferedFiatCurrency; + } +} diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/yobit/IYobitAPI.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/yobit/IYobitAPI.java new file mode 100644 index 0000000..f89f839 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/yobit/IYobitAPI.java @@ -0,0 +1,17 @@ +package com.generalbytes.batm.server.extensions.extra.futurocoin.sources.yobit; + +import com.generalbytes.batm.server.extensions.extra.futurocoin.sources.yobit.dto.YobitResponse; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +@Path("/api/3/") +@Produces(MediaType.APPLICATION_JSON) +public interface IYobitAPI { + @GET + @Path("ticker/{cryptocurrency}_{fiatcurrency}") + YobitResponse getTicker(@PathParam("cryptocurrency") String cryptoCurrency, @PathParam("fiatcurrency") String fiatCurrency); +} \ No newline at end of file diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/yobit/YobitRateSource.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/yobit/YobitRateSource.java new file mode 100644 index 0000000..bb515f9 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/yobit/YobitRateSource.java @@ -0,0 +1,49 @@ +package com.generalbytes.batm.server.extensions.extra.futurocoin.sources.yobit; + +import com.generalbytes.batm.server.extensions.Currencies; +import com.generalbytes.batm.server.extensions.IRateSource; +import com.generalbytes.batm.server.extensions.extra.futurocoin.sources.yobit.dto.YobitResponse; + +import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Set; + +import si.mazi.rescu.RestProxyFactory; + +public class YobitRateSource implements IRateSource { + + private IYobitAPI api; + + public YobitRateSource() { + api = RestProxyFactory.createProxy(IYobitAPI.class, "https://yobit.net"); + } + + @Override + public Set getCryptoCurrencies() { + Set result = new HashSet(); + result.add(Currencies.FTO); + return result; + } + + @Override + public Set getFiatCurrencies() { + Set result = new HashSet(); + result.add(Currencies.USD); + return result; + } + + @Override + public BigDecimal getExchangeRateLast(String cryptoCurrency, String fiatCurrency) { + if (!getFiatCurrencies().contains(fiatCurrency) || !getCryptoCurrencies().contains(cryptoCurrency)) { + return null; + } + + YobitResponse response = api.getTicker(cryptoCurrency.toLowerCase(), fiatCurrency.toLowerCase()); + return response.getFto_usd().getLast(); + } + + @Override + public String getPreferredFiatCurrency() { + return Currencies.USD; + } +} diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/yobit/dto/Ticker.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/yobit/dto/Ticker.java new file mode 100644 index 0000000..f9579ab --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/yobit/dto/Ticker.java @@ -0,0 +1,87 @@ +package com.generalbytes.batm.server.extensions.extra.futurocoin.sources.yobit.dto; + +import java.math.BigDecimal; + +public class Ticker { + private BigDecimal high; + private BigDecimal low; + private BigDecimal avg; + private BigDecimal vol; + private BigDecimal vol_cur; + private BigDecimal last; + private BigDecimal buy; + private BigDecimal sell; + private long updated; + + public BigDecimal getHigh() { + return high; + } + + public void setHigh(BigDecimal high) { + this.high = high; + } + + public BigDecimal getLow() { + return low; + } + + public void setLow(BigDecimal low) { + this.low = low; + } + + public BigDecimal getAvg() { + return avg; + } + + public void setAvg(BigDecimal avg) { + this.avg = avg; + } + + public BigDecimal getVol() { + return vol; + } + + public void setVol(BigDecimal vol) { + this.vol = vol; + } + + public BigDecimal getVol_cur() { + return vol_cur; + } + + public void setVol_cur(BigDecimal vol_cur) { + this.vol_cur = vol_cur; + } + + public BigDecimal getLast() { + return last; + } + + public void setLast(BigDecimal last) { + this.last = last; + } + + public BigDecimal getBuy() { + return buy; + } + + public void setBuy(BigDecimal buy) { + this.buy = buy; + } + + public BigDecimal getSell() { + return sell; + } + + public void setSell(BigDecimal sell) { + this.sell = sell; + } + + public long getUpdated() { + return updated; + } + + public void setUpdated(long updated) { + this.updated = updated; + } +} diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/yobit/dto/YobitResponse.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/yobit/dto/YobitResponse.java new file mode 100644 index 0000000..8f2e2d7 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/sources/yobit/dto/YobitResponse.java @@ -0,0 +1,13 @@ +package com.generalbytes.batm.server.extensions.extra.futurocoin.sources.yobit.dto; + +public class YobitResponse { + private Ticker fot_usd; + + public Ticker getFto_usd() { + return fot_usd; + } + + public void setFot_usd(Ticker fot_usd) { + this.fot_usd = fot_usd; + } +} diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/wallets/futurocoind/FuturocoinRPCWallet.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/wallets/futurocoind/FuturocoinRPCWallet.java new file mode 100644 index 0000000..74f7927 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/futurocoin/wallets/futurocoind/FuturocoinRPCWallet.java @@ -0,0 +1,104 @@ +package com.generalbytes.batm.server.extensions.extra.futurocoin.wallets.futurocoind; + +import com.azazar.bitcoin.jsonrpcclient.BitcoinException; +import com.azazar.bitcoin.jsonrpcclient.BitcoinJSONRPCClient; +import com.generalbytes.batm.server.extensions.Currencies; +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 FuturocoinRPCWallet implements IWallet { + + private static final Logger log = LoggerFactory.getLogger(FuturocoinRPCWallet.class); + private static final String CRYPTO_CURRENCY = Currencies.FTO; + + public FuturocoinRPCWallet(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, String description) { + if (!CRYPTO_CURRENCY.equalsIgnoreCase(cryptoCurrency)) { + log.error("Futurocoind wallet error: unknown cryptocurrency."); + return null; + } + + log.info("Futurocoind 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("Futurocoind 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("Futurocoind wallet error: unknown cryptocurrency: " + cryptoCurrency); + return null; + } + try { + double balance = getClient(rpcURL).getBalance(accountName); + return BigDecimal.valueOf(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; + } +} diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/maxcoin/sources/MaxcoinTickerRateSource.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/maxcoin/sources/MaxcoinTickerRateSource.java index 28d6070..7f0589a 100644 --- a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/maxcoin/sources/MaxcoinTickerRateSource.java +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/maxcoin/sources/MaxcoinTickerRateSource.java @@ -17,7 +17,6 @@ ************************************************************************************/ package com.generalbytes.batm.server.extensions.extra.maxcoin.sources; -import com.generalbytes.batm.server.extensions.Currencies; import com.generalbytes.batm.server.extensions.Currencies; import com.generalbytes.batm.server.extensions.IRateSource; import org.slf4j.Logger; diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/SmartcashExtension.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/SmartcashExtension.java index c80590b..5fc47dc 100644 --- a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/SmartcashExtension.java +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/SmartcashExtension.java @@ -19,6 +19,7 @@ package com.generalbytes.batm.server.extensions.extra.smartcash; import com.generalbytes.batm.server.extensions.*; import com.generalbytes.batm.server.extensions.extra.smartcash.sources.FixPriceRateSource; +import com.generalbytes.batm.server.extensions.extra.smartcash.sources.smartcash.SmartCashRateSource; import com.generalbytes.batm.server.extensions.extra.smartcash.wallets.smartcashd.SmartcashRPCWallet; import com.generalbytes.batm.server.extensions.watchlist.IWatchList; @@ -99,6 +100,12 @@ public class SmartcashExtension implements IExtension{ preferedFiatCurrency = st.nextToken().toUpperCase(); } return new FixPriceRateSource(rate,preferedFiatCurrency); + }else if ("smartapi".equalsIgnoreCase(exchangeType)) { + String preferredFiatCurrency = Currencies.USD; + if (st.hasMoreTokens()) { + preferredFiatCurrency = st.nextToken(); + } + return new SmartCashRateSource(preferredFiatCurrency); } } diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/sources/smartcash/APIResponse.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/sources/smartcash/APIResponse.java new file mode 100644 index 0000000..1e51207 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/sources/smartcash/APIResponse.java @@ -0,0 +1,68 @@ +/* ## +# Part of the SmartCash API price extension +# +# Copyright 2018 dustinface +# Created 29.04.2018 +# +* 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"). +# +## */ + +package com.generalbytes.batm.server.extensions.extra.smartcash.sources.smartcash; + +import java.math.BigDecimal; +import java.lang.reflect.Field; + +public class APIResponse { + + public BigDecimal count; + public Item[] items; + public Last last; + public String resource; + public BigDecimal status; + public BigDecimal execution; + + public static class Item { + public String updated; + public Currency currencies; + } + + public static class Currency { + public BigDecimal USD; + public BigDecimal EUR; + public BigDecimal CHF; + public BigDecimal CAD; + public BigDecimal AUD; + public BigDecimal GBP; + public BigDecimal BRL; + public BigDecimal VEF; + public BigDecimal SGD; + public BigDecimal KRW; + public BigDecimal JPY; + } + + public class Last { + public String id; + public String created; + } + + public BigDecimal getPrice(String fiatCurrency) { + + BigDecimal price = null; + + try { + Field field = this.items[0].currencies.getClass().getDeclaredField(fiatCurrency); + field.setAccessible(true); + price = (BigDecimal)field.get(this.items[0].currencies); + } catch (Exception e){ + + } + + return price; + } +} diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/sources/smartcash/ISmartCashAPI.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/sources/smartcash/ISmartCashAPI.java new file mode 100644 index 0000000..e95f8b4 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/sources/smartcash/ISmartCashAPI.java @@ -0,0 +1,31 @@ +/* ## +# Part of the SmartCash API price extension +# +# Copyright 2018 dustinface +# Created 29.04.2018 +# +* 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"). +# +## */ + +package com.generalbytes.batm.server.extensions.extra.smartcash.sources.smartcash; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +@Path("/v1/") +@Produces(MediaType.APPLICATION_JSON) +public interface ISmartCashAPI { + + @GET + @Path("exchange/currencies?limit=2") + public APIResponse returnResponse(); +} diff --git a/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/sources/smartcash/SmartCashRateSource.java b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/sources/smartcash/SmartCashRateSource.java new file mode 100644 index 0000000..2757c72 --- /dev/null +++ b/server_extensions_extra/src/main/java/com/generalbytes/batm/server/extensions/extra/smartcash/sources/smartcash/SmartCashRateSource.java @@ -0,0 +1,127 @@ +/* ## +# Part of the SmartCash API price extension +# +# Copyright 2018 dustinface +# Created 29.04.2018 +# +* 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"). +# +## */ + +package com.generalbytes.batm.server.extensions.extra.smartcash.sources.smartcash; + +import com.generalbytes.batm.server.extensions.Currencies; +import com.generalbytes.batm.server.extensions.Currencies; +import com.generalbytes.batm.server.extensions.IRateSource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import si.mazi.rescu.ClientConfig; +import si.mazi.rescu.RestProxyFactory; +import si.mazi.rescu.serialization.jackson.DefaultJacksonObjectMapperFactory; +import si.mazi.rescu.serialization.jackson.JacksonObjectMapperFactory; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.lang.reflect.Field; + +public class SmartCashRateSource implements IRateSource{ + private static final Logger log = LoggerFactory.getLogger(SmartCashRateSource.class); + + private String preferedFiatCurrency; + private ISmartCashAPI api; + + private static HashMap rateAmounts = new HashMap(); + private static HashMap rateTimes = new HashMap(); + private static final long MAXIMUM_ALLOWED_TIME_OFFSET = 30 * 1000; //30sec + + public SmartCashRateSource(String preferedFiatCurrency) { + + if (!getFiatCurrencies().contains(preferedFiatCurrency)) { + preferedFiatCurrency = Currencies.USD; + } + + this.preferedFiatCurrency = preferedFiatCurrency; + + api = RestProxyFactory.createProxy(ISmartCashAPI.class, "https://api.smartcash.cc"); + } + + @Override + public Set getFiatCurrencies() { + Set fiatCurrencies = new HashSet(); + + Field[] fields = APIResponse.Currency.class.getFields(); + + for (Field f : fields) { + fiatCurrencies.add(f.getName()); + } + + return fiatCurrencies; + } + + @Override + public String getPreferredFiatCurrency() { + return this.preferedFiatCurrency; + } + + @Override + public Set getCryptoCurrencies() { + Set result = new HashSet(); + result.add(Currencies.SMART); + return result; + } + + @Override + public BigDecimal getExchangeRateLast(String cryptoCurrency, String fiatCurrency) { + + 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 smartcash 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 smartcash 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 (!Currencies.SMART.equalsIgnoreCase(cryptoCurrency)) { + return null; //unsupported currency + } + APIResponse response = api.returnResponse(); + + if (response != null) { + return response.getPrice(fiatCurrency); + } + + return null; + } + +} diff --git a/server_extensions_extra/src/main/resources/batm-extensions.xml b/server_extensions_extra/src/main/resources/batm-extensions.xml index 7146710..23ac2c9 100644 --- a/server_extensions_extra/src/main/resources/batm-extensions.xml +++ b/server_extensions_extra/src/main/resources/batm-extensions.xml @@ -227,6 +227,26 @@ + + + + + + + + + DGB + + + + DGB + + + + DGB + + + @@ -327,6 +347,10 @@ SMART + + + SMART + @@ -432,6 +456,25 @@ BTX - + + + + + + + + + + FTO + + + FTO + + + + FTO + + + diff --git a/server_extensions_extra/src/main/resources/digibyte.png b/server_extensions_extra/src/main/resources/digibyte.png new file mode 100644 index 0000000..592454a Binary files /dev/null and b/server_extensions_extra/src/main/resources/digibyte.png differ diff --git a/server_extensions_extra/src/main/resources/fto.png b/server_extensions_extra/src/main/resources/fto.png new file mode 100644 index 0000000..350b38a Binary files /dev/null and b/server_extensions_extra/src/main/resources/fto.png differ