{-# LANGUAGE DataKinds         #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies      #-}

module CoinbasePro.Authenticated
  ( accounts
  , account
  , accountHistory
  , accountHolds
  , listOrders
  , getOrder
  , getClientOrder
  , placeOrder
  , placeOrderBody
  , cancelOrder
  , cancelAll
  , fills
  , fees
  , trailingVolume
  , limits
  , deposits
  , withdrawals
  , transfer
  , makeDeposit
  , makeCoinbaseDeposit
  , cryptoDepositAddress
  , makeWithdrawal
  , makeCoinbaseWithdrawal
  , makeCryptoWithdrawal
  , withdrawalFeeEstimate
  , createStablecoinConversion
  , paymentMethods
  , coinbaseAccounts
  , profiles
  , profile
  , profileTransfer
  , createReport
  , getReport
  , getOracle
  ) where

import           Control.Monad                              (void)
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
import           Data.Text                                  (Text, pack)
import           Data.Text.Encoding                         (encodeUtf8)
import           Data.Time.Clock                            (UTCTime)
import           Data.UUID                                  (toText)
import           Network.HTTP.Types                         (SimpleQuery,
                                                             SimpleQueryItem,
                                                             methodDelete,
                                                             methodGet,
                                                             methodPost,
                                                             renderQuery,
                                                             simpleQueryToQuery)
import           Servant.Client                             (ClientM)

import qualified CoinbasePro.Authenticated.API              as API
import           CoinbasePro.Authenticated.Accounts         (Account,
                                                             AccountHistory,
                                                             AccountId (..),
                                                             Fees, Hold,
                                                             TrailingVolume (..))
import           CoinbasePro.Authenticated.CoinbaseAccounts (CoinbaseAccount)
import           CoinbasePro.Authenticated.Conversion       (StablecoinConversionRequest (..),
                                                             StablecoinConversionResponse)
import           CoinbasePro.Authenticated.Deposit          (CoinbaseDepositRequest (..),
                                                             CryptoDepositAddress,
                                                             DepositRequest (..),
                                                             DepositResponse)
import           CoinbasePro.Authenticated.Fills            (Fill)
import           CoinbasePro.Authenticated.Limits           (Limits)
import           CoinbasePro.Authenticated.Oracle           (OracleResponse)
import           CoinbasePro.Authenticated.Orders           (Order,
                                                             PlaceOrderBody (..),
                                                             STP, Status (..),
                                                             Statuses (..),
                                                             TimeInForce,
                                                             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                        (emptyBody,
                                                             encodeRequestPath)


import           CoinbasePro.Types                          (ClientOrderId (..),
                                                             CryptoAddress (..),
                                                             CurrencyType (..),
                                                             OrderId (..),
                                                             OrderType, Price,
                                                             ProductId (..),
                                                             ProfileId, Side,
                                                             Size)


accountsPath :: Text
accountsPath :: Text
accountsPath = Text
"accounts"


ordersPath :: Text
ordersPath :: Text
ordersPath = Text
"orders"


depositsPath :: Text
depositsPath :: Text
depositsPath = Text
"deposits"


withdrawalsPath :: Text
withdrawalsPath :: Text
withdrawalsPath = Text
"withdrawals"


coinbaseAccountPath :: Text
coinbaseAccountPath :: Text
coinbaseAccountPath = Text
"coinbase-account"


profilesPath :: Text
profilesPath :: Text
profilesPath = Text
"profiles"


transferPath :: Text
transferPath :: Text
transferPath = Text
"transfer"


usersPath :: Text
usersPath :: Text
usersPath = Text
"users"


selfPath :: Text
selfPath :: Text
selfPath = Text
"self"


reportsPath :: Text
reportsPath :: Text
reportsPath = Text
"reports"


mkSimpleQueryItem :: Show a => Text -> a -> SimpleQueryItem
mkSimpleQueryItem :: forall a. Show a => Text -> a -> SimpleQueryItem
mkSimpleQueryItem Text
s a
a = (Text -> RequestPath
encodeUtf8 Text
s, Text -> RequestPath
encodeUtf8 forall a b. (a -> b) -> a -> b
$ String -> Text
pack (forall a. Show a => a -> String
show a
a))


optionalQuery :: Show a => Text -> Maybe a -> [SimpleQueryItem]
optionalQuery :: forall a. Show a => Text -> Maybe a -> SimpleQuery
optionalQuery Text
t = forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => Text -> a -> SimpleQueryItem
mkSimpleQueryItem Text
t)


mkProductQuery :: Maybe ProductId -> [SimpleQueryItem]
mkProductQuery :: Maybe ProductId -> SimpleQuery
mkProductQuery = forall a. Show a => Text -> Maybe a -> SimpleQuery
optionalQuery Text
"product_id"


mkOrderIdQuery :: Maybe OrderId -> SimpleQuery
mkOrderIdQuery :: Maybe OrderId -> SimpleQuery
mkOrderIdQuery = forall a. Show a => Text -> Maybe a -> SimpleQuery
optionalQuery Text
"order_id"


encodeBody :: (ToJSON b) => b -> ByteString
encodeBody :: forall b. ToJSON b => b -> RequestPath
encodeBody = ByteString -> RequestPath
LC8.toStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ToJSON a => a -> ByteString
encode


-- | https://docs.pro.coinbase.com/#accounts
accounts :: CBAuthT ClientM [Account]
accounts :: CBAuthT ClientM [Account]
accounts = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM [Account]
API.accounts
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
accountsPath]


-- | https://docs.pro.coinbase.com/#get-an-account
account :: AccountId -> CBAuthT ClientM Account
account :: AccountId -> CBAuthT ClientM Account
account aid :: AccountId
aid@(AccountId Text
t) = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ AccountId
-> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM Account
API.singleAccount AccountId
aid
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
accountsPath, Text
t]


-- | https://docs.pro.coinbase.com/#get-account-history
accountHistory :: AccountId -> CBAuthT ClientM [AccountHistory]
accountHistory :: AccountId -> CBAuthT ClientM [AccountHistory]
accountHistory aid :: AccountId
aid@(AccountId Text
t) = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ AccountId
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM [AccountHistory]
API.accountHistory AccountId
aid
  where
    ledgerPath :: Text
ledgerPath  = Text
"ledger"
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
accountsPath, Text
t, Text
ledgerPath]


-- | https://docs.pro.coinbase.com/#get-holds
accountHolds :: AccountId -> CBAuthT ClientM [Hold]
accountHolds :: AccountId -> CBAuthT ClientM [Hold]
accountHolds aid :: AccountId
aid@(AccountId Text
t) = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ AccountId
-> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM [Hold]
API.accountHolds AccountId
aid
  where
    holdsPath :: Text
holdsPath   = Text
"holds"
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
accountsPath, Text
t, Text
holdsPath]


-- | https://docs.pro.coinbase.com/#list-orders
listOrders :: Maybe [Status] -> Maybe ProductId -> CBAuthT ClientM [Order]
listOrders :: Maybe [Status] -> Maybe ProductId -> CBAuthT ClientM [Order]
listOrders Maybe [Status]
st Maybe ProductId
prid = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ [Status]
-> Maybe ProductId
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM [Order]
API.listOrders (Maybe [Status] -> [Status]
defaultStatus Maybe [Status]
st) Maybe ProductId
prid
  where
    query :: RequestPath
query       = Bool -> Query -> RequestPath
renderQuery Bool
True forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimpleQuery -> Query
simpleQueryToQuery forall a b. (a -> b) -> a -> b
$ Maybe [Status] -> Maybe ProductId -> SimpleQuery
orderQuery Maybe [Status]
st Maybe ProductId
prid
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
ordersPath] forall a. Semigroup a => a -> a -> a
<> RequestPath
query

    orderQuery :: Maybe [Status] -> Maybe ProductId -> SimpleQuery
    orderQuery :: Maybe [Status] -> Maybe ProductId -> SimpleQuery
orderQuery Maybe [Status]
ss Maybe ProductId
p = Maybe [Status] -> SimpleQuery
statusQuery Maybe [Status]
ss forall a. Semigroup a => a -> a -> a
<> Maybe ProductId -> SimpleQuery
mkProductQuery Maybe ProductId
p

    statusQuery :: Maybe [Status] -> [SimpleQueryItem]
    statusQuery :: Maybe [Status] -> SimpleQuery
statusQuery Maybe [Status]
ss = forall a. Show a => Text -> a -> SimpleQueryItem
mkSimpleQueryItem Text
"status" forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Set a -> [a]
S.toList (Statuses -> Set Status
unStatuses forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Status] -> Statuses
statuses forall a b. (a -> b) -> a -> b
$ Maybe [Status] -> [Status]
defaultStatus Maybe [Status]
ss)

    defaultStatus :: Maybe [Status] -> [Status]
    defaultStatus :: Maybe [Status] -> [Status]
defaultStatus = forall a. a -> Maybe a -> a
fromMaybe [Status
All]


-- | https://docs.pro.coinbase.com/#get-an-order
getOrder :: OrderId -> CBAuthT ClientM Order
getOrder :: OrderId -> CBAuthT ClientM Order
getOrder OrderId
oid = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ OrderId
-> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM Order
API.getOrder OrderId
oid
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
ordersPath, OrderId -> Text
unOrderId OrderId
oid]


-- | https://docs.pro.coinbase.com/#get-an-order
getClientOrder :: ClientOrderId -> CBAuthT ClientM Order
getClientOrder :: ClientOrderId -> CBAuthT ClientM Order
getClientOrder ClientOrderId
cloid = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ ClientOrderId
-> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM Order
API.getClientOrder ClientOrderId
cloid
  where
    oid :: Text
oid         = UUID -> Text
toText forall a b. (a -> b) -> a -> b
$ ClientOrderId -> UUID
unClientOrderId ClientOrderId
cloid
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
ordersPath, Text
"client:" forall a. Semigroup a => a -> a -> a
<> Text
oid]


-- | https://docs.pro.coinbase.com/#place-a-new-order
placeOrder :: Maybe ClientOrderId
           -> ProductId
           -> Side
           -> Maybe Size
           -> Maybe Price
           -> Maybe Bool
           -> Maybe OrderType
           -> Maybe STP
           -> Maybe TimeInForce
           -> CBAuthT ClientM Order
placeOrder :: Maybe ClientOrderId
-> ProductId
-> Side
-> Maybe Size
-> Maybe Price
-> Maybe Bool
-> Maybe OrderType
-> Maybe STP
-> Maybe TimeInForce
-> CBAuthT ClientM Order
placeOrder Maybe ClientOrderId
clordid ProductId
prid Side
sd Maybe Size
sz Maybe Price
price Maybe Bool
po Maybe OrderType
ot Maybe STP
stp Maybe TimeInForce
tif =
    forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodPost RequestPath
requestPath (forall b. ToJSON b => b -> RequestPath
encodeBody PlaceOrderBody
body) forall a b. (a -> b) -> a -> b
$ PlaceOrderBody
-> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM Order
API.placeOrder PlaceOrderBody
body
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
ordersPath]
    body :: PlaceOrderBody
body        = Maybe ClientOrderId
-> ProductId
-> Side
-> Maybe Size
-> Maybe Funds
-> Maybe Price
-> Maybe Bool
-> Maybe OrderType
-> Maybe STP
-> Maybe TimeInForce
-> Maybe StopLossSide
-> Maybe Price
-> PlaceOrderBody
PlaceOrderBody Maybe ClientOrderId
clordid ProductId
prid Side
sd Maybe Size
sz forall a. Maybe a
Nothing Maybe Price
price Maybe Bool
po Maybe OrderType
ot Maybe STP
stp Maybe TimeInForce
tif forall a. Maybe a
Nothing forall a. Maybe a
Nothing


-- | https://docs.pro.coinbase.com/#place-a-new-order
-- Use the underlying post body record
placeOrderBody :: PlaceOrderBody -> CBAuthT ClientM Order
placeOrderBody :: PlaceOrderBody -> CBAuthT ClientM Order
placeOrderBody PlaceOrderBody
body =
    forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodPost RequestPath
requestPath (forall b. ToJSON b => b -> RequestPath
encodeBody PlaceOrderBody
body) forall a b. (a -> b) -> a -> b
$ PlaceOrderBody
-> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM Order
API.placeOrder PlaceOrderBody
body
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
ordersPath]


-- | https://docs.pro.coinbase.com/#cancel-an-order
cancelOrder :: OrderId -> CBAuthT ClientM ()
cancelOrder :: OrderId -> CBAuthT ClientM ()
cancelOrder OrderId
oid = forall (f :: * -> *) a. Functor f => f a -> f ()
void forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodDelete RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ OrderId
-> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM NoContent
API.cancelOrder OrderId
oid
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
ordersPath, OrderId -> Text
unOrderId OrderId
oid]


-- | https://docs.pro.coinbase.com/#cancel-all
cancelAll :: Maybe ProductId -> CBAuthT ClientM [OrderId]
cancelAll :: Maybe ProductId -> CBAuthT ClientM [OrderId]
cancelAll Maybe ProductId
prid = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodDelete RequestPath
requestPath RequestPath
emptyBody (Maybe ProductId
-> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM [OrderId]
API.cancelAll Maybe ProductId
prid)
  where
    query :: RequestPath
query       = Bool -> Query -> RequestPath
renderQuery Bool
True forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimpleQuery -> Query
simpleQueryToQuery forall a b. (a -> b) -> a -> b
$ Maybe ProductId -> SimpleQuery
mkProductQuery Maybe ProductId
prid
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
ordersPath] forall a. Semigroup a => a -> a -> a
<> RequestPath
query


-- | https://docs.pro.coinbase.com/#fills
fills :: Maybe ProductId -> Maybe OrderId -> CBAuthT ClientM [Fill]
fills :: Maybe ProductId -> Maybe OrderId -> CBAuthT ClientM [Fill]
fills Maybe ProductId
prid Maybe OrderId
oid = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody (Maybe ProductId
-> Maybe OrderId
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM [Fill]
API.fills Maybe ProductId
prid Maybe OrderId
oid)
  where
    fillsPath :: Text
fillsPath   = Text
"fills"
    query :: RequestPath
query       = Bool -> Query -> RequestPath
renderQuery Bool
True forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimpleQuery -> Query
simpleQueryToQuery forall a b. (a -> b) -> a -> b
$ Maybe ProductId -> Maybe OrderId -> SimpleQuery
mkSimpleQuery Maybe ProductId
prid Maybe OrderId
oid
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
fillsPath] forall a. Semigroup a => a -> a -> a
<> RequestPath
query

    mkSimpleQuery :: Maybe ProductId -> Maybe OrderId -> SimpleQuery
    mkSimpleQuery :: Maybe ProductId -> Maybe OrderId -> SimpleQuery
mkSimpleQuery Maybe ProductId
p Maybe OrderId
o = Maybe ProductId -> SimpleQuery
mkProductQuery Maybe ProductId
p forall a. Semigroup a => a -> a -> a
<> Maybe OrderId -> SimpleQuery
mkOrderIdQuery Maybe OrderId
o


-- | https://docs.pro.coinbase.com/#get-current-fees
fees :: CBAuthT ClientM Fees
fees :: CBAuthT ClientM Fees
fees = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
feesRequestPath RequestPath
emptyBody AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM Fees
API.fees
  where
    feesPath :: Text
feesPath        = Text
"fees"
    feesRequestPath :: RequestPath
feesRequestPath = [Text] -> RequestPath
encodeRequestPath [Text
feesPath]


-- | https://docs.pro.coinbase.com/#trailing-volume
trailingVolume :: CBAuthT ClientM [TrailingVolume]
trailingVolume :: CBAuthT ClientM [TrailingVolume]
trailingVolume = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM [TrailingVolume]
API.trailingVolume
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
usersPath, Text
selfPath, Text
"trailing-volume"]


-- | https://docs.pro.coinbase.com/#get-current-exchange-limits
limits :: CBAuthT ClientM Limits
limits :: CBAuthT ClientM Limits
limits = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM Limits
API.limits
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
usersPath, Text
selfPath, Text
"exchange-limits"]


-- | https://docs.pro.coinbase.com/#list-deposits
deposits :: Maybe ProfileId
         -> Maybe UTCTime
         -> Maybe UTCTime
         -> Maybe Int
         -> CBAuthT ClientM [Transfer]
deposits :: Maybe Text
-> Maybe UTCTime
-> Maybe UTCTime
-> Maybe Int
-> CBAuthT ClientM [Transfer]
deposits = TransferType
-> Maybe Text
-> Maybe UTCTime
-> Maybe UTCTime
-> Maybe Int
-> CBAuthT ClientM [Transfer]
transfers TransferType
DepositTransferType


-- | https://docs.pro.coinbase.com/#list-withdrawals
withdrawals :: Maybe ProfileId
            -> Maybe UTCTime
            -> Maybe UTCTime
            -> Maybe Int
            -> CBAuthT ClientM [Transfer]
withdrawals :: Maybe Text
-> Maybe UTCTime
-> Maybe UTCTime
-> Maybe Int
-> CBAuthT ClientM [Transfer]
withdrawals = TransferType
-> Maybe Text
-> Maybe UTCTime
-> Maybe UTCTime
-> Maybe Int
-> CBAuthT ClientM [Transfer]
transfers TransferType
WithdrawTransferType


transfers :: TransferType
          -> Maybe ProfileId
          -> Maybe UTCTime
          -> Maybe UTCTime
          -> Maybe Int
          -> CBAuthT ClientM [Transfer]
transfers :: TransferType
-> Maybe Text
-> Maybe UTCTime
-> Maybe UTCTime
-> Maybe Int
-> CBAuthT ClientM [Transfer]
transfers TransferType
tt Maybe Text
prof Maybe UTCTime
before Maybe UTCTime
after Maybe Int
lm = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$
    TransferType
-> Maybe Text
-> Maybe UTCTime
-> Maybe UTCTime
-> Maybe Int
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM [Transfer]
API.transfers TransferType
tt Maybe Text
prof Maybe UTCTime
before Maybe UTCTime
after Maybe Int
lm
  where
    typeQ :: SimpleQuery
typeQ   = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Show a => Text -> a -> SimpleQueryItem
mkSimpleQueryItem Text
"type" TransferType
tt
    profQ :: SimpleQuery
profQ   = forall a. Show a => Text -> Maybe a -> SimpleQuery
optionalQuery Text
"profile_id" Maybe Text
prof
    beforeQ :: SimpleQuery
beforeQ = forall a. Show a => Text -> Maybe a -> SimpleQuery
optionalQuery Text
"before" Maybe UTCTime
before
    afterQ :: SimpleQuery
afterQ  = forall a. Show a => Text -> Maybe a -> SimpleQuery
optionalQuery Text
"after" Maybe UTCTime
after
    lmQ :: SimpleQuery
lmQ     = forall a. Show a => Text -> Maybe a -> SimpleQuery
optionalQuery Text
"limit" Maybe Int
lm

    query :: RequestPath
query       = Bool -> Query -> RequestPath
renderQuery Bool
True forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimpleQuery -> Query
simpleQueryToQuery forall a b. (a -> b) -> a -> b
$ SimpleQuery
typeQ forall a. Semigroup a => a -> a -> a
<> SimpleQuery
profQ forall a. Semigroup a => a -> a -> a
<> SimpleQuery
beforeQ forall a. Semigroup a => a -> a -> a
<> SimpleQuery
afterQ forall a. Semigroup a => a -> a -> a
<> SimpleQuery
lmQ
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
transferPath forall a. Semigroup a => a -> a -> a
<> Text
"s"] forall a. Semigroup a => a -> a -> a
<> RequestPath
query


-- | https://docs.pro.coinbase.com/#single-deposit
-- | https://docs.pro.coinbase.com/#single-withdrawal
transfer :: PaymentMethodId -> CBAuthT ClientM Transfer
transfer :: PaymentMethodId -> CBAuthT ClientM Transfer
transfer pmt :: PaymentMethodId
pmt@(PaymentMethodId Text
p) = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ PaymentMethodId
-> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM Transfer
API.transfer PaymentMethodId
pmt
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
transferPath forall a. Semigroup a => a -> a -> a
<> Text
"s", Text
p]


-- | https://docs.pro.coinbase.com/#payment-method
makeDeposit :: Double
            -> Text
            -> PaymentMethodId
            -> CBAuthT ClientM DepositResponse
makeDeposit :: Double
-> Text -> PaymentMethodId -> CBAuthT ClientM DepositResponse
makeDeposit Double
amt Text
cur PaymentMethodId
pmi =
    forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodPost RequestPath
requestPath (forall b. ToJSON b => b -> RequestPath
encodeBody DepositRequest
body) forall a b. (a -> b) -> a -> b
$ DepositRequest
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM DepositResponse
API.makeDeposit DepositRequest
body
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
depositsPath, Text
"payment-method"]
    body :: DepositRequest
body        = Double -> Text -> PaymentMethodId -> DepositRequest
DepositRequest Double
amt Text
cur PaymentMethodId
pmi


-- | https://docs.pro.coinbase.com/#coinbase
makeCoinbaseDeposit :: Double
                    -> Text
                    -> AccountId
                    -> CBAuthT ClientM DepositResponse
makeCoinbaseDeposit :: Double -> Text -> AccountId -> CBAuthT ClientM DepositResponse
makeCoinbaseDeposit Double
amt Text
cur AccountId
act =
    forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodPost RequestPath
requestPath (forall b. ToJSON b => b -> RequestPath
encodeBody CoinbaseDepositRequest
body) forall a b. (a -> b) -> a -> b
$ CoinbaseDepositRequest
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM DepositResponse
API.makeCoinbaseDeposit CoinbaseDepositRequest
body
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
depositsPath, Text
coinbaseAccountPath]
    body :: CoinbaseDepositRequest
body        = Double -> Text -> AccountId -> CoinbaseDepositRequest
CoinbaseDepositRequest Double
amt Text
cur AccountId
act


-- | https://docs.pro.coinbase.com/#generate-a-crypto-deposit-address
cryptoDepositAddress :: AccountId -> CBAuthT ClientM CryptoDepositAddress
cryptoDepositAddress :: AccountId -> CBAuthT ClientM CryptoDepositAddress
cryptoDepositAddress AccountId
act =
    forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodPost RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ AccountId
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM CryptoDepositAddress
API.cryptoDepositAddress AccountId
act
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
coinbaseAccountPath forall a. Semigroup a => a -> a -> a
<> Text
"s", String -> Text
pack forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show AccountId
act, Text
"addresses"]


-- | https://docs.pro.coinbase.com/#payment-method55
makeWithdrawal :: Double
               -> Text
               -> PaymentMethodId
               -> CBAuthT ClientM WithdrawalResponse
makeWithdrawal :: Double
-> Text -> PaymentMethodId -> CBAuthT ClientM WithdrawalResponse
makeWithdrawal Double
amt Text
cur PaymentMethodId
pmi =
    forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodPost RequestPath
requestPath (forall b. ToJSON b => b -> RequestPath
encodeBody WithdrawalRequest
body) forall a b. (a -> b) -> a -> b
$ WithdrawalRequest
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM WithdrawalResponse
API.makeWithdrawal WithdrawalRequest
body
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
withdrawalsPath, Text
"payment-method"]
    body :: WithdrawalRequest
body        = Double -> Text -> PaymentMethodId -> WithdrawalRequest
WithdrawalRequest Double
amt Text
cur PaymentMethodId
pmi


-- | https://docs.pro.coinbase.com/#coinbase56
makeCoinbaseWithdrawal :: Double
                       -> Text
                       -> AccountId
                       -> CBAuthT ClientM WithdrawalResponse
makeCoinbaseWithdrawal :: Double -> Text -> AccountId -> CBAuthT ClientM WithdrawalResponse
makeCoinbaseWithdrawal Double
amt Text
cur AccountId
act =
    forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodPost RequestPath
requestPath (forall b. ToJSON b => b -> RequestPath
encodeBody CoinbaseWithdrawalRequest
body) forall a b. (a -> b) -> a -> b
$ CoinbaseWithdrawalRequest
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM WithdrawalResponse
API.makeCoinbaseWithdrawal CoinbaseWithdrawalRequest
body
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
withdrawalsPath, Text
coinbaseAccountPath]
    body :: CoinbaseWithdrawalRequest
body        = Double -> Text -> AccountId -> CoinbaseWithdrawalRequest
CoinbaseWithdrawalRequest Double
amt Text
cur AccountId
act


-- | https://docs.pro.coinbase.com/#crypto
makeCryptoWithdrawal :: Double
                     -> Text
                     -> Text
                     -> CBAuthT ClientM CryptoWithdrawalResponse
makeCryptoWithdrawal :: Double -> Text -> Text -> CBAuthT ClientM CryptoWithdrawalResponse
makeCryptoWithdrawal Double
amt Text
cur Text
addr =
    forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodPost RequestPath
requestPath (forall b. ToJSON b => b -> RequestPath
encodeBody CryptoWithdrawalRequest
body) forall a b. (a -> b) -> a -> b
$ CryptoWithdrawalRequest
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM CryptoWithdrawalResponse
API.makeCryptoWithdrawal CryptoWithdrawalRequest
body
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
withdrawalsPath, Text
"crypto"]
    body :: CryptoWithdrawalRequest
body        = Double -> Text -> Text -> CryptoWithdrawalRequest
CryptoWithdrawalRequest Double
amt Text
cur Text
addr


-- | https://docs.pro.coinbase.com/#fee-estimate
withdrawalFeeEstimate :: CurrencyType
                      -> CryptoAddress
                      -> CBAuthT ClientM WithdrawalFeeEstimateResponse
withdrawalFeeEstimate :: CurrencyType
-> CryptoAddress -> CBAuthT ClientM WithdrawalFeeEstimateResponse
withdrawalFeeEstimate CurrencyType
cur CryptoAddress
addr =
    forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ CurrencyType
-> CryptoAddress
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM WithdrawalFeeEstimateResponse
API.withdrawalFeeEstimate CurrencyType
cur CryptoAddress
addr
  where
    curQ :: SimpleQuery
curQ  = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Show a => Text -> a -> SimpleQueryItem
mkSimpleQueryItem Text
"currency" CurrencyType
cur
    addrQ :: SimpleQuery
addrQ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Show a => Text -> a -> SimpleQueryItem
mkSimpleQueryItem Text
"crypto_address" CryptoAddress
addr

    query :: RequestPath
query       = Bool -> Query -> RequestPath
renderQuery Bool
True forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimpleQuery -> Query
simpleQueryToQuery forall a b. (a -> b) -> a -> b
$ SimpleQuery
curQ forall a. Semigroup a => a -> a -> a
<> SimpleQuery
addrQ
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
withdrawalsPath, Text
"fee-estimate"] forall a. Semigroup a => a -> a -> a
<> RequestPath
query


-- | https://docs.pro.coinbase.com/#stablecoin-conversions
createStablecoinConversion :: CurrencyType -> CurrencyType -> Double -> CBAuthT ClientM StablecoinConversionResponse
createStablecoinConversion :: CurrencyType
-> CurrencyType
-> Double
-> CBAuthT ClientM StablecoinConversionResponse
createStablecoinConversion CurrencyType
fromCur CurrencyType
toCur Double
amt =
    forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodPost RequestPath
requestPath (forall b. ToJSON b => b -> RequestPath
encodeBody StablecoinConversionRequest
body) forall a b. (a -> b) -> a -> b
$ StablecoinConversionRequest
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM StablecoinConversionResponse
API.createStablecoinConversion StablecoinConversionRequest
body
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
"conversions"]
    body :: StablecoinConversionRequest
body        = CurrencyType
-> CurrencyType -> Double -> StablecoinConversionRequest
StablecoinConversionRequest CurrencyType
fromCur CurrencyType
toCur Double
amt


-- | https://docs.pro.coinbase.com/#list-payment-methods
paymentMethods :: CBAuthT ClientM [PaymentMethod]
paymentMethods :: CBAuthT ClientM [PaymentMethod]
paymentMethods = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM [PaymentMethod]
API.paymentMethods
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
"payment-methods"]


-- | https://docs.pro.coinbase.com/#list-accounts64
coinbaseAccounts :: CBAuthT ClientM [CoinbaseAccount]
coinbaseAccounts :: CBAuthT ClientM [CoinbaseAccount]
coinbaseAccounts = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM [CoinbaseAccount]
API.coinbaseAccounts
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
coinbaseAccountPath forall a. Semigroup a => a -> a -> a
<> Text
"s"]


-- | https://docs.pro.coinbase.com/#list-profiles
profiles :: Maybe Bool -> CBAuthT ClientM [Profile]
profiles :: Maybe Bool -> CBAuthT ClientM [Profile]
profiles Maybe Bool
active = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ Maybe Bool
-> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM [Profile]
API.profiles Maybe Bool
active
  where
    activeQ :: SimpleQuery
activeQ  = forall a. Show a => Text -> Maybe a -> SimpleQuery
optionalQuery Text
"active" Maybe Bool
active

    query :: RequestPath
query       = Bool -> Query -> RequestPath
renderQuery Bool
True forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimpleQuery -> Query
simpleQueryToQuery forall a b. (a -> b) -> a -> b
$ SimpleQuery
activeQ
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
profilesPath] forall a. Semigroup a => a -> a -> a
<> RequestPath
query


-- | https://docs.pro.coinbase.com/#get-a-profile
profile :: ProfileId -> CBAuthT ClientM Profile
profile :: Text -> CBAuthT ClientM Profile
profile Text
profId = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ Text
-> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM Profile
API.profile Text
profId
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
profilesPath, Text
profId]


-- | https://docs.pro.coinbase.com/#create-profile-transfer
profileTransfer :: ProfileId
                -> ProfileId
                -> CurrencyType
                -> String
                -> CBAuthT ClientM ()
profileTransfer :: Text -> Text -> CurrencyType -> String -> CBAuthT ClientM ()
profileTransfer Text
fromProf Text
toProf CurrencyType
cur String
amt = forall (f :: * -> *) a. Functor f => f a -> f ()
void forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodPost RequestPath
requestPath (forall b. ToJSON b => b -> RequestPath
encodeBody ProfileTransfer
body) forall a b. (a -> b) -> a -> b
$ ProfileTransfer
-> AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM NoContent
API.profileTransfer ProfileTransfer
body
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
profilesPath, Text
transferPath]
    body :: ProfileTransfer
body        = Text -> Text -> CurrencyType -> String -> ProfileTransfer
ProfileTransfer Text
fromProf Text
toProf CurrencyType
cur String
amt


-- | https://docs.pro.coinbase.com/#create-a-new-report
createReport :: ReportRequest -> CBAuthT ClientM ReportResponse
createReport :: ReportRequest -> CBAuthT ClientM ReportResponse
createReport ReportRequest
req = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodPost RequestPath
requestPath (forall b. ToJSON b => b -> RequestPath
encodeBody ReportRequest
req) forall a b. (a -> b) -> a -> b
$ ReportRequest
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM ReportResponse
API.createReport ReportRequest
req
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
reportsPath]


-- | https://docs.pro.coinbase.com/#get-report-status
getReport :: ReportId -> CBAuthT ClientM ReportResponse
getReport :: ReportId -> CBAuthT ClientM ReportResponse
getReport ReportId
rid = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody forall a b. (a -> b) -> a -> b
$ ReportId
-> AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM ReportResponse
API.getReport ReportId
rid
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
reportsPath, UUID -> Text
toText forall a b. (a -> b) -> a -> b
$ ReportId -> UUID
unReportId ReportId
rid]


-- | https://docs.pro.coinbase.com/#oracle
getOracle :: CBAuthT ClientM OracleResponse
getOracle :: CBAuthT ClientM OracleResponse
getOracle = forall b.
RequestPath
-> RequestPath
-> RequestPath
-> (AuthenticatedRequest (AuthProtect "CBAuth") -> ClientM b)
-> CBAuthT ClientM b
authRequest RequestPath
methodGet RequestPath
requestPath RequestPath
emptyBody AuthenticatedRequest (AuthProtect "CBAuth")
-> ClientM OracleResponse
API.getOracle
  where
    requestPath :: RequestPath
requestPath = [Text] -> RequestPath
encodeRequestPath [Text
"oracle"]