@@ -25,6 +25,8 @@ public class AccountProvider extends BasicProvider implements IAccountProvider {
25
25
private static final int MAX_END_BLOCK = 999999999 ;
26
26
private static final int MIN_START_BLOCK = 0 ;
27
27
28
+ private static final int OFFSET_MAX = 10000 ;
29
+
28
30
private static final String BALANCE_ACTION = ACTION_PARAM + "balance" ;
29
31
private static final String BALANCE_MULTI_ACTION = ACTION_PARAM + "balancemulti" ;
30
32
private static final String TX_ACTION = ACTION_PARAM + "txlist" ;
@@ -55,11 +57,11 @@ public Balance balance(final String address) {
55
57
BasicUtils .validateAddress (address );
56
58
57
59
final String urlParams = BALANCE_ACTION + TAG_LATEST_PARAM + ADDRESS_PARAM + address ;
58
- final StringResponseTO converted = getRequest (urlParams , StringResponseTO .class );
59
- if (converted .getStatus () != 1 )
60
- throw new EtherScanException (converted .getMessage () + ", with status " + converted .getStatus ());
60
+ final StringResponseTO response = getRequest (urlParams , StringResponseTO .class );
61
+ if (response .getStatus () != 1 )
62
+ throw new EtherScanException (response .getMessage () + ", with status " + response .getStatus ());
61
63
62
- return new Balance (address , Long .valueOf (converted .getResult ()));
64
+ return new Balance (address , Long .valueOf (response .getResult ()));
63
65
}
64
66
65
67
@ NotNull
@@ -76,12 +78,12 @@ public List<Balance> balances(final List<String> addresses) {
76
78
77
79
for (final List <String > batch : addressesAsBatches ) {
78
80
final String urlParams = BALANCE_MULTI_ACTION + TAG_LATEST_PARAM + ADDRESS_PARAM + toAddressParam (batch );
79
- final BalanceResponseTO converted = getRequest (urlParams , BalanceResponseTO .class );
80
- if (converted .getStatus () != 1 )
81
- throw new EtherScanException (converted .getMessage () + ", with status " + converted .getStatus ());
81
+ final BalanceResponseTO response = getRequest (urlParams , BalanceResponseTO .class );
82
+ if (response .getStatus () != 1 )
83
+ throw new EtherScanException (response .getMessage () + ", with status " + response .getStatus ());
82
84
83
- if (!BasicUtils .isEmpty (converted . getBalances ()))
84
- balances .addAll (converted . getBalances ().stream ()
85
+ if (!BasicUtils .isEmpty (response . getResult ()))
86
+ balances .addAll (response . getResult ().stream ()
85
87
.map (Balance ::of )
86
88
.collect (Collectors .toList ()));
87
89
}
@@ -96,7 +98,6 @@ private String toAddressParam(final List<String> addresses) {
96
98
@ NotNull
97
99
@ Override
98
100
public List <Tx > txs (final String address ) {
99
- //TODO all txs implementations with pagination
100
101
return txs (address , MIN_START_BLOCK );
101
102
}
102
103
@@ -111,21 +112,44 @@ public List<Tx> txs(final String address, final long startBlock) {
111
112
public List <Tx > txs (final String address , final long startBlock , final long endBlock ) {
112
113
BasicUtils .validateAddress (address );
113
114
115
+ final String offsetParam = PAGE_PARAM + "%s" + OFFSET_PARAM + OFFSET_MAX ;
114
116
final String blockParam = START_BLOCK_PARAM + startBlock + END_BLOCK_PARAM + endBlock ;
115
- final String urlParams = TX_ACTION + ADDRESS_PARAM + address + blockParam + SORT_ASC_PARAM ;
116
- final TxResponseTO converted = getRequest (urlParams , TxResponseTO .class );
117
- if (converted .getStatus () != 1 )
118
- throw new EtherScanException (converted .getMessage () + " with status " + converted .getStatus ());
117
+ final String urlParams = TX_ACTION + offsetParam + ADDRESS_PARAM + address + blockParam + SORT_ASC_PARAM ;
119
118
120
- return (converted .getResult () == null )
121
- ? Collections .emptyList ()
122
- : converted .getResult ();
119
+ return getRequestUsingOffset (urlParams , TxResponseTO .class );
120
+ }
121
+
122
+ /**
123
+ * Generic search for txs using offset api param
124
+ * To avoid 10k limit per response
125
+ *
126
+ * @param urlParams Url params for #getRequest()
127
+ * @param tClass responseListTO class
128
+ * @param <T> responseTO list T type
129
+ * @param <R> responseListTO type
130
+ * @return List of T values
131
+ */
132
+ private <T , R extends BaseListResponseTO > List <T > getRequestUsingOffset (final String urlParams , Class <R > tClass ) {
133
+ final List <T > result = new ArrayList <>();
134
+ int page = 1 ;
135
+ while (true ) {
136
+ final String formattedUrl = String .format (urlParams , page ++);
137
+ final R response = getRequest (formattedUrl , tClass );
138
+ BasicUtils .validateTxResponse (response );
139
+ if (BasicUtils .isEmpty (response .getResult ()))
140
+ break ;
141
+
142
+ result .addAll (response .getResult ());
143
+ if (response .getResult ().size () < OFFSET_MAX )
144
+ break ;
145
+ }
146
+
147
+ return result ;
123
148
}
124
149
125
150
@ NotNull
126
151
@ Override
127
152
public List <TxInternal > txsInternal (final String address ) {
128
- //TODO all txs implementations with pagination
129
153
return txsInternal (address , MIN_START_BLOCK );
130
154
}
131
155
@@ -140,36 +164,31 @@ public List<TxInternal> txsInternal(final String address, final long startBlock)
140
164
public List <TxInternal > txsInternal (final String address , final long startBlock , final long endBlock ) {
141
165
BasicUtils .validateAddress (address );
142
166
167
+ final String offsetParam = PAGE_PARAM + "%s" + OFFSET_PARAM + OFFSET_MAX ;
143
168
final String blockParam = START_BLOCK_PARAM + startBlock + END_BLOCK_PARAM + endBlock ;
144
- final String urlParams = TX_INTERNAL_ACTION + ADDRESS_PARAM + address + blockParam + SORT_ASC_PARAM ;
145
- final TxInternalResponseTO converted = getRequest (urlParams , TxInternalResponseTO .class );
146
- if (converted .getStatus () != 1 )
147
- throw new EtherScanException (converted .getMessage () + " with status " + converted .getStatus ());
169
+ final String urlParams = TX_INTERNAL_ACTION + offsetParam + ADDRESS_PARAM + address + blockParam + SORT_ASC_PARAM ;
148
170
149
- return (converted .getResult () == null )
150
- ? Collections .emptyList ()
151
- : converted .getResult ();
171
+ return getRequestUsingOffset (urlParams , TxInternalResponseTO .class );
152
172
}
153
173
174
+
154
175
@ NotNull
155
176
@ Override
156
177
public List <TxInternal > txsInternalByHash (final String txhash ) {
157
178
BasicUtils .validateTxHash (txhash );
158
179
159
180
final String urlParams = TX_INTERNAL_ACTION + TXHASH_PARAM + txhash ;
160
- final TxInternalResponseTO converted = getRequest (urlParams , TxInternalResponseTO .class );
161
- if (converted .getStatus () != 1 )
162
- throw new EtherScanException (converted .getMessage () + " with status " + converted .getStatus ());
181
+ final TxInternalResponseTO response = getRequest (urlParams , TxInternalResponseTO .class );
182
+ BasicUtils .validateTxResponse (response );
163
183
164
- return ( converted .getResult () == null )
184
+ return BasicUtils . isEmpty ( response .getResult ())
165
185
? Collections .emptyList ()
166
- : converted .getResult ();
186
+ : response .getResult ();
167
187
}
168
188
169
189
@ NotNull
170
190
@ Override
171
191
public List <TxToken > txsToken (final String address ) {
172
- //TODO all txs implementations with pagination
173
192
return txsToken (address , MIN_START_BLOCK );
174
193
}
175
194
@@ -184,29 +203,21 @@ public List<TxToken> txsToken(final String address, final long startBlock) {
184
203
public List <TxToken > txsToken (final String address , final long startBlock , final long endBlock ) {
185
204
BasicUtils .validateAddress (address );
186
205
206
+ final String offsetParam = PAGE_PARAM + "%s" + OFFSET_PARAM + OFFSET_MAX ;
187
207
final String blockParam = START_BLOCK_PARAM + startBlock + END_BLOCK_PARAM + endBlock ;
188
- final String urlParams = TX_TOKEN_ACTION + ADDRESS_PARAM + address + blockParam + SORT_ASC_PARAM ;
189
- final TxTokenResponseTO converted = getRequest (urlParams , TxTokenResponseTO .class );
190
- if (converted .getStatus () != 1 )
191
- throw new EtherScanException (converted .getMessage () + " with status " + converted .getStatus ());
208
+ final String urlParams = TX_TOKEN_ACTION + offsetParam + ADDRESS_PARAM + address + blockParam + SORT_ASC_PARAM ;
192
209
193
- return (converted .getResult () == null )
194
- ? Collections .emptyList ()
195
- : converted .getResult ();
210
+ return getRequestUsingOffset (urlParams , TxTokenResponseTO .class );
196
211
}
197
212
198
213
@ NotNull
199
214
@ Override
200
215
public List <Block > minedBlocks (final String address ) {
201
216
BasicUtils .validateAddress (address );
202
217
203
- final String urlParams = MINED_ACTION + BLOCK_TYPE_PARAM + ADDRESS_PARAM + address ;
204
- final BlockResponseTO converted = getRequest (urlParams , BlockResponseTO .class );
205
- if (converted .getStatus () != 1 )
206
- throw new EtherScanException (converted .getMessage () + " with status " + converted .getStatus ());
218
+ final String offsetParam = PAGE_PARAM + "%s" + OFFSET_PARAM + OFFSET_MAX ;
219
+ final String urlParams = MINED_ACTION + offsetParam + BLOCK_TYPE_PARAM + ADDRESS_PARAM + address ;
207
220
208
- return (converted .getResult () == null )
209
- ? Collections .emptyList ()
210
- : converted .getResult ();
221
+ return getRequestUsingOffset (urlParams , BlockResponseTO .class );
211
222
}
212
223
}
0 commit comments