coinbase-pro 0.9.0.0 → 0.9.1.0
raw patch · 17 files changed
+490/−110 lines, 17 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- CoinbasePro.WebSocketFeed.Request: AuthenticatedWebSocketFeedRequest :: WebSocketFeedRequest -> CBAccessSign -> CBAccessKey -> CBAccessPassphrase -> CBAccessTimeStamp -> AuthenticatedWebSocketFeedRequest
- CoinbasePro.WebSocketFeed.Request: [cbKey] :: AuthenticatedWebSocketFeedRequest -> CBAccessKey
- CoinbasePro.WebSocketFeed.Request: [cbPassphrase] :: AuthenticatedWebSocketFeedRequest -> CBAccessPassphrase
- CoinbasePro.WebSocketFeed.Request: [cbSig] :: AuthenticatedWebSocketFeedRequest -> CBAccessSign
- CoinbasePro.WebSocketFeed.Request: [cbTimestamp] :: AuthenticatedWebSocketFeedRequest -> CBAccessTimeStamp
- CoinbasePro.WebSocketFeed.Request: [request] :: AuthenticatedWebSocketFeedRequest -> WebSocketFeedRequest
- CoinbasePro.WebSocketFeed.Request: instance GHC.Classes.Eq CoinbasePro.WebSocketFeed.Request.AuthenticatedWebSocketFeedRequest
+ CoinbasePro.Authenticated: createReport :: ReportRequest -> CBAuthT ClientM ReportResponse
+ CoinbasePro.Authenticated: getReport :: ReportId -> CBAuthT ClientM ReportResponse
+ CoinbasePro.Authenticated: profile :: ProfileId -> CBAuthT ClientM Profile
+ CoinbasePro.Authenticated: profileTransfer :: ProfileId -> ProfileId -> CurrencyType -> String -> CBAuthT ClientM ()
+ CoinbasePro.Authenticated: profiles :: Maybe Bool -> CBAuthT ClientM [Profile]
+ CoinbasePro.Authenticated.API: createReport :: ReportRequest -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM ReportResponse
+ CoinbasePro.Authenticated.API: getReport :: ReportId -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM ReportResponse
+ CoinbasePro.Authenticated.API: profile :: ProfileId -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM Profile
+ CoinbasePro.Authenticated.API: profileTransfer :: ProfileTransfer -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM NoContent
+ CoinbasePro.Authenticated.API: profiles :: Maybe Bool -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM [Profile]
+ CoinbasePro.Authenticated.Profile: Profile :: ProfileId -> UserId -> Text -> Bool -> Bool -> CreatedAt -> Profile
+ CoinbasePro.Authenticated.Profile: ProfileTransfer :: ProfileId -> ProfileId -> CurrencyType -> String -> ProfileTransfer
+ CoinbasePro.Authenticated.Profile: [amount] :: ProfileTransfer -> String
+ CoinbasePro.Authenticated.Profile: [currency] :: ProfileTransfer -> CurrencyType
+ CoinbasePro.Authenticated.Profile: [from] :: ProfileTransfer -> ProfileId
+ CoinbasePro.Authenticated.Profile: [pActive] :: Profile -> Bool
+ CoinbasePro.Authenticated.Profile: [pCreatedAt] :: Profile -> CreatedAt
+ CoinbasePro.Authenticated.Profile: [pId] :: Profile -> ProfileId
+ CoinbasePro.Authenticated.Profile: [pIsDefault] :: Profile -> Bool
+ CoinbasePro.Authenticated.Profile: [pName] :: Profile -> Text
+ CoinbasePro.Authenticated.Profile: [pUserId] :: Profile -> UserId
+ CoinbasePro.Authenticated.Profile: [to] :: ProfileTransfer -> ProfileId
+ CoinbasePro.Authenticated.Profile: data Profile
+ CoinbasePro.Authenticated.Profile: data ProfileTransfer
+ CoinbasePro.Authenticated.Profile: instance Data.Aeson.Types.FromJSON.FromJSON CoinbasePro.Authenticated.Profile.Profile
+ CoinbasePro.Authenticated.Profile: instance Data.Aeson.Types.FromJSON.FromJSON CoinbasePro.Authenticated.Profile.ProfileTransfer
+ CoinbasePro.Authenticated.Profile: instance Data.Aeson.Types.ToJSON.ToJSON CoinbasePro.Authenticated.Profile.Profile
+ CoinbasePro.Authenticated.Profile: instance Data.Aeson.Types.ToJSON.ToJSON CoinbasePro.Authenticated.Profile.ProfileTransfer
+ CoinbasePro.Authenticated.Profile: instance GHC.Show.Show CoinbasePro.Authenticated.Profile.Profile
+ CoinbasePro.Authenticated.Profile: instance GHC.Show.Show CoinbasePro.Authenticated.Profile.ProfileTransfer
+ CoinbasePro.Authenticated.Report: Accounts :: AccountsReportRequest -> ReportRequest
+ CoinbasePro.Authenticated.Report: Fills :: FillsReportRequest -> ReportRequest
+ CoinbasePro.Authenticated.Report: ReportId :: UUID -> ReportId
+ CoinbasePro.Authenticated.Report: ReportResponse :: ReportId -> ReportRequestType -> ReportStatus -> Maybe CreatedAt -> Maybe UTCTime -> Maybe UTCTime -> Maybe Text -> Maybe ReportParams -> ReportResponse
+ CoinbasePro.Authenticated.Report: [rrCompletedAt] :: ReportResponse -> Maybe UTCTime
+ CoinbasePro.Authenticated.Report: [rrCreatedAt] :: ReportResponse -> Maybe CreatedAt
+ CoinbasePro.Authenticated.Report: [rrExpiresAt] :: ReportResponse -> Maybe UTCTime
+ CoinbasePro.Authenticated.Report: [rrFileUrl] :: ReportResponse -> Maybe Text
+ CoinbasePro.Authenticated.Report: [rrId] :: ReportResponse -> ReportId
+ CoinbasePro.Authenticated.Report: [rrParams] :: ReportResponse -> Maybe ReportParams
+ CoinbasePro.Authenticated.Report: [rrStatus] :: ReportResponse -> ReportStatus
+ CoinbasePro.Authenticated.Report: [rrType] :: ReportResponse -> ReportRequestType
+ CoinbasePro.Authenticated.Report: [unReportId] :: ReportId -> UUID
+ CoinbasePro.Authenticated.Report: accountsReportRequest :: AccountId -> Maybe ProductId -> UTCTime -> UTCTime -> Maybe ReportFormat -> Maybe Email -> ReportRequest
+ CoinbasePro.Authenticated.Report: data AccountsReportRequest
+ CoinbasePro.Authenticated.Report: data FillsReportRequest
+ CoinbasePro.Authenticated.Report: data ReportRequest
+ CoinbasePro.Authenticated.Report: data ReportResponse
+ CoinbasePro.Authenticated.Report: fillsReportRequest :: ProductId -> Maybe AccountId -> UTCTime -> UTCTime -> Maybe ReportFormat -> Maybe Email -> ReportRequest
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.FromJSON.FromJSON CoinbasePro.Authenticated.Report.Email
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.FromJSON.FromJSON CoinbasePro.Authenticated.Report.ReportFormat
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.FromJSON.FromJSON CoinbasePro.Authenticated.Report.ReportId
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.FromJSON.FromJSON CoinbasePro.Authenticated.Report.ReportParams
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.FromJSON.FromJSON CoinbasePro.Authenticated.Report.ReportRequestType
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.FromJSON.FromJSON CoinbasePro.Authenticated.Report.ReportResponse
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.FromJSON.FromJSON CoinbasePro.Authenticated.Report.ReportStatus
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.ToJSON.ToJSON CoinbasePro.Authenticated.Report.Email
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.ToJSON.ToJSON CoinbasePro.Authenticated.Report.ReportFormat
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.ToJSON.ToJSON CoinbasePro.Authenticated.Report.ReportId
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.ToJSON.ToJSON CoinbasePro.Authenticated.Report.ReportParams
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.ToJSON.ToJSON CoinbasePro.Authenticated.Report.ReportRequest
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.ToJSON.ToJSON CoinbasePro.Authenticated.Report.ReportRequestType
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.ToJSON.ToJSON CoinbasePro.Authenticated.Report.ReportResponse
+ CoinbasePro.Authenticated.Report: instance Data.Aeson.Types.ToJSON.ToJSON CoinbasePro.Authenticated.Report.ReportStatus
+ CoinbasePro.Authenticated.Report: instance GHC.Classes.Eq CoinbasePro.Authenticated.Report.ReportId
+ CoinbasePro.Authenticated.Report: instance GHC.Show.Show CoinbasePro.Authenticated.Report.AccountsReportRequest
+ CoinbasePro.Authenticated.Report: instance GHC.Show.Show CoinbasePro.Authenticated.Report.Email
+ CoinbasePro.Authenticated.Report: instance GHC.Show.Show CoinbasePro.Authenticated.Report.FillsReportRequest
+ CoinbasePro.Authenticated.Report: instance GHC.Show.Show CoinbasePro.Authenticated.Report.ReportFormat
+ CoinbasePro.Authenticated.Report: instance GHC.Show.Show CoinbasePro.Authenticated.Report.ReportId
+ CoinbasePro.Authenticated.Report: instance GHC.Show.Show CoinbasePro.Authenticated.Report.ReportParams
+ CoinbasePro.Authenticated.Report: instance GHC.Show.Show CoinbasePro.Authenticated.Report.ReportRequest
+ CoinbasePro.Authenticated.Report: instance GHC.Show.Show CoinbasePro.Authenticated.Report.ReportRequestType
+ CoinbasePro.Authenticated.Report: instance GHC.Show.Show CoinbasePro.Authenticated.Report.ReportResponse
+ CoinbasePro.Authenticated.Report: instance GHC.Show.Show CoinbasePro.Authenticated.Report.ReportStatus
+ CoinbasePro.Authenticated.Report: instance GHC.Show.Show CoinbasePro.Authenticated.Report.Request
+ CoinbasePro.Authenticated.Report: instance Web.Internal.HttpApiData.ToHttpApiData CoinbasePro.Authenticated.Report.ReportId
+ CoinbasePro.Authenticated.Report: newtype ReportId
+ CoinbasePro.Request: encodeRequestPath :: [Text] -> RequestPath
+ CoinbasePro.Types: instance Data.Aeson.Types.FromJSON.FromJSON CoinbasePro.Types.CryptoAddress
+ CoinbasePro.Types: instance Data.Aeson.Types.FromJSON.FromJSON CoinbasePro.Types.CurrencyType
+ CoinbasePro.Types: instance Data.Aeson.Types.ToJSON.ToJSON CoinbasePro.Types.CryptoAddress
+ CoinbasePro.Types: instance Data.Aeson.Types.ToJSON.ToJSON CoinbasePro.Types.CurrencyType
+ CoinbasePro.WebSocketFeed.Request: authenticatedWebSocketFeedRequest :: WebSocketFeedRequest -> CoinbaseProCredentials -> IO AuthenticatedWebSocketFeedRequest
Files
- LICENSE +1/−1
- README.md +9/−10
- changelog.md +10/−0
- coinbase-pro.cabal +4/−2
- src/example/request/Main.hs +36/−20
- src/lib/CoinbasePro/Authenticated.hs +111/−32
- src/lib/CoinbasePro/Authenticated/API.hs +22/−1
- src/lib/CoinbasePro/Authenticated/Fills.hs +3/−2
- src/lib/CoinbasePro/Authenticated/Profile.hs +36/−0
- src/lib/CoinbasePro/Authenticated/Report.hs +195/−0
- src/lib/CoinbasePro/Headers.hs +0/−1
- src/lib/CoinbasePro/Request.hs +17/−9
- src/lib/CoinbasePro/Types.hs +12/−0
- src/lib/CoinbasePro/Unauthenticated.hs +1/−2
- src/lib/CoinbasePro/WebSocketFeed.hs +8/−20
- src/lib/CoinbasePro/WebSocketFeed/Request.hs +22/−8
- src/lib/CoinbasePro/WebSocketFeed/Response.hs +3/−2
LICENSE view
@@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2018 Michael Dunn <michaelsdunn1@gmail.com>+Copyright (c) 2021 Michael Dunn <michaelsdunn1@gmail.com> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
README.md view
@@ -37,10 +37,9 @@ - [x] Payment Method - [x] Coinbase - [x] Generate a Crypto Deposit Address- - [ ] Withdrawals+ - [x] Withdrawals - [x] List Withdrawals - [x] Single Withdrawal- - [ ] Canceled Withdrawal - [x] Payment Method - [x] Coinbase - [x] Crypto@@ -53,16 +52,16 @@ - [x] List Accounts - [x] Fees - [x] Get Current Fees- - [ ] Reports- - [ ] Create a new report- - [ ] Get report status- - [ ] Profiles- - [ ] List Profiles- - [ ] Get a Profile- - [ ] Create a Profile Transfer+ - [x] Reports+ - [x] Create a new report+ - [x] Get report status+ - [x] Profiles+ - [x] List Profiles+ - [x] Get a Profile+ - [x] Create a Profile Transfer - [x] User Account - [x] Trailing Volume- - [ ] Margin+ - ~~[ ] Margin~~ (Disabled)[https://blog.coinbase.com/coinbase-pro-disables-margin-trading-42f5862f8a66] - [ ] Oracle - [ ] Get Oracle - Websocket Feed
changelog.md view
@@ -1,3 +1,13 @@+# Version 0.9.1.0++- Minor refactors + linting.++## Additional Features++- Added support for the following endpoints:+ - `Profiles`+ - `Reports`+ # Version 0.9.0.0 - Upgraded to lts-17.4 (ghc 8.10.4)
coinbase-pro.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 6d5d68b6e7e2760dac46a876ebbca9195bb32e0cb846b290d8db552d28a24647+-- hash: 99c50583d7d248741138631c4b28753ea1333f29565c1567516c183489a6d05d name: coinbase-pro-version: 0.9.0.0+version: 0.9.1.0 synopsis: Client for Coinbase Pro description: Client for Coinbase Pro REST and Websocket APIs category: Web, Finance@@ -39,6 +39,8 @@ CoinbasePro.Authenticated.Limits CoinbasePro.Authenticated.Orders CoinbasePro.Authenticated.Payment+ CoinbasePro.Authenticated.Profile+ CoinbasePro.Authenticated.Report CoinbasePro.Authenticated.Request CoinbasePro.Authenticated.Transfer CoinbasePro.Authenticated.Withdrawal
src/example/request/Main.hs view
@@ -3,11 +3,16 @@ module Main where import Control.Monad.IO.Class (liftIO)+import Data.Maybe (fromJust)+import Data.Time (defaultTimeLocale,+ parseTimeOrError)+import Data.UUID (fromText) import CoinbasePro.Authenticated import CoinbasePro.Authenticated.Accounts import CoinbasePro.Authenticated.Headers import CoinbasePro.Authenticated.Orders+import CoinbasePro.Authenticated.Report import CoinbasePro.Authenticated.Request import CoinbasePro.Environment import CoinbasePro.MarketData.Types hiding (time)@@ -18,27 +23,38 @@ main :: IO () main = do- run Sandbox (stats btcusd) >>= print- run Sandbox (candles btcusd Nothing Nothing Minute) >>= print- run Sandbox (trades btcusd) >>= print- run Sandbox time >>= print- run Sandbox products >>= print- run Sandbox (aggregateOrderBook btcusd (Just Best)) >>= print- run Sandbox (aggregateOrderBook btcusd (Just TopFifty)) >>= print- run Sandbox (fullOrderBook btcusd) >>= print+ -- run Sandbox (stats btcusd) >>= print+ -- run Sandbox (candles btcusd Nothing Nothing Minute) >>= print+ -- run Sandbox (trades btcusd) >>= print+ -- run Sandbox time >>= print+ -- run Sandbox products >>= print+ -- run Sandbox (aggregateOrderBook btcusd (Just Best)) >>= print+ -- run Sandbox (aggregateOrderBook btcusd (Just TopFifty)) >>= print+ -- run Sandbox (fullOrderBook btcusd) >>= print runCbAuthT (run Sandbox) cpc $ do- accounts >>= liftIO . print- account aid >>= liftIO . print- accountHistory aid >>= liftIO . print- fills (Just btcusd) Nothing >>= liftIO . print- listOrders (Just [All]) (Just btcusd) >>= liftIO . print- placeOrder Nothing btcusd Sell (Size 0.001) (Price 99999.00) True Nothing Nothing Nothing >>= liftIO . print- placeOrder Nothing btcusd Buy (Size 1.0) (Price 1.00) True Nothing Nothing Nothing >>= liftIO . print- cancelAll (Just btcusd) >>= liftIO . print+ -- resp <- createReport fillReportReq+ getReport rid >>= liftIO . print+ -- profiles Nothing >>= liftIO . print+ -- profile "94fa1f9e-131f-4295-b0d5-695b8a92c382" >>= liftIO . print+ -- accounts >>= liftIO . print+ -- account aid >>= liftIO . print+ -- accountHistory aid >>= liftIO . print+ -- fills (Just btcusd) Nothing >>= liftIO . print+ -- listOrders (Just [All]) (Just btcusd) >>= liftIO . print+ -- placeOrder Nothing btcusd Sell (Size 0.001) (Price 99999.00) True Nothing Nothing Nothing >>= liftIO . print+ -- placeOrder Nothing btcusd Buy (Size 1.0) (Price 1.00) True Nothing Nothing Nothing >>= liftIO . print+ -- cancelAll (Just btcusd) >>= liftIO . print where- accessKey = CBAccessKey "accesskey"- secretKey = CBSecretKey "secretkey"- passphrase = CBAccessPassphrase "passphrase"+ accessKey = CBAccessKey "6e5972897a617f9c7807190c72019f2e"+ secretKey = CBSecretKey "1MJfkRmYd+AgSo6SeGlKD1XZS7AkTikEagz0EKKn6hNHzY9Ff7+H2cc76E0vbzo+0yvwCNCBsIedi0QXwRSdGw=="+ passphrase = CBAccessPassphrase "83f2vnptwln" cpc = CoinbaseProCredentials accessKey secretKey passphrase- aid = AccountId "accountid"+ aid = AccountId "74598a56-abef-4ffe-8d98-dd3c878d718d" btcusd = ProductId "BTC-USD"++ startDate = parseTimeOrError False defaultTimeLocale "%Y-%m-%d" "2020-01-01"+ endDate = parseTimeOrError False defaultTimeLocale "%Y-%m-%d" "2021-01-01"+ actReportReq = accountsReportRequest aid Nothing startDate endDate Nothing Nothing+ fillReportReq = fillsReportRequest btcusd Nothing startDate endDate Nothing Nothing++ rid = ReportId $ fromJust $ fromText "5b99f31a-7bcb-43f4-b8b3-7e1299e67a3e"
src/lib/CoinbasePro/Authenticated.hs view
@@ -1,7 +1,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-} module CoinbasePro.Authenticated ( accounts@@ -30,11 +29,16 @@ , withdrawalFeeEstimate , paymentMethods , coinbaseAccounts+ , profiles+ , profile+ , profileTransfer+ , createReport+ , getReport ) where import Control.Monad (void)-import Data.Aeson (encode)-import qualified Data.ByteString.Builder as BB+import Data.Aeson (ToJSON, encode)+import Data.ByteString (ByteString) import qualified Data.ByteString.Lazy.Char8 as LC8 import Data.Maybe (fromMaybe) import qualified Data.Set as S@@ -44,7 +48,6 @@ import Data.UUID (toText) import Network.HTTP.Types (SimpleQuery, SimpleQueryItem,- encodePathSegments, methodDelete, methodGet, methodPost,@@ -73,18 +76,24 @@ statuses) import CoinbasePro.Authenticated.Payment (PaymentMethod, PaymentMethodId (..))+import CoinbasePro.Authenticated.Profile (Profile,+ ProfileTransfer (..))+import CoinbasePro.Authenticated.Report (ReportId (..),+ ReportRequest (..),+ ReportResponse) import CoinbasePro.Authenticated.Request (CBAuthT (..), authRequest) import CoinbasePro.Authenticated.Transfer (Transfer, TransferType (..))+ import CoinbasePro.Authenticated.Withdrawal (CoinbaseWithdrawalRequest (..), CryptoWithdrawalRequest (..), CryptoWithdrawalResponse, WithdrawalFeeEstimateResponse (..), WithdrawalRequest (..), WithdrawalResponse)-import CoinbasePro.Request (RequestPath,- emptyBody)+import CoinbasePro.Request (emptyBody,+ encodeRequestPath) import CoinbasePro.Types (ClientOrderId (..),@@ -96,6 +105,7 @@ ProfileId, Side, Size) + accountsPath :: Text accountsPath = "accounts" @@ -104,10 +114,38 @@ ordersPath = "orders" -encodeRequestPath :: [Text] -> RequestPath-encodeRequestPath = LC8.toStrict . BB.toLazyByteString . encodePathSegments+depositsPath :: Text+depositsPath = "deposits" +withdrawalsPath :: Text+withdrawalsPath = "withdrawals"+++coinbaseAccountPath :: Text+coinbaseAccountPath = "coinbase-account"+++profilesPath :: Text+profilesPath = "profiles"+++transferPath :: Text+transferPath = "transfer"+++usersPath :: Text+usersPath = "users"+++selfPath :: Text+selfPath = "self"+++reportsPath :: Text+reportsPath = "reports"++ mkSimpleQueryItem :: Show a => Text -> a -> SimpleQueryItem mkSimpleQueryItem s a = (encodeUtf8 s, encodeUtf8 $ pack (show a)) @@ -124,6 +162,10 @@ mkOrderIdQuery = optionalQuery "order_id" +encodeBody :: (ToJSON b) => b -> ByteString+encodeBody = LC8.toStrict . encode++ -- | https://docs.pro.coinbase.com/#accounts accounts :: CBAuthT ClientM [Account] accounts = authRequest methodGet requestPath emptyBody API.accounts@@ -198,11 +240,10 @@ -> Maybe TimeInForce -> CBAuthT ClientM Order placeOrder clordid prid sd sz price po ot stp tif =- authRequest methodPost requestPath seBody $ API.placeOrder body+ authRequest methodPost requestPath (encodeBody body) $ API.placeOrder body where requestPath = encodeRequestPath [ordersPath] body = PlaceOrderBody clordid prid sd sz price po ot stp tif- seBody = LC8.toStrict $ encode body -- | https://docs.pro.coinbase.com/#cancel-an-order@@ -244,14 +285,14 @@ trailingVolume :: CBAuthT ClientM [TrailingVolume] trailingVolume = authRequest methodGet requestPath emptyBody API.trailingVolume where- requestPath = encodeRequestPath ["users", "self", "trailing-volume"]+ requestPath = encodeRequestPath [usersPath, selfPath, "trailing-volume"] -- | https://docs.pro.coinbase.com/#get-current-exchange-limits limits :: CBAuthT ClientM Limits limits = authRequest methodGet requestPath emptyBody API.limits where- requestPath = encodeRequestPath ["users", "self", "exchange-limits"]+ requestPath = encodeRequestPath [usersPath, selfPath, "exchange-limits"] -- | https://docs.pro.coinbase.com/#list-deposits@@ -288,7 +329,7 @@ lmQ = optionalQuery "limit" lm query = renderQuery True . simpleQueryToQuery $ typeQ <> profQ <> beforeQ <> afterQ <> lmQ- requestPath = encodeRequestPath ["transfers"] <> query+ requestPath = encodeRequestPath [transferPath <> "s"] <> query -- | https://docs.pro.coinbase.com/#single-deposit@@ -296,7 +337,7 @@ transfer :: PaymentMethodId -> CBAuthT ClientM Transfer transfer pmt@(PaymentMethodId p) = authRequest methodGet requestPath emptyBody $ API.transfer pmt where- requestPath = encodeRequestPath ["transfers", p]+ requestPath = encodeRequestPath [transferPath <> "s", p] -- | https://docs.pro.coinbase.com/#payment-method@@ -305,11 +346,10 @@ -> PaymentMethodId -> CBAuthT ClientM DepositResponse makeDeposit amt cur pmi =- authRequest methodPost requestPath seBody $ API.makeDeposit body+ authRequest methodPost requestPath (encodeBody body) $ API.makeDeposit body where- requestPath = encodeRequestPath ["deposits", "payment-method"]+ requestPath = encodeRequestPath [depositsPath, "payment-method"] body = DepositRequest amt cur pmi- seBody = LC8.toStrict $ encode body -- | https://docs.pro.coinbase.com/#coinbase@@ -318,11 +358,10 @@ -> AccountId -> CBAuthT ClientM DepositResponse makeCoinbaseDeposit amt cur act =- authRequest methodPost requestPath seBody $ API.makeCoinbaseDeposit body+ authRequest methodPost requestPath (encodeBody body) $ API.makeCoinbaseDeposit body where- requestPath = encodeRequestPath ["deposits", "coinbase-account"]+ requestPath = encodeRequestPath [depositsPath, coinbaseAccountPath] body = CoinbaseDepositRequest amt cur act- seBody = LC8.toStrict $ encode body -- | https://docs.pro.coinbase.com/#generate-a-crypto-deposit-address@@ -330,7 +369,7 @@ cryptoDepositAddress act = authRequest methodPost requestPath emptyBody $ API.cryptoDepositAddress act where- requestPath = encodeRequestPath ["coinbase-accounts", pack $ show act, "addresses"]+ requestPath = encodeRequestPath [coinbaseAccountPath <> "s", pack $ show act, "addresses"] -- | https://docs.pro.coinbase.com/#payment-method55@@ -339,11 +378,10 @@ -> PaymentMethodId -> CBAuthT ClientM WithdrawalResponse makeWithdrawal amt cur pmi =- authRequest methodPost requestPath seBody $ API.makeWithdrawal body+ authRequest methodPost requestPath (encodeBody body) $ API.makeWithdrawal body where- requestPath = encodeRequestPath ["withdrawals", "payment-method"]+ requestPath = encodeRequestPath [withdrawalsPath, "payment-method"] body = WithdrawalRequest amt cur pmi- seBody = LC8.toStrict $ encode body -- | https://docs.pro.coinbase.com/#coinbase56@@ -352,11 +390,10 @@ -> AccountId -> CBAuthT ClientM WithdrawalResponse makeCoinbaseWithdrawal amt cur act =- authRequest methodPost requestPath seBody $ API.makeCoinbaseWithdrawal body+ authRequest methodPost requestPath (encodeBody body) $ API.makeCoinbaseWithdrawal body where- requestPath = encodeRequestPath ["withdrawals", "coinbase-account"]+ requestPath = encodeRequestPath [withdrawalsPath, coinbaseAccountPath] body = CoinbaseWithdrawalRequest amt cur act- seBody = LC8.toStrict $ encode body -- | https://docs.pro.coinbase.com/#crypto@@ -365,11 +402,10 @@ -> Text -> CBAuthT ClientM CryptoWithdrawalResponse makeCryptoWithdrawal amt cur addr =- authRequest methodPost requestPath seBody $ API.makeCryptoWithdrawal body+ authRequest methodPost requestPath (encodeBody body) $ API.makeCryptoWithdrawal body where- requestPath = encodeRequestPath ["withdrawals", "crypto"]+ requestPath = encodeRequestPath [withdrawalsPath, "crypto"] body = CryptoWithdrawalRequest amt cur addr- seBody = LC8.toStrict $ encode body -- | https://docs.pro.coinbase.com/#fee-estimate@@ -383,7 +419,7 @@ addrQ = return $ mkSimpleQueryItem "crypto_address" addr query = renderQuery True . simpleQueryToQuery $ curQ <> addrQ- requestPath = encodeRequestPath ["withdrawals", "fee-estimate"] <> query+ requestPath = encodeRequestPath [withdrawalsPath, "fee-estimate"] <> query -- | https://docs.pro.coinbase.com/#list-payment-methods@@ -397,4 +433,47 @@ coinbaseAccounts :: CBAuthT ClientM [CoinbaseAccount] coinbaseAccounts = authRequest methodGet requestPath emptyBody API.coinbaseAccounts where- requestPath = encodeRequestPath ["coinbase-accounts"]+ requestPath = encodeRequestPath [coinbaseAccountPath <> "s"]+++-- | https://docs.pro.coinbase.com/#list-profiles+profiles :: Maybe Bool -> CBAuthT ClientM [Profile]+profiles active = authRequest methodGet requestPath emptyBody $ API.profiles active+ where+ activeQ = optionalQuery "active" active++ query = renderQuery True . simpleQueryToQuery $ activeQ+ requestPath = encodeRequestPath [profilesPath] <> query+++-- | https://docs.pro.coinbase.com/#get-a-profile+profile :: ProfileId -> CBAuthT ClientM Profile+profile profId = authRequest methodGet requestPath emptyBody $ API.profile profId+ where+ requestPath = encodeRequestPath [profilesPath, profId]+++-- | https://docs.pro.coinbase.com/#create-profile-transfer+profileTransfer :: ProfileId+ -> ProfileId+ -> CurrencyType+ -> String+ -> CBAuthT ClientM ()+profileTransfer fromProf toProf cur amt = void . authRequest methodPost requestPath (encodeBody body) $ API.profileTransfer body+ where+ requestPath = encodeRequestPath [profilesPath, transferPath]+ body = ProfileTransfer fromProf toProf cur amt+++-- | https://docs.pro.coinbase.com/#create-a-new-report+createReport :: ReportRequest -> CBAuthT ClientM ReportResponse+createReport req = authRequest methodPost requestPath (encodeBody req) $ API.createReport req+ where+ requestPath = encodeRequestPath [reportsPath]+++-- | https://docs.pro.coinbase.com/#get-report-status+getReport :: ReportId -> CBAuthT ClientM ReportResponse+getReport rid = authRequest methodGet requestPath emptyBody $ API.getReport rid+ where+ requestPath = encodeRequestPath [reportsPath, toText $ unReportId rid]
src/lib/CoinbasePro/Authenticated/API.hs view
@@ -28,6 +28,11 @@ , withdrawalFeeEstimate , paymentMethods , coinbaseAccounts+ , profiles+ , profile+ , profileTransfer+ , createReport+ , getReport ) where import Data.Proxy (Proxy (..))@@ -60,6 +65,11 @@ Status (..)) import CoinbasePro.Authenticated.Payment (PaymentMethod (..), PaymentMethodId)+import CoinbasePro.Authenticated.Profile (Profile,+ ProfileTransfer)+import CoinbasePro.Authenticated.Report (ReportId,+ ReportRequest (..),+ ReportResponse (..)) import CoinbasePro.Authenticated.Request (AuthDelete, AuthGet, AuthPost) import CoinbasePro.Authenticated.Transfer (Transfer,@@ -112,6 +122,11 @@ :> AuthGet WithdrawalFeeEstimateResponse :<|> "payment-methods" :> AuthGet [PaymentMethod] :<|> "coinbase-accounts" :> AuthGet [CoinbaseAccount]+ :<|> "profiles" :> QueryParam "active" Bool :> AuthGet [Profile]+ :<|> "profiles" :> Capture "profile_id" ProfileId :> AuthGet Profile+ :<|> "profiles" :> "transfer" :> ReqBody '[JSON] ProfileTransfer :> AuthPost NoContent+ :<|> "reports" :> ReqBody '[JSON] ReportRequest :> AuthPost ReportResponse+ :<|> "reports" :> Capture "report_id" ReportId :> AuthGet ReportResponse api :: Proxy API@@ -143,8 +158,14 @@ withdrawalFeeEstimate :: CurrencyType -> CryptoAddress -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM WithdrawalFeeEstimateResponse paymentMethods :: AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM [PaymentMethod] coinbaseAccounts :: AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM [CoinbaseAccount]+profiles :: Maybe Bool -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM [Profile]+profile :: ProfileId -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM Profile+profileTransfer :: ProfileTransfer -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM NoContent+createReport :: ReportRequest -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM ReportResponse+getReport :: ReportId -> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM ReportResponse accounts :<|> singleAccount :<|> accountHistory :<|> accountHolds :<|> listOrders :<|> getOrder :<|> getClientOrder :<|> placeOrder :<|> cancelOrder :<|> cancelAll :<|> fills :<|> fees :<|> trailingVolume :<|> limits :<|> transfers :<|> transfer :<|> makeDeposit :<|> makeCoinbaseDeposit :<|> cryptoDepositAddress :<|> makeWithdrawal :<|> makeCoinbaseWithdrawal- :<|> makeCryptoWithdrawal :<|> withdrawalFeeEstimate :<|> paymentMethods :<|> coinbaseAccounts = client api+ :<|> makeCryptoWithdrawal :<|> withdrawalFeeEstimate :<|> paymentMethods :<|> coinbaseAccounts :<|> profiles :<|> profile+ :<|> profileTransfer :<|> createReport :<|> getReport = client api
src/lib/CoinbasePro/Authenticated/Fills.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} module CoinbasePro.Authenticated.Fills@@ -17,8 +18,8 @@ instance FromJSON Liquidity where- parseJSON = withText "liquidity" $ \t ->- case t of+ parseJSON = withText "liquidity" $+ \case "M" -> return Maker "T" -> return Taker _ -> fail "parse error"
+ src/lib/CoinbasePro/Authenticated/Profile.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE TemplateHaskell #-}++module CoinbasePro.Authenticated.Profile+ ( Profile (..)+ , ProfileTransfer (..)+ ) where++import Data.Aeson.Casing (snakeCase)+import Data.Aeson.TH (defaultOptions, deriveJSON,+ fieldLabelModifier)+import Data.Text (Text)++import CoinbasePro.Types (CreatedAt, CurrencyType, ProfileId, UserId)++data Profile = Profile+ { pId :: ProfileId+ , pUserId :: UserId+ , pName :: Text+ , pActive :: Bool+ , pIsDefault :: Bool+ , pCreatedAt :: CreatedAt+ } deriving Show+++deriveJSON defaultOptions { fieldLabelModifier = snakeCase . drop 1 } ''Profile+++data ProfileTransfer = ProfileTransfer+ { from :: ProfileId+ , to :: ProfileId+ , currency :: CurrencyType+ , amount :: String+ } deriving Show+++deriveJSON defaultOptions { fieldLabelModifier = snakeCase } ''ProfileTransfer
+ src/lib/CoinbasePro/Authenticated/Report.hs view
@@ -0,0 +1,195 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-}++module CoinbasePro.Authenticated.Report+ ( ReportId (..)+ , ReportRequest (..)+ , ReportResponse (..)++ , FillsReportRequest+ , AccountsReportRequest++ , accountsReportRequest+ , fillsReportRequest+ ) where++import Data.Aeson (ToJSON (..), object, (.=))+import Data.Aeson.Casing (snakeCase)+import Data.Aeson.TH (constructorTagModifier,+ defaultOptions, deriveJSON,+ fieldLabelModifier,+ unwrapUnaryRecords)+import qualified Data.Char as Char+import Data.Text (Text)+import Data.Time.Clock (UTCTime)+import Data.UUID (UUID)+import Servant.API (ToHttpApiData)++import CoinbasePro.Authenticated.Accounts (AccountId)+import CoinbasePro.Types (CreatedAt, ProductId)+++newtype ReportId = ReportId { unReportId:: UUID }+ deriving (Eq, Show, ToHttpApiData)+++deriveJSON defaultOptions+ { fieldLabelModifier = snakeCase+ , unwrapUnaryRecords = True+ } ''ReportId+++data ReportFormat = PDF | CSV+ deriving Show+++deriveJSON defaultOptions { constructorTagModifier = fmap Char.toLower } ''ReportFormat+++newtype Email = Email Text+ deriving Show+++deriveJSON defaultOptions { fieldLabelModifier = snakeCase } ''Email+++data Request = Request+ { rStartDate :: UTCTime+ , rEndDate :: UTCTime+ , rFormat :: Maybe ReportFormat+ , rEmail :: Maybe Email+ } deriving Show+++data FillsReportRequest = FillsReportRequest+ { frProductId :: ProductId+ , frAccountId :: Maybe AccountId+ , frRequest :: Request+ } deriving Show+++data AccountsReportRequest = AccountsReportRequest+ { arAccountId :: AccountId+ , arProductId :: Maybe ProductId+ , arRequest :: Request+ } deriving Show+++data ReportRequest = Fills FillsReportRequest | Accounts AccountsReportRequest+ deriving Show+++accountsReportRequest :: AccountId+ -> Maybe ProductId+ -- ^ start date+ -> UTCTime+ -- ^ end date+ -> UTCTime+ -- ^ pdf or csv+ -> Maybe ReportFormat+ -> Maybe Email+ -> ReportRequest+accountsReportRequest aid prid start end format =+ Accounts . AccountsReportRequest aid prid . Request start end format+++fillsReportRequest :: ProductId+ -> Maybe AccountId+ -- ^ start date+ -> UTCTime+ -- ^ end date+ -> UTCTime+ -- ^ pdf or csv+ -> Maybe ReportFormat+ -> Maybe Email+ -> ReportRequest+fillsReportRequest prid aid start end format =+ Fills . FillsReportRequest prid aid . Request start end format+++instance ToJSON ReportRequest where+ toJSON (Fills frr) =+ object ([ "type" .= ("fills" :: Text)+ , "start_date" .= rStartDate (frRequest frr)+ , "end_date" .= rEndDate (frRequest frr)+ , "product_id" .= frProductId frr+ ] <> maybe mempty (\aid -> ["account_id" .= aid]) (frAccountId frr)+ <> maybe mempty (\em -> ["email" .= em]) (rEmail (frRequest frr))+ <> maybe mempty (\fmt -> ["format" .= fmt]) (rFormat (frRequest frr))+ )+ toJSON (Accounts arr) =+ object ([ "type" .= ("account" :: Text)+ , "start_date" .= rStartDate (arRequest arr)+ , "end_date" .= rEndDate (arRequest arr)+ , "account_id" .= arAccountId arr+ ] <> maybe mempty (\prid -> ["product_id" .= prid]) (arProductId arr)+ <> maybe mempty (\em -> ["email" .= em]) (rEmail (arRequest arr))+ <> maybe mempty (\fmt -> ["format" .= fmt]) (rFormat (arRequest arr))+ )+++data ReportRequestType = FillsType | AccountType+++instance Show ReportRequestType where+ show FillsType = "fills"+ show AccountType = "account"+++deriveJSON defaultOptions { constructorTagModifier = snakeCase . init . init . init . init } ''ReportRequestType+++data ReportStatus = Pending | Creating | Ready+++instance Show ReportStatus where+ show Pending = "pending"+ show Creating = "creating"+ show Ready = "ready"+++deriveJSON defaultOptions { constructorTagModifier = fmap Char.toLower+ , fieldLabelModifier = snakeCase+ } ''ReportStatus+++data ReportParams = ReportParams+ { startDate :: UTCTime+ , endDate :: UTCTime+ } deriving Show+++deriveJSON defaultOptions { fieldLabelModifier = snakeCase } ''ReportParams+++{-|+ Example JSON Response:+ {+ "id": "0428b97b-bec1-429e-a94c-59232926778d",+ "type": "fills",+ "status": "pending",+ "created_at": "2015-01-06T10:34:47.000Z",+ "completed_at": undefined,+ "expires_at": "2015-01-13T10:35:47.000Z",+ "file_url": undefined,+ "params": {+ "start_date": "2014-11-01T00:00:00.000Z",+ "end_date": "2014-11-30T23:59:59.000Z"+ }+ }+-}+data ReportResponse = ReportResponse+ { rrId :: ReportId+ , rrType :: ReportRequestType+ , rrStatus :: ReportStatus+ , rrCreatedAt :: Maybe CreatedAt+ , rrCompletedAt :: Maybe UTCTime+ , rrExpiresAt :: Maybe UTCTime+ , rrFileUrl :: Maybe Text+ , rrParams :: Maybe ReportParams+ } deriving Show+++deriveJSON defaultOptions { fieldLabelModifier = snakeCase . drop 2 } ''ReportResponse
src/lib/CoinbasePro/Headers.hs view
@@ -1,7 +1,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TypeOperators #-} module CoinbasePro.Headers ( RequiredHeader
src/lib/CoinbasePro/Request.hs view
@@ -18,19 +18,23 @@ , Runner , emptyBody+ , encodeRequestPath ) where -import Control.Exception (throw)-import Control.Monad (void)-import Data.ByteString (ByteString)-import Data.Text (unpack)-import Network.HTTP.Client (Manager, newManager)-import Network.HTTP.Client.TLS (tlsManagerSettings)-import Servant.API (Get, JSON, (:>))+import Control.Exception (throw)+import Control.Monad (void)+import Data.ByteString (ByteString)+import qualified Data.ByteString.Builder as BB+import qualified Data.ByteString.Lazy.Char8 as LC8+import Data.Text (Text, unpack)+import Network.HTTP.Client (Manager, newManager)+import Network.HTTP.Client.TLS (tlsManagerSettings)+import Network.HTTP.Types (encodePathSegments)+import Servant.API (Get, JSON, (:>)) import Servant.Client -import CoinbasePro.Environment (Environment, apiEndpoint)-import CoinbasePro.Headers (UserAgent, UserAgentHeader)+import CoinbasePro.Environment (Environment, apiEndpoint)+import CoinbasePro.Headers (UserAgent, UserAgentHeader) type CBGet a = UserAgentHeader :> Get '[JSON] a@@ -85,3 +89,7 @@ emptyBody :: ByteString emptyBody = ""+++encodeRequestPath :: [Text] -> RequestPath+encodeRequestPath = LC8.toStrict . BB.toLazyByteString . encodePathSegments
src/lib/CoinbasePro/Types.hs view
@@ -298,6 +298,12 @@ show (CurrencyType c) = unpack c +deriveJSON defaultOptions+ { fieldLabelModifier = snakeCase+ , unwrapUnaryRecords = True+ } ''CurrencyType++ data Currency = Currency { id :: Text , name :: Text@@ -324,3 +330,9 @@ instance Show CryptoAddress where show (CryptoAddress ca) = unpack ca+++deriveJSON defaultOptions+ { fieldLabelModifier = snakeCase+ , unwrapUnaryRecords = True+ } ''CryptoAddress
src/lib/CoinbasePro/Unauthenticated.hs view
@@ -1,5 +1,4 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE DataKinds #-} module CoinbasePro.Unauthenticated ( products
src/lib/CoinbasePro/WebSocketFeed.hs view
@@ -7,27 +7,22 @@ import Control.Concurrent (forkIO) import Control.Exception (Exception, throwIO) import Control.Monad (forever)-import Control.Monad.IO.Class (liftIO) import Data.Aeson (decode', encode)-import Network.HTTP.Types (methodGet) import qualified Network.WebSockets as WS import qualified System.IO.Streams as Streams import System.IO.Streams.Concurrent.Unagi (makeChanPipe) import qualified Wuss as WU -import CoinbasePro.Authenticated.Request (CoinbaseProCredentials (..),- mkCBAccessSign,- mkCBAccessTimeStamp)+import CoinbasePro.Authenticated.Request (CoinbaseProCredentials (..)) import CoinbasePro.Environment (Environment, WSConnection (..), wsEndpoint)-import CoinbasePro.Request (emptyBody) import CoinbasePro.Types (ProductId) import CoinbasePro.WebSocketFeed.Channel (ChannelMessage (..))-import CoinbasePro.WebSocketFeed.Request (AuthenticatedWebSocketFeedRequest (..),- ChannelName (..),+import CoinbasePro.WebSocketFeed.Request (ChannelName (..), RequestMessageType (..),- WebSocketFeedRequest (..))+ WebSocketFeedRequest (..),+ authenticatedWebSocketFeedRequest) data ParseException = ParseException deriving Show@@ -52,18 +47,11 @@ wsHost = host wsConn wsPort = port wsConn - mkWsRequest = maybe (return $ encode wsRequest) (fmap encode . authWsRequest)-- wsRequest = WebSocketFeedRequest Subscribe prids channels-- authWsRequest cpc' = do- ts <- liftIO mkCBAccessTimeStamp- let cbs = mkCBAccessSign (cbSecretKey cpc') ts methodGet authSubscriptionPath emptyBody- return $ AuthenticatedWebSocketFeedRequest wsRequest cbs (cbAccessKey cpc') (cbAccessPassphrase cpc') ts-- authSubscriptionPath = "/users/self/verify"+ mkWsRequest = maybe (return $ encode wsRequest) (fmap encode . authWsRequest)+ wsRequest = WebSocketFeedRequest Subscribe prids channels+ authWsRequest = authenticatedWebSocketFeedRequest wsRequest parseFeed :: WS.Connection -> IO ChannelMessage-parseFeed conn = maybe err return =<< (decode' <$> WS.receiveData conn)+parseFeed conn = WS.receiveData conn >>= maybe err return . decode' where err = throwIO ParseException
src/lib/CoinbasePro/WebSocketFeed/Request.hs view
@@ -5,16 +5,25 @@ ( RequestMessageType (..) , ChannelName(..) , WebSocketFeedRequest (..)- , AuthenticatedWebSocketFeedRequest (..)+ , AuthenticatedWebSocketFeedRequest++ , authenticatedWebSocketFeedRequest ) where +import Control.Monad.IO.Class (liftIO) import Data.Aeson (FromJSON (..), ToJSON (..), object, withText, (.=))+import Network.HTTP.Types (methodGet) import CoinbasePro.Authenticated.Headers (CBAccessKey (..), CBAccessPassphrase (..), CBAccessSign (..), CBAccessTimeStamp (..))+import CoinbasePro.Authenticated.Request (CoinbaseProCredentials (..),+ mkCBAccessSign,+ mkCBAccessTimeStamp)+import CoinbasePro.Request (emptyBody,+ encodeRequestPath) import CoinbasePro.Types (ProductId) @@ -74,13 +83,8 @@ , "channels" .= rc ] -data AuthenticatedWebSocketFeedRequest = AuthenticatedWebSocketFeedRequest- { request :: WebSocketFeedRequest- , cbSig :: CBAccessSign- , cbKey :: CBAccessKey- , cbPassphrase :: CBAccessPassphrase- , cbTimestamp :: CBAccessTimeStamp- } deriving (Eq)+data AuthenticatedWebSocketFeedRequest =+ AuthenticatedWebSocketFeedRequest WebSocketFeedRequest CBAccessSign CBAccessKey CBAccessPassphrase CBAccessTimeStamp instance ToJSON AuthenticatedWebSocketFeedRequest where@@ -93,3 +97,13 @@ , "passphrase" .= p , "timestamp" .= t ]++authenticatedWebSocketFeedRequest :: WebSocketFeedRequest+ -> CoinbaseProCredentials+ -> IO AuthenticatedWebSocketFeedRequest+authenticatedWebSocketFeedRequest wsRequest cpc = do+ ts <- liftIO mkCBAccessTimeStamp+ let cbs = mkCBAccessSign (cbSecretKey cpc) ts methodGet authSubscriptionPath emptyBody+ return $ AuthenticatedWebSocketFeedRequest wsRequest cbs (cbAccessKey cpc) (cbAccessPassphrase cpc) ts+ where+ authSubscriptionPath = encodeRequestPath ["users", "self", "verify"]
src/lib/CoinbasePro/WebSocketFeed/Response.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} module CoinbasePro.WebSocketFeed.Response@@ -24,8 +25,8 @@ instance FromJSON ResponseMessageType where- parseJSON v = withText "response message type" (\t ->- case t of+ parseJSON v = withText "response message type" (+ \case "subscriptions" -> return Subscriptions _ -> typeMismatch "response message type" v) v