Skip to content

[1.2.0] #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Dec 2, 2021
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ sonarqube {

dependencies {
implementation "org.jetbrains:annotations:22.0.0"
implementation "com.google.code.gson:gson:2.8.8"
implementation "com.google.code.gson:gson:2.8.9"

testImplementation "junit:junit:4.13.1"
}
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
groupId=com.github.goodforgod
artifactId=java-etherscan-api
artifactVersion=1.1.1
artifactVersion=1.2.0
buildNumber=1


Expand Down
20 changes: 19 additions & 1 deletion src/main/java/io/api/etherscan/core/IAccountApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public interface IAccountApi {
List<TxInternal> txsInternalByHash(String txhash) throws ApiException;

/**
* All token txs for given address
* All ERC-20 token txs for given address
*
* @param address get txs for
* @param startBlock tx from this blockNumber
Expand All @@ -110,6 +110,24 @@ public interface IAccountApi {
@NotNull
List<TxToken> txsToken(String address) throws ApiException;

/**
* All ERC-721 (NFT) token txs for given address
*
* @param address get txs for
* @param startBlock tx from this blockNumber
* @param endBlock tx to this blockNumber
* @return txs for address
* @throws ApiException parent exception class
*/
@NotNull
List<TxToken> txsNftToken(String address, long startBlock, long endBlock) throws ApiException;

@NotNull
List<TxToken> txsNftToken(String address, long startBlock) throws ApiException;

@NotNull
List<TxToken> txsNftToken(String address) throws ApiException;

/**
* All blocks mined by address
*
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/io/api/etherscan/core/impl/AccountApiProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class AccountApiProvider extends BasicProvider implements IAccountApi {
private static final String ACT_TX_ACTION = ACT_PREFIX + "txlist";
private static final String ACT_TX_INTERNAL_ACTION = ACT_PREFIX + "txlistinternal";
private static final String ACT_TX_TOKEN_ACTION = ACT_PREFIX + "tokentx";
private static final String ACT_TX_NFT_TOKEN_ACTION = ACT_PREFIX + "tokennfttx";
private static final String ACT_MINED_ACTION = ACT_PREFIX + "getminedblocks";

private static final String BLOCK_TYPE_PARAM = "&blocktype=blocks";
Expand Down Expand Up @@ -229,6 +230,31 @@ public List<TxToken> txsToken(final String address, final long startBlock, final
return getRequestUsingOffset(urlParams, TxTokenResponseTO.class);
}

@NotNull
@Override
public List<TxToken> txsNftToken(String address) throws ApiException {
return txsNftToken(address, MIN_START_BLOCK);
}

@NotNull
@Override
public List<TxToken> txsNftToken(String address, long startBlock) throws ApiException {
return txsNftToken(address, startBlock, MAX_END_BLOCK);
}

@NotNull
@Override
public List<TxToken> txsNftToken(String address, long startBlock, long endBlock) throws ApiException {
BasicUtils.validateAddress(address);
final BlockParam blocks = BasicUtils.compensateBlocks(startBlock, endBlock);

final String offsetParam = PAGE_PARAM + "%s" + OFFSET_PARAM + OFFSET_MAX;
final String blockParam = START_BLOCK_PARAM + blocks.start() + END_BLOCK_PARAM + blocks.end();
final String urlParams = ACT_TX_NFT_TOKEN_ACTION + offsetParam + ADDRESS_PARAM + address + blockParam + SORT_ASC_PARAM;

return getRequestUsingOffset(urlParams, TxTokenResponseTO.class);
}

@NotNull
@Override
public List<Block> minedBlocks(final String address) throws ApiException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/
public class QueueManager implements IQueueManager, AutoCloseable {

public static final QueueManager DEFAULT_KEY_QUEUE = new QueueManager(1, 7);
public static final QueueManager DEFAULT_KEY_QUEUE = new QueueManager(1, 5200L, 5200L, 0);
public static final QueueManager PERSONAL_KEY_QUEUE = new QueueManager(5, 1100L, 1100L, 5);

private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
Expand Down
5 changes: 4 additions & 1 deletion src/test/java/io/api/ApiRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ public class ApiRunner extends Assert {
? EtherScanApi.DEFAULT_KEY
: key;

final QueueManager queueManager = new QueueManager(1, 1200L, 1200L, 0);
final QueueManager queueManager = (EtherScanApi.DEFAULT_KEY.equals(apiKey))
? QueueManager.DEFAULT_KEY_QUEUE
: new QueueManager(1, 1200L, 1200L, 0);

api = new EtherScanApi(ApiRunner.apiKey, EthNetwork.MAINNET, queueManager);
apiKovan = new EtherScanApi(ApiRunner.apiKey, EthNetwork.KOVAN, queueManager);
apiRopsten = new EtherScanApi(ApiRunner.apiKey, EthNetwork.ROPSTEN, queueManager);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package io.api.etherscan.account;

import io.api.ApiRunner;
import io.api.etherscan.error.InvalidAddressException;
import io.api.etherscan.model.TxToken;
import org.junit.Test;

import java.util.List;

/**
* @author NGuggs
* @since 11.28.2021
*/
public class AccountTxRc721TokenTest extends ApiRunner {

@Test
public void correct() {
List<TxToken> txs = getApi().account().txsNftToken("0x1a1ebe0d86f72884c3fd484ae1e796e08f8ffa67");
assertNotNull(txs);
assertEquals(16, txs.size());
assertTxs(txs);
assertNotEquals(0, txs.get(0).getGasPrice());
assertNotEquals(-1, txs.get(0).getNonce());

assertNotNull(txs.get(0).toString());
assertNotEquals(txs.get(0).toString(), txs.get(1).toString());

assertNotEquals(txs.get(0), txs.get(1));
assertNotEquals(txs.get(0).hashCode(), txs.get(1).hashCode());

assertEquals(txs.get(1), txs.get(1));
assertEquals(txs.get(1).hashCode(), txs.get(1).hashCode());
}

@Test
public void correctStartBlock() {
List<TxToken> txs = getApi().account().txsNftToken("0x1a1ebe0d86f72884c3fd484ae1e796e08f8ffa67", 4762071);
System.out.println(txs);
assertNotNull(txs);
assertEquals(5, txs.size());
assertTxs(txs);
}

@Test
public void correctStartBlockEndBlock() {
List<TxToken> txs = getApi().account().txsNftToken("0x1a1ebe0d86f72884c3fd484ae1e796e08f8ffa67", 4761862, 4761934);
System.out.println(txs);
assertNotNull(txs);
assertEquals(11, txs.size());
assertTxs(txs);
}

@Test(expected = InvalidAddressException.class)
public void invalidParamWithError() {
getApi().account().txsNftToken("0x6ec53A8fBa6358d59B3C4476D82cc60A2B0FaD7");
}

@Test
public void correctParamWithEmptyExpectedResult() {
List<TxToken> txs = getApi().account().txsNftToken("0x31ec53A8fBa6358d59B3C4476D82cc60A2B0FaD7");
assertNotNull(txs);
assertTrue(txs.isEmpty());
}

private void assertTxs(List<TxToken> txs) {
for (TxToken tx : txs) {
assertNotNull(tx.getBlockHash());
assertNotNull(tx.getTokenName());
assertNotNull(tx.getTokenSymbol());
assertNotNull(tx.getFrom());
assertNotNull(tx.getTo());
assertNotNull(tx.getTimeStamp());
assertNotNull(tx.getTokenDecimal());
assertNotEquals(-1, (tx.getConfirmations()));
assertNotNull(tx.getGasUsed());
assertNotEquals(-1, tx.getCumulativeGasUsed());
assertNotEquals(-1, tx.getTransactionIndex());
}
}
}