From 0c3a4a7851628dad6186940db8d8169555e11fc9 Mon Sep 17 00:00:00 2001 From: Monil Patel Date: Sun, 8 Dec 2024 13:26:06 -0800 Subject: [PATCH] add advanced trade folder --- packages/plugin-coinbase/advanced-sdk-ts | 1 - .../advanced-sdk-ts/.eslintrc.js | 21 + .../advanced-sdk-ts/.gitignore | 6 + .../advanced-sdk-ts/.prettierrc | 5 + .../advanced-sdk-ts/CHANGELOG.md | 9 + .../plugin-coinbase/advanced-sdk-ts/README.md | 126 +++++ .../advanced-sdk-ts/package.json | 34 ++ .../advanced-sdk-ts/src/constants.ts | 6 + .../advanced-sdk-ts/src/jwt-generator.ts | 31 ++ .../advanced-sdk-ts/src/rest/accounts.ts | 36 ++ .../advanced-sdk-ts/src/rest/converts.ts | 53 +++ .../advanced-sdk-ts/src/rest/dataAPI.ts | 17 + .../advanced-sdk-ts/src/rest/errors.ts | 36 ++ .../advanced-sdk-ts/src/rest/fees.ts | 21 + .../advanced-sdk-ts/src/rest/futures.ts | 133 ++++++ .../advanced-sdk-ts/src/rest/index.ts | 95 ++++ .../advanced-sdk-ts/src/rest/orders.ts | 149 ++++++ .../advanced-sdk-ts/src/rest/payments.ts | 33 ++ .../advanced-sdk-ts/src/rest/perpetuals.ts | 97 ++++ .../advanced-sdk-ts/src/rest/portfolios.ts | 100 ++++ .../advanced-sdk-ts/src/rest/products.ts | 101 ++++ .../advanced-sdk-ts/src/rest/public.ts | 95 ++++ .../advanced-sdk-ts/src/rest/rest-base.ts | 123 +++++ .../src/rest/types/accounts-types.ts | 26 + .../src/rest/types/common-types.ts | 447 ++++++++++++++++++ .../src/rest/types/converts-types.ts | 42 ++ .../src/rest/types/dataAPI-types.ts | 10 + .../src/rest/types/fees-types.ts | 23 + .../src/rest/types/futures-types.ts | 71 +++ .../src/rest/types/orders-types.ts | 185 ++++++++ .../src/rest/types/payments-types.ts | 16 + .../src/rest/types/perpetuals-types.ts | 72 +++ .../src/rest/types/portfolios-types.ts | 68 +++ .../src/rest/types/products-types.ts | 96 ++++ .../src/rest/types/public-types.ts | 88 ++++ .../src/rest/types/request-types.ts | 14 + .../advanced-sdk-ts/tsconfig.json | 106 +++++ 37 files changed, 2591 insertions(+), 1 deletion(-) delete mode 160000 packages/plugin-coinbase/advanced-sdk-ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/.eslintrc.js create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/.gitignore create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/.prettierrc create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/CHANGELOG.md create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/README.md create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/package.json create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/constants.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/jwt-generator.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/accounts.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/converts.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/dataAPI.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/errors.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/fees.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/futures.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/index.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/orders.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/payments.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/perpetuals.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/portfolios.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/products.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/public.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/rest-base.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/accounts-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/common-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/converts-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/dataAPI-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/fees-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/futures-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/orders-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/payments-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/perpetuals-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/portfolios-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/products-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/public-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/request-types.ts create mode 100644 packages/plugin-coinbase/advanced-sdk-ts/tsconfig.json diff --git a/packages/plugin-coinbase/advanced-sdk-ts b/packages/plugin-coinbase/advanced-sdk-ts deleted file mode 160000 index 1fba324dc5..0000000000 --- a/packages/plugin-coinbase/advanced-sdk-ts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1fba324dc5bb2dc527d9cd09cbd0d4946e450252 diff --git a/packages/plugin-coinbase/advanced-sdk-ts/.eslintrc.js b/packages/plugin-coinbase/advanced-sdk-ts/.eslintrc.js new file mode 100644 index 0000000000..ec00d481ab --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/.eslintrc.js @@ -0,0 +1,21 @@ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + parser: '@typescript-eslint/parser', + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'prettier', + 'plugin:prettier/recommended', + ], + plugins: ['prettier'], + rules: { + 'prettier/prettier': 'error', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-explicit-any': 'off', + }, + ignorePatterns: ['**/dist/**', '**/node_modules/**', '**/*.md'], + env: { + node: true, // Add this line to recognize Node.js globals + es2021: true, // Optionally include modern JavaScript features + }, +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/.gitignore b/packages/plugin-coinbase/advanced-sdk-ts/.gitignore new file mode 100644 index 0000000000..722ad2ade5 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/.gitignore @@ -0,0 +1,6 @@ +.env +src/rest/main.ts +dist/ +node_modules/ +.idea/ +package-lock.json \ No newline at end of file diff --git a/packages/plugin-coinbase/advanced-sdk-ts/.prettierrc b/packages/plugin-coinbase/advanced-sdk-ts/.prettierrc new file mode 100644 index 0000000000..c3e03287be --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/.prettierrc @@ -0,0 +1,5 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "es5" +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/CHANGELOG.md b/packages/plugin-coinbase/advanced-sdk-ts/CHANGELOG.md new file mode 100644 index 0000000000..eda768580a --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +## [0.1.0] - 2024-SEP-06 + +### Added + +- Support for all Coinbase Advanced API REST endpoints via central client +- Custom Request and Response objects for endpoints +- Custom error types diff --git a/packages/plugin-coinbase/advanced-sdk-ts/README.md b/packages/plugin-coinbase/advanced-sdk-ts/README.md new file mode 100644 index 0000000000..73f0bf459d --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/README.md @@ -0,0 +1,126 @@ +# Coinbase Advanced API TypeScript SDK + +Welcome to the Coinbase Advanced API TypeScript SDK. This TypeScript project was created to allow developers to easily plug into the [Coinbase Advanced API](https://docs.cdp.coinbase.com/advanced-trade/docs/welcome). + +Coinbase Advanced Trade offers a comprehensive API for traders, providing access to real-time market data, order management, and execution. Elevate your trading strategies and develop sophisticated solutions using our powerful tools and features. + +For more information on all the available REST endpoints, see the [API Reference](https://docs.cdp.coinbase.com/advanced-trade/reference/). + +--- + +## Installation + +```bash +npm install +``` + +--- + +## Build and Use + +To build the project, run the following command: + +```bash +npm run build +``` + +_Note: To avoid potential issues, do not forget to build your project again after making any changes to it._ + +After building the project, each `.ts` file will have its `.js` counterpart generated. + +To run a file, use the following command: + +``` +node dist/{INSERT-FILENAME}.js +``` + +For example, a `main.ts` file would be run like: + +```bash +node dist/main.js +``` + +--- + +## Coinbase Developer Platform (CDP) API Keys + +This SDK uses Cloud Developer Platform (CDP) API keys. To use this SDK, you will need to create a CDP API key and secret by following the instructions [here](https://docs.cdp.coinbase.com/advanced-trade/docs/getting-started). +Make sure to save your API key and secret in a safe place. You will not be able to retrieve your secret again. + +--- + +## Importing the RESTClient + +All the REST endpoints are available directly from the client, therefore it's all you need to import. + +``` +import { RESTClient } from './rest'; +``` + +--- + +## Authentication + +Authentication of CDP API Keys is handled automatically by the SDK when making a REST request. + +After creating your CDP API keys, store them using your desired method and simply pass them into the client during initialization like: + +``` +const client = new RESTClient(API_KEY, API_SECRET); +``` + +--- + +## Making Requests + +Here are a few examples requests: + +**[List Accounts](https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getaccounts)** + +``` +client + .listAccounts({}) + .then((result) => { + console.log(result); + }) + .catch((error) => { + console.error(error.message); + }); +``` + +**[Get Product](https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getproduct)** + +``` +client + .getProduct({productId: "BTC-USD"}) + .then((result) => { + console.log(result); + }) + .catch((error) => { + console.error(error.message); + }); +``` + +**[Create Order](https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_postorder)** + +_$10 Market Buy on BTC-USD_ + +``` +client + .createOrder({ + clientOrderId: "00000001", + productId: "BTC-USD", + side: OrderSide.BUY, + orderConfiguration:{ + market_market_ioc: { + quote_size: "10" + } + } + }) + .then((result) => { + console.log(result); + }) + .catch((error) => { + console.error(error.message); + }); +``` diff --git a/packages/plugin-coinbase/advanced-sdk-ts/package.json b/packages/plugin-coinbase/advanced-sdk-ts/package.json new file mode 100644 index 0000000000..78480e529e --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/package.json @@ -0,0 +1,34 @@ +{ + "name": "@coinbase-samples/advanced-sdk-ts", + "version": "0.1.0", + "main": "dist/main.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "tsc", + "lint": "eslint . --ext .js,.ts", + "format": "prettier --write \"**/*.{js,ts,tsx,json,css,md}\"" + }, + "files": [ + "dist/" + ], + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "jsonwebtoken": "^9.0.2", + "node-fetch": "^2.6.1" + }, + "devDependencies": { + "@types/jsonwebtoken": "^9.0.7", + "@types/node-fetch": "^2.6.11", + "@typescript-eslint/eslint-plugin": "^5.59.0", + "@typescript-eslint/parser": "^5.59.0", + "dotenv": "^16.4.5", + "eslint": "^8.35.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-prettier": "^4.2.1", + "prettier": "^2.8.8", + "typescript": "^5.5.4" + } +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/constants.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/constants.ts new file mode 100644 index 0000000000..8962365907 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/constants.ts @@ -0,0 +1,6 @@ +export const BASE_URL = 'api.coinbase.com'; +export const API_PREFIX = '/api/v3/brokerage'; +export const ALGORITHM = 'ES256'; +export const VERSION = '0.1.0'; +export const USER_AGENT = `coinbase-advanced-ts/${VERSION}`; +export const JWT_ISSUER = 'cdp'; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/jwt-generator.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/jwt-generator.ts new file mode 100644 index 0000000000..275fc876e6 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/jwt-generator.ts @@ -0,0 +1,31 @@ +import jwt from 'jsonwebtoken'; +import { BASE_URL, ALGORITHM, JWT_ISSUER } from './constants'; +import crypto from 'crypto'; + +export function generateToken( + requestMethod: string, + requestPath: string, + apiKey: string, + apiSecret: string +): string { + const uri = `${requestMethod} ${BASE_URL}${requestPath}`; + const payload = { + iss: JWT_ISSUER, + nbf: Math.floor(Date.now() / 1000), + exp: Math.floor(Date.now() / 1000) + 120, + sub: apiKey, + uri, + }; + + const header = { + alg: ALGORITHM, + kid: apiKey, + nonce: crypto.randomBytes(16).toString('hex'), + }; + const options: jwt.SignOptions = { + algorithm: ALGORITHM as jwt.Algorithm, + header: header, + }; + + return jwt.sign(payload, apiSecret as string, options); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/accounts.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/accounts.ts new file mode 100644 index 0000000000..04cec4b934 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/accounts.ts @@ -0,0 +1,36 @@ +import { API_PREFIX } from '../constants'; +import { RESTBase } from './rest-base'; +import { + GetAccountRequest, + GetAccountResponse, + ListAccountsRequest, + ListAccountsResponse, +} from './types/accounts-types'; +import { method } from './types/request-types'; + +// [GET] Get Account +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getaccount +export function getAccount( + this: RESTBase, + { accountUuid }: GetAccountRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/accounts/${accountUuid}`, + isPublic: false, + }); +} + +// [GET] List Accounts +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getaccounts +export function listAccounts( + this: RESTBase, + requestParams: ListAccountsRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/accounts`, + queryParams: requestParams, + isPublic: false, + }); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/converts.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/converts.ts new file mode 100644 index 0000000000..435a807e28 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/converts.ts @@ -0,0 +1,53 @@ +import { API_PREFIX } from '../constants'; +import { RESTBase } from './rest-base'; +import { + CommitConvertTradeRequest, + CommitConvertTradeResponse, + CreateConvertQuoteRequest, + CreateConvertQuoteResponse, + GetConvertTradeRequest, + GetConvertTradeResponse, +} from './types/converts-types'; +import { method } from './types/request-types'; + +// [POST] Create Convert Quote +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_createconvertquote +export function createConvertQuote( + this: RESTBase, + requestParams: CreateConvertQuoteRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/convert/quote`, + bodyParams: requestParams, + isPublic: false, + }); +} + +// [GET] Get Convert Trade +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getconverttrade +export function getConvertTrade( + this: RESTBase, + { tradeId, ...requestParams }: GetConvertTradeRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/convert/trade/${tradeId}`, + queryParams: requestParams, + isPublic: false, + }); +} + +// [POST] Commit Connvert Trade +// https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_commitconverttrade +export function commitConvertTrade( + this: RESTBase, + { tradeId, ...requestParams }: CommitConvertTradeRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/convert/trade/${tradeId}`, + bodyParams: requestParams, + isPublic: false, + }); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/dataAPI.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/dataAPI.ts new file mode 100644 index 0000000000..2adc646607 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/dataAPI.ts @@ -0,0 +1,17 @@ +import { API_PREFIX } from '../constants'; +import { RESTBase } from './rest-base'; + +import { method } from './types/request-types'; +import { GetAPIKeyPermissionsResponse } from './types/dataAPI-types'; + +// [GET] Get API Key Permissions +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getapikeypermissions +export function getAPIKeyPermissions( + this: RESTBase +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/key_permissions`, + isPublic: false, + }); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/errors.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/errors.ts new file mode 100644 index 0000000000..5d9695ef67 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/errors.ts @@ -0,0 +1,36 @@ +import { Response } from 'node-fetch'; + +class CoinbaseError extends Error { + statusCode: number; + response: Response; + + constructor(message: string, statusCode: number, response: Response) { + super(message); + this.name = 'CoinbaseError'; + this.statusCode = statusCode; + this.response = response; + } +} + +export function handleException( + response: Response, + responseText: string, + reason: string +) { + let message: string | undefined; + + if ( + (400 <= response.status && response.status <= 499) || + (500 <= response.status && response.status <= 599) + ) { + if ( + response.status == 403 && + responseText.includes('"error_details":"Missing required scopes"') + ) { + message = `${response.status} Coinbase Error: Missing Required Scopes. Please verify your API keys include the necessary permissions.`; + } else + message = `${response.status} Coinbase Error: ${reason} ${responseText}`; + + throw new CoinbaseError(message, response.status, response); + } +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/fees.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/fees.ts new file mode 100644 index 0000000000..9f9c08e5cf --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/fees.ts @@ -0,0 +1,21 @@ +import { API_PREFIX } from '../constants'; +import { RESTBase } from './rest-base'; +import { + GetTransactionsSummaryRequest, + GetTransactionsSummaryResponse, +} from './types/fees-types'; +import { method } from './types/request-types'; + +// [GET] Get Transaction Summary +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_commitconverttrade +export function getTransactionSummary( + this: RESTBase, + requestParams: GetTransactionsSummaryRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/transaction_summary`, + queryParams: requestParams, + isPublic: false, + }); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/futures.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/futures.ts new file mode 100644 index 0000000000..82412ec4e3 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/futures.ts @@ -0,0 +1,133 @@ +import { API_PREFIX } from '../constants'; +import { RESTBase } from './rest-base'; +import { + CancelPendingFuturesSweep, + GetCurrentMarginWindowRequest, + GetCurrentMarginWindowResponse, + GetFuturesBalanceSummaryResponse, + GetFuturesPositionRequest, + GetFuturesPositionResponse, + GetIntradayMarginSettingResponse, + ListFuturesPositionsResponse, + ListFuturesSweepsResponse, + ScheduleFuturesSweepRequest, + ScheduleFuturesSweepResponse, + SetIntradayMarginSettingRequest, + SetIntradayMarginSettingResponse, +} from './types/futures-types'; +import { method } from './types/request-types'; + +// [GET] Get Futures Balance Summary +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmbalancesummary +export function getFuturesBalanceSummary( + this: RESTBase +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/cfm/balance_summary`, + isPublic: false, + }); +} + +// [GET] Get Intraday Margin Setting +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getintradaymarginsetting +export function getIntradayMarginSetting( + this: RESTBase +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/cfm/intraday/margin_setting`, + isPublic: false, + }); +} + +// [POST] Set Intraday Margin Setting +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_setintradaymarginsetting +export function setIntradayMarginSetting( + this: RESTBase, + requestParams: SetIntradayMarginSettingRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/cfm/intraday/margin_setting`, + bodyParams: requestParams, + isPublic: false, + }); +} + +// [GET] Get Current Margin Window +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getcurrentmarginwindow +export function getCurrentMarginWindow( + this: RESTBase, + requestParams: GetCurrentMarginWindowRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/cfm/intraday/current_margin_window`, + queryParams: requestParams, + isPublic: false, + }); +} + +// [GET] List Futures Positions +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmpositions +export function listFuturesPositions( + this: RESTBase +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/cfm/positions`, + isPublic: false, + }); +} + +// [GET] Get Futures Position +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmposition +export function getFuturesPosition( + this: RESTBase, + { productId }: GetFuturesPositionRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/cfm/positions/${productId}`, + isPublic: false, + }); +} + +// [POST] Schedule Futures Sweep +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_schedulefcmsweep +export function scheduleFuturesSweep( + this: RESTBase, + requestParams: ScheduleFuturesSweepRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/cfm/sweeps/schedule`, + bodyParams: requestParams, + isPublic: false, + }); +} + +// [GET] List Futures Sweeps +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmsweeps +export function listFuturesSweeps( + this: RESTBase +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/cfm/sweeps`, + isPublic: false, + }); +} + +// [DELETE] Cancel Pending Futures Sweep +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_cancelfcmsweep +export function cancelPendingFuturesSweep( + this: RESTBase +): Promise { + return this.request({ + method: method.DELETE, + endpoint: `${API_PREFIX}/cfm/sweeps`, + isPublic: false, + }); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/index.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/index.ts new file mode 100644 index 0000000000..101223a645 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/index.ts @@ -0,0 +1,95 @@ +import { RESTBase } from './rest-base'; +import * as Accounts from './accounts'; +import * as Converts from './converts'; +import * as DataAPI from './dataAPI'; +import * as Fees from './fees'; +import * as Futures from './futures'; +import * as Orders from './orders'; +import * as Payments from './payments'; +import * as Perpetuals from './perpetuals'; +import * as Portfolios from './portfolios'; +import * as Products from './products'; +import * as Public from './public'; + +export class RESTClient extends RESTBase { + constructor(key?: string | undefined, secret?: string | undefined) { + super(key, secret); + } + + // =============== ACCOUNTS endpoints =============== + public getAccount = Accounts.getAccount.bind(this); + public listAccounts = Accounts.listAccounts.bind(this); + + // =============== CONVERTS endpoints =============== + public createConvertQuote = Converts.createConvertQuote.bind(this); + public commitConvertTrade = Converts.commitConvertTrade.bind(this); + public getConvertTrade = Converts.getConvertTrade.bind(this); + + // =============== DATA API endpoints =============== + public getAPIKeyPermissions = DataAPI.getAPIKeyPermissions.bind(this); + + // =============== FEES endpoints =============== + public getTransactionSummary = Fees.getTransactionSummary.bind(this); + + // =============== FUTURES endpoints =============== + public getFuturesBalanceSummary = Futures.getFuturesBalanceSummary.bind(this); + public getIntradayMarginSetting = Futures.getIntradayMarginSetting.bind(this); + public setIntradayMarginSetting = Futures.setIntradayMarginSetting.bind(this); + public getCurrentMarginWindow = Futures.getCurrentMarginWindow.bind(this); + public listFuturesPositions = Futures.listFuturesPositions.bind(this); + public getFuturesPosition = Futures.getFuturesPosition.bind(this); + public scheduleFuturesSweep = Futures.scheduleFuturesSweep.bind(this); + public listFuturesSweeps = Futures.listFuturesSweeps.bind(this); + public cancelPendingFuturesSweep = + Futures.cancelPendingFuturesSweep.bind(this); + + // =============== ORDERS endpoints =============== + public createOrder = Orders.createOrder.bind(this); + public cancelOrders = Orders.cancelOrders.bind(this); + public editOrder = Orders.editOrder.bind(this); + public editOrderPreview = Orders.editOrderPreview.bind(this); + public listOrders = Orders.listOrders.bind(this); + public listFills = Orders.listFills.bind(this); + public getOrder = Orders.getOrder.bind(this); + public previewOrder = Orders.previewOrder.bind(this); + public closePosition = Orders.closePosition.bind(this); + + // =============== PAYMENTS endpoints =============== + public listPaymentMethods = Payments.listPaymentMethods.bind(this); + public getPaymentMethod = Payments.getPaymentMethod.bind(this); + + // =============== PERPETUALS endpoints =============== + public allocatePortfolio = Perpetuals.allocatePortfolio.bind(this); + public getPerpetualsPortfolioSummary = + Perpetuals.getPerpetualsPortfolioSummary.bind(this); + public listPerpetualsPositions = + Perpetuals.listPerpetualsPositions.bind(this); + public getPerpetualsPosition = Perpetuals.getPerpertualsPosition.bind(this); + public getPortfolioBalances = Perpetuals.getPortfolioBalances.bind(this); + public optInOutMultiAssetCollateral = + Perpetuals.optInOutMultiAssetCollateral.bind(this); + + // =============== PORTFOLIOS endpoints =============== + public listPortfolios = Portfolios.listPortfolios.bind(this); + public createPortfolio = Portfolios.createPortfolio.bind(this); + public deletePortfolio = Portfolios.deletePortfolio.bind(this); + public editPortfolio = Portfolios.editPortfolio.bind(this); + public movePortfolioFunds = Portfolios.movePortfolioFunds.bind(this); + public getPortfolioBreakdown = Portfolios.getPortfolioBreakdown.bind(this); + + // =============== PRODUCTS endpoints =============== + public getBestBidAsk = Products.getBestBidAsk.bind(this); + public getProductBook = Products.getProductBook.bind(this); + public listProducts = Products.listProducts.bind(this); + public getProduct = Products.getProduct.bind(this); + public getProductCandles = Products.getProductCandles.bind(this); + public getMarketTrades = Products.getMarketTrades.bind(this); + + // =============== PUBLIC endpoints =============== + public getServerTime = Public.getServerTime.bind(this); + public getPublicProductBook = Public.getPublicProductBook.bind(this); + public listPublicProducts = Public.listPublicProducts.bind(this); + public getPublicProduct = Public.getPublicProduct.bind(this); + public getPublicProductCandles = Public.getPublicProductCandles.bind(this); + public getPublicMarketTrades = Public.getPublicMarketTrades.bind(this); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/orders.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/orders.ts new file mode 100644 index 0000000000..04bf2aefbc --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/orders.ts @@ -0,0 +1,149 @@ +import { API_PREFIX } from '../constants'; +import { RESTBase } from './rest-base'; +import { + CancelOrdersRequest, + CancelOrdersResponse, + ClosePositionRequest, + ClosePositionResponse, + CreateOrderRequest, + CreateOrderResponse, + EditOrderPreviewRequest, + EditOrderPreviewResponse, + EditOrderRequest, + EditOrderResponse, + GetOrderRequest, + GetOrderResponse, + ListFillsRequest, + ListFillsResponse, + ListOrdersRequest, + ListOrdersResponse, + PreviewOrderRequest, + PreviewOrderResponse, +} from './types/orders-types'; +import { method } from './types/request-types'; + +// [POST] Create Order +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_postorder +export function createOrder( + this: RESTBase, + requestParams: CreateOrderRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/orders`, + bodyParams: requestParams, + isPublic: false, + }); +} + +// [POST] Cancel Orders +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_cancelorders +export function cancelOrders( + this: RESTBase, + requestParams: CancelOrdersRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/orders/batch_cancel`, + bodyParams: requestParams, + isPublic: false, + }); +} + +// [POST] Edit Order +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_editorder +export function editOrder( + this: RESTBase, + requestParams: EditOrderRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/orders/edit`, + bodyParams: requestParams, + isPublic: false, + }); +} + +// [POST] Edit Order Preview +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_previeweditorder +export function editOrderPreview( + this: RESTBase, + requestParams: EditOrderPreviewRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/orders/edit_preview`, + bodyParams: requestParams, + isPublic: false, + }); +} + +// [GET] List Orders +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders +export function listOrders( + this: RESTBase, + requestParams: ListOrdersRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/orders/historical/batch`, + queryParams: requestParams, + isPublic: false, + }); +} + +// [GET] List Fills +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfills +export function listFills( + this: RESTBase, + requestParams: ListFillsRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/orders/historical/fills`, + queryParams: requestParams, + isPublic: false, + }); +} + +// [GET] Get Order +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorder +export function getOrder( + this: RESTBase, + { orderId }: GetOrderRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/orders/historical/${orderId}`, + isPublic: false, + }); +} + +// [POST] Preview Order +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_previeworder +export function previewOrder( + this: RESTBase, + requestParams: PreviewOrderRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/orders/preview`, + bodyParams: requestParams, + isPublic: false, + }); +} + +// [POST] Close Position +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_closeposition +export function closePosition( + this: RESTBase, + requestParams: ClosePositionRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/orders/close_position`, + queryParams: undefined, + bodyParams: requestParams, + isPublic: false, + }); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/payments.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/payments.ts new file mode 100644 index 0000000000..defa3f4dd6 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/payments.ts @@ -0,0 +1,33 @@ +import { API_PREFIX } from '../constants'; +import { RESTBase } from './rest-base'; +import { + GetPaymentMethodRequest, + GetPaymentMethodResponse, + ListPaymentMethodsResponse, +} from './types/payments-types'; +import { method } from './types/request-types'; + +// [GET] List Payment Methods +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpaymentmethods +export function listPaymentMethods( + this: RESTBase +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/payment_methods`, + isPublic: false, + }); +} + +// [GET] Get Payment Method +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpaymentmethod +export function getPaymentMethod( + this: RESTBase, + { paymentMethodId }: GetPaymentMethodRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/payment_methods/${paymentMethodId}`, + isPublic: false, + }); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/perpetuals.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/perpetuals.ts new file mode 100644 index 0000000000..6e1c568d69 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/perpetuals.ts @@ -0,0 +1,97 @@ +import { API_PREFIX } from '../constants'; +import { RESTBase } from './rest-base'; +import { + AllocatePortfolioRequest, + AllocatePortfolioResponse, + GetPerpetualsPortfolioSummaryRequest, + GetPerpetualsPortfolioSummaryResponse, + GetPerpetualsPositionRequest, + GetPerpetualsPositionResponse, + GetPortfolioBalancesRequest, + GetPortfolioBalancesResponse, + ListPerpetualsPositionsRequest, + ListPerpetualsPositionsResponse, + OptInOutMultiAssetCollateralRequest, + OptInOutMultiAssetCollateralResponse, +} from './types/perpetuals-types'; +import { method } from './types/request-types'; + +// [POST] Allocate Portfolio +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_allocateportfolio +export function allocatePortfolio( + this: RESTBase, + requestParams: AllocatePortfolioRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/intx/allocate`, + bodyParams: requestParams, + isPublic: false, + }); +} + +// [GET] Get Perpetuals Portfolio Summary +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getintxportfoliosummary +export function getPerpetualsPortfolioSummary( + this: RESTBase, + { portfolioUuid }: GetPerpetualsPortfolioSummaryRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/intx/portfolio/${portfolioUuid}`, + isPublic: false, + }); +} + +// [GET] List Perpetuals Positions +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getintxpositions +export function listPerpetualsPositions( + this: RESTBase, + { portfolioUuid }: ListPerpetualsPositionsRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/intx/positions/${portfolioUuid}`, + isPublic: false, + }); +} + +// [GET] Get Perpetuals Position +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getintxposition +export function getPerpertualsPosition( + this: RESTBase, + { portfolioUuid, symbol }: GetPerpetualsPositionRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/intx/positions/${portfolioUuid}/${symbol}`, + isPublic: false, + }); +} + +// [GET] Get Portfolio Balances +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getintxbalances +export function getPortfolioBalances( + this: RESTBase, + { portfolioUuid }: GetPortfolioBalancesRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/intx/balances/${portfolioUuid}`, + isPublic: false, + }); +} + +// [POST] Opt In or Out of Multi Asset Collateral +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_intxmultiassetcollateral +export function optInOutMultiAssetCollateral( + this: RESTBase, + requestParams: OptInOutMultiAssetCollateralRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/intx/multi_asset_collateral`, + bodyParams: requestParams, + isPublic: false, + }); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/portfolios.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/portfolios.ts new file mode 100644 index 0000000000..df5e5791f8 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/portfolios.ts @@ -0,0 +1,100 @@ +import { API_PREFIX } from '../constants'; +import { RESTBase } from './rest-base'; +import { + CreatePortfolioRequest, + CreatePortfolioResponse, + DeletePortfolioRequest, + DeletePortfolioResponse, + EditPortfolioRequest, + EditPortfolioResponse, + GetPortfolioBreakdownRequest, + GetPortfolioBreakdownResponse, + ListPortfoliosRequest, + ListPortfoliosResponse, + MovePortfolioFundsRequest, + MovePortfolioFundsResponse, +} from './types/portfolios-types'; +import { method } from './types/request-types'; + +// [GET] List Portfolios +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getportfolios +export function listPortfolios( + this: RESTBase, + requestParams: ListPortfoliosRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/portfolios`, + queryParams: requestParams, + isPublic: false, + }); +} + +// [POST] Create Portfolio +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_createportfolio +export function createPortfolio( + this: RESTBase, + requestParams: CreatePortfolioRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/portfolios`, + bodyParams: requestParams, + isPublic: false, + }); +} + +// [POST] Move Portfolio Funds +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_moveportfoliofunds +export function movePortfolioFunds( + this: RESTBase, + requestParams: MovePortfolioFundsRequest +): Promise { + return this.request({ + method: method.POST, + endpoint: `${API_PREFIX}/portfolios/move_funds`, + bodyParams: requestParams, + isPublic: false, + }); +} + +// [GET] Get Portfolio Breakdown +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getportfoliobreakdown +export function getPortfolioBreakdown( + this: RESTBase, + { portfolioUuid, ...requestParams }: GetPortfolioBreakdownRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/portfolios/${portfolioUuid}`, + queryParams: requestParams, + isPublic: false, + }); +} + +// [DELETE] Delete Portfolio +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_deleteportfolio +export function deletePortfolio( + this: RESTBase, + { portfolioUuid }: DeletePortfolioRequest +): Promise { + return this.request({ + method: method.DELETE, + endpoint: `${API_PREFIX}/portfolios/${portfolioUuid}`, + isPublic: false, + }); +} + +// [PUT] Edit Portfolio +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_editportfolio +export function editPortfolio( + this: RESTBase, + { portfolioUuid, ...requestParams }: EditPortfolioRequest +): Promise { + return this.request({ + method: method.PUT, + endpoint: `${API_PREFIX}/portfolios/${portfolioUuid}`, + bodyParams: requestParams, + isPublic: false, + }); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/products.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/products.ts new file mode 100644 index 0000000000..7cd2ca1f0a --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/products.ts @@ -0,0 +1,101 @@ +import { API_PREFIX } from '../constants'; +import { RESTBase } from './rest-base'; +import { + GetBestBidAskRequest, + GetBestBidAskResponse, + GetMarketTradesRequest, + GetMarketTradesResponse, + GetProductBookRequest, + GetProductBookResponse, + GetProductCandlesRequest, + GetProductCandlesResponse, + GetProductRequest, + GetProductResponse, + ListProductsRequest, + ListProductsResponse, +} from './types/products-types'; +import { method } from './types/request-types'; + +// [GET] Get Best Bid Ask +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getbestbidask +export function getBestBidAsk( + this: RESTBase, + requestParams: GetBestBidAskRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/best_bid_ask`, + queryParams: requestParams, + isPublic: false, + }); +} + +// [GET] Get Product Book +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getproductbook +export function getProductBook( + this: RESTBase, + requestParams: GetProductBookRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/product_book`, + queryParams: requestParams, + isPublic: false, + }); +} + +// [GET] List Products +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getproducts +export function listProducts( + this: RESTBase, + requestParams: ListProductsRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/products`, + queryParams: requestParams, + isPublic: false, + }); +} + +// [GET] Get Product +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getproduct +export function getProduct( + this: RESTBase, + { productId, ...requestParams }: GetProductRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/products/${productId}`, + queryParams: requestParams, + isPublic: false, + }); +} + +// [GET] Get Product Candles +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getcandles +export function getProductCandles( + this: RESTBase, + { productId, ...requestParams }: GetProductCandlesRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/products/${productId}/candles`, + queryParams: requestParams, + isPublic: false, + }); +} + +// [GET] Get Market Trades +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getmarkettrades +export function getMarketTrades( + this: RESTBase, + { productId, ...requestParams }: GetMarketTradesRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/products/${productId}/ticker`, + queryParams: requestParams, + isPublic: false, + }); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/public.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/public.ts new file mode 100644 index 0000000000..1b9577e514 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/public.ts @@ -0,0 +1,95 @@ +import { API_PREFIX } from '../constants'; +import { RESTBase } from './rest-base'; +import { + GetPublicMarketTradesRequest, + GetPublicMarketTradesResponse, + GetPublicProductBookRequest, + GetPublicProductBookResponse, + GetPublicProductCandlesRequest, + GetPublicProductCandlesResponse, + GetPublicProductRequest, + GetPublicProductResponse, + GetServerTimeResponse, + ListPublicProductsRequest, + ListPublicProductsResponse, +} from './types/public-types'; +import { method } from './types/request-types'; + +// [GET] Get Server Time +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getservertime +export function getServerTime(this: RESTBase): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/time`, + isPublic: true, + }); +} + +// [GET] Get Public Product Book +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicproductbook +export function getPublicProductBook( + this: RESTBase, + requestParams: GetPublicProductBookRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/market/product_book`, + queryParams: requestParams, + isPublic: true, + }); +} + +// [GET] List Public Products +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicproducts +export function listPublicProducts( + this: RESTBase, + requestParams: ListPublicProductsRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/market/products`, + queryParams: requestParams, + isPublic: true, + }); +} + +// [GET] Get Public Product +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicproduct +export function getPublicProduct( + this: RESTBase, + { productId }: GetPublicProductRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/market/products/${productId}`, + isPublic: true, + }); +} + +// [GET] Get Public Product Candles +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpubliccandles +export function getPublicProductCandles( + this: RESTBase, + { productId, ...requestParams }: GetPublicProductCandlesRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/market/products/${productId}/candles`, + queryParams: requestParams, + isPublic: true, + }); +} + +// [GET] Get Public Market Trades +// Official Documentation: https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicmarkettrades +export function getPublicMarketTrades( + this: RESTBase, + { productId, ...requestParams }: GetPublicMarketTradesRequest +): Promise { + return this.request({ + method: method.GET, + endpoint: `${API_PREFIX}/products/${productId}/ticker`, + queryParams: requestParams, + isPublic: true, + }); +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/rest-base.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/rest-base.ts new file mode 100644 index 0000000000..9084df5612 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/rest-base.ts @@ -0,0 +1,123 @@ +import { generateToken } from '../jwt-generator'; +import fetch, { Headers, RequestInit, Response } from 'node-fetch'; +import { BASE_URL, USER_AGENT } from '../constants'; +import { RequestOptions } from './types/request-types'; +import { handleException } from './errors'; + +export class RESTBase { + private apiKey: string | undefined; + private apiSecret: string | undefined; + + constructor(key?: string, secret?: string) { + if (!key || !secret) { + console.log('Could not authenticate. Only public endpoints accessible.'); + } + this.apiKey = key; + this.apiSecret = secret; + } + + request(options: RequestOptions): Promise { + const { method, endpoint, isPublic } = options; + let { queryParams, bodyParams } = options; + + queryParams = queryParams ? this.filterParams(queryParams) : {}; + + if (bodyParams !== undefined) + bodyParams = bodyParams ? this.filterParams(bodyParams) : {}; + + return this.prepareRequest( + method, + endpoint, + queryParams, + bodyParams, + isPublic + ); + } + + prepareRequest( + httpMethod: string, + urlPath: string, + queryParams?: Record, + bodyParams?: Record, + isPublic?: boolean + ) { + const headers: Headers = this.setHeaders(httpMethod, urlPath, isPublic); + + const requestOptions: RequestInit = { + method: httpMethod, + headers: headers, + body: JSON.stringify(bodyParams), + }; + + const queryString = this.buildQueryString(queryParams); + const url = `https://${BASE_URL}${urlPath}${queryString}`; + + return this.sendRequest(headers, requestOptions, url); + } + + async sendRequest( + headers: Headers, + requestOptions: RequestInit, + url: string + ) { + const response: Response = await fetch(url, requestOptions); + const responseText = await response.text(); + handleException(response, responseText, response.statusText); + + return responseText; + } + + setHeaders(httpMethod: string, urlPath: string, isPublic?: boolean) { + const headers: Headers = new Headers(); + headers.append('Content-Type', 'application/json'); + headers.append('User-Agent', USER_AGENT); + if (this.apiKey !== undefined && this.apiSecret !== undefined) + headers.append( + 'Authorization', + `Bearer ${generateToken( + httpMethod, + urlPath, + this.apiKey, + this.apiSecret + )}` + ); + else if (isPublic == undefined || isPublic == false) + throw new Error( + 'Attempting to access authenticated endpoint with invalid API_KEY or API_SECRET.' + ); + + return headers; + } + + filterParams(data: Record) { + const filteredParams: Record = {}; + + for (const key in data) { + if (data[key] !== undefined) { + filteredParams[key] = data[key]; + } + } + + return filteredParams; + } + + buildQueryString(queryParams?: Record): string { + if (!queryParams || Object.keys(queryParams).length === 0) { + return ''; + } + + const queryString = Object.entries(queryParams) + .flatMap(([key, value]) => { + if (Array.isArray(value)) { + return value.map( + (item) => `${encodeURIComponent(key)}=${encodeURIComponent(item)}` + ); + } else { + return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`; + } + }) + .join('&'); + + return `?${queryString}`; + } +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/accounts-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/accounts-types.ts new file mode 100644 index 0000000000..ca1301c3f4 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/accounts-types.ts @@ -0,0 +1,26 @@ +import { Account } from './common-types'; + +// Get Account +export type GetAccountRequest = { + // Path Params + accountUuid: string; +}; + +export type GetAccountResponse = { + account?: Account; +}; + +// List Accounts +export type ListAccountsRequest = { + // Query Params + limit?: number; + cursor?: string; + retailPortfolioId?: string; +}; + +export type ListAccountsResponse = { + accounts?: Account[]; + has_next: boolean; + cursor?: string; + size?: number; +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/common-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/common-types.ts new file mode 100644 index 0000000000..a27d9fb34e --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/common-types.ts @@ -0,0 +1,447 @@ +// ----- ENUMS ----- +export enum ProductType { + UNKNOWN = 'UNKNOWN_PRODUCT_TYPE', + SPOT = 'SPOT', + FUTURE = 'FUTURE', +} + +export enum ContractExpiryType { + UNKNOWN = 'UNKNOWN_CONTRACT_EXPIRY_TYPE', + EXPIRING = 'EXPIRING', + PERPETUAL = 'PERPETUAL', +} + +export enum ExpiringContractStatus { + UNKNOWN = 'UNKNOWN_EXPIRING_CONTRACT_STATUS', + UNEXPIRED = 'STATUS_UNEXPIRED', + EXPIRED = 'STATUS_EXPIRED', + ALL = 'STATUS_ALL', +} + +export enum PortfolioType { + UNDEFINED = 'UNDEFINED', + DEFAULT = 'DEFAULT', + CONSUMER = 'CONSUMER', + INTX = 'INTX', +} + +export enum MarginType { + CROSS = 'CROSS', + ISOLATED = 'ISOLATED', +} + +export enum OrderPlacementSource { + UNKNOWN = 'UNKNOWN_PLACEMENT_SOURCE', + RETAIL_SIMPLE = 'RETAIL_SIMPLE', + RETAIL_ADVANCED = 'RETAIL_ADVANCED', +} + +export enum SortBy { + UNKNOWN = 'UNKNOWN_SORT_BY', + LIMIT_PRICE = 'LIMIT_PRICE', + LAST_FILL_TIME = 'LAST_FILL_TIME', +} + +export enum OrderSide { + BUY = 'BUY', + SELL = 'SELL', +} + +export enum StopDirection { + UP = 'STOP_DIRECTION_STOP_UP', + DOWN = 'STOP_DIRECTION_STOP_DOWN', +} + +export enum Granularity { + UNKNOWN = 'UNKNOWN_GRANULARITY', + ONE_MINUTE = 'ONE_MINUTE', + FIVE_MINUTE = 'FIVE_MINUTE', + FIFTEEN_MINUTE = 'FIFTEEN_MINUTE', + THIRTY_MINUTE = 'THIRTY_MINUTE', + ONE_HOUR = 'ONE_HOUR', + TWO_HOUR = 'TWO_HOUR', + SIX_HOUR = 'SIX_HOUR', + ONE_DAY = 'ONE_DAY', +} + +export enum ProductVenue { + UNKNOWN = 'UNKNOWN_VENUE_TYPE', + CBE = 'CBE', + FCM = 'FCM', + INTX = 'INTX', +} + +export enum IntradayMarginSetting { + UNSPECIFIED = 'INTRADAY_MARGIN_SETTING_UNSPECIFIED', + STANDARD = 'INTRADAY_MARGIN_SETTING_STANDARD', + INTRADAY = 'INTRADAY_MARGIN_SETTING_INTRADAY', +} + +// ----- TYPES ----- +export type Account = { + uuid?: string; + name?: string; + currency?: string; + available_balance?: Record; + default?: boolean; + active?: boolean; + created_at?: string; + updated_at?: string; + deleted_at?: string; + type?: Record; + ready?: boolean; + hold?: Record; + retail_portfolio_id?: string; +}; + +export type TradeIncentiveMetadata = { + userIncentiveId?: string; + codeVal?: string; +}; + +export type OrderConfiguration = + | { market_market_ioc: MarketMarketIoc } + | { sor_limit_ioc: SorLimitIoc } + | { limit_limit_gtc: LimitLimitGtc } + | { limit_limit_gtd: LimitLimitGtd } + | { limit_limit_fok: LimitLimitFok } + | { stop_limit_stop_limit_gtc: StopLimitStopLimitGtc } + | { stop_limit_stop_limit_gtd: StopLimitStopLimitGtd } + | { trigger_bracket_gtc: TriggerBracketGtc } + | { trigger_bracket_gtd: TriggerBracketGtd }; + +export type MarketMarketIoc = { quote_size: string } | { base_size: string }; + +export type SorLimitIoc = { + baseSize: string; + limitPrice: string; +}; + +export type LimitLimitGtc = { + baseSize: string; + limitPrice: string; + postOnly: boolean; +}; + +export type LimitLimitGtd = { + baseSize: string; + limitPrice: string; + endTime: string; + postOnly: boolean; +}; + +export type LimitLimitFok = { + baseSize: string; + limitPrice: string; +}; + +export type StopLimitStopLimitGtc = { + baseSize: string; + limitPrice: string; + stopPrice: string; + stopDirection: StopDirection; +}; + +export type StopLimitStopLimitGtd = { + baseSize: string; + limitPrice: string; + stopPrice: string; + endTime: string; + stopDirection: StopDirection; +}; + +export type TriggerBracketGtc = { + baseSize: string; + limitPrice: string; + stopTriggerPrice: string; +}; + +export type TriggerBracketGtd = { + baseSize: string; + limitPrice: string; + stopTriggerPrice: string; + endTime: string; +}; + +export type RatConvertTrade = { + id?: string; + status?: Record; + user_entered_amount?: Record; + amount?: Record; + subtotal?: Record; + total?: Record; + fees?: Record; + total_fee?: Record; + source?: Record; + target?: Record; + unit_price?: Record; + user_warnings?: Record; + user_reference?: string; + source_curency?: string; + cancellation_reason?: Record; + source_id?: string; + target_id?: string; + subscription_info?: Record; + exchange_rate?: Record; + tax_details?: Record; + trade_incentive_info?: Record; + total_fee_without_tax?: Record; + fiat_denoted_total?: Record; +}; + +export type FCMBalanceSummary = { + futures_buying_power?: Record; + total_usd_balance?: Record; + cbi_usd_balance?: Record; + cfm_usd_balance?: Record; + total_open_orders_hold_amount?: Record; + unrealized_pnl?: Record; + daily_realized_pnl?: Record; + initial_margin?: Record; + available_margin?: Record; + liquidation_threshold?: Record; + liquidation_buffer_amount?: Record; + liquidation_buffer_percentage?: string; + intraday_margin_window_measure?: Record; + overnight_margin_window_measure?: Record; +}; + +export type FCMPosition = { + product_id?: string; + expiration_time?: Record; + side?: Record; + number_of_contracts?: string; + current_price?: string; + avg_entry_price?: string; + unrealized_pnl?: string; + daily_realized_pnl?: string; +}; + +export type FCMSweep = { + id: string; + requested_amount: Record; + should_sweep_all: boolean; + status: Record; + schedule_time: Record; +}; + +export type CancelOrderObject = { + success: boolean; + failure_reason: Record; + order_id: string; +}; + +export type Order = { + order_id: string; + product_id: string; + user_id: string; + order_configuration: OrderConfiguration; + side: OrderSide; + client_order_id: string; + status: Record; + time_in_force?: Record; + created_time: Record; + completion_percentage: string; + filled_size?: string; + average_filled_price: string; + fee?: string; + number_of_fills: string; + filled_value?: string; + pending_cancel: boolean; + size_in_quote: boolean; + total_fees: string; + size_inclusive_of_fees: boolean; + total_value_after_fees: string; + trigger_status?: Record; + order_type?: Record; + reject_reason?: Record; + settled?: boolean; + product_type?: ProductType; + reject_message?: string; + cancel_message?: string; + order_placement_source?: OrderPlacementSource; + outstanding_hold_amount?: string; + is_liquidation?: boolean; + last_fill_time?: Record; + edit_history?: Record[]; + leverage?: string; + margin_type?: MarginType; + retail_portfolio_id?: string; + originating_order_id?: string; + attached_order_id?: string; +}; + +export type PaymentMethod = { + id?: string; + type?: string; + name?: string; + currency?: string; + verified?: boolean; + allow_buy?: boolean; + allow_sell?: boolean; + allow_deposit?: boolean; + allow_withdraw?: boolean; + created_at?: string; + updated_at?: string; +}; + +export type PerpetualPortfolio = { + portfolio_uuid?: string; + collateral?: string; + position_notional?: string; + open_position_notional?: string; + pending_fees?: string; + borrow?: string; + accrued_interest?: string; + rolling_debt?: string; + portfolio_initial_margin?: string; + portfolio_im_notional?: Record; + liquidation_percentage?: string; + liquidation_buffer?: string; + margin_type?: Record; + margin_flags?: Record; + liquidation_status?: Record; + unrealized_pnl?: Record; + total_balance?: Record; +}; + +export type PortfolioSummary = { + unrealized_pnl?: Record; + buying_power?: Record; + total_balance?: Record; + max_withdrawal_amount?: Record; +}; + +export type PositionSummary = { + aggregated_pnl?: Record; +}; + +export type Position = { + product_id?: string; + product_uuid?: string; + portfolio_uuid?: string; + symbol?: string; + vwap?: Record; + entry_vwap?: Record; + position_side?: Record; + margin_type?: Record; + net_size?: string; + buy_order_size?: string; + sell_order_size?: string; + im_contribution?: string; + unrealized_pnl?: Record; + mark_price?: Record; + liquidation_price?: Record; + leverage?: string; + im_notional?: Record; + mm_notional?: Record; + position_notional?: Record; + aggregated_pnl?: Record; +}; + +export type Balance = { + asset: Record; + quantity: string; + hold: string; + transfer_hold: string; + collateral_value: string; + collateral_weight: string; + max_withdraw_amount: string; + loan: string; + loan_collateral_requirement_usd: string; + pledged_quantity: string; +}; + +export type Portfolio = { + name?: string; + uuid?: string; + type?: string; +}; + +export type PortfolioBreakdown = { + portfolio?: Portfolio; + portfolio_balances?: Record; + spot_positions?: Record[]; + perp_positions?: Record[]; + futures_positions?: Record[]; +}; + +export type PriceBook = { + product_id: string; + bids: Record[]; + asks: Record[]; + time?: Record; +}; + +export type Products = { + products?: Product[]; + num_products?: number; +}; + +export type Product = { + product_id: string; + price: string; + price_percentage_change_24h: string; + volume_24h: string; + volume_percentage_change_24h: string; + base_increment: string; + quote_increment: string; + quote_min_size: string; + quote_max_size: string; + base_min_size: string; + base_max_size: string; + base_name: string; + quote_name: string; + watched: boolean; + is_disabled: boolean; + new: boolean; + status: string; + cancel_only: boolean; + limit_only: boolean; + post_only: boolean; + trading_disabled: boolean; + auction_mode: boolean; + product_type?: ProductType; + quote_currency_id?: string; + base_currency_id?: string; + fcm_trading_session_details?: Record; + mid_market_price?: string; + alias?: string; + alias_to?: string[]; + base_display_symbol: string; + quote_display_symbol?: string; + view_only?: boolean; + price_increment?: string; + display_name?: string; + product_venue?: ProductVenue; + approximate_quote_24h_volume?: string; + future_product_details?: Record; +}; + +export type Candles = { + candles?: Candle[]; +}; + +export type Candle = { + start?: string; + low?: string; + high?: string; + open?: string; + close?: string; + volume?: string; +}; + +export type HistoricalMarketTrade = { + trade_id?: string; + product_id?: string; + price?: string; + size?: string; + time?: string; + side?: OrderSide; +}; + +export type PortfolioBalance = { + portfolio_uuid?: string; + balances?: Balance[]; + is_margin_limit_reached?: boolean; +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/converts-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/converts-types.ts new file mode 100644 index 0000000000..8724b89d19 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/converts-types.ts @@ -0,0 +1,42 @@ +// Create Convert Quote +import { RatConvertTrade, TradeIncentiveMetadata } from './common-types'; + +export type CreateConvertQuoteRequest = { + // Body Params + fromAccount: string; + toAccount: string; + amount: string; + tradeIncentiveMetadata?: TradeIncentiveMetadata; +}; + +export type CreateConvertQuoteResponse = { + trade?: RatConvertTrade; +}; + +// Get Convert Trade +export type GetConvertTradeRequest = { + // Path Params + tradeId: string; + + //Query Params + fromAccount: string; + toAccount: string; +}; + +export type GetConvertTradeResponse = { + trade?: RatConvertTrade; +}; + +// Commit Convert Trade +export type CommitConvertTradeRequest = { + // Path Params + tradeId: string; + + // Body Params + fromAccount: string; + toAccount: string; +}; + +export type CommitConvertTradeResponse = { + trade?: RatConvertTrade; +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/dataAPI-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/dataAPI-types.ts new file mode 100644 index 0000000000..7a773a0e8f --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/dataAPI-types.ts @@ -0,0 +1,10 @@ +import { PortfolioType } from './common-types'; + +// Get API Key Permissions +export type GetAPIKeyPermissionsResponse = { + can_view?: boolean; + can_trade?: boolean; + can_transfer?: boolean; + portfolio_uuid?: string; + portfolio_type?: PortfolioType; +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/fees-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/fees-types.ts new file mode 100644 index 0000000000..e9db653b37 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/fees-types.ts @@ -0,0 +1,23 @@ +import { ContractExpiryType, ProductType, ProductVenue } from './common-types'; + +// Get Transactions Summary +export type GetTransactionsSummaryRequest = { + // Query Params + productType?: ProductType; + contractExpiryType?: ContractExpiryType; + productVenue?: ProductVenue; +}; + +export type GetTransactionsSummaryResponse = { + total_volume: number; + total_fees: number; + fee_tier: Record; + margin_rate?: Record; + goods_and_services_tax?: Record; + advanced_trade_only_volumes?: number; + advanced_trade_only_fees?: number; + coinbase_pro_volume?: number; // deprecated + coinbase_pro_fees?: number; // deprecated + total_balance?: string; + has_promo_fee?: boolean; +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/futures-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/futures-types.ts new file mode 100644 index 0000000000..61bbf97b1d --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/futures-types.ts @@ -0,0 +1,71 @@ +import { + FCMBalanceSummary, + FCMPosition, + FCMSweep, + IntradayMarginSetting, +} from './common-types'; + +// Get Futures Balance Summary +export type GetFuturesBalanceSummaryResponse = { + balance_summary?: FCMBalanceSummary; +}; + +// Get Intraday Margin Setting +export type GetIntradayMarginSettingResponse = { + setting?: IntradayMarginSetting; +}; + +// Set Intraday Margin Setting +export type SetIntradayMarginSettingRequest = { + // Body Params + setting?: IntradayMarginSetting; +}; + +export type SetIntradayMarginSettingResponse = Record; + +// Get Current Margin Window +export type GetCurrentMarginWindowRequest = { + // Query Params + marginProfileType?: string; +}; + +export type GetCurrentMarginWindowResponse = { + margin_window?: Record; + is_intraday_margin_killswitch_enabled?: boolean; + is_intraday_margin_enrollment_killswitch_enabled?: boolean; +}; + +// List Futures Positions +export type ListFuturesPositionsResponse = { + positions?: FCMPosition[]; +}; + +// Get Futures Position +export type GetFuturesPositionRequest = { + // Path Params + productId: string; +}; + +export type GetFuturesPositionResponse = { + position?: FCMPosition; +}; + +// Schedule Futures Sweep +export type ScheduleFuturesSweepRequest = { + // Body Params + usdAmount?: string; +}; + +export type ScheduleFuturesSweepResponse = { + success?: boolean; +}; + +// List Futures Sweeps +export type ListFuturesSweepsResponse = { + sweeps: FCMSweep[]; +}; + +// Cancel Pending Futures Sweep = { +export type CancelPendingFuturesSweep = { + success?: boolean; +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/orders-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/orders-types.ts new file mode 100644 index 0000000000..486d93cd16 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/orders-types.ts @@ -0,0 +1,185 @@ +import { + CancelOrderObject, + ContractExpiryType, + MarginType, + Order, + OrderConfiguration, + OrderPlacementSource, + OrderSide, + ProductType, + SortBy, +} from './common-types'; + +// Create Order +export type CreateOrderRequest = { + // Body Params + clientOrderId: string; + productId: string; + side: OrderSide; + orderConfiguration: OrderConfiguration; + selfTradePreventionId?: string; + leverage?: string; + marginType?: MarginType; + retailPortfolioId?: string; +}; + +export type CreateOrderResponse = { + success: boolean; + failure_reason?: Record; // deprecated + order_id?: string; // deprecated + response?: + | { success_response: Record } + | { error_response: Record }; + order_configuration?: OrderConfiguration; +}; + +// Cancel Orders +export type CancelOrdersRequest = { + // Body Params + orderIds: string[]; +}; + +export type CancelOrdersResponse = { + results?: CancelOrderObject[]; +}; + +// Edit Order +export type EditOrderRequest = { + // Body Params + orderId: string; + price?: string; + size?: string; +}; + +export type EditOrderResponse = { + success: boolean; + response?: + | { success_response: Record } // deprecated + | { error_response: Record }; // deprecated + errors?: Record[]; +}; + +// Edit Order Preview +export type EditOrderPreviewRequest = { + // Body Params + orderId: string; + price?: string; + size?: string; +}; + +export type EditOrderPreviewResponse = { + errors: Record[]; + slippage?: string; + order_total?: string; + commission_total?: string; + quote_size?: string; + base_size?: string; + best_bid?: string; + average_filled_price?: string; +}; + +// List Orders +export type ListOrdersRequest = { + // Query Params + orderIds?: string[]; + productIds?: string[]; + orderStatus?: string[]; + limit?: number; + startDate?: string; + endDate?: string; + orderType?: string; + orderSide?: OrderSide; + cursor?: string; + productType?: ProductType; + orderPlacementSource?: OrderPlacementSource; + contractExpiryType?: ContractExpiryType; + assetFilters?: string[]; + retailPortfolioId?: string; + timeInForces?: string; + sortBy?: SortBy; +}; + +export type ListOrdersResponse = { + orders: Order[]; + sequence?: number; // deprecated + has_next: boolean; + cursor?: string; +}; + +// List Fills +export type ListFillsRequest = { + // Query Params + orderIds?: string[]; + tradeIds?: string[]; + productIds?: string[]; + startSequenceTimestamp?: string; + endSequenceTimestamp?: string; + retailPortfolioId?: string; + limit?: number; + cursor?: string; + sortBy?: SortBy; +}; + +export type ListFillsResponse = { + fills?: Record[]; + cursor?: string; +}; + +// Get Order +export type GetOrderRequest = { + // Path Params + orderId: string; +}; + +export type GetOrderResponse = { + order?: Order; +}; + +// Preview Order +export type PreviewOrderRequest = { + // Body Params + productId: string; + side: OrderSide; + orderConfiguration: OrderConfiguration; + leverage?: string; + marginType?: MarginType; + retailPortfolioId?: string; +}; + +export type PreviewOrderResponse = { + order_total: string; + commission_total: string; + errs: Record[]; + warning: Record[]; + quote_size: string; + base_size: string; + best_bid: string; + best_ask: string; + is_max: boolean; + order_margin_total?: string; + leverage?: string; + long_leverage?: string; + short_leverage?: string; + slippage?: string; + preview_id?: string; + current_liquidation_buffer?: string; + projected_liquidation_buffer?: string; + max_leverage?: string; + pnl_configuration?: Record; +}; + +// Close Position +export type ClosePositionRequest = { + // Body Params + clientOrderId: string; + productId: string; + size?: string; +}; + +export type ClosePositionResponse = { + success: boolean; + response?: + | { success_response: Record } + | { error_response: Record }; + order_configuration?: OrderConfiguration; +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/payments-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/payments-types.ts new file mode 100644 index 0000000000..064046f85a --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/payments-types.ts @@ -0,0 +1,16 @@ +import { PaymentMethod } from './common-types'; + +// List Payment Methods +export type ListPaymentMethodsResponse = { + paymentMethods?: PaymentMethod; +}; + +// Get Payment Method +export type GetPaymentMethodRequest = { + // Path Params + paymentMethodId: string; +}; + +export type GetPaymentMethodResponse = { + paymentMethod?: PaymentMethod; +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/perpetuals-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/perpetuals-types.ts new file mode 100644 index 0000000000..d1c1235a1e --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/perpetuals-types.ts @@ -0,0 +1,72 @@ +import { + PerpetualPortfolio, + PortfolioBalance, + PortfolioSummary, + Position, + PositionSummary, +} from './common-types'; + +// Allocate Portfolio +export type AllocatePortfolioRequest = { + // Body Params + portfolioUuid: string; + symbol: string; + amount: string; + currency: string; +}; + +export type AllocatePortfolioResponse = Record; + +// Get Perpetuals Portfolio Summary +export type GetPerpetualsPortfolioSummaryRequest = { + // Path Params + portfolioUuid: string; +}; + +export type GetPerpetualsPortfolioSummaryResponse = { + portfolios?: PerpetualPortfolio[]; + summary?: PortfolioSummary; +}; + +// List Perpetuals Positions +export type ListPerpetualsPositionsRequest = { + // Path Params + portfolioUuid: string; +}; + +export type ListPerpetualsPositionsResponse = { + positions?: Position[]; + summary?: PositionSummary; +}; + +// Get Perpetuals Position +export type GetPerpetualsPositionRequest = { + // Path Params + portfolioUuid: string; + symbol: string; +}; + +export type GetPerpetualsPositionResponse = { + position?: Position; +}; + +// Get Portfolio Balances +export type GetPortfolioBalancesRequest = { + // Path Params + portfolioUuid: string; +}; + +export type GetPortfolioBalancesResponse = { + portfolio_balancces?: PortfolioBalance[]; +}; + +// Opt In or Out of Multi Asset Collateral +export type OptInOutMultiAssetCollateralRequest = { + // Body Params + portfolioUuid?: string; + multiAssetCollateralEnabled?: boolean; +}; + +export type OptInOutMultiAssetCollateralResponse = { + cross_collateral_enabled?: boolean; +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/portfolios-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/portfolios-types.ts new file mode 100644 index 0000000000..e26698da0c --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/portfolios-types.ts @@ -0,0 +1,68 @@ +import { Portfolio, PortfolioBreakdown, PortfolioType } from './common-types'; + +// List Portfolios +export type ListPortfoliosRequest = { + // Query Params + portfolioType?: PortfolioType; +}; + +export type ListPortfoliosResponse = { + portfolios?: Portfolio[]; +}; + +// Create Portfolio +export type CreatePortfolioRequest = { + // Body Params + name: string; +}; + +export type CreatePortfolioResponse = { + portfolio?: Portfolio; +}; + +// Move Portfolio Funds +export type MovePortfolioFundsRequest = { + // Body Params + funds: Record; + sourcePortfolioUuid: string; + targetPortfolioUuid: string; +}; + +export type MovePortfolioFundsResponse = { + source_portfolio_uuid?: string; + target_portfolio_uuid?: string; +}; + +// Get Portfolio Breakdown +export type GetPortfolioBreakdownRequest = { + // Path Params + portfolioUuid: string; + + // Query Params + currency?: string; +}; + +export type GetPortfolioBreakdownResponse = { + breakdown?: PortfolioBreakdown; +}; + +// Delete Portfolio +export type DeletePortfolioRequest = { + // Path Params + portfolioUuid: string; +}; + +export type DeletePortfolioResponse = Record; + +// Edit Portfolio +export type EditPortfolioRequest = { + // Path Params + portfolioUuid: string; + + // Body Params + name: string; +}; + +export type EditPortfolioResponse = { + portfolio?: Portfolio; +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/products-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/products-types.ts new file mode 100644 index 0000000000..9713e617df --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/products-types.ts @@ -0,0 +1,96 @@ +import { + Candles, + ContractExpiryType, + ExpiringContractStatus, + Granularity, + HistoricalMarketTrade, + PriceBook, + Product, + Products, + ProductType, +} from './common-types'; + +// Get Best Bid Ask +export type GetBestBidAskRequest = { + // Query Params + productIds?: string[]; +}; + +export type GetBestBidAskResponse = { + pricebooks: PriceBook[]; +}; + +// Get Product Book +export type GetProductBookRequest = { + // Query Params + productId: string; + limit?: number; + aggregationPriceIncrement?: number; +}; + +export type GetProductBookResponse = { + pricebook: PriceBook; +}; + +// List Products +export type ListProductsRequest = { + // Query Params + limit?: number; + offset?: number; + productType?: ProductType; + productIds?: string[]; + contractExpiryType?: ContractExpiryType; + expiringContractStatus?: ExpiringContractStatus; + getTradabilityStatus?: boolean; + getAllProducts?: boolean; +}; + +export type ListProductsResponse = { + body?: Products; +}; + +// Get Product +export type GetProductRequest = { + // Path Params + productId: string; + + // Query Params + getTradabilityStatus?: boolean; +}; + +export type GetProductResponse = { + body?: Product; +}; + +// Get Product Candles +export type GetProductCandlesRequest = { + // Path Params + productId: string; + + // Query Params + start: string; + end: string; + granularity: Granularity; + limit?: number; +}; + +export type GetProductCandlesResponse = { + body?: Candles; +}; + +// Get Market Trades +export type GetMarketTradesRequest = { + // Path Params + productId: string; + + // Query Params + limit: number; + start?: string; + end?: string; +}; + +export type GetMarketTradesResponse = { + trades?: HistoricalMarketTrade[]; + best_bid?: string; + best_ask?: string; +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/public-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/public-types.ts new file mode 100644 index 0000000000..4f5bbe4a4e --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/public-types.ts @@ -0,0 +1,88 @@ +import { + Candles, + ContractExpiryType, + ExpiringContractStatus, + HistoricalMarketTrade, + PriceBook, + Product, + Products, + ProductType, +} from './common-types'; + +// Get Server Time +export type GetServerTimeResponse = { + iso?: string; + epochSeconds?: number; + epochMillis?: number; +}; + +// Get Public Product Book +export type GetPublicProductBookRequest = { + // Query Params + productId: string; + limit?: number; + aggregationPriceIncrement?: number; +}; + +export type GetPublicProductBookResponse = { + pricebook: PriceBook; +}; + +// List Public Products +export type ListPublicProductsRequest = { + // Query Params + limit?: number; + offset?: number; + productType?: ProductType; + productIds?: string[]; + contractExpiryType?: ContractExpiryType; + expiringContractStatus?: ExpiringContractStatus; + getAllProducts?: boolean; +}; + +export type ListPublicProductsResponse = { + body?: Products; +}; + +// Get Public Product +export type GetPublicProductRequest = { + // Path Params + productId: string; +}; + +export type GetPublicProductResponse = { + body?: Product; +}; + +//Get Public Product Candles +export type GetPublicProductCandlesRequest = { + // Path Params + productId: string; + + // Query Params + start: string; + end: string; + granularity: string; + limit?: number; +}; + +export type GetPublicProductCandlesResponse = { + body?: Candles; +}; + +// Get Public Market Trades +export type GetPublicMarketTradesRequest = { + // Path Params + productId: string; + + // Query Params + limit: number; + start?: string; + end?: string; +}; + +export type GetPublicMarketTradesResponse = { + trades?: HistoricalMarketTrade[]; + best_bid?: string; + best_ask?: string; +}; diff --git a/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/request-types.ts b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/request-types.ts new file mode 100644 index 0000000000..56c7a926a9 --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/src/rest/types/request-types.ts @@ -0,0 +1,14 @@ +export enum method { + GET = 'GET', + POST = 'POST', + PUT = 'PUT', + DELETE = 'DELETE', +} + +export interface RequestOptions { + method: method; + endpoint: string; + queryParams?: Record; + bodyParams?: Record; + isPublic: boolean; +} diff --git a/packages/plugin-coinbase/advanced-sdk-ts/tsconfig.json b/packages/plugin-coinbase/advanced-sdk-ts/tsconfig.json new file mode 100644 index 0000000000..9a8f3ef63b --- /dev/null +++ b/packages/plugin-coinbase/advanced-sdk-ts/tsconfig.json @@ -0,0 +1,106 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + /* Language and Environment */ + "target": "es6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + /* Modules */ + "module": "commonjs" /* Specify what module code is generated. */, + "rootDir": "./src" /* Specify the root folder within your source files. */, + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist" /* Specify an output folder for all emitted files. */, + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + /* Type Checking */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": [ + "src/**/*.ts" + ], // Include all .ts files in the src directory and subdirectories + "exclude": [ + "node_modules" + ] +} \ No newline at end of file