Skip to content

Add support for PolygonScan #20

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

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions src/main/java/io/api/etherscan/core/IAccountApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,59 @@ public interface IAccountApi {
*/
@NotNull
List<Block> minedBlocks(String address) throws ApiException;

@NotNull
List<TxErc20> erc20Transfers(String address) throws ApiException;

@NotNull
List<TxErc20> erc20Transfers(String address, long startBlock) throws ApiException;

/**
* All ERC-20 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<TxErc20> erc20Transfers(String address, long startBlock, long endBlock) throws ApiException;

@NotNull
List<TxErc721> erc721Transfers(String address) throws ApiException;

@NotNull
List<TxErc721> erc721Transfers(String address, long startBlock) 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<TxErc721> erc721Transfers(String address, long startBlock, long endBlock) throws ApiException;

@NotNull
List<TxErc1155> erc1155Transfers(String address) throws ApiException;

@NotNull
List<TxErc1155> erc1155Transfers(String address, long startBlock) throws ApiException;

/**
* All ERC-1155 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<TxErc1155> erc1155Transfers(String address, long startBlock, long endBlock) throws ApiException;

}
67 changes: 67 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 @@ -35,6 +35,7 @@ public class AccountApiProvider extends BasicProvider implements IAccountApi {
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_TX_1155_TOKEN_ACTION = ACT_PREFIX + "token1155tx";
private static final String ACT_MINED_ACTION = ACT_PREFIX + "getminedblocks";

private static final String BLOCK_TYPE_PARAM = "&blocktype=blocks";
Expand Down Expand Up @@ -265,4 +266,70 @@ public List<Block> minedBlocks(final String address) throws ApiException {

return getRequestUsingOffset(urlParams, BlockResponseTO.class);
}

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

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

@NotNull
@Override
public List<TxErc20> erc20Transfers(String address, long startBlock, long endBlock) throws ApiException {
return getTokenTransfers(address, startBlock, endBlock, ACT_TX_TOKEN_ACTION, TxErc20ResponseTO.class);
}

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

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

@NotNull
@Override
public List<TxErc721> erc721Transfers(String address, long startBlock, long endBlock) throws ApiException {
return getTokenTransfers(address, startBlock, endBlock, ACT_TX_NFT_TOKEN_ACTION, TxErc721ResponseTO.class);
}

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

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

@NotNull
@Override
public List<TxErc1155> erc1155Transfers(String address, long startBlock, long endBlock) throws ApiException {
return getTokenTransfers(address, startBlock, endBlock, ACT_TX_1155_TOKEN_ACTION, TxErc1155ResponseTO.class);
}

@NotNull
private <T extends BaseTxToken, R extends BaseListResponseTO<T>> List<T> getTokenTransfers(String address, long startBlock, long endBlock, String tokenAction, Class<R> responseTOClass) 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 = tokenAction + offsetParam + ADDRESS_PARAM + address + blockParam + SORT_ASC_PARAM;

return getRequestUsingOffset(urlParams, responseTOClass);
}
}
135 changes: 135 additions & 0 deletions src/main/java/io/api/etherscan/core/impl/BaseApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package io.api.etherscan.core.impl;

import io.api.etherscan.core.*;
import io.api.etherscan.error.ApiException;
import io.api.etherscan.error.ApiKeyException;
import io.api.etherscan.executor.IHttpExecutor;
import io.api.etherscan.executor.impl.HttpExecutor;
import io.api.etherscan.manager.IQueueManager;
import io.api.etherscan.manager.impl.FakeQueueManager;
import io.api.etherscan.manager.impl.QueueManager;
import io.api.etherscan.model.EthNetwork;
import io.api.etherscan.model.network.Network;
import io.api.etherscan.util.BasicUtils;
import org.jetbrains.annotations.NotNull;

import java.util.function.Supplier;

public abstract class BaseApi implements AutoCloseable {

private static final Supplier<IHttpExecutor> DEFAULT_SUPPLIER = HttpExecutor::new;

public static final String DEFAULT_KEY = "YourApiKeyToken";

private final IQueueManager queueManager;
private final IAccountApi account;
private final IBlockApi block;
private final IContractApi contract;
private final ILogsApi logs;
private final IProxyApi proxy;
private final IStatisticApi stats;
private final ITransactionApi txs;

public BaseApi() {
this(DEFAULT_KEY, EthNetwork.MAINNET);
}

public BaseApi(final Network network) {
this(DEFAULT_KEY, network);
}

public BaseApi(final String apiKey) {
this(apiKey, EthNetwork.MAINNET);
}

public BaseApi(final Network network,
final Supplier<IHttpExecutor> executorSupplier) {
this(DEFAULT_KEY, network, executorSupplier);
}

public BaseApi(final String apiKey,
final Network network,
final IQueueManager queue) {
this(apiKey, network, DEFAULT_SUPPLIER, queue);
}

public BaseApi(final String apiKey,
final Network network) {
this(apiKey, network, DEFAULT_SUPPLIER);
}

public BaseApi(final String apiKey,
final Network network,
final Supplier<IHttpExecutor> executorSupplier) {
this(apiKey, network, executorSupplier,
DEFAULT_KEY.equals(apiKey)
? QueueManager.DEFAULT_KEY_QUEUE
: new FakeQueueManager());
}

public BaseApi(final String apiKey,
final Network network,
final Supplier<IHttpExecutor> executorSupplier,
final IQueueManager queue) {
if (BasicUtils.isBlank(apiKey))
throw new ApiKeyException("API key can not be null or empty");

if (network == null)
throw new ApiException("Ethereum Network is set to NULL value");

// EtherScan 1request\5sec limit support by queue manager
final IHttpExecutor executor = executorSupplier.get();

final String baseUrl = network.getUrl() + apiKey;

this.queueManager = queue;
this.account = new AccountApiProvider(queue, baseUrl, executor);
this.block = new BlockApiProvider(queue, baseUrl, executor);
this.contract = new ContractApiProvider(queue, baseUrl, executor);
this.logs = new LogsApiProvider(queue, baseUrl, executor);
this.proxy = new ProxyApiProvider(queue, baseUrl, executor);
this.stats = new StatisticApiProvider(queue, baseUrl, executor);
this.txs = new TransactionApiProvider(queue, baseUrl, executor);
}

@NotNull
public IAccountApi account() {
return account;
}

@NotNull
public IContractApi contract() {
return contract;
}

@NotNull
public ITransactionApi txs() {
return txs;
}

@NotNull
public IBlockApi block() {
return block;
}

@NotNull
public ILogsApi logs() {
return logs;
}

@NotNull
public IProxyApi proxy() {
return proxy;
}

@NotNull
public IStatisticApi stats() {
return stats;
}

@Override
public void close() throws Exception {
queueManager.close();
}

}
Loading