All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.coinbase.client.CoinbaseRestClient Maven / Gradle / Ivy

package com.coinbase.client;

import com.coinbase.client.connection.RestConnection;
import com.coinbase.domain.account.CbAccount;
import com.coinbase.domain.account.request.CbAccountUpdateRequest;
import com.coinbase.domain.account.response.CbAccountListResponse;
import com.coinbase.domain.account.response.CbAccountResponse;
import com.coinbase.domain.general.response.CbResponse;
import com.coinbase.domain.order.request.CbOrderRequest;
import com.coinbase.domain.pagination.response.CbPaginatedResponse;
import com.coinbase.domain.trade.*;
import com.coinbase.domain.trade.response.CbTradeListResponse;
import com.coinbase.domain.transaction.payment.CbPaymentMethod;
import com.coinbase.domain.transaction.response.CbPaymentMethodListResponse;
import com.coinbase.domain.transaction.response.CbPaymentMethodResponse;
import com.coinbase.domain.address.request.CbCreateAddressRequest;
import com.coinbase.domain.trade.request.CbCashTransactionRequest;
import com.coinbase.domain.trade.response.CbCashTransactionListResponse;
import com.coinbase.domain.trade.response.CbCashTransactionResponse;
import com.coinbase.exception.CbApiException;
import com.coinbase.domain.address.response.CbAddressTransactionResponse;
import com.coinbase.domain.address.CbAddress;
import com.coinbase.domain.address.CbAddressTransaction;
import com.coinbase.domain.address.response.CbAddressTransactionsResponse;
import com.coinbase.domain.address.response.CbAddressListResponse;
import com.coinbase.domain.address.response.CbAddressResponse;
import com.coinbase.domain.price.CbCurrencyCode;
import com.coinbase.domain.price.CbExchangeRate;
import com.coinbase.domain.price.CbPrice;
import com.coinbase.domain.price.response.CbCurrencyCodeListResponse;
import com.coinbase.domain.price.response.CbExchangeRateResponse;
import com.coinbase.domain.price.response.CbPriceResponse;
import com.coinbase.domain.price.PriceType;
import com.coinbase.domain.system.CbTime;
import com.coinbase.domain.system.response.CbTimeResponse;
import com.coinbase.domain.trade.response.CbTradeResponse;
import com.coinbase.domain.transaction.TransactionType;
import com.coinbase.domain.transaction.request.CbMoneyRequest;
import com.coinbase.domain.user.CbUser;
import com.coinbase.domain.user.response.CbUserResponse;
import com.coinbase.domain.user.request.CbUserUpdateRequest;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * The MIT License (MIT)
 *
 *	Copyright (c) 2021 antlen
 *
 *	Permission is hereby granted, free of charge, to any person obtaining a copy
 *	of this software and associated documentation files (the "Software"), to deal
 *	in the Software without restriction, including without limitation the rights
 *	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *	copies of the Software, and to permit persons to whom the Software is
 *	furnished to do so, subject to the following conditions:
 *
 *	The above copyright notice and this permission notice shall be included in all
 *	copies or substantial portions of the Software.
 *
 *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *	SOFTWARE.
 *
 * ------------------------------------------------
 * The main implementation of CoinbaseClient
 *
 * @author antlen
 */
public class CoinbaseRestClient implements CoinbaseClient {
    private static DateTimeFormatter PRICE_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    public static final String ACCOUNTS = "/accounts";
    public static final String PAYMENT_METHODS = "/payment-methods";
    public static final String USER = "/user";
    public static final String USERS = "/users";
    public static final String AUTH = "/auth";
    public static final String ADDRESSES = "addresses";
    public static final String TIME = "/time";
    public static final String PRICES = "/prices";
    public static final String STARTING_AFTER = "starting_after";
    public static final String TRANSACTIONS = "transactions";
    public static final String DATE = "date";
    public static final String CURRENCIES = "/currencies";
    public static final String EXCHANGE_RATES = "/exchange-rates";
    public static final String COMMIT = "commit";

    private final RestConnection restApi;
    private final String paginationSize;

    public CoinbaseRestClient(RestConnection restApi, int paginationSize) {
        this.restApi = restApi;
        this.paginationSize=Integer.toString(paginationSize);
    }

    private final > X get(Class responseType, String path){
        return get(responseType, path, null);
    }

    private final > X get(Class responseType, String path, Map params){
        return restApi.get(responseType, path, params).getData();
    }

    private final > List getPaginated(Class responseType, final String uri){
        ArrayList results = new ArrayList<>();
        boolean loop = true;
        Map from = new HashMap<>();
        from.put("limit",paginationSize);
        while(loop){
            T response = restApi.get(responseType, uri, from);
            from.clear();
            results.addAll(response.getData());
            loop =  (response.getPagination()!=null && response.getPagination().getNextUri()!=null);
            if(loop){
                from.put("limit",paginationSize);
                from.put(STARTING_AFTER,response.getPagination().getNextStartingAfter());
            }
        }
        return results;
    }

    @Override
    public void ping() {
        getServerTime();
    }

    @Override
    public void reconnect() {
        restApi.reconnect();
    }

    @Override
    public CbUser getUser() {
        return get(CbUserResponse.class, USER);
    }

    @Override
    public CoinbaseClient clone() {
        return new CoinbaseRestClient(restApi.clone(),  Integer.parseInt(paginationSize));
    }

    @Override
    public CbUser getUser(String userId) {
        try{
            return get(CbUserResponse.class, toUri(USERS, userId));
        }catch(Exception e){
            throw new CbApiException("Something went wrong, it's likely user "
                    + userId+" does not exist.", e);
        }
    }

    @Override
    public List getAccounts() {
        return getPaginated(CbAccountListResponse.class, ACCOUNTS);
    }

    @Override
    public CbAccount getAccount(String id) {

        return get(CbAccountResponse.class, toUri(ACCOUNTS,id));
    }

    @Override
    public List getPaymentMethods() {
        return getPaginated(CbPaymentMethodListResponse.class, PAYMENT_METHODS);
    }

    @Override
    public CbPaymentMethod getPaymentMethod(String id) {
        return get(CbPaymentMethodResponse.class, toUri(PAYMENT_METHODS,id));
    }

    public void setLogResponsesEnabled(boolean b){
        restApi.setLogJsonMessages(b);
    }


    @Override
    public CbUser updateUser(CbUserUpdateRequest u) {
        return restApi.put(CbUserResponse.class, USER, u ).getData();
    }

    @Override
    public CbAccount updateAccountName(CbAccountUpdateRequest req) {
        return restApi.put(CbAccountResponse.class, toUri(ACCOUNTS,req.getAccount()), req).getData();
    }

    @Override
    public boolean deleteAccount(String id) {
        return restApi.delete(toUri(ACCOUNTS,id));
    }

    @Override
    public List getAddresses(String id) {
        return getPaginated(CbAddressListResponse.class, toUri(ACCOUNTS,id, ADDRESSES));
    }

    @Override
    public CbAddress getAddress(String account, String addressId) {
        return get(CbAddressResponse.class, toUri(ACCOUNTS,account, ADDRESSES, addressId));
    }

    @Override
    public CbAddress createAddress(CbCreateAddressRequest request) {
        return restApi.post(CbAddressResponse.class,
                toUri(ACCOUNTS,request.getAccount(), ADDRESSES), request).getData();
    }

    @Override
    public List getTransactions(String accountId, String address) {
        return getPaginated(CbAddressTransactionsResponse.class,
                toUri(ACCOUNTS,accountId, ADDRESSES, address, TRANSACTIONS));
    }

    private CbAddressTransaction sendMoneyRequest(CbMoneyRequest req) {
        return restApi.post(CbAddressTransactionResponse.class,
                toUri(ACCOUNTS,req.getFrom(), TRANSACTIONS), req).getData();
    }

    @Override
    public CbAddressTransaction sendMoney(CbMoneyRequest req) {
        if(!req.getType().equals(TransactionType.SEND.toString().toLowerCase())){
            throw new CbApiException("Incorrect type '"+req.getType()+"' for sendMoney request.");
        }
        return sendMoneyRequest(req);
    }

    @Override
    public CbAddressTransaction requestMoney(CbMoneyRequest req) {
        if(!req.getType().equals(TransactionType.REQUEST.toString().toLowerCase())){
            throw new CbApiException("Incorrect type '"+req.getType()+"' for requestMoney request.");
        }
        return sendMoneyRequest(req);
    }

    @Override
    public CbAddressTransaction transferMoney(CbMoneyRequest req) {
        if(!req.getType().equals(TransactionType.TRANSFER.toString().toLowerCase())){
            throw new CbApiException("Incorrect type '"+req.getType()+"' for transferMoney request.");
        }
        return sendMoneyRequest(req);
    }

    @Override
    public Collection getTrades(String account) {
        return new CbTradeCollection().add(getTrades(account, Side.BUY))
                .add(getTrades(account, Side.SELL)).toCollection();
    }

    @Override
    public Collection getTrades(String account, Side side) {
        Collection res = getPaginated(CbTradeListResponse.class, toUri(ACCOUNTS,account, side.getUri()));
        res.stream().forEach(t ->t.setSide(side));
        return res;
    }

    @Override
    public CbTime getServerTime() {
        return get(CbTimeResponse.class, TIME);
    }

    @Override
    public CbPrice getPrice(PriceType t, String pair){
        String uri = toUri(PRICES, pair, t.toString().toLowerCase());
        CbPrice res = get(CbPriceResponse.class, uri);
        res.setType(t);
        return res;
    }

    @Override
    public CbPrice getSpotPrice(String pair, LocalDate date){
        String uri = toUri(PRICES, pair, PriceType.SPOT.toString().toLowerCase());
        Map params = null;
        if(date !=null){
            params = new HashMap<>();
            params.put(DATE, date.format(PRICE_DATE_FORMAT));
        }
        return get(CbPriceResponse.class, uri, params).setType(PriceType.SPOT);
    }

    @Override
    public List getCurrencyCodes() {
        return getPaginated(CbCurrencyCodeListResponse.class, CURRENCIES);
    }

    @Override
    public CbTrade getTrade(String account, String id, Side side) {
        return get(CbTradeResponse.class, toUri(ACCOUNTS,account, side.getUri(), id)).setSide(side);
    }

    @Override
    public Collection getCashTransaction(String account, CashTransactionType type) {
        return getPaginated(CbCashTransactionListResponse.class,
                toUri(ACCOUNTS,account, type.getUri()));
    }

    @Override
    public CbCashTransaction getCashTransaction(String account, String depositId, CashTransactionType type) {
        return get(CbCashTransactionResponse.class,
                toUri(ACCOUNTS,account, type.getUri(), depositId));
    }

    @Override
    public CbCashTransaction executeCashTransaction(CbCashTransactionRequest req) {
        return restApi.post(CbCashTransactionResponse.class,
                toUri(ACCOUNTS, req.getFrom(),req.getType().getUri()), req).getData();
    }

    @Override
    public CbCashTransaction commitCashTransaction(String account, String id, CashTransactionType type) {
        String path = toUri(ACCOUNTS, account, type.getUri(), id, COMMIT);
        return restApi.post(CbCashTransactionResponse.class, path).getData();
    }

    @Override
    public CbCashTransaction commitCashTransaction(CbCashTransaction t) {
        if(t.getCommitted() !=null && !t.getCommitted()){
            return restApi.post(CbCashTransactionResponse.class, toUri(t.getResourcePath(), COMMIT)).getData();
        }
        throw new CbApiException("The cash transaction is already committed.");
    }

    @Override
    public CbTrade placeOrder(CbOrderRequest req) {
        String path = toUri(ACCOUNTS, req.getFrom(),req.getSide().getUri());
        return restApi.post(CbTradeResponse.class, path, req).getData().setSide(req.getSide());
    }

    @Override
    public CbTrade commitOrder(String account, String orderId, Side side) {
        String path = toUri(ACCOUNTS, account, side.getUri(), orderId, COMMIT);
        return restApi.post(CbTradeResponse.class, path).getData().setSide(side);
    }

    @Override
    public CbTrade commitOrder(CbTrade t) {
        if(t.getCommitted() !=null && !t.getCommitted()){
            return restApi.post(CbTradeResponse.class, toUri(t.getResourcePath(), COMMIT)).getData().setSide(t.getSide());
        }
        throw new CbApiException("The trade is already committed.");
    }

    @Override
    public CbExchangeRate getExchangeRate() {
        return get(CbExchangeRateResponse.class, EXCHANGE_RATES);
    }

    @Override
    public CbExchangeRate getExchangeRate(String base) {
        Map m = new HashMap<>();
        m.put("currency", base);
       return  restApi.get(CbExchangeRateResponse.class, EXCHANGE_RATES, m).getData();
    }

    private String toUri(String ... s){
        String path = s[0];
        for(int i=1; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy