Skip to content

Commit

Permalink
blockchain proxy through explorer
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardstock committed Oct 1, 2018
1 parent 283049e commit 8699643
Show file tree
Hide file tree
Showing 9 changed files with 285 additions and 19 deletions.
7 changes: 7 additions & 0 deletions RELEASE.md
@@ -1,5 +1,12 @@
# Release notes

## 0.2.3
- added proxy methods for blockchain node through the Explorer:
- send transaction
- calculate transaction fee by transaction hash
- coin exchange currency (sell/buy)
- counting transactions by address to get **nonce**

## 0.2.2
- package dependencies fix

Expand Down
16 changes: 9 additions & 7 deletions build.gradle
Expand Up @@ -30,7 +30,7 @@ buildscript {
mavenLocal()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0-rc03'
classpath 'com.android.tools.build:gradle:3.2.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
}
}
Expand All @@ -55,14 +55,15 @@ apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.bintray'

group = 'network.minter.android'
version = '0.2.2'
version = '0.2.3'

ext {
minterMinSdk = 16
minterMaxSdk = 28
minterBuildTools = "28.0.2"
minterLibSupport = "27.1.1"
minterCoreVers = "0.1.3"
minterLibSupport = "28.0.0"
minterCoreSDK = "0.1.3"
minterBlockchainSDK = "0.1.4"
pomDescription = "Minter Android Explorer API SDK"
}

Expand Down Expand Up @@ -116,8 +117,10 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])

netTestImplementation "network.minter.android:minter-android-core-testnet:${minterCoreVers}"
netMainImplementation "network.minter.android:minter-android-core:${minterCoreVers}"
netTestImplementation "network.minter.android:minter-android-core-testnet:${minterCoreSDK}"
netMainImplementation "network.minter.android:minter-android-core:${minterCoreSDK}"
netTestImplementation "network.minter.android:minter-android-blockchain-testnet:${minterBlockchainSDK}"
netMainImplementation "network.minter.android:minter-android-blockchain:${minterBlockchainSDK}"

// network
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
Expand All @@ -131,7 +134,6 @@ dependencies {
annotationProcessor 'org.parceler:parceler:1.1.11'
implementation 'com.annimon:stream:1.2.0'

implementation 'com.android.support:appcompat-v7:27.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
Expand Down
2 changes: 1 addition & 1 deletion scripts
Expand Up @@ -28,6 +28,9 @@

import java.util.List;

import network.minter.blockchain.models.ExchangeBuyValue;
import network.minter.blockchain.models.ExchangeSellValue;
import network.minter.explorer.models.BCExplorerResult;
import network.minter.explorer.models.CoinItem;
import network.minter.explorer.models.ExpResult;
import retrofit2.Call;
Expand All @@ -45,4 +48,32 @@ public interface ExplorerCoinsEndpoint {

@GET("v1/coins")
Call<ExpResult<List<CoinItem>>> search(@Query("symbol") String symbol);

/**
* Give an estimation about coin exchange (selling)
* @param coinToSell coin to convert from
* @param valueToSell BigInteger string value
* @param coinToBuy coin to convert to
* @return
*/
@GET("v1/estimate/coin-sell")
Call<BCExplorerResult<ExchangeSellValue>> getCoinExchangeCurrencyToSell(
@Query("coinToSell") String coinToSell,
@Query("valueToSell") String valueToSell,
@Query("coinToBuy") String coinToBuy
);

/**
* Give an estimation about coin exchange (buying)
* @param coinToSell coin to convert from
* @param valueToBuy BigInteger string value
* @param coinToBuy coin to convert to
* @return
*/
@GET("v1/estimate/coin-buy")
Call<BCExplorerResult<ExchangeBuyValue>> getCoinExchangeCurrencyToBuy(
@Query("coinToSell") String coinToSell,
@Query("valueToBuy") String valueToBuy,
@Query("coinToBuy") String coinToBuy
);
}
Expand Up @@ -29,30 +29,36 @@
import java.util.List;
import java.util.Map;

import network.minter.blockchain.models.CountableData;
import network.minter.blockchain.models.TransactionCommissionValue;
import network.minter.blockchain.models.TransactionSendResult;
import network.minter.explorer.models.BCExplorerResult;
import network.minter.explorer.models.ExpResult;
import network.minter.explorer.models.HistoryTransaction;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Query;
import retrofit2.http.QueryMap;

/**
* minter-android-explorer. 2018
*
* @author Eduard Maximovich <edward.vstock@gmail.com>
*/
public interface ExplorerTransactionEndpoint {
/**
* @param query
* @return
*/
@GET("v1/transactions")
/**
* @param query
* @return
*/
@GET("v1/transactions")
Call<ExpResult<List<HistoryTransaction>>> getTransactions(@QueryMap Map<String, String> query);

@GET("v1/transactions")
@GET("v1/transactions")
Call<ExpResult<List<HistoryTransaction>>> getTransactions(@Query(value = "addresses[]", encoded = true) List<String> addresses);

@GET("v1/transactions")
@GET("v1/transactions")
Call<ExpResult<List<HistoryTransaction>>> getTransactions(@Query(value = "addresses[]", encoded = true) List<String> addresses, @Query("page") long page);

@GET("v1/transactions")
Expand All @@ -61,4 +67,23 @@ Call<ExpResult<List<HistoryTransaction>>> getTransactions(
@Query("page") long page,
@Query("perPage") int limit
);

@GET("v1/transaction/{hash}")
Call<ExpResult<HistoryTransaction>> findTransactionByHash(@Path("hash") String hash);

@GET("v1/transaction/get-count/{address}")
Call<BCExplorerResult<CountableData>> getTransactionsCount(@Path("address") String address);

@POST("v1/transaction/push")
Call<BCExplorerResult<TransactionSendResult>> sendTransaction(@Body Map<String, String> data);

/**
* Calculates signed transaction commission
* @param signedTx Valid transaction, signed with private key
* @return
*/
@GET("v1/estimate/tx-commission")
Call<BCExplorerResult<TransactionCommissionValue>> getTxCommission(@Query("transaction") String signedTx);


}
92 changes: 92 additions & 0 deletions src/main/java/network/minter/explorer/models/BCExplorerResult.java
@@ -0,0 +1,92 @@
/*
* Copyright (C) by MinterTeam. 2018
* @link <a href="https://github.com/MinterTeam">Org Github</a>
* @link <a href="https://github.com/edwardstock">Maintainer Github</a>
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package network.minter.explorer.models;

import android.support.annotation.Nullable;

import com.google.gson.annotations.SerializedName;

import java.math.BigDecimal;

import network.minter.blockchain.models.BCResult;

/**
* minter-android-explorer. 2018
* @author Eduard Maximovich [edward.vstock@gmail.com]
*/
public class BCExplorerResult<Result> {
public int statusCode = 200;
@SerializedName("data")
public Result result;
public ErrorResult error;

public static <T> BCExplorerResult<T> copyError(BCExplorerResult<?> another) {
BCExplorerResult<T> out = new BCExplorerResult<>();
out.statusCode = another.statusCode;
out.error = another.error;

return out;
}

public String getMessage() {
if (error == null) {
return null;
}

return error.message;
}

public BCResult.ResultCode getErrorCode() {
if (error == null) {
return BCResult.ResultCode.Success;
}

return error.code;
}

public boolean isSuccess() {
return statusCode == 200 && getErrorCode() == BCResult.ResultCode.Success;
}

public static class ErrorResult {
@SerializedName("log")
public String message;
public BCResult.ResultCode code = BCResult.ResultCode.Success;

/**
* Not null only on send transaction error caused by insufficient funds
*/
@Nullable
public String coin;
/**
* The same
*/
@Nullable
public BigDecimal value;
}

}
Expand Up @@ -28,15 +28,23 @@

import android.support.annotation.NonNull;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;

import network.minter.blockchain.models.ExchangeBuyValue;
import network.minter.blockchain.models.ExchangeSellValue;
import network.minter.blockchain.models.operational.Transaction;
import network.minter.core.internal.api.ApiService;
import network.minter.core.internal.data.DataRepository;
import network.minter.explorer.api.ExplorerCoinsEndpoint;
import network.minter.explorer.models.BCExplorerResult;
import network.minter.explorer.models.CoinItem;
import network.minter.explorer.models.ExpResult;
import retrofit2.Call;

import static network.minter.core.internal.common.Preconditions.checkNotNull;

/**
* minter-android-explorer. 2018
* @author Eduard Maximovich [edward.vstock[at]gmail.com]
Expand All @@ -54,6 +62,56 @@ public Call<ExpResult<List<CoinItem>>> getAll() {
return getInstantService().getAll();
}

/**
* @param coinToSell Selling coin
* @param valueToSell Selling amount of exchange (big integer amount like: 1 BIP equals
* 1000000000000000000 (18 zeroes) in big integer equivalent)
* @param coinToBuy Buying coin coin
* @return Exchange calculation
*/
public Call<BCExplorerResult<ExchangeSellValue>> getCoinExchangeCurrencyToSell(@NonNull String coinToSell, BigDecimal valueToSell, @NonNull String coinToBuy) {
return getCoinExchangeCurrencyToSell(coinToSell, valueToSell.multiply(Transaction.VALUE_MUL_DEC).toBigInteger(), coinToBuy);
}

/**
* @param coinToSell Selling coin
* @param valueToSell Selling amount of exchange (big integer amount like: 1 BIP equals
* 1000000000000000000 (18 zeroes) in big integer equivalent)
* @param coinToBuy Buying coin coin
* @return Exchange calculation
*/
public Call<BCExplorerResult<ExchangeSellValue>> getCoinExchangeCurrencyToSell(@NonNull String coinToSell, BigInteger valueToSell, @NonNull String coinToBuy) {
return getInstantService().getCoinExchangeCurrencyToSell(
checkNotNull(coinToSell, "Source coin required").toUpperCase(),
valueToSell.toString(), checkNotNull(coinToBuy, "Target coin required").toUpperCase()
);
}

/**
* @param coinToSell Selling coin
* @param valueToBuy Buying amount of exchange (human readable amount like: 1 BIP equals 1.0 in
* float equivalent)
* @param coinToBuy Buying coin
* @return Exchange calculation
*/
public Call<BCExplorerResult<ExchangeBuyValue>> getCoinExchangeCurrencyToBuy(@NonNull String coinToSell, BigDecimal valueToBuy, @NonNull String coinToBuy) {
return getCoinExchangeCurrencyToBuy(coinToSell, valueToBuy.multiply(Transaction.VALUE_MUL_DEC).toBigInteger(), coinToBuy);
}

/**
* @param coinToSell Selling coin
* @param valueToBuy Buying amount of exchange (big integer amount like: 1 BIP equals
* 1000000000000000000 (18 zeroes) in big integer equivalent)
* @param coinToBuy Buying coin
* @return Exchange calculation
*/
public Call<BCExplorerResult<ExchangeBuyValue>> getCoinExchangeCurrencyToBuy(@NonNull String coinToSell, BigInteger valueToBuy, @NonNull String coinToBuy) {
return getInstantService().getCoinExchangeCurrencyToBuy(
checkNotNull(coinToSell, "Source coin required").toUpperCase(),
valueToBuy.toString(), checkNotNull(coinToBuy, "Target coin required").toUpperCase()
);
}

/**
* Search coin by it symbol
* @return Retrofit call
Expand Down

0 comments on commit 8699643

Please sign in to comment.