From 86b23733301daa15e575f263be8411fbbd57861c Mon Sep 17 00:00:00 2001 From: Michael Dunn Date: Sun, 7 Mar 2021 16:40:32 -0600 Subject: [PATCH] Added support for oracle endpoint. --- README.md | 4 +- coinbase-pro.cabal | 3 +- src/lib/CoinbasePro/Authenticated.hs | 9 ++++ src/lib/CoinbasePro/Authenticated/API.hs | 8 ++- src/lib/CoinbasePro/Authenticated/Oracle.hs | 55 +++++++++++++++++++++ src/lib/CoinbasePro/Types.hs | 2 +- 6 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 src/lib/CoinbasePro/Authenticated/Oracle.hs diff --git a/README.md b/README.md index 4324601..b982bd1 100644 --- a/README.md +++ b/README.md @@ -62,8 +62,8 @@ Here is a list of implemented/unimplemented features: - [x] User Account - [x] Trailing Volume - ~~[ ] Margin~~ (Disabled)[https://blog.coinbase.com/coinbase-pro-disables-margin-trading-42f5862f8a66] - - [ ] Oracle - - [ ] Get Oracle + - [x] Oracle + - [x] Get Oracle - Websocket Feed - [x] Channels - [x] The heartbeat channel diff --git a/coinbase-pro.cabal b/coinbase-pro.cabal index 3056d17..8d162ab 100644 --- a/coinbase-pro.cabal +++ b/coinbase-pro.cabal @@ -4,7 +4,7 @@ cabal-version: 1.12 -- -- see: https://github.com/sol/hpack -- --- hash: add46fa3fa358a678cd7bcb5b32037fe01956ba49cae6d6385b9de0105063e50 +-- hash: 0482a3909f589fcef459af8d11acc45ae48f1918d4659454f25b36f471e2764d name: coinbase-pro version: 0.9.1.0 @@ -38,6 +38,7 @@ library CoinbasePro.Authenticated.Fills CoinbasePro.Authenticated.Headers CoinbasePro.Authenticated.Limits + CoinbasePro.Authenticated.Oracle CoinbasePro.Authenticated.Orders CoinbasePro.Authenticated.Payment CoinbasePro.Authenticated.Profile diff --git a/src/lib/CoinbasePro/Authenticated.hs b/src/lib/CoinbasePro/Authenticated.hs index d45958f..baf05e5 100644 --- a/src/lib/CoinbasePro/Authenticated.hs +++ b/src/lib/CoinbasePro/Authenticated.hs @@ -35,6 +35,7 @@ module CoinbasePro.Authenticated , profileTransfer , createReport , getReport + , getOracle ) where import Control.Monad (void) @@ -71,6 +72,7 @@ import CoinbasePro.Authenticated.Deposit (CoinbaseDepositRequ DepositResponse) import CoinbasePro.Authenticated.Fills (Fill) import CoinbasePro.Authenticated.Limits (Limits) +import CoinbasePro.Authenticated.Oracle (OracleResponse) import CoinbasePro.Authenticated.Orders (Order, PlaceOrderBody (..), STP, Status (..), @@ -488,3 +490,10 @@ getReport :: ReportId -> CBAuthT ClientM ReportResponse getReport rid = authRequest methodGet requestPath emptyBody $ API.getReport rid where requestPath = encodeRequestPath [reportsPath, toText $ unReportId rid] + + +-- | https://docs.pro.coinbase.com/#oracle +getOracle :: CBAuthT ClientM OracleResponse +getOracle = authRequest methodGet requestPath emptyBody API.getOracle + where + requestPath = encodeRequestPath ["oracle"] diff --git a/src/lib/CoinbasePro/Authenticated/API.hs b/src/lib/CoinbasePro/Authenticated/API.hs index 9bf1c82..6f57c0d 100644 --- a/src/lib/CoinbasePro/Authenticated/API.hs +++ b/src/lib/CoinbasePro/Authenticated/API.hs @@ -34,6 +34,7 @@ module CoinbasePro.Authenticated.API , profileTransfer , createReport , getReport + , getOracle ) where import Data.Proxy (Proxy (..)) @@ -63,6 +64,7 @@ import CoinbasePro.Authenticated.Deposit (CoinbaseDepositRequ DepositResponse) import CoinbasePro.Authenticated.Fills (Fill) import CoinbasePro.Authenticated.Limits (Limits) +import CoinbasePro.Authenticated.Oracle (OracleResponse) import CoinbasePro.Authenticated.Orders (Order, PlaceOrderBody (..), Status (..)) @@ -131,6 +133,7 @@ type API = "accounts" :> AuthGet [Account] :<|> "profiles" :> "transfer" :> ReqBody '[JSON] ProfileTransfer :> AuthPost NoContent :<|> "reports" :> ReqBody '[JSON] ReportRequest :> AuthPost ReportResponse :<|> "reports" :> Capture "report_id" ReportId :> AuthGet ReportResponse + :<|> "oracle" :> AuthGet OracleResponse api :: Proxy API @@ -168,9 +171,10 @@ profile :: ProfileId -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM P profileTransfer :: ProfileTransfer -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM NoContent createReport :: ReportRequest -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM ReportResponse getReport :: ReportId -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM ReportResponse +getOracle :: AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM OracleResponse accounts :<|> singleAccount :<|> accountHistory :<|> accountHolds :<|> listOrders :<|> getOrder :<|> getClientOrder :<|> placeOrder :<|> cancelOrder :<|> cancelAll :<|> fills :<|> fees :<|> trailingVolume :<|> limits :<|> transfers :<|> transfer :<|> makeDeposit :<|> makeCoinbaseDeposit :<|> cryptoDepositAddress :<|> makeWithdrawal :<|> makeCoinbaseWithdrawal - :<|> makeCryptoWithdrawal :<|> withdrawalFeeEstimate :<|> createStablecoinConversion :<|> paymentMethods :<|> - coinbaseAccounts :<|> profiles :<|> profile :<|> profileTransfer :<|> createReport :<|> getReport = client api + :<|> makeCryptoWithdrawal :<|> withdrawalFeeEstimate :<|> createStablecoinConversion :<|> paymentMethods :<|> coinbaseAccounts + :<|> profiles :<|> profile :<|> profileTransfer :<|> createReport :<|> getReport :<|> getOracle = client api diff --git a/src/lib/CoinbasePro/Authenticated/Oracle.hs b/src/lib/CoinbasePro/Authenticated/Oracle.hs new file mode 100644 index 0000000..8dddd45 --- /dev/null +++ b/src/lib/CoinbasePro/Authenticated/Oracle.hs @@ -0,0 +1,55 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TemplateHaskell #-} +{-# OPTIONS_GHC -fno-warn-type-defaults #-} + +module CoinbasePro.Authenticated.Oracle + ( OracleResponse (..) + ) where + + +import Data.Aeson (FromJSON, parseJSON, withObject, (.:)) +import Data.Aeson.Casing (snakeCase) +import Data.Aeson.TH (defaultOptions, deriveJSON, + fieldLabelModifier, unwrapUnaryRecords) +import Data.Map.Strict (Map) +import Data.Text (Text) +import Data.Time.Clock (UTCTime) +import Data.Time.Clock.POSIX (posixSecondsToUTCTime) + +import CoinbasePro.Types (CurrencyType, Price) + + +newtype Message = Message Text + deriving Show + + +deriveJSON defaultOptions + { fieldLabelModifier = snakeCase + , unwrapUnaryRecords = True + } ''Message + + +newtype Signature = Signature Text + deriving Show + + +deriveJSON defaultOptions + { fieldLabelModifier = snakeCase + , unwrapUnaryRecords = True + } ''Signature + + +data OracleResponse = OracleResponse + { timestamp :: UTCTime + , messages :: [Message] + , signatures :: [Signature] + , prices :: Map CurrencyType Price + } deriving Show + + +instance FromJSON OracleResponse where + parseJSON = withObject "oracle response" $ \o -> OracleResponse + <$> (posixSecondsToUTCTime . realToFrac . read <$> o .: "timestamp") + <*> o .: "messages" + <*> o .: "signatures" + <*> o .: "prices" diff --git a/src/lib/CoinbasePro/Types.hs b/src/lib/CoinbasePro/Types.hs index 3ba01b3..e4cf87a 100644 --- a/src/lib/CoinbasePro/Types.hs +++ b/src/lib/CoinbasePro/Types.hs @@ -291,7 +291,7 @@ instance FromJSON CurrencyDetails where newtype CurrencyType = CurrencyType Text - deriving ToHttpApiData + deriving (Eq, Ord, ToHttpApiData, FromJSONKey) instance Show CurrencyType where