@@ -25,6 +25,8 @@ public class AccountProvider extends BasicProvider implements IAccountProvider {
2525 private static final int MAX_END_BLOCK = 999999999 ;
2626 private static final int MIN_START_BLOCK = 0 ;
2727
28+ private static final int OFFSET_MAX = 10000 ;
29+
2830 private static final String BALANCE_ACTION = ACTION_PARAM + "balance" ;
2931 private static final String BALANCE_MULTI_ACTION = ACTION_PARAM + "balancemulti" ;
3032 private static final String TX_ACTION = ACTION_PARAM + "txlist" ;
@@ -55,11 +57,11 @@ public Balance balance(final String address) {
5557 BasicUtils .validateAddress (address );
5658
5759 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 ());
6163
62- return new Balance (address , Long .valueOf (converted .getResult ()));
64+ return new Balance (address , Long .valueOf (response .getResult ()));
6365 }
6466
6567 @ NotNull
@@ -76,12 +78,12 @@ public List<Balance> balances(final List<String> addresses) {
7678
7779 for (final List <String > batch : addressesAsBatches ) {
7880 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 ());
8284
83- if (!BasicUtils .isEmpty (converted . getBalances ()))
84- balances .addAll (converted . getBalances ().stream ()
85+ if (!BasicUtils .isEmpty (response . getResult ()))
86+ balances .addAll (response . getResult ().stream ()
8587 .map (Balance ::of )
8688 .collect (Collectors .toList ()));
8789 }
@@ -96,7 +98,6 @@ private String toAddressParam(final List<String> addresses) {
9698 @ NotNull
9799 @ Override
98100 public List <Tx > txs (final String address ) {
99- //TODO all txs implementations with pagination
100101 return txs (address , MIN_START_BLOCK );
101102 }
102103
@@ -111,21 +112,44 @@ public List<Tx> txs(final String address, final long startBlock) {
111112 public List <Tx > txs (final String address , final long startBlock , final long endBlock ) {
112113 BasicUtils .validateAddress (address );
113114
115+ final String offsetParam = PAGE_PARAM + "%s" + OFFSET_PARAM + OFFSET_MAX ;
114116 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 ;
119118
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 ;
123148 }
124149
125150 @ NotNull
126151 @ Override
127152 public List <TxInternal > txsInternal (final String address ) {
128- //TODO all txs implementations with pagination
129153 return txsInternal (address , MIN_START_BLOCK );
130154 }
131155
@@ -140,36 +164,31 @@ public List<TxInternal> txsInternal(final String address, final long startBlock)
140164 public List <TxInternal > txsInternal (final String address , final long startBlock , final long endBlock ) {
141165 BasicUtils .validateAddress (address );
142166
167+ final String offsetParam = PAGE_PARAM + "%s" + OFFSET_PARAM + OFFSET_MAX ;
143168 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 ;
148170
149- return (converted .getResult () == null )
150- ? Collections .emptyList ()
151- : converted .getResult ();
171+ return getRequestUsingOffset (urlParams , TxInternalResponseTO .class );
152172 }
153173
174+
154175 @ NotNull
155176 @ Override
156177 public List <TxInternal > txsInternalByHash (final String txhash ) {
157178 BasicUtils .validateTxHash (txhash );
158179
159180 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 );
163183
164- return ( converted .getResult () == null )
184+ return BasicUtils . isEmpty ( response .getResult ())
165185 ? Collections .emptyList ()
166- : converted .getResult ();
186+ : response .getResult ();
167187 }
168188
169189 @ NotNull
170190 @ Override
171191 public List <TxToken > txsToken (final String address ) {
172- //TODO all txs implementations with pagination
173192 return txsToken (address , MIN_START_BLOCK );
174193 }
175194
@@ -184,29 +203,21 @@ public List<TxToken> txsToken(final String address, final long startBlock) {
184203 public List <TxToken > txsToken (final String address , final long startBlock , final long endBlock ) {
185204 BasicUtils .validateAddress (address );
186205
206+ final String offsetParam = PAGE_PARAM + "%s" + OFFSET_PARAM + OFFSET_MAX ;
187207 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 ;
192209
193- return (converted .getResult () == null )
194- ? Collections .emptyList ()
195- : converted .getResult ();
210+ return getRequestUsingOffset (urlParams , TxTokenResponseTO .class );
196211 }
197212
198213 @ NotNull
199214 @ Override
200215 public List <Block > minedBlocks (final String address ) {
201216 BasicUtils .validateAddress (address );
202217
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 ;
207220
208- return (converted .getResult () == null )
209- ? Collections .emptyList ()
210- : converted .getResult ();
221+ return getRequestUsingOffset (urlParams , BlockResponseTO .class );
211222 }
212223}
0 commit comments