Skip to content

Commit

Permalink
BATM-6424 Transaction has at sell via bitgo (#925)
Browse files Browse the repository at this point in the history
  • Loading branch information
d0by1 authored Aug 26, 2024
1 parent f09800a commit 98f9ba8
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package com.generalbytes.batm.server.extensions.payment;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

/**
Expand All @@ -28,6 +29,7 @@ public class ReceivedAmount {

private final BigDecimal totalAmountReceived;
private final int confirmations;
private List<String> transactionHashes;

public ReceivedAmount(BigDecimal totalAmountReceived, int confirmations) {
this.totalAmountReceived = Objects.requireNonNull(totalAmountReceived);
Expand All @@ -49,4 +51,18 @@ public BigDecimal getTotalAmountReceived() {
public int getConfirmations() {
return confirmations;
}

/**
* @return hashes of all incoming transactions
*/
public List<String> getTransactionHashes() {
return transactionHashes;
}

/**
* @param transactionHashes hashes of all incoming transactions
*/
public void setTransactionHashes(List<String> transactionHashes) {
this.transactionHashes = transactionHashes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,27 @@
import com.generalbytes.batm.common.currencies.CryptoCurrency;
import com.generalbytes.batm.server.extensions.IGeneratesNewDepositCryptoAddress;
import com.generalbytes.batm.server.extensions.IQueryableWallet;
import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.BitGoCreateAddressRequest;
import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.BitGoAddressResponse;
import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.BitGoCreateAddressRequest;
import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.BitGoTransfer;
import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.BitGoTransfersResponse;
import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.ErrorResponseException;
import com.generalbytes.batm.server.extensions.payment.ReceivedAmount;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import si.mazi.rescu.HttpStatusIOException;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BitgoWalletWithUniqueAddresses extends BitgoWallet implements IGeneratesNewDepositCryptoAddress, IQueryableWallet {
private static final Logger log = LoggerFactory.getLogger(BitgoWalletWithUniqueAddresses.class);

private static final String TRANSFER_STATE_CONFIRMED = "confirmed";
private static final String TRANSFER_TYPE_RECEIVE = "receive";
private static final Map<String, String> newAddressCryptoCurrency = new HashMap<String, String>() {
{
put(CryptoCurrency.USDT.getCode(), "eth");
Expand Down Expand Up @@ -93,11 +99,30 @@ public ReceivedAmount getReceivedAmount(String address, String cryptoCurrency) {
}

try {
BitGoAddressResponse resp = api.getAddress(bitgoCryptoCurrency, walletId, address);
if (resp.getBalance().getConfirmedBalance().compareTo(BigDecimal.ZERO) > 0) {
return new ReceivedAmount(fromSatoshis(cryptoCurrency, resp.getBalance().getConfirmedBalance()), 999);
BitGoTransfersResponse transfersResponse = api.getTransfers(
bitgoCryptoCurrency,
walletId,
TRANSFER_STATE_CONFIRMED,
TRANSFER_TYPE_RECEIVE,
address
);
BigDecimal totalInBaseUnits = BigDecimal.ZERO;
int confirmations = 0;
List<String> transactionHashes = new ArrayList<>();

for (BitGoTransfer confirmedTransfer : transfersResponse.getTransfers()) {
BigDecimal valueInBaseUnits = fromSatoshis(cryptoCurrency, confirmedTransfer.getValue());

totalInBaseUnits = totalInBaseUnits.add(valueInBaseUnits);
if (confirmations == 0 || confirmedTransfer.getConfirmations() < confirmations) {
confirmations = confirmedTransfer.getConfirmations();
}
transactionHashes.add(confirmedTransfer.getTransactionHash());
}
return new ReceivedAmount(fromSatoshis(cryptoCurrency, resp.getBalance().getBalance()), 0);

ReceivedAmount receivedAmount = new ReceivedAmount(totalInBaseUnits, confirmations);
receivedAmount.setTransactionHashes(transactionHashes);
return receivedAmount;
} catch (HttpStatusIOException e) {
log.debug("get address error: {}", e.getHttpBody());
} catch (ErrorResponseException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,20 @@
************************************************************************************/
package com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2;

import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.BitGoAddressResponse;
import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.BitGoCoinRequest;
import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.BitGoCreateAddressRequest;
import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.BitGoAddressResponse;
import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.BitGoSendManyRequest;
import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.BitGoTransfersResponse;
import com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto.ErrorResponseException;

import javax.ws.rs.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.util.Map;
Expand Down Expand Up @@ -54,6 +61,14 @@ public interface IBitgoAPI {
@Path("/{coin}/wallet/{id}")
Map<String, Object> getWalletById(@PathParam("coin") String coin, @PathParam("id") String id) throws IOException, ErrorResponseException;

@GET
@Path("/{coin}/wallet/{walletId}/transfer")
BitGoTransfersResponse getTransfers(@PathParam("coin") String coin,
@PathParam("walletId") String walletId,
@QueryParam("state") String state,
@QueryParam("type") String type,
@QueryParam("address") String address) throws IOException, ErrorResponseException;

@GET
@Path("/{coin}/wallet/{walletId}/address/{addressOrId}")
BitGoAddressResponse getAddress(@PathParam("coin") String coin, @PathParam("walletId") String walletId, @PathParam("addressOrId") String addressOrId) throws IOException, ErrorResponseException;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.math.BigDecimal;

@JsonIgnoreProperties(ignoreUnknown = true)
public class BitGoTransfer {

@JsonProperty("txid")
private String transactionHash;
@JsonProperty("valueString")
private BigDecimal value;
@JsonProperty("confirmations")
private int confirmations;

public String getTransactionHash() {
return transactionHash;
}

public BigDecimal getValue() {
return value;
}

public int getConfirmations() {
return confirmations;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.generalbytes.batm.server.extensions.extra.bitcoin.wallets.bitgo.v2.dto;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;

@JsonIgnoreProperties(ignoreUnknown = true)
public class BitGoTransfersResponse {

@JsonProperty("transfers")
private List<BitGoTransfer> transfers;

public List<BitGoTransfer> getTransfers() {
return transfers;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.generalbytes.batm.server.extensions.payment.ReceivedAmount;

import java.math.BigDecimal;
import java.util.List;

public abstract class QueryableWalletPaymentSupport extends PollingPaymentSupport {

Expand Down Expand Up @@ -46,6 +47,7 @@ public void poll(PaymentRequest request) {
if (request.getState() == PaymentRequest.STATE_NEW) {
log.info("Received: {}, amounts matches. {}", totalReceived, request);
request.setTxValue(totalReceived);
request.setIncomingTransactionHash(getLastTransactionHash(receivedAmount));
setState(request, PaymentRequest.STATE_SEEN_TRANSACTION);
}

Expand All @@ -63,6 +65,14 @@ public void poll(PaymentRequest request) {
}
}

private String getLastTransactionHash(ReceivedAmount receivedAmount) {
List<String> transactionHashes = receivedAmount.getTransactionHashes();
if (transactionHashes != null && !transactionHashes.isEmpty()) {
return transactionHashes.get(transactionHashes.size() - 1);
}
return null;
}

private boolean receivedAmountMatchesRequestedAmountInTolerance(PaymentRequest request, BigDecimal totalReceived) {
BigDecimal requestedAmount = request.getAmount();
BigDecimal tolerance = request.getTolerance();
Expand Down

0 comments on commit 98f9ba8

Please sign in to comment.