Skip to content

Commit 095288c

Browse files
authoredJan 30, 2025··
Merge pull request #4994 from donald-jackson/binance/network-deposit-support
[binance] add support for network specific withdrawals and deposit addresses
2 parents 6fa9e64 + 647e26e commit 095288c

File tree

5 files changed

+124
-9
lines changed

5 files changed

+124
-9
lines changed
 

‎xchange-binance/src/main/java/org/knowm/xchange/binance/BinanceAuthenticated.java

+2
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ WithdrawResponse withdraw(
371371
@FormParam("addressTag") String addressTag,
372372
@FormParam("amount") BigDecimal amount,
373373
@FormParam("name") String name,
374+
@FormParam("network") String network,
374375
@FormParam("recvWindow") Long recvWindow,
375376
@FormParam("timestamp") SynchronizedValueFactory<Long> timestamp,
376377
@HeaderParam(X_MBX_APIKEY) String apiKey,
@@ -499,6 +500,7 @@ List<TransferSubUserHistory> transferSubUserHistory(
499500
@Path("/sapi/v1/capital/deposit/address")
500501
DepositAddress depositAddress(
501502
@QueryParam("coin") String coin,
503+
@QueryParam("network") String network,
502504
@QueryParam("recvWindow") Long recvWindow,
503505
@QueryParam("timestamp") SynchronizedValueFactory<Long> timestamp,
504506
@HeaderParam(X_MBX_APIKEY) String apiKey,

‎xchange-binance/src/main/java/org/knowm/xchange/binance/dto/trade/TimeInForce.java

+2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package org.knowm.xchange.binance.dto.trade;
22

33
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
45
import org.knowm.xchange.dto.Order.IOrderFlags;
56

7+
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
68
public enum TimeInForce implements IOrderFlags {
79
GTC,
810
GTX,

‎xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceAccountService.java

+65-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package org.knowm.xchange.binance.service;
22

33
import static org.knowm.xchange.binance.BinanceExchange.EXCHANGE_TYPE;
4-
import static org.knowm.xchange.binance.dto.ExchangeType.FUTURES;
5-
import static org.knowm.xchange.binance.dto.ExchangeType.SPOT;
64

75
import java.io.IOException;
86
import java.math.BigDecimal;
@@ -13,13 +11,16 @@
1311
import java.util.HashMap;
1412
import java.util.List;
1513
import java.util.Map;
14+
import org.apache.commons.lang3.StringUtils;
1615
import org.knowm.xchange.binance.BinanceAdapters;
1716
import org.knowm.xchange.binance.BinanceErrorAdapter;
1817
import org.knowm.xchange.binance.BinanceExchange;
1918
import org.knowm.xchange.binance.dto.BinanceException;
2019
import org.knowm.xchange.binance.dto.ExchangeType;
2120
import org.knowm.xchange.binance.dto.account.AssetDetail;
2221
import org.knowm.xchange.binance.dto.account.BinanceAccountInformation;
22+
import org.knowm.xchange.binance.dto.account.BinanceCurrencyInfo;
23+
import org.knowm.xchange.binance.dto.account.BinanceCurrencyInfo.Network;
2324
import org.knowm.xchange.binance.dto.account.BinanceFundingHistoryParams;
2425
import org.knowm.xchange.binance.dto.account.BinanceMasterAccountTransferHistoryParams;
2526
import org.knowm.xchange.binance.dto.account.BinanceSubAccountTransferHistoryParams;
@@ -38,8 +39,10 @@
3839
import org.knowm.xchange.dto.account.Wallet;
3940
import org.knowm.xchange.instrument.Instrument;
4041
import org.knowm.xchange.service.account.AccountService;
42+
import org.knowm.xchange.service.account.params.RequestDepositAddressParams;
4143
import org.knowm.xchange.service.trade.params.DefaultWithdrawFundsParams;
4244
import org.knowm.xchange.service.trade.params.HistoryParamsFundingType;
45+
import org.knowm.xchange.service.trade.params.NetworkWithdrawFundsParams;
4346
import org.knowm.xchange.service.trade.params.RippleWithdrawFundsParams;
4447
import org.knowm.xchange.service.trade.params.TradeHistoryParamCurrency;
4548
import org.knowm.xchange.service.trade.params.TradeHistoryParamLimit;
@@ -187,15 +190,26 @@ public String withdrawFunds(WithdrawFundsParams params) throws IOException {
187190
rippleParams.getCurrency().getCurrencyCode(),
188191
rippleParams.getAddress(),
189192
rippleParams.getTag(),
190-
rippleParams.getAmount());
193+
rippleParams.getAmount(),
194+
Currency.XRP.getCurrencyCode());
195+
} else if (params instanceof NetworkWithdrawFundsParams) {
196+
NetworkWithdrawFundsParams p = (NetworkWithdrawFundsParams) params;
197+
withdraw =
198+
super.withdraw(
199+
p.getCurrency().getCurrencyCode(),
200+
p.getAddress(),
201+
p.getAddressTag(),
202+
p.getAmount(),
203+
p.getNetwork());
191204
} else {
192205
DefaultWithdrawFundsParams p = (DefaultWithdrawFundsParams) params;
193206
withdraw =
194207
super.withdraw(
195208
p.getCurrency().getCurrencyCode(),
196209
p.getAddress(),
197210
p.getAddressTag(),
198-
p.getAmount());
211+
p.getAmount(),
212+
null);
199213
}
200214
return withdraw.getId();
201215
} catch (BinanceException e) {
@@ -215,14 +229,60 @@ public String requestDepositAddress(Currency currency, String... args) throws IO
215229
@Override
216230
public AddressWithTag requestDepositAddressData(Currency currency, String... args)
217231
throws IOException {
218-
DepositAddress depositAddress = super.requestDepositAddress(currency);
232+
return prepareAddressWithTag(super.requestDepositAddress(currency));
233+
}
234+
235+
@Override
236+
public AddressWithTag requestDepositAddressData(
237+
RequestDepositAddressParams requestDepositAddressParams) throws IOException {
238+
if (StringUtils.isEmpty(requestDepositAddressParams.getNetwork())) {
239+
return requestDepositAddressData(
240+
requestDepositAddressParams.getCurrency(),
241+
requestDepositAddressParams.getExtraArguments());
242+
}
243+
244+
BinanceCurrencyInfo binanceCurrencyInfo =
245+
super.getCurrencyInfo(requestDepositAddressParams.getCurrency())
246+
.orElseThrow(
247+
() ->
248+
new IllegalArgumentException(
249+
"Currency not supported: " + requestDepositAddressParams.getCurrency()));
250+
251+
Network binanceNetwork =
252+
binanceCurrencyInfo.getNetworks().stream()
253+
.filter(
254+
network ->
255+
requestDepositAddressParams.getNetwork().equals(network.getId())
256+
|| network
257+
.getId()
258+
.equals(requestDepositAddressParams.getCurrency().getCurrencyCode()))
259+
.findFirst()
260+
.orElseThrow(
261+
() ->
262+
new IllegalArgumentException(
263+
"Network not supported: " + requestDepositAddressParams.getNetwork()));
264+
265+
DepositAddress depositAddress =
266+
super.requestDepositAddressWithNetwork(
267+
requestDepositAddressParams.getCurrency(), binanceNetwork.getId());
268+
269+
return prepareAddressWithTag(depositAddress);
270+
}
271+
272+
private static AddressWithTag prepareAddressWithTag(DepositAddress depositAddress) {
219273
String destinationTag =
220274
(depositAddress.addressTag == null || depositAddress.addressTag.isEmpty())
221275
? null
222276
: depositAddress.addressTag;
223277
return new AddressWithTag(depositAddress.address, destinationTag);
224278
}
225279

280+
@Override
281+
public String requestDepositAddress(RequestDepositAddressParams requestDepositAddressParams)
282+
throws IOException {
283+
return requestDepositAddressData(requestDepositAddressParams).getAddress();
284+
}
285+
226286
public Map<String, AssetDetail> getAssetDetails() throws IOException {
227287
try {
228288
return super.requestAssetDetail();

‎xchange-binance/src/main/java/org/knowm/xchange/binance/service/BinanceAccountServiceRaw.java

+41-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import java.math.BigDecimal;
88
import java.util.List;
99
import java.util.Map;
10+
import java.util.Optional;
11+
import java.util.concurrent.locks.Lock;
12+
import java.util.concurrent.locks.ReentrantLock;
1013
import org.knowm.xchange.binance.BinanceAdapters;
1114
import org.knowm.xchange.binance.BinanceExchange;
1215
import org.knowm.xchange.binance.dto.BinanceException;
@@ -25,6 +28,8 @@
2528
import org.knowm.xchange.currency.Currency;
2629

2730
public class BinanceAccountServiceRaw extends BinanceBaseService {
31+
private List<BinanceCurrencyInfo> currencyInfos;
32+
private final Lock currencyInfoLock = new ReentrantLock();
2833

2934
public BinanceAccountServiceRaw(
3035
BinanceExchange exchange, ResilienceRegistries resilienceRegistries) {
@@ -63,19 +68,24 @@ public WithdrawResponse withdraw(String coin, String address, BigDecimal amount)
6368
throws IOException, BinanceException {
6469
// the name parameter seams to be mandatory
6570
String name = address.length() <= 10 ? address : address.substring(0, 10);
66-
return withdraw(coin, address, null, amount, name);
71+
return withdraw(coin, address, null, amount, name, null);
6772
}
6873

6974
public WithdrawResponse withdraw(
70-
String coin, String address, String addressTag, BigDecimal amount)
75+
String coin, String address, String addressTag, BigDecimal amount, String network)
7176
throws IOException, BinanceException {
7277
// the name parameter seams to be mandatory
7378
String name = address.length() <= 10 ? address : address.substring(0, 10);
74-
return withdraw(coin, address, addressTag, amount, name);
79+
return withdraw(coin, address, addressTag, amount, name, network);
7580
}
7681

7782
private WithdrawResponse withdraw(
78-
String coin, String address, String addressTag, BigDecimal amount, String name)
83+
String coin,
84+
String address,
85+
String addressTag,
86+
BigDecimal amount,
87+
String name,
88+
String network)
7989
throws IOException, BinanceException {
8090
return decorateApiCall(
8191
() ->
@@ -85,6 +95,7 @@ private WithdrawResponse withdraw(
8595
addressTag,
8696
amount,
8797
name,
98+
network,
8899
getRecvWindow(),
89100
getTimestampFactory(),
90101
apiKey,
@@ -95,10 +106,16 @@ private WithdrawResponse withdraw(
95106
}
96107

97108
public DepositAddress requestDepositAddress(Currency currency) throws IOException {
109+
return requestDepositAddressWithNetwork(currency, null);
110+
}
111+
112+
public DepositAddress requestDepositAddressWithNetwork(Currency currency, String network)
113+
throws IOException {
98114
return decorateApiCall(
99115
() ->
100116
binance.depositAddress(
101117
BinanceAdapters.toSymbol(currency),
118+
network,
102119
getRecvWindow(),
103120
getTimestampFactory(),
104121
apiKey,
@@ -214,4 +231,24 @@ public List<TransferSubUserHistory> getSubUserHistory(
214231
.withRateLimiter(rateLimiter(REQUEST_WEIGHT_RATE_LIMITER))
215232
.call();
216233
}
234+
235+
protected List<BinanceCurrencyInfo> getCurrencyInfoCached() throws IOException {
236+
currencyInfoLock.lock();
237+
try {
238+
if (currencyInfos == null) {
239+
currencyInfos = currencyInfos();
240+
}
241+
currencyInfos = currencyInfos();
242+
} finally {
243+
currencyInfoLock.unlock();
244+
}
245+
246+
return currencyInfos;
247+
}
248+
249+
protected Optional<BinanceCurrencyInfo> getCurrencyInfo(Currency currency) throws IOException {
250+
return getCurrencyInfoCached().stream()
251+
.filter(info -> currency.equals(info.getCurrency()))
252+
.findFirst();
253+
}
217254
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.knowm.xchange.service.trade.params;
2+
3+
import lombok.ToString;
4+
import lombok.Value;
5+
import lombok.experimental.NonFinal;
6+
import lombok.experimental.SuperBuilder;
7+
8+
@Value
9+
@NonFinal
10+
@SuperBuilder
11+
@ToString(callSuper = true)
12+
public class NetworkWithdrawFundsParams extends DefaultWithdrawFundsParams {
13+
String network;
14+
}

0 commit comments

Comments
 (0)
Please sign in to comment.