@altangent/lib-coinbase-prime
Version:
Coinbase Prime API client
127 lines (110 loc) • 4 kB
text/typescript
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { request } from "@altangent/lib-http";
import qs from "querystring";
import crypto from "crypto";
import { Results } from "./Results";
export class CoinbasePrimeClient {
constructor(
readonly key: string,
readonly passphrase: string,
readonly signingKey: string,
readonly urlBase = "https://api.prime.coinbase.com",
) {}
public async listPortfolios(): Promise<Results.PortfolioList> {
return this.request("/v1/portfolios");
}
public async listPortfolioBalances(portfolio_id: string): Promise<Results.ListBalances> {
return this.request(`/v1/portfolios/${portfolio_id}/balances`);
}
public async listPortfolioTransactions(
portfolio_id: string,
params?: Partial<{
symbols: string;
types: string[];
start_time: string;
end_time: string;
cursor: string;
limit: number;
sort_direction: string;
}>,
): Promise<Results.ListTransactions> {
return this.request(`/v1/portfolios/${portfolio_id}/transactions`, params);
}
public async listPortfolioWallets(portfolio_id: string): Promise<Results.ListWallets> {
return this.request(`/v1/portfolios/${portfolio_id}/wallets`);
}
public async listPortfolioOrders(
portfolio_id: string,
params?: Partial<{
product_ids: string[];
order_type: string;
cursor: string;
limit: string;
sort_direction: string;
start_date: string;
order_side: string;
end_date: string;
}>,
): Promise<Results.ListOrders> {
return this.request(`/v1/portfolios/${portfolio_id}/orders`, params);
}
/**
* Refer to https://docs.cdp.coinbase.com/prime/reference/primerestapi_getportfoliofills
* @param portfolio_id
* @param params
*/
public async listPortfolioFills(
portfolio_id: string,
params?: Partial<{
cursor: string;
limit: number;
start_date: string;
end_date: string;
sort_direction: "ASC" | "DESC";
}>,
): Promise<Results.PortfolioFills> {
return this.request(`/v1/portfolios/${portfolio_id}/fills`, params);
}
public request<T>(path: string, query?: any): Promise<T> {
const key = this.key;
const passphrase = this.passphrase;
const signingKey = this.signingKey;
const pathQuery = query ? path + "?" + qs.encode(query) : path;
const timestamp = Math.floor(new Date().getTime() / 1000);
const method = "GET";
const body = "";
const sig = this._sign(this._createSigData(timestamp, method, path, body), signingKey);
const headers = {
"X-CB-ACCESS-KEY": key,
"X-CB-ACCESS-PASSPHRASE": passphrase,
"X-CB-ACCESS-SIGNATURE": sig.toString("base64"),
"X-CB-ACCESS-TIMESTAMP": timestamp,
};
const url = this.urlBase + pathQuery;
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
return request({ url, method, headers }) as Promise<T>;
}
protected _cleanOptions(options: any): any {
const result = {};
for (const key in options) {
if (options[key] !== undefined) {
result[key] = options[key];
}
}
return result;
}
protected _createSigData(
timestamp: number,
method: string,
path: string,
body: string,
): string {
return `${timestamp}${method.toUpperCase()}${path}${body}`;
}
protected _sign(data: string, key: string): Buffer {
const hmac = crypto.createHmac("sha256", key);
hmac.update(data, "utf-8");
return hmac.digest();
}
}