Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[binance] deposit addresses and network support #76

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Expand Up @@ -242,14 +242,25 @@ public static UserTrades adaptTradeHistory(BitstampUserTransaction[] bitstampUse
.timestamp(t.getDatetime())
.id(Long.toString(tradeId))
.orderId(Long.toString(t.getOrderId()))
.feeAmount(t.getFee())
.feeAmount(getFeeFromString(t.getFee()))
.feeCurrency(Currency.getInstance(t.getFeeCurrency().toUpperCase()))
.build();
trades.add(trade);
}
return new UserTrades(trades, lastTradeId, TradeSortType.SortByID);
}

private static BigDecimal getFeeFromString(String value) {
if("None".equals(value)) {
return BigDecimal.ZERO;
}
try {
return new BigDecimal(value);
} catch (NumberFormatException e) {
return BigDecimal.ZERO;
}
}

public static Map.Entry<String, BigDecimal> findNonzeroAmount(BitstampUserTransaction transaction)
throws ExchangeException {
for (Map.Entry<String, BigDecimal> entry : transaction.getAmounts().entrySet()) {
Expand Down Expand Up @@ -294,7 +305,7 @@ public static List<FundingRecord> adaptFundingHistory(
type,
FundingRecord.Status.COMPLETE,
null,
trans.getFee(),
getFeeFromString(trans.getFee()),
null);
fundingRecords.add(record);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public final class BitstampUserTransaction {
private final long id;
private final long order_id;
private final TransactionType type;
private final BigDecimal fee;
private final String fee;
private final Map<String, BigDecimal> amounts = new HashMap<>();
// possible pairs at the moment: btcusd, btceur, eurusd, xrpusd, xrpeur, xrpbtc
private String base; // btc, eur, xrp
Expand All @@ -41,7 +41,7 @@ public BitstampUserTransaction(
@JsonProperty("id") long id,
@JsonProperty("order_id") long order_id,
@JsonProperty("type") TransactionType type,
@JsonProperty("fee") BigDecimal fee) {
@JsonProperty("fee") String fee) {

this.datetime = BitstampUtils.parseDate(datetime);
this.id = id;
Expand Down Expand Up @@ -88,11 +88,11 @@ public TransactionType getType() {
}

public boolean isDeposit() {
return type == TransactionType.deposit;
return type == TransactionType.deposit || type == TransactionType.rippleDeposit || type == TransactionType.settlementTransfer;
}

public boolean isWithdrawal() {
return type == TransactionType.withdrawal;
return type == TransactionType.withdrawal || type == TransactionType.rippleWithdrawal;
}

public boolean isMarketTrade() {
Expand Down Expand Up @@ -123,7 +123,7 @@ public String getBaseCurrency() {
return base;
}

public BigDecimal getFee() {
public String getFee() {
return fee;
}

Expand Down Expand Up @@ -169,7 +169,9 @@ public enum TransactionType {
sentAssetsToStaking,
stakingReward,
referralReward,
interAccountTransfer;
interAccountTransfer,
settlementTransfer,
unknown;

@JsonCreator
public static TransactionType fromString(int type) {
Expand All @@ -194,10 +196,12 @@ public static TransactionType fromString(int type) {
return stakingReward;
case 32:
return referralReward;
case 33:
return settlementTransfer;
case 35:
return interAccountTransfer;
default:
throw new IllegalArgumentException(type + " has no corresponding value");
return unknown;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.knowm.xchange.bitstamp;

import java.util.Date;
import java.util.List;
import org.knowm.xchange.Exchange;
import org.knowm.xchange.ExchangeFactory;
import org.knowm.xchange.dto.account.AccountInfo;
import org.knowm.xchange.dto.account.FundingRecord;
import org.knowm.xchange.dto.trade.UserTrades;
import org.knowm.xchange.service.account.AccountService;
import org.knowm.xchange.service.trade.TradeService;
import org.knowm.xchange.service.trade.params.DefaultTradeHistoryParamsTimeSpan;

public class BitstampCliTester {
public static void main(String[] args) throws Exception{
Exchange exchange = ExchangeFactory.INSTANCE.createExchange(BitstampExchange.class, System.getenv("BITSTAMP_API_KEY"), System.getenv("BITSTAMP_SECRET_KEY"));

AccountService accountService = exchange.getAccountService();

DefaultTradeHistoryParamsTimeSpan defaultTradeHistoryParamsTimeSpan = new DefaultTradeHistoryParamsTimeSpan();
defaultTradeHistoryParamsTimeSpan.setStartTime(new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24));

List<FundingRecord> fundingRecordList= accountService.getFundingHistory(defaultTradeHistoryParamsTimeSpan);

System.out.println(fundingRecordList);


AccountInfo accountInfo = accountService.getAccountInfo();

System.out.println(accountInfo);

TradeService tradeService = exchange.getTradeService();

UserTrades userTrades = tradeService.getTradeHistory(tradeService.createTradeHistoryParams());

System.out.println(userTrades);
}
}
Loading
Loading