Skip to content

Commit 2df9d68

Browse files
committed
Make LogApi usage bug-free
1 parent 0480bf3 commit 2df9d68

40 files changed

+1395
-257
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package io.api.etherscan.model;
2+
3+
import io.api.etherscan.util.BasicUtils;
4+
5+
import java.util.Objects;
6+
7+
public class Address {
8+
9+
private final String address;
10+
11+
private Address(String address) {
12+
this.address = address;
13+
}
14+
15+
public static Address of(String address) {
16+
BasicUtils.validateAddress(address);
17+
return new Address(address);
18+
}
19+
20+
public String getAddress() {
21+
return address;
22+
}
23+
24+
public String to64Hex() {
25+
String addressWithoutOx = address.substring(2);
26+
return "0x" + padLeftZeros(addressWithoutOx);
27+
}
28+
29+
@Override
30+
public boolean equals(Object o) {
31+
if (this == o) return true;
32+
if (o == null || getClass() != o.getClass()) return false;
33+
Address other = (Address) o;
34+
return address.equals(other.address);
35+
}
36+
37+
@Override
38+
public int hashCode() {
39+
return Objects.hash(address);
40+
}
41+
42+
private String padLeftZeros(String inputString) {
43+
if (inputString.length() >= 64) {
44+
return inputString;
45+
}
46+
StringBuilder sb = new StringBuilder();
47+
while (sb.length() < 64 - inputString.length()) {
48+
sb.append('0');
49+
}
50+
sb.append(inputString);
51+
52+
return sb.toString();
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.api.etherscan.model.query;
2+
3+
import io.api.etherscan.model.Address;
4+
import io.api.etherscan.util.BasicUtils;
5+
6+
import java.util.Objects;
7+
8+
public class LogTopic {
9+
10+
private final String hex;
11+
12+
private LogTopic(String hex) {
13+
this.hex = hex;
14+
}
15+
16+
public static LogTopic of(Address address) {
17+
return of(address.to64Hex());
18+
}
19+
20+
public static LogTopic of(String hex) {
21+
BasicUtils.validateTxHash(hex);
22+
return new LogTopic(hex);
23+
}
24+
25+
public String getHex() {
26+
return hex;
27+
}
28+
29+
@Override
30+
public boolean equals(Object o) {
31+
if (this == o) return true;
32+
if (o == null || getClass() != o.getClass()) return false;
33+
LogTopic other = (LogTopic) o;
34+
return hex.equals(other.hex);
35+
}
36+
37+
@Override
38+
public int hashCode() {
39+
return Objects.hash(hex);
40+
}
41+
42+
}

src/main/java/io/api/etherscan/model/query/impl/LogQuery.java

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package io.api.etherscan.model.query.impl;
22

33
import io.api.etherscan.core.ILogsApi;
4+
import io.api.etherscan.model.query.impl.topic.TopicParams;
5+
import org.jetbrains.annotations.NotNull;
46

57
/**
68
* Final builded container for The Event Log API
@@ -24,6 +26,10 @@ public class LogQuery {
2426
this.params = params;
2527
}
2628

29+
public LogQuery(@NotNull StandardLogQueryParams standardLogQueryParams, @NotNull TopicParams topicParams) {
30+
this.params = standardLogQueryParams.getApiParams() + topicParams.getApiParams();
31+
}
32+
2733
public String getParams() {
2834
return params;
2935
}

src/main/java/io/api/etherscan/model/query/impl/LogQueryBuilder.java

+22
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import io.api.etherscan.core.ILogsApi;
44
import io.api.etherscan.error.LogQueryException;
55
import io.api.etherscan.model.query.IQueryBuilder;
6+
import io.api.etherscan.model.query.impl.topic.TopicParams;
67
import io.api.etherscan.util.BasicUtils;
8+
import org.jetbrains.annotations.NotNull;
79

810
/**
911
* Builder for The Event Log API
@@ -40,12 +42,20 @@ public static LogQueryBuilder with(String address, long startBlock, long endBloc
4042
return new LogQueryBuilder(address, startBlock, endBlock);
4143
}
4244

45+
/**
46+
* @deprecated use {@link LogQueryBuilder#topic(TopicParams)}
47+
*/
48+
@Deprecated
4349
public LogTopicSingle topic(String topic0) {
4450
if (BasicUtils.isNotHex(topic0))
4551
throw new LogQueryException("topic0 can not be empty or non hex.");
4652
return new LogTopicSingle(address, startBlock, endBlock, topic0);
4753
}
4854

55+
/**
56+
* @deprecated use {@link LogQueryBuilder#topic(TopicParams)}
57+
*/
58+
@Deprecated
4959
public LogTopicTuple topic(String topic0, String topic1) {
5060
if (BasicUtils.isNotHex(topic0))
5161
throw new LogQueryException("topic0 can not be empty or non hex.");
@@ -54,6 +64,10 @@ public LogTopicTuple topic(String topic0, String topic1) {
5464
return new LogTopicTuple(address, startBlock, endBlock, topic0, topic1);
5565
}
5666

67+
/**
68+
* @deprecated use {@link LogQueryBuilder#topic(TopicParams)}
69+
*/
70+
@Deprecated
5771
public LogTopicTriple topic(String topic0, String topic1, String topic2) {
5872
if (BasicUtils.isNotHex(topic0))
5973
throw new LogQueryException("topic0 can not be empty or non hex.");
@@ -64,6 +78,10 @@ public LogTopicTriple topic(String topic0, String topic1, String topic2) {
6478
return new LogTopicTriple(address, startBlock, endBlock, topic0, topic1, topic2);
6579
}
6680

81+
/**
82+
* @deprecated use {@link LogQueryBuilder#topic(TopicParams)}
83+
*/
84+
@Deprecated
6785
public LogTopicQuadro topic(String topic0, String topic1, String topic2, String topic3) {
6886
if (BasicUtils.isNotHex(topic0))
6987
throw new LogQueryException("topic0 can not be empty or non hex.");
@@ -77,6 +95,10 @@ public LogTopicQuadro topic(String topic0, String topic1, String topic2, String
7795
return new LogTopicQuadro(address, startBlock, endBlock, topic0, topic1, topic2, topic3);
7896
}
7997

98+
public LogQueryWithTopicsBuilder topic(@NotNull TopicParams topicParams) {
99+
return new LogQueryWithTopicsBuilder(new StandardLogQueryParams(address, startBlock, endBlock), topicParams);
100+
}
101+
80102
@Override
81103
public LogQuery build() throws LogQueryException {
82104
return new LogQuery("&address=" + this.address + "&fromBlock=" + this.startBlock + "&toBlock=" + this.endBlock);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package io.api.etherscan.model.query.impl;
2+
3+
import io.api.etherscan.error.LogQueryException;
4+
import io.api.etherscan.model.query.IQueryBuilder;
5+
import io.api.etherscan.model.query.impl.topic.TopicParams;
6+
7+
public class LogQueryWithTopicsBuilder implements IQueryBuilder {
8+
9+
private final StandardLogQueryParams standardLogQueryParams;
10+
private final TopicParams topicParams;
11+
12+
public LogQueryWithTopicsBuilder(StandardLogQueryParams standardLogQueryParams, TopicParams topicParams) {
13+
this.standardLogQueryParams = standardLogQueryParams;
14+
this.topicParams = topicParams;
15+
}
16+
17+
@Override
18+
public LogQuery build() throws LogQueryException {
19+
return new LogQuery(standardLogQueryParams, topicParams);
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package io.api.etherscan.model.query.impl;
2+
3+
public class StandardLogQueryParams {
4+
5+
private final String address;
6+
private final long startBlock;
7+
private final long endBlock;
8+
9+
public StandardLogQueryParams(String address, long startBlock, long endBlock) {
10+
this.address = address;
11+
this.startBlock = startBlock;
12+
this.endBlock = endBlock;
13+
}
14+
15+
public String getApiParams() {
16+
return "&address=" + address
17+
+ "&fromBlock=" + startBlock
18+
+ "&toBlock=" + endBlock;
19+
}
20+
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.api.etherscan.model.query.impl.topic;
2+
3+
import io.api.etherscan.model.query.LogTopic;
4+
5+
public abstract class BaseTopic {
6+
7+
private final TopicNr topicNr;
8+
private final LogTopic logTopic;
9+
10+
public BaseTopic(TopicNr topicNr, LogTopic logTopic) {
11+
this.topicNr = topicNr;
12+
this.logTopic = logTopic;
13+
}
14+
15+
public String getApiParams() {
16+
return topicNr.getTopicParam() + logTopic.getHex();
17+
}
18+
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.api.etherscan.model.query.impl.topic;
2+
3+
enum TopicNr {
4+
TOPIC_0("&topic0="),
5+
TOPIC_1("&topic1="),
6+
TOPIC_2("&topic2="),
7+
TOPIC_3("&topic3=");
8+
9+
private final String topicParam;
10+
11+
TopicNr(String topicParam) {
12+
this.topicParam = topicParam;
13+
}
14+
15+
public String getTopicParam() {
16+
return topicParam;
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.api.etherscan.model.query.impl.topic;
2+
3+
import io.api.etherscan.model.query.LogTopic;
4+
5+
public class TopicOne extends BaseTopic{
6+
7+
public TopicOne(LogTopic logTopic) {
8+
super(TopicNr.TOPIC_1, logTopic);
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package io.api.etherscan.model.query.impl.topic;
2+
3+
public interface TopicParams {
4+
5+
String getApiParams();
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package io.api.etherscan.model.query.impl.topic;
2+
3+
import io.api.etherscan.model.query.impl.topic.operator.*;
4+
import io.api.etherscan.model.query.impl.topic.pair.*;
5+
import io.api.etherscan.model.query.impl.topic.quadruple.TopicQuadruple;
6+
import io.api.etherscan.model.query.impl.topic.single.SingleTopic;
7+
import io.api.etherscan.model.query.impl.topic.triple.TopicTripleOneTwoThree;
8+
import io.api.etherscan.model.query.impl.topic.triple.TopicTripleZeroOneThree;
9+
import io.api.etherscan.model.query.impl.topic.triple.TopicTripleZeroOneTwo;
10+
import io.api.etherscan.model.query.impl.topic.triple.TopicTripleZeroTwoThree;
11+
12+
public class TopicParamsFactory {
13+
14+
/**
15+
* Factory Method for single Topic
16+
*/
17+
18+
public static TopicParams of(BaseTopic topic) {
19+
return new SingleTopic(topic);
20+
}
21+
22+
/**
23+
* Factory Methods for TopicPairs
24+
*/
25+
26+
public static TopicParams of(TopicZero topicZero, TopicOne topicOne, LogOperatorZeroOne operator) {
27+
return new TopicPairZeroOne(topicZero, topicOne, operator);
28+
}
29+
30+
public static TopicParams of(TopicZero topicZero, TopicTwo topicTwo, LogOperatorZeroTwo operator) {
31+
return new TopicPairZeroTwo(topicZero, topicTwo, operator);
32+
}
33+
34+
public static TopicParams of(TopicZero topicZero, TopicThree topicThree, LogOperatorZeroThree operator) {
35+
return new TopicPairZeroThree(topicZero, topicThree, operator);
36+
}
37+
38+
public static TopicParams of(TopicOne topicOne, TopicTwo topicTwo, LogOperatorOneTwo operator) {
39+
return new TopicPairOneTwo(topicOne, topicTwo, operator);
40+
}
41+
42+
public static TopicParams of(TopicOne topicOne, TopicThree topicThree, LogOperatorOneThree operator) {
43+
return new TopicPairOneThree(topicOne, topicThree, operator);
44+
}
45+
46+
public static TopicParams of(TopicTwo topicTwo, TopicThree topicThree, LogOperatorTwoThree operator) {
47+
return new TopicPairTwoThree(topicTwo, topicThree, operator);
48+
}
49+
50+
/**
51+
* Factory Methods for TopicTriples
52+
*/
53+
54+
public static TopicParams of(TopicZero topicZero,
55+
TopicOne topicOne,
56+
TopicTwo topicTwo,
57+
LogOperatorZeroOne operatorZeroOne,
58+
LogOperatorZeroTwo operatorZeroTwo,
59+
LogOperatorOneTwo operatorOneTwo) {
60+
return new TopicTripleZeroOneTwo(topicZero, topicOne, topicTwo, operatorZeroOne, operatorZeroTwo, operatorOneTwo);
61+
}
62+
63+
public static TopicParams of(TopicZero topicZero,
64+
TopicOne topicOne,
65+
TopicThree topicThree,
66+
LogOperatorZeroOne operatorZeroOne,
67+
LogOperatorZeroThree operatorZeroThree,
68+
LogOperatorOneThree operatorOneThree) {
69+
return new TopicTripleZeroOneThree(topicZero, topicOne, topicThree, operatorZeroOne, operatorZeroThree, operatorOneThree);
70+
}
71+
72+
public static TopicParams of(TopicZero topicZero,
73+
TopicTwo topicTwo,
74+
TopicThree topicThree,
75+
LogOperatorZeroTwo operatorZeroTwo,
76+
LogOperatorZeroThree operatorZeroThree,
77+
LogOperatorTwoThree operatorTwoThree) {
78+
return new TopicTripleZeroTwoThree(topicZero, topicTwo, topicThree, operatorZeroTwo, operatorZeroThree, operatorTwoThree);
79+
}
80+
81+
public static TopicParams of(TopicOne topicOne,
82+
TopicTwo topicTwo,
83+
TopicThree topicThree,
84+
LogOperatorOneTwo operatorOneTwo,
85+
LogOperatorOneThree operatorOneThree,
86+
LogOperatorTwoThree operatorTwoThree) {
87+
return new TopicTripleOneTwoThree(topicOne, topicTwo, topicThree, operatorOneTwo, operatorOneThree, operatorTwoThree);
88+
}
89+
90+
/**
91+
* Factory Method for TopicQuadruple
92+
*/
93+
94+
public static TopicParams of(TopicZero topicZero,
95+
TopicOne topicOne,
96+
TopicTwo topicTwo,
97+
TopicThree topicThree,
98+
LogOperatorZeroOne operatorZeroOne,
99+
LogOperatorZeroTwo operatorZeroTwo,
100+
LogOperatorZeroThree operatorZeroThree,
101+
LogOperatorOneTwo operatorOneTwo,
102+
LogOperatorOneThree operatorOneThree,
103+
LogOperatorTwoThree operatorTwoThree) {
104+
return new TopicQuadruple(topicZero,
105+
topicOne,
106+
topicTwo,
107+
topicThree,
108+
operatorZeroOne,
109+
operatorZeroTwo,
110+
operatorZeroThree,
111+
operatorOneTwo,
112+
operatorOneThree,
113+
operatorTwoThree);
114+
}
115+
}

0 commit comments

Comments
 (0)