coinbase-pro-0.9.0.0: src/lib/CoinbasePro/Authenticated/CoinbaseAccounts.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module CoinbasePro.Authenticated.CoinbaseAccounts
( CoinbaseAccount (..)
) where
import Data.Aeson (FromJSON (..), Value (..), withObject, (.:),
(.:?))
import Data.Aeson.Casing (snakeCase)
import Data.Aeson.TH (defaultOptions, deriveJSON,
fieldLabelModifier)
import Data.Text (Text)
data BankCountry = BankCountry
{ code :: Text
, name :: Text
} deriving Show
deriveJSON defaultOptions
{ fieldLabelModifier = snakeCase
} ''BankCountry
data WireDepositInformation = WireDepositInformation
{ accountNumber :: Maybe Text
, routingNumber :: Text
, bankName :: Text
, bankAddress :: Text
, bankCountry :: BankCountry
, accountName :: Text
, accountAddress :: Text
, reference :: Text
} deriving Show
instance FromJSON WireDepositInformation where
parseJSON = withObject "wire deposit information" $ \o -> WireDepositInformation
<$> o .: "account_number"
<*> o .: "routing_number"
<*> o .: "bank_name"
<*> o .: "bank_address"
<*> (parseJSON =<< (o .: "bank_country"))
<*> o .: "account_name"
<*> o .: "account_address"
<*> o .: "reference"
data SepaDepositInformation = SepaDepositInformation
{ sIban :: Text
, sSwift :: Text
, sBankName :: Text
, sBankAddress :: Text
, sBankCountryName :: Text
, sAccountName :: Text
, sAccountAddress :: Text
, sReference :: Text
} deriving Show
deriveJSON defaultOptions
{ fieldLabelModifier = snakeCase . drop 1
} ''SepaDepositInformation
data DepositInformation = Wire WireDepositInformation | Sepa SepaDepositInformation
deriving Show
-- TODO: this is slightly messy, potentially refactor
instance FromJSON DepositInformation where
parseJSON = withObject "deposit_information" $ \o -> do
w <- o .:? "wire_deposit_information"
case w of
Just (Object w') -> Wire <$> parseJSON (Object w')
Nothing -> do
s <- o .:? "sepa_deposit_information"
case s of
Just (Object s') -> Sepa <$> parseJSON (Object s')
_ -> fail "Unable to parse deposit information"
_ -> fail "Unable to parse deposit information"
data Account = Account
{ aId :: Text
, aName :: Text
, aBalance :: Double
, aCurrency :: Text
, aType :: Text
, aPrimary :: Bool
, aActive :: Bool
} deriving (Show)
instance FromJSON Account where
parseJSON = withObject "account" $ \o -> Account
<$> o .: "id"
<*> o .: "name"
<*> (read <$> o .: "balance")
<*> o .: "currency"
<*> o .: "type"
<*> o .: "primary"
<*> o .: "active"
data FiatAccount = FiatAccount
{ fAccount :: Account
, fDepositInformation :: DepositInformation
} deriving Show
instance FromJSON FiatAccount where
parseJSON = withObject "fiat account" $ \o -> FiatAccount
<$> parseJSON (Object o)
<*> parseJSON (Object o)
newtype CryptoAccount = CryptoAccount Account
deriving Show
instance FromJSON CryptoAccount where
parseJSON = withObject "crypto account" $ \o -> CryptoAccount
<$> parseJSON (Object o)
data CoinbaseAccount = Fiat FiatAccount | Crypto CryptoAccount
deriving Show
instance FromJSON CoinbaseAccount where
parseJSON = withObject "coinbase account" $ \o -> do
t <- String <$> o .: "type"
case t of
"fiat" -> Fiat <$> parseJSON (Object o)
"wallet" -> Crypto <$> parseJSON (Object o)
_ -> fail "Unable to parse coinbase account"