Skip to content

Commit

Permalink
Merge pull request #4994 from donald-jackson/binance/network-deposit-…
Browse files Browse the repository at this point in the history
…support

[binance] add support for network specific withdrawals and deposit addresses
  • Loading branch information
timmolter authored Jan 30, 2025
2 parents 6fa9e64 + 647e26e commit 095288c
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ WithdrawResponse withdraw(
@FormParam("addressTag") String addressTag,
@FormParam("amount") BigDecimal amount,
@FormParam("name") String name,
@FormParam("network") String network,
@FormParam("recvWindow") Long recvWindow,
@FormParam("timestamp") SynchronizedValueFactory<Long> timestamp,
@HeaderParam(X_MBX_APIKEY) String apiKey,
Expand Down Expand Up @@ -499,6 +500,7 @@ List<TransferSubUserHistory> transferSubUserHistory(
@Path("/sapi/v1/capital/deposit/address")
DepositAddress depositAddress(
@QueryParam("coin") String coin,
@QueryParam("network") String network,
@QueryParam("recvWindow") Long recvWindow,
@QueryParam("timestamp") SynchronizedValueFactory<Long> timestamp,
@HeaderParam(X_MBX_APIKEY) String apiKey,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.knowm.xchange.binance.dto.trade;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.knowm.xchange.dto.Order.IOrderFlags;

@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
public enum TimeInForce implements IOrderFlags {
GTC,
GTX,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package org.knowm.xchange.binance.service;

import static org.knowm.xchange.binance.BinanceExchange.EXCHANGE_TYPE;
import static org.knowm.xchange.binance.dto.ExchangeType.FUTURES;
import static org.knowm.xchange.binance.dto.ExchangeType.SPOT;

import java.io.IOException;
import java.math.BigDecimal;
Expand All @@ -13,13 +11,16 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.knowm.xchange.binance.BinanceAdapters;
import org.knowm.xchange.binance.BinanceErrorAdapter;
import org.knowm.xchange.binance.BinanceExchange;
import org.knowm.xchange.binance.dto.BinanceException;
import org.knowm.xchange.binance.dto.ExchangeType;
import org.knowm.xchange.binance.dto.account.AssetDetail;
import org.knowm.xchange.binance.dto.account.BinanceAccountInformation;
import org.knowm.xchange.binance.dto.account.BinanceCurrencyInfo;
import org.knowm.xchange.binance.dto.account.BinanceCurrencyInfo.Network;
import org.knowm.xchange.binance.dto.account.BinanceFundingHistoryParams;
import org.knowm.xchange.binance.dto.account.BinanceMasterAccountTransferHistoryParams;
import org.knowm.xchange.binance.dto.account.BinanceSubAccountTransferHistoryParams;
Expand All @@ -38,8 +39,10 @@
import org.knowm.xchange.dto.account.Wallet;
import org.knowm.xchange.instrument.Instrument;
import org.knowm.xchange.service.account.AccountService;
import org.knowm.xchange.service.account.params.RequestDepositAddressParams;
import org.knowm.xchange.service.trade.params.DefaultWithdrawFundsParams;
import org.knowm.xchange.service.trade.params.HistoryParamsFundingType;
import org.knowm.xchange.service.trade.params.NetworkWithdrawFundsParams;
import org.knowm.xchange.service.trade.params.RippleWithdrawFundsParams;
import org.knowm.xchange.service.trade.params.TradeHistoryParamCurrency;
import org.knowm.xchange.service.trade.params.TradeHistoryParamLimit;
Expand Down Expand Up @@ -187,15 +190,26 @@ public String withdrawFunds(WithdrawFundsParams params) throws IOException {
rippleParams.getCurrency().getCurrencyCode(),
rippleParams.getAddress(),
rippleParams.getTag(),
rippleParams.getAmount());
rippleParams.getAmount(),
Currency.XRP.getCurrencyCode());
} else if (params instanceof NetworkWithdrawFundsParams) {
NetworkWithdrawFundsParams p = (NetworkWithdrawFundsParams) params;
withdraw =
super.withdraw(
p.getCurrency().getCurrencyCode(),
p.getAddress(),
p.getAddressTag(),
p.getAmount(),
p.getNetwork());
} else {
DefaultWithdrawFundsParams p = (DefaultWithdrawFundsParams) params;
withdraw =
super.withdraw(
p.getCurrency().getCurrencyCode(),
p.getAddress(),
p.getAddressTag(),
p.getAmount());
p.getAmount(),
null);
}
return withdraw.getId();
} catch (BinanceException e) {
Expand All @@ -215,14 +229,60 @@ public String requestDepositAddress(Currency currency, String... args) throws IO
@Override
public AddressWithTag requestDepositAddressData(Currency currency, String... args)
throws IOException {
DepositAddress depositAddress = super.requestDepositAddress(currency);
return prepareAddressWithTag(super.requestDepositAddress(currency));
}

@Override
public AddressWithTag requestDepositAddressData(
RequestDepositAddressParams requestDepositAddressParams) throws IOException {
if (StringUtils.isEmpty(requestDepositAddressParams.getNetwork())) {
return requestDepositAddressData(
requestDepositAddressParams.getCurrency(),
requestDepositAddressParams.getExtraArguments());
}

BinanceCurrencyInfo binanceCurrencyInfo =
super.getCurrencyInfo(requestDepositAddressParams.getCurrency())
.orElseThrow(
() ->
new IllegalArgumentException(
"Currency not supported: " + requestDepositAddressParams.getCurrency()));

Network binanceNetwork =
binanceCurrencyInfo.getNetworks().stream()
.filter(
network ->
requestDepositAddressParams.getNetwork().equals(network.getId())
|| network
.getId()
.equals(requestDepositAddressParams.getCurrency().getCurrencyCode()))
.findFirst()
.orElseThrow(
() ->
new IllegalArgumentException(
"Network not supported: " + requestDepositAddressParams.getNetwork()));

DepositAddress depositAddress =
super.requestDepositAddressWithNetwork(
requestDepositAddressParams.getCurrency(), binanceNetwork.getId());

return prepareAddressWithTag(depositAddress);
}

private static AddressWithTag prepareAddressWithTag(DepositAddress depositAddress) {
String destinationTag =
(depositAddress.addressTag == null || depositAddress.addressTag.isEmpty())
? null
: depositAddress.addressTag;
return new AddressWithTag(depositAddress.address, destinationTag);
}

@Override
public String requestDepositAddress(RequestDepositAddressParams requestDepositAddressParams)
throws IOException {
return requestDepositAddressData(requestDepositAddressParams).getAddress();
}

public Map<String, AssetDetail> getAssetDetails() throws IOException {
try {
return super.requestAssetDetail();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.knowm.xchange.binance.BinanceAdapters;
import org.knowm.xchange.binance.BinanceExchange;
import org.knowm.xchange.binance.dto.BinanceException;
Expand All @@ -25,6 +28,8 @@
import org.knowm.xchange.currency.Currency;

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

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

public WithdrawResponse withdraw(
String coin, String address, String addressTag, BigDecimal amount)
String coin, String address, String addressTag, BigDecimal amount, String network)
throws IOException, BinanceException {
// the name parameter seams to be mandatory
String name = address.length() <= 10 ? address : address.substring(0, 10);
return withdraw(coin, address, addressTag, amount, name);
return withdraw(coin, address, addressTag, amount, name, network);
}

private WithdrawResponse withdraw(
String coin, String address, String addressTag, BigDecimal amount, String name)
String coin,
String address,
String addressTag,
BigDecimal amount,
String name,
String network)
throws IOException, BinanceException {
return decorateApiCall(
() ->
Expand All @@ -85,6 +95,7 @@ private WithdrawResponse withdraw(
addressTag,
amount,
name,
network,
getRecvWindow(),
getTimestampFactory(),
apiKey,
Expand All @@ -95,10 +106,16 @@ private WithdrawResponse withdraw(
}

public DepositAddress requestDepositAddress(Currency currency) throws IOException {
return requestDepositAddressWithNetwork(currency, null);
}

public DepositAddress requestDepositAddressWithNetwork(Currency currency, String network)
throws IOException {
return decorateApiCall(
() ->
binance.depositAddress(
BinanceAdapters.toSymbol(currency),
network,
getRecvWindow(),
getTimestampFactory(),
apiKey,
Expand Down Expand Up @@ -214,4 +231,24 @@ public List<TransferSubUserHistory> getSubUserHistory(
.withRateLimiter(rateLimiter(REQUEST_WEIGHT_RATE_LIMITER))
.call();
}

protected List<BinanceCurrencyInfo> getCurrencyInfoCached() throws IOException {
currencyInfoLock.lock();
try {
if (currencyInfos == null) {
currencyInfos = currencyInfos();
}
currencyInfos = currencyInfos();
} finally {
currencyInfoLock.unlock();
}

return currencyInfos;
}

protected Optional<BinanceCurrencyInfo> getCurrencyInfo(Currency currency) throws IOException {
return getCurrencyInfoCached().stream()
.filter(info -> currency.equals(info.getCurrency()))
.findFirst();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.knowm.xchange.service.trade.params;

import lombok.ToString;
import lombok.Value;
import lombok.experimental.NonFinal;
import lombok.experimental.SuperBuilder;

@Value
@NonFinal
@SuperBuilder
@ToString(callSuper = true)
public class NetworkWithdrawFundsParams extends DefaultWithdrawFundsParams {
String network;
}

0 comments on commit 095288c

Please sign in to comment.