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

[Coinbase] Http requests with CDP api keys #4906

Open
wants to merge 36 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
e83844d
ETD:235-connectors-coinbase-api-block - bug fix - null point exceptio…
martinkyov Feb 4, 2022
1c6b959
ETD:235-connectors-coinbase-api-block - bug fix - null point exceptio…
martinkyov Feb 4, 2022
a580cbd
ETD:191-connectors-coinbase-deposit/withdrawal
martinkyov Feb 7, 2022
7ab24f9
ETD:191-connectors-coinbase-deposit/withdrawal
martinkyov Feb 8, 2022
beb4264
ETD:191-connectors-coinbase-deposit/withdrawal
martinkyov Feb 8, 2022
36809c7
ETD:235-connectors-coinbase-api-block - bug fix - null point exceptio…
martinkyov Feb 4, 2022
d12af68
ETD:235-connectors-coinbase-api-block - bug fix - null point exceptio…
martinkyov Feb 4, 2022
92362a7
CoinbaseConnectorFixingAndAddingTransfers
martinkyov Feb 23, 2022
337dfaf
Merge branch 'bugfix/ETD-235-connectors-coinbase-api-block-no' into C…
martinkyov Feb 24, 2022
1362897
CoinbaseConnectorFixingAndAddingTransfers
martinkyov Feb 24, 2022
39a9d83
feature/ETD-755-connectors-coinbase-api---add-su
martinkyov Feb 27, 2023
e55e846
feature/ETD-755-connectors-coinbase-api---add-su
martinkyov Mar 1, 2023
874ff9e
feature/ETD-755-connectors-coinbase-api---add-su
martinkyov Mar 20, 2023
bccfa65
bugfix/ETD-1107-connectors-coinbase-api-
martinkyov Feb 1, 2024
87ec090
bugfix/ETD-1107-connectors-coinbase-api-
martinkyov Feb 1, 2024
a646389
etd 1182
Slithercze May 13, 2024
1c3b1d8
etd 1182
Slithercze May 14, 2024
c68f87c
etd 1182
Slithercze May 14, 2024
1169721
etd 1182 ordertype
Slithercze May 14, 2024
24cad0c
Revert "etd 1182 ordertype"
Slithercze May 14, 2024
47e0f5c
Revert "etd 1182"
Slithercze May 14, 2024
b8ee378
bugfix/1179-connectors-fixed-bug-when-downl
Slithercze May 21, 2024
8e989b9
bugfix/1179-connectors-fixed-bug-when-downl
Slithercze May 21, 2024
da4c159
bugfix/1179-connectors-fixed-bug-when-downl
Slithercze May 21, 2024
a41a39f
bugfix/1179-connectors-fixed-bug-when-downl
Slithercze May 21, 2024
620dea9
bugfix/1179-connectors-fixed-bug-when-downl
Slithercze May 22, 2024
a6f6015
bugfix/1179-connectors-fixed-bug-when-downl
Slithercze May 22, 2024
926bec0
bugfix/1179-connectors-fixed-bug-when-downl
Slithercze May 22, 2024
34ff4e3
bugfix/1179-connectors-fixed-bug-when-downl
Slithercze May 23, 2024
dbbf4aa
bugfix/ETD-1285-connectors-coinbase-api-review-
Slithercze Jun 4, 2024
6728ccc
bugfix/ETD-1285-connectors-coinbase-api-review-
Slithercze Jun 5, 2024
4d445a2
bugfix/ETD-1285-connectors-coinbase-api-review-
Slithercze Jun 6, 2024
37859ce
feature/ETD-1237-connectors-coinbase-cdp-api-key
Slithercze Jun 10, 2024
cf69e6b
feature/ETD-1237-connectors-coinbase-cdp-api-key
Slithercze Jun 10, 2024
3ded337
feature/ETD-1237-connectors-coinbase-cdp-api-key
Slithercze Jun 11, 2024
12d7016
Merge branch 'develop' into feature/ETD-1237-connectors-coinbase-cdp-…
Slithercze Jun 12, 2024
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
24 changes: 24 additions & 0 deletions xchange-coinbase/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,31 @@
<artifactId>xchange-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

<!-- Nimbus JOSE+JWT -->
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>9.40</version>
</dependency>

<!-- Bouncy Castle Provider -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.78.1</version>
</dependency>

<!-- Bouncy Castle PKIX -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
<version>1.78.1</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.knowm.xchange.dto.Order.OrderType;
import org.knowm.xchange.dto.account.AccountInfo;
import org.knowm.xchange.dto.account.Balance;
import org.knowm.xchange.dto.account.FundingRecord;
import org.knowm.xchange.dto.account.Wallet;
import org.knowm.xchange.dto.marketdata.Ticker;
import org.knowm.xchange.dto.marketdata.Trades.TradeSortType;
Expand Down Expand Up @@ -56,8 +57,76 @@ public static UserTrades adaptTrades(List<CoinbaseBuySell> transactions, OrderTy
return new UserTrades(trades, TradeSortType.SortByTimestamp);
}

public static List<FundingRecord> adaptFundings(List<CoinbaseBuySell> trades) {
final List<FundingRecord> records = new ArrayList<>();

for (CoinbaseBuySell record : trades) {
records.add(adaptFunding(record));
}

return records;
}

private static FundingRecord adaptFunding(CoinbaseBuySell transaction) {

FundingRecord.Type type = null;
FundingRecord.Status status;
String recordType = transaction.getResource().toUpperCase();

switch (recordType) {
case "WITHDRAWAL":
case "CREATE_VOUCHER":
type = FundingRecord.Type.WITHDRAWAL;
break;
case "DEPOSIT":
case "USED_VOUCHER":
case "NEW_USER_REWARD":
case "REFERRAL":
type = FundingRecord.Type.DEPOSIT;
break;
default:
// here we ignore the other types which are trading
}

switch (transaction.getStatus().toUpperCase()) {
case "OK":
case "COMPLETED":
status = FundingRecord.Status.COMPLETE;
break;
case "NEW":
case "SENT":
case "CREATED":
case "WAITING":
case "PENDING":
status = FundingRecord.Status.PROCESSING;
break;
default:
status = FundingRecord.Status.FAILED;
}

FundingRecord funding =
new FundingRecord(
null,
Date.from(transaction.getCreatedAt().toInstant()),
Currency.getInstance(transaction.getAmount().getCurrency()),
transaction.getAmount().getAmount(),
transaction.getId(),
null,
type,
status,
null,
transaction.getFee().getAmount(),
null);
return funding;
}

private static UserTrade adaptTrade(CoinbaseBuySell transaction, OrderType orderType) {
return UserTrade.builder()
// Bug fix - Null point exception in case of cancelled transactions

String transactionId = transaction.getTransaction() == null ?
null : (transaction.getTransaction().getId() == null ?
null : transaction.getTransaction().getId());
return new UserTrade.Builder()
.type(orderType)
.originalAmount(transaction.getAmount().getAmount())
.currencyPair(
Expand All @@ -70,7 +139,7 @@ private static UserTrade adaptTrade(CoinbaseBuySell transaction, OrderType order
.divide(transaction.getAmount().getAmount(), PRICE_SCALE, RoundingMode.HALF_UP))
.timestamp(Date.from(transaction.getCreatedAt().toInstant()))
.id(transaction.getId())
.orderId(transaction.getTransaction().getId())
.orderId(transactionId)
.feeAmount(transaction.getFee().getAmount())
.feeCurrency(Currency.getInstance(transaction.getFee().getCurrency()))
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
package org.knowm.xchange.coinbase.cdp;

import org.knowm.xchange.coinbase.v2.Coinbase;
import org.knowm.xchange.coinbase.v2.dto.CoinbaseException;
import org.knowm.xchange.coinbase.v2.dto.account.CoinbaseAccountData;
import org.knowm.xchange.coinbase.v2.dto.account.CoinbaseAccountsData;
import org.knowm.xchange.coinbase.v2.dto.account.CoinbaseBuyData;
import org.knowm.xchange.coinbase.v2.dto.account.CoinbaseExpandTransactionsResponse;
import org.knowm.xchange.coinbase.v2.dto.account.CoinbasePaymentMethodsData;
import org.knowm.xchange.coinbase.v2.dto.account.CoinbaseSellData;
import org.knowm.xchange.coinbase.v2.dto.account.CoinbaseTransactionsResponse;
import org.knowm.xchange.coinbase.v2.dto.account.transactions.CoinbaseBuySellResponse;
import si.mazi.rescu.ParamsDigest;


import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
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.math.BigDecimal;
import java.util.Map;

@Path("/v2")
@Produces(MediaType.APPLICATION_JSON)
public interface CoinbaseAuthenticatedCDP extends Coinbase {

/**
* All API key requests must be signed and contain the following headers.
*
* <p>All request bodies should have content type application/json and be valid JSON.
*
* <p>The CB-ACCESS-SIGN header is generated by creating a sha256 HMAC using the secret key on the
* prehash string timestamp + method + requestPath + body (where + represents string
* concatenation). The timestamp value is the same as the CB-ACCESS-TIMESTAMP header.
*
* <p>The body is the request body string or omitted if there is no request body (typically for
* GET requests).
*
* <p>The method should be UPPER CASE.
*
* <p><a
* href="https://developers.coinbase.com/api/v2#api-key">developers.coinbase.com/api/v2#api-key</a>
*/
String CB_ACCESS_KEY = "CB-ACCESS-KEY";


String CB_ACCESS_SIGN = "CB-ACCESS-SIGN";
String CB_ACCESS_TIMESTAMP = "CB-ACCESS-TIMESTAMP";

String CONTENT_TYPE = "Content-Type";

@GET
@Path("accounts/{accountId}/transactions")
CoinbaseTransactionsResponse getTransactions(
@HeaderParam("Authorization") ParamsDigest signature,
@PathParam("accountId") String accountId)
throws IOException, CoinbaseException;

@GET
@Path("accounts/{accountId}/transactions")
CoinbaseExpandTransactionsResponse getExpandedTransactions(
@HeaderParam("Authorization") ParamsDigest signature,
@PathParam("accountId") String accountId,
@QueryParam("limit") int limit,
@QueryParam("order") String orderType,
@QueryParam("starting_after") String startingFrom)
throws IOException, CoinbaseException;

@GET
@Path("accounts/{accountId}/buys")
CoinbaseBuySellResponse getBuys(
@HeaderParam("Authorization") ParamsDigest signature,
@PathParam("accountId") String accountId,
@QueryParam("limit") Integer limit,
@QueryParam("starting_after") String startingAfter)
throws IOException, CoinbaseException;

@GET
@Path("accounts/{accountId}/sells")
CoinbaseBuySellResponse getSells(
@HeaderParam("Authorization") ParamsDigest signature,
@PathParam("accountId") String accountId,
@QueryParam("limit") Integer limit,
@QueryParam("starting_after") String startingAfter)
throws IOException, CoinbaseException;

@GET
@Path("accounts/{accountId}/deposits")
CoinbaseBuySellResponse getAllDeposits(
@HeaderParam("Authorization") ParamsDigest signature,
@PathParam("accountId") String accountId,
@QueryParam("limit") Integer limit,
@QueryParam("starting_after") String startingAfter)
throws IOException, CoinbaseException;

@GET
@Path("accounts/{accountId}/withdrawals")
CoinbaseBuySellResponse getAllWithdrawals(
@HeaderParam("Authorization") ParamsDigest signature,
@PathParam("accountId") String accountId,
@QueryParam("limit") Integer limit,
@QueryParam("starting_after") String startingAfter)
throws IOException, CoinbaseException;

@GET
@Path("accounts/{accountId}/deposits")
Map getDeposits(
@HeaderParam(CB_VERSION) String apiVersion,
@HeaderParam(CB_ACCESS_KEY) String apiKey,
@HeaderParam(CB_ACCESS_SIGN) ParamsDigest signature,
@HeaderParam(CB_ACCESS_TIMESTAMP) BigDecimal timestamp,
@PathParam("accountId") String accountId)
throws IOException, CoinbaseException;

@GET
@Path("accounts/{accountId}/withdrawals")
Map getWithdrawals(
@HeaderParam(CB_VERSION) String apiVersion,
@HeaderParam(CB_ACCESS_KEY) String apiKey,
@HeaderParam(CB_ACCESS_SIGN) ParamsDigest signature,
@HeaderParam(CB_ACCESS_TIMESTAMP) BigDecimal timestamp,
@PathParam("accountId") String accountId)
throws IOException, CoinbaseException;

@GET
@Path("accounts")
CoinbaseAccountsData getAccounts(
@HeaderParam("Authorization") ParamsDigest signature,
@QueryParam("limit") Integer limit,
@QueryParam("starting_after") String starting_after)
throws IOException, CoinbaseException;

@GET
@Path("accounts/{currency}")
CoinbaseAccountData getAccount(
@HeaderParam("Authorization") ParamsDigest signature,
@PathParam("currency") String currency)
throws IOException, CoinbaseException;

@POST
@Path("accounts")
@Consumes(MediaType.APPLICATION_JSON)
CoinbaseAccountData createAccount(
@HeaderParam(CONTENT_TYPE) String contentType,
@HeaderParam(CB_VERSION) String apiVersion,
@HeaderParam(CB_ACCESS_KEY) String apiKey,
@HeaderParam(CB_ACCESS_SIGN) String signature,
@HeaderParam(CB_ACCESS_TIMESTAMP) BigDecimal timestamp,
Object payload)
throws IOException, CoinbaseException;

@GET
@Path("payment-methods")
CoinbasePaymentMethodsData getPaymentMethods(
@HeaderParam("Authorization") ParamsDigest signature)
throws IOException, CoinbaseException;

@POST
@Path("accounts/{account}/buys")
@Consumes(MediaType.APPLICATION_JSON)
CoinbaseBuyData buy(
@HeaderParam(CONTENT_TYPE) String contentType,
@HeaderParam(CB_VERSION) String apiVersion,
@HeaderParam(CB_ACCESS_KEY) String apiKey,
@HeaderParam(CB_ACCESS_SIGN) String signature,
@HeaderParam(CB_ACCESS_TIMESTAMP) BigDecimal timestamp,
@PathParam("account") String accountId,
Object payload)
throws IOException, CoinbaseException;

@POST
@Path("accounts/{account}/sells")
@Consumes(MediaType.APPLICATION_JSON)
CoinbaseSellData sell(
@HeaderParam(CONTENT_TYPE) String contentType,
@HeaderParam(CB_VERSION) String apiVersion,
@HeaderParam(CB_ACCESS_KEY) String apiKey,
@HeaderParam(CB_ACCESS_SIGN) String signature,
@HeaderParam(CB_ACCESS_TIMESTAMP) BigDecimal timestamp,
@PathParam("account") String accountId,
Object payload)
throws IOException, CoinbaseException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.knowm.xchange.coinbase.cdp;

import org.knowm.xchange.BaseExchange;
import org.knowm.xchange.Exchange;
import org.knowm.xchange.ExchangeSpecification;
import org.knowm.xchange.coinbase.v2.service.CoinbaseMarketDataService;
import org.knowm.xchange.coinbase.cdp.service.CoinbaseAccountServiceCDP;
import org.knowm.xchange.coinbase.cdp.service.CoinbaseTradeServiceCDP;

public class CoinbaseExchangeCDP extends BaseExchange implements Exchange {

@Override
protected void initServices() {
this.marketDataService = new CoinbaseMarketDataService(this);
this.accountService = new CoinbaseAccountServiceCDP(this);
this.tradeService = new CoinbaseTradeServiceCDP(this);
}

@Override
public ExchangeSpecification getDefaultExchangeSpecification() {

final ExchangeSpecification exchangeSpecification = new ExchangeSpecification(this.getClass());
exchangeSpecification.setSslUri("https://api.coinbase.com");
exchangeSpecification.setHost("api.coinbase.com");
exchangeSpecification.setExchangeName("Coinbase");
exchangeSpecification.setExchangeDescription(
"Founded in June of 2012, Coinbase is a bitcoin wallet and platform where merchants and consumers can transact with the new digital currency bitcoin.");
return exchangeSpecification;
}
}
Loading