From f0f845f59517af385f9b09b09761043ed10b145d Mon Sep 17 00:00:00 2001 From: Ebenezer Ackon Date: Thu, 26 Apr 2018 14:13:45 -0400 Subject: [PATCH] handle issue #14, blocks --- README.md | 41 +++++++++----- .../etherscan/helloetherescan/MainActivity.kt | 41 +++++++++----- .../src/main/java/jfyg/data/BlocksMined.kt | 10 ++++ .../src/main/java/jfyg/data/Uncles.kt | 10 ++++ .../main/java/jfyg/data/block/BlocksMined.kt | 19 +++++++ .../jfyg/data/block/BlocksMinedContract.kt | 16 ++++++ .../main/java/jfyg/network/NetworkService.kt | 7 +++ .../java/jfyg/network/queries/ApiQuery.kt | 8 ++- .../java/jfyg/network/queries/BlocksApi.kt | 15 ++++++ .../network/response/block/BlockResponse.kt | 9 ++++ .../java/jfyg/data/block/BlocksMinedTest.kt | 54 +++++++++++++++++++ 11 files changed, 204 insertions(+), 26 deletions(-) create mode 100644 etherscanapi/src/main/java/jfyg/data/BlocksMined.kt create mode 100644 etherscanapi/src/main/java/jfyg/data/Uncles.kt create mode 100644 etherscanapi/src/main/java/jfyg/data/block/BlocksMined.kt create mode 100644 etherscanapi/src/main/java/jfyg/data/block/BlocksMinedContract.kt create mode 100644 etherscanapi/src/main/java/jfyg/network/queries/BlocksApi.kt create mode 100644 etherscanapi/src/main/java/jfyg/network/response/block/BlockResponse.kt create mode 100644 etherscanapi/src/test/java/jfyg/data/block/BlocksMinedTest.kt diff --git a/README.md b/README.md index f7ec93f..ae7f6b5 100644 --- a/README.md +++ b/README.md @@ -28,20 +28,37 @@ Create an Instance of one of the reactive Singles and access values by specifyin ``[accounts, contracts, transactions, blocks, eventLogs, geth, websockets, tokens, stat]`` ``` -val stat = Stat() -val account = Account() - - //stat test - stat.getLastPriceInBtc()?.observeOn(AndroidSchedulers.mainThread()) - ?.subscribeBy { - Log.d(TAG, "The current price of Ether in Btc: $it") - } + val stat = Stat() + val account = Account() + val contract = ContractABI() + val tx = TxStatus() + val blocks = BlocksMined() //account test - account.getTransactions("0x2c1ba59d6f58433fb1eaee7d20b26ed83bda51a3")?.observeOn(AndroidSchedulers.mainThread()) - ?.subscribeBy { - Log.d(TAG, "The Account Size of Transactions is: ${it.size}") - } + account.getERC20Tokens("0x4e83362442b8d1bec281594cea3050c8eb01311c") + .observeOn(AndroidSchedulers.mainThread()) + ?.subscribeBy( + onSuccess = { Log.d(TAG, "The Account Size of Transactions is: ${it.size}") }, + onError = { Log.d(TAG, "error receiving ERC20") }) + + //contracts test + contract.getContractABI("0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413") + .observeOn(AndroidSchedulers.mainThread()) + ?.subscribeBy( + onSuccess = { Log.d(TAG, "The ABI has returned: $it") }, + onError = { Log.d(TAG, "error receiving abi contract") }) + + + + //blocks test + blocks.getBlocksMined("2165403") + .observeOn(AndroidSchedulers.mainThread()) + ?.subscribeBy( + onSuccess = { + Log.d(TAG, "The block miner is: ${it.blockMiner} and " + + "the first miner : ${it.uncles?.get(0)?.miner}") + }, + onError = { Log.d(TAG, "error receiving blocks mined") }) ``` ## Authors diff --git a/app/src/main/java/jfyg/etherscan/helloetherescan/MainActivity.kt b/app/src/main/java/jfyg/etherscan/helloetherescan/MainActivity.kt index 29b7dd4..22300d9 100644 --- a/app/src/main/java/jfyg/etherscan/helloetherescan/MainActivity.kt +++ b/app/src/main/java/jfyg/etherscan/helloetherescan/MainActivity.kt @@ -6,6 +6,7 @@ import android.util.Log import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.rxkotlin.subscribeBy import jfyg.data.account.Account +import jfyg.data.block.BlocksMined import jfyg.data.contract.ContractABI import jfyg.data.stat.Stat import jfyg.data.transaction.TxStatus @@ -25,6 +26,7 @@ class MainActivity : AppCompatActivity() { val account = Account() val contract = ContractABI() val tx = TxStatus() + val blocks = BlocksMined() fab.setOnClickListener { @@ -32,31 +34,44 @@ class MainActivity : AppCompatActivity() { //stat test stat.getLastPriceInBtc() .observeOn(AndroidSchedulers.mainThread()) - ?.subscribeBy { - Log.d(TAG, "The current price of Ether in Btc: $it") - } + ?.subscribeBy( + onSuccess = { Log.d(TAG, "The current price of Ether in Btc: $it") }, + onError = { Log.d(TAG, "error receiving stat") }) + //account test account.getERC20Tokens("0x4e83362442b8d1bec281594cea3050c8eb01311c") .observeOn(AndroidSchedulers.mainThread()) - ?.subscribeBy { - Log.d(TAG, "The Account Size of Transactions is: ${it.size}") - } + ?.subscribeBy( + onSuccess = { Log.d(TAG, "The Account Size of Transactions is: ${it.size}") }, + onError = { Log.d(TAG, "error receiving ERC20") }) //contracts test contract.getContractABI("0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413") .observeOn(AndroidSchedulers.mainThread()) - ?.subscribeBy { - Log.d(TAG, "The ABI has returned: $it") - } + ?.subscribeBy( + onSuccess = { Log.d(TAG, "The ABI has returned: $it") }, + onError = { Log.d(TAG, "error receiving abi contract") }) //transaction test tx.getTxExecutionStatus("0x15f8e5ea1079d9a0bb04a4c58ae5fe7654b5b2b4463375ff7ffb490aa0032f3a") .observeOn(AndroidSchedulers.mainThread()) - ?.subscribeBy { - Log.d(TAG, "The transaction's Error Status is: ${it.isError} and " + - "transactions's error description is: ${it.errDescription}") - } + ?.subscribeBy( + onSuccess = { + Log.d(TAG, "The transaction's Error Status is: ${it.isError} and " + + "transactions's error description is: ${it.errDescription}") + }, + onError = { Log.d(TAG, "error receiving tx status") }) + + //blocks test + blocks.getBlocksMined("2165403") + .observeOn(AndroidSchedulers.mainThread()) + ?.subscribeBy( + onSuccess = { + Log.d(TAG, "The block miner is: ${it.blockMiner} and " + + "the first minor : ${it.uncles?.get(0)?.miner}") + }, + onError = { Log.d(TAG, "error receiving blocks mined") }) } } diff --git a/etherscanapi/src/main/java/jfyg/data/BlocksMined.kt b/etherscanapi/src/main/java/jfyg/data/BlocksMined.kt new file mode 100644 index 0000000..4da4940 --- /dev/null +++ b/etherscanapi/src/main/java/jfyg/data/BlocksMined.kt @@ -0,0 +1,10 @@ +package jfyg.data + +/** + * https://etherscan.io/apis#blocks + */ +data class BlocksMined(var blockNumber: String? = null, + var timeStamp: String? = null, + var blockMiner: String? = null, + var blockReward: String? = null, + var uncles: ArrayList? = null) \ No newline at end of file diff --git a/etherscanapi/src/main/java/jfyg/data/Uncles.kt b/etherscanapi/src/main/java/jfyg/data/Uncles.kt new file mode 100644 index 0000000..de79002 --- /dev/null +++ b/etherscanapi/src/main/java/jfyg/data/Uncles.kt @@ -0,0 +1,10 @@ +package jfyg.data + +import com.google.gson.annotations.SerializedName + +data class Uncles(var miner: String? = null, + + var unclePosition: String? = null, + + @SerializedName("blockreward") + var blockReward: String? = null) \ No newline at end of file diff --git a/etherscanapi/src/main/java/jfyg/data/block/BlocksMined.kt b/etherscanapi/src/main/java/jfyg/data/block/BlocksMined.kt new file mode 100644 index 0000000..8123795 --- /dev/null +++ b/etherscanapi/src/main/java/jfyg/data/block/BlocksMined.kt @@ -0,0 +1,19 @@ +package jfyg.data.block + +import io.reactivex.Single +import jfyg.data.BlocksMined +import jfyg.network.queries.ApiQuery + +/** + * https://etherscan.io/apis#blocks + */ +class BlocksMined : BlocksMinedContract { + private val query = ApiQuery() + + /** + * [BETA] Get Block And Uncle Rewards by BlockNo + */ + override fun getBlocksMined(blockNo: String?): Single = + query.blocksMined("block", "getblockreward", blockNo).map { it.result } + +} \ No newline at end of file diff --git a/etherscanapi/src/main/java/jfyg/data/block/BlocksMinedContract.kt b/etherscanapi/src/main/java/jfyg/data/block/BlocksMinedContract.kt new file mode 100644 index 0000000..059936c --- /dev/null +++ b/etherscanapi/src/main/java/jfyg/data/block/BlocksMinedContract.kt @@ -0,0 +1,16 @@ +package jfyg.data.block + +import io.reactivex.Single +import jfyg.data.BlocksMined + +/** + * https://etherscan.io/apis#blocks + */ +internal interface BlocksMinedContract { + + /** + * [BETA] Get Block And Uncle Rewards by BlockNo + */ + fun getBlocksMined(blockNo: String?): Single + +} \ No newline at end of file diff --git a/etherscanapi/src/main/java/jfyg/network/NetworkService.kt b/etherscanapi/src/main/java/jfyg/network/NetworkService.kt index 902cbe6..b7e75d4 100644 --- a/etherscanapi/src/main/java/jfyg/network/NetworkService.kt +++ b/etherscanapi/src/main/java/jfyg/network/NetworkService.kt @@ -7,6 +7,7 @@ import jfyg.network.response.account.ERC20Response import jfyg.network.response.account.AccountInternalTxResponse import jfyg.network.response.account.AccountMultiBalanceResponse import jfyg.network.response.account.AccountTxResponse +import jfyg.network.response.block.BlockResponse import jfyg.network.response.contract.ContractABIResponse import jfyg.network.response.stat.StatPriceResponse import jfyg.network.response.stat.StatSupplyResponse @@ -96,4 +97,10 @@ internal interface NetworkService { @Query("txhash") address: String?, @Query("apikey") apikey: String?): Single + @GET("api") + fun getBlocksMined(@Query("module") module: String?, + @Query("action") action: String?, + @Query("blockno") address: String?, + @Query("apikey") apikey: String?): Single + } \ No newline at end of file diff --git a/etherscanapi/src/main/java/jfyg/network/queries/ApiQuery.kt b/etherscanapi/src/main/java/jfyg/network/queries/ApiQuery.kt index 4bb934d..1243173 100644 --- a/etherscanapi/src/main/java/jfyg/network/queries/ApiQuery.kt +++ b/etherscanapi/src/main/java/jfyg/network/queries/ApiQuery.kt @@ -9,6 +9,7 @@ import jfyg.network.response.account.ERC20Response import jfyg.network.response.account.AccountInternalTxResponse import jfyg.network.response.account.AccountMultiBalanceResponse import jfyg.network.response.account.AccountTxResponse +import jfyg.network.response.block.BlockResponse import jfyg.network.response.contract.ContractABIResponse import jfyg.network.response.stat.StatPriceResponse import jfyg.network.response.stat.StatSupplyResponse @@ -18,7 +19,7 @@ import jfyg.network.response.transaction.TxContractReceiptResponse /** * A mediator between the responses and errors that come from every query */ -internal class ApiQuery : AccountApi, StatApi, ContractABIApi, TxApi { +internal class ApiQuery : AccountApi, StatApi, ContractABIApi, TxApi, BlocksApi { override fun accountBalance(module: String?, @@ -85,4 +86,9 @@ internal class ApiQuery : AccountApi, StatApi, ContractABIApi, TxApi { txHash: String?): Single = RestClient().getQuery().getContractTransactionReceipt(module, action, txHash, ApiKey.takeOff.callApiKey()) + override fun blocksMined(module: String?, + action: String?, + blockno: String?): Single = + RestClient().getQuery().getBlocksMined(module, action, blockno, ApiKey.takeOff.callApiKey()) + } \ No newline at end of file diff --git a/etherscanapi/src/main/java/jfyg/network/queries/BlocksApi.kt b/etherscanapi/src/main/java/jfyg/network/queries/BlocksApi.kt new file mode 100644 index 0000000..e11620f --- /dev/null +++ b/etherscanapi/src/main/java/jfyg/network/queries/BlocksApi.kt @@ -0,0 +1,15 @@ +package jfyg.network.queries + +import io.reactivex.Single +import jfyg.network.response.block.BlockResponse + +internal interface BlocksApi { + + /** + * [BETA] Get Block And Uncle Rewards by BlockNo + */ + fun blocksMined(module: String?, + action: String?, + blockno: String?): Single + +} \ No newline at end of file diff --git a/etherscanapi/src/main/java/jfyg/network/response/block/BlockResponse.kt b/etherscanapi/src/main/java/jfyg/network/response/block/BlockResponse.kt new file mode 100644 index 0000000..d443360 --- /dev/null +++ b/etherscanapi/src/main/java/jfyg/network/response/block/BlockResponse.kt @@ -0,0 +1,9 @@ +package jfyg.network.response.block + +import jfyg.data.BlocksMined +import jfyg.network.response.BaseResponse + +/** + * Check contract execution status + */ +internal data class BlockResponse(var result: BlocksMined) : BaseResponse() \ No newline at end of file diff --git a/etherscanapi/src/test/java/jfyg/data/block/BlocksMinedTest.kt b/etherscanapi/src/test/java/jfyg/data/block/BlocksMinedTest.kt new file mode 100644 index 0000000..7001839 --- /dev/null +++ b/etherscanapi/src/test/java/jfyg/data/block/BlocksMinedTest.kt @@ -0,0 +1,54 @@ +package jfyg.data.block + +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import jfyg.network.response.block.BlockResponse +import org.junit.Test + +import org.junit.Assert.* +import org.junit.Before + +class BlocksMinedTest { + lateinit var gson: Gson + + private val minedBlocks = """ + { + "status": "1", + "message": "OK", + "result": { + "blockNumber": "2165403", + "timeStamp": "1472533979", + "blockMiner": "0x13a06d3dfe21e0db5c016c03ea7d2509f7f8d1e3", + "blockReward": "5314181600000000000", + "uncles": [ + { + "miner": "0xbcdfc35b86bedf72f0cda046a3c16829a2ef41d1", + "unclePosition": "0", + "blockreward": "3750000000000000000" + }, + { + "miner": "0x0d0c9855c722ff0c78f21e43aa275a5b8ea60dce", + "unclePosition": "1", + "blockreward": "3750000000000000000" + } + ], + "uncleInclusionReward": "312500000000000000" + } + }""" + + @Before + fun setUp() { + val gb = GsonBuilder() + gson = gb.create() + } + + @Test + fun getBlocksMined() { + val response = gson.fromJson(minedBlocks, BlockResponse::class.java) + assertEquals("0x13a06d3dfe21e0db5c016c03ea7d2509f7f8d1e3", response.result.blockMiner) + assertEquals("2165403", response.result.blockNumber) + assertEquals("5314181600000000000", response.result.blockReward) + assertEquals("3750000000000000000", response.result.uncles?.get(0)?.blockReward) + } + +} \ No newline at end of file