Skip to content

Commit 1e03995

Browse files
iSnowGoodforGod
authored andcommitted
Higher-level API to read well-known ETH events as polymorphic classes
(cherry picked from commit ec0cf80)
1 parent c1e995f commit 1e03995

File tree

11 files changed

+250
-0
lines changed

11 files changed

+250
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.api.etherscan.core;
2+
3+
import io.api.etherscan.error.ApiException;
4+
import io.api.etherscan.model.Log;
5+
import io.api.etherscan.model.event.IEvent;
6+
import io.api.etherscan.model.query.impl.LogQuery;
7+
import org.jetbrains.annotations.NotNull;
8+
9+
import java.util.List;
10+
11+
/**
12+
* EtherScan - API Descriptions
13+
* https://etherscan.io/apis#logs
14+
*/
15+
public interface IEventsApi {
16+
17+
/**
18+
* This is a high-level alternative to the ILogsApi and an alternative to the native eth_getLogs
19+
* Read at EtherScan API description for full info!
20+
* @param query build log query
21+
* @return logs according to query
22+
* @throws ApiException parent exception class
23+
*
24+
* @see io.api.etherscan.model.query.impl.LogQueryBuilder
25+
*/
26+
@NotNull
27+
List<IEvent> events(LogQuery query) throws ApiException;
28+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package io.api.etherscan.core.impl;
2+
3+
import io.api.etherscan.core.IEventsApi;
4+
import io.api.etherscan.core.ILogsApi;
5+
import io.api.etherscan.error.ApiException;
6+
import io.api.etherscan.executor.IHttpExecutor;
7+
import io.api.etherscan.manager.IQueueManager;
8+
import io.api.etherscan.model.Log;
9+
import io.api.etherscan.model.event.IEvent;
10+
import io.api.etherscan.model.event.impl.Event;
11+
import io.api.etherscan.model.query.impl.LogQuery;
12+
import io.api.etherscan.model.utility.LogResponseTO;
13+
import io.api.etherscan.util.BasicUtils;
14+
import org.jetbrains.annotations.NotNull;
15+
16+
import java.util.Collections;
17+
import java.util.List;
18+
import java.util.stream.Collectors;
19+
20+
/**
21+
* Logs API Implementation
22+
*
23+
* @see IEventsApi
24+
*
25+
*/
26+
public class EventsApiProvider extends BasicProvider implements IEventsApi {
27+
28+
private static final String ACT_LOGS_PARAM = ACT_PREFIX + "getLogs";
29+
30+
EventsApiProvider(final IQueueManager queue,
31+
final String baseUrl,
32+
final IHttpExecutor executor) {
33+
super(queue, "logs", baseUrl, executor);
34+
}
35+
36+
@NotNull
37+
@Override
38+
public List<IEvent> events(final LogQuery query) throws ApiException {
39+
final String urlParams = ACT_LOGS_PARAM + query.getParams();
40+
final LogResponseTO response = getRequest(urlParams, LogResponseTO.class);
41+
BasicUtils.validateTxResponse(response);
42+
43+
if (BasicUtils.isEmpty(response.getResult())) {
44+
return Collections.emptyList();
45+
};
46+
return response
47+
.getResult()
48+
.stream()
49+
.map((log) -> {
50+
String eventTypeHash = log.getTopics().get(0);
51+
return IEvent.createEvent(eventTypeHash, log);
52+
})
53+
.collect(Collectors.toList());
54+
}
55+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package io.api.etherscan.error;
2+
3+
public class EventModelException extends ApiException {
4+
public EventModelException(String message) {
5+
super(message);
6+
}
7+
8+
public EventModelException(String message, Throwable cause) {
9+
super(message, cause);
10+
}
11+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.api.etherscan.model.event;
2+
3+
import io.api.etherscan.error.ApiException;
4+
import io.api.etherscan.error.EventModelException;
5+
import io.api.etherscan.model.Log;
6+
7+
import java.util.HashMap;
8+
import java.util.Map;
9+
10+
public interface IEvent {
11+
static final Map<String, Class<?>> subTypes = new HashMap<>();
12+
13+
void setLog(Log log);
14+
15+
static void registerEventType(String typeHash, Class<?> clazz) {
16+
subTypes.put(typeHash, clazz);
17+
}
18+
19+
static IEvent createEvent(String typeHash, Log log) {
20+
if (null == typeHash) {
21+
throw new EventModelException("Event type hash cannot be null");
22+
}
23+
Class<?> clazz = subTypes.get(typeHash);
24+
try {
25+
IEvent evt = (IEvent) clazz.newInstance();
26+
evt.setLog(log);
27+
return evt;
28+
} catch (InstantiationException | IllegalAccessException ex) {
29+
throw new ApiException("Client-side error instantiating Event object", ex);
30+
}
31+
}
32+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.api.etherscan.model.event.impl;
2+
3+
import io.api.etherscan.model.event.IEvent;
4+
5+
public class ApprovalEvent extends Event {
6+
static final String eventTypeHash = "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925";
7+
static {
8+
IEvent.registerEventType(ApprovalEvent.eventTypeHash, ApprovalEvent.class);
9+
}
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.api.etherscan.model.event.impl;
2+
3+
import io.api.etherscan.model.event.IEvent;
4+
5+
public class DepositEvent extends Event {
6+
static final String eventTypeHash = "0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c";
7+
static {
8+
IEvent.registerEventType(DepositEvent.eventTypeHash, DepositEvent.class);
9+
}
10+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.api.etherscan.model.event.impl;
2+
3+
import io.api.etherscan.error.ApiException;
4+
import io.api.etherscan.error.EventModelException;
5+
import io.api.etherscan.model.Log;
6+
import io.api.etherscan.model.event.IEvent;
7+
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
11+
/**
12+
* Base class for a higher-level API on top of {@link Log}. Each Event class has an identifying hash
13+
*/
14+
public class Event implements IEvent {
15+
16+
static String eventTypeHash;
17+
18+
private Log log;
19+
20+
String address;
21+
22+
public static String getEventTypeHash() {
23+
return eventTypeHash;
24+
}
25+
26+
public Log getLog() {
27+
return log;
28+
}
29+
30+
public String getAddress() {
31+
return address;
32+
}
33+
34+
public void setLog(Log log) {
35+
this.log = log;
36+
}
37+
38+
public void setAddress(String address) {
39+
this.address = address;
40+
}
41+
42+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package io.api.etherscan.model.event.impl;
2+
3+
import io.api.etherscan.model.event.IEvent;
4+
5+
public class MintEvent extends Event {
6+
static final String eventTypeHash = "0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f";
7+
static {
8+
IEvent.registerEventType(MintEvent.eventTypeHash, MintEvent.class);
9+
}
10+
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.api.etherscan.model.event.impl;
2+
3+
import io.api.etherscan.model.event.IEvent;
4+
5+
public class SyncEvent extends Event {
6+
static final String eventTypeHash = "0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1";
7+
static {
8+
IEvent.registerEventType(SyncEvent.eventTypeHash, SyncEvent.class);
9+
}
10+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.api.etherscan.model.event.impl;
2+
3+
import io.api.etherscan.model.event.IEvent;
4+
5+
public class TransferErc20Event extends Event {
6+
static final String eventTypeHash = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
7+
static {
8+
IEvent.registerEventType(TransferErc20Event.eventTypeHash, TransferErc20Event.class);
9+
}
10+
11+
String fromAddress;
12+
13+
String toAddress;
14+
15+
public String getFromAddress() {
16+
return fromAddress;
17+
}
18+
19+
public void setFromAddress(String fromAddress) {
20+
this.fromAddress = fromAddress;
21+
}
22+
23+
public String getToAddress() {
24+
return toAddress;
25+
}
26+
27+
public void setToAddress(String toAddress) {
28+
this.toAddress = toAddress;
29+
}
30+
31+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy