-
Notifications
You must be signed in to change notification settings - Fork 213
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
This pull request sketches how the `Cardano.Wallet.Deposit.HTTP` modules related to the `Cardano.Wallet.Deposit.IO` modules. ### Issue number ADP-3320
- Loading branch information
Showing
11 changed files
with
482 additions
and
8 deletions.
There are no files selected for viewing
5 changes: 0 additions & 5 deletions
5
lib/customer-deposit-wallet/api/http/Cardano/Wallet/Deposit/HTTP.hs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
lib/customer-deposit-wallet/http/Cardano/Wallet/Deposit/HTTP.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
-- | | ||
-- Copyright: © 2024 Cardano Foundation | ||
-- License: Apache-2.0 | ||
-- | ||
-- HTTP API for the wallet. | ||
-- | ||
module Cardano.Wallet.Deposit.HTTP | ||
( serveHTTP | ||
) | ||
where | ||
|
||
import Prelude | ||
|
||
import Cardano.Wallet.Deposit.HTTP.Implementation | ||
( api | ||
, implementation | ||
) | ||
import Servant.Server | ||
( Application | ||
, serve | ||
) | ||
|
||
import qualified Cardano.Wallet.Deposit.IO as Wallet | ||
import qualified Network.Wai.Handler.Warp | ||
|
||
{----------------------------------------------------------------------------- | ||
Serving our HTTP API | ||
------------------------------------------------------------------------------} | ||
|
||
app :: Wallet.WalletInstance -> Application | ||
app = serve api . implementation | ||
|
||
serveHTTP :: Wallet.WalletInstance -> IO () | ||
serveHTTP = Network.Wai.Handler.Warp.run 8090 . app |
66 changes: 66 additions & 0 deletions
66
lib/customer-deposit-wallet/http/Cardano/Wallet/Deposit/HTTP/Endpoints.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
-- | | ||
-- Copyright: © 2024 Cardano Foundation | ||
-- License: Apache-2.0 | ||
-- | ||
-- HTTP endpoints. | ||
-- | ||
-- Each HTTP endpoint corresponds to a single function from the | ||
-- "Cardano.Wallet.Deposit.IO" module. | ||
-- | ||
module Cardano.Wallet.Deposit.HTTP.Endpoints | ||
( listCustomers | ||
, createAddress | ||
) where | ||
|
||
import Prelude | ||
|
||
import Cardano.Wallet.Deposit.HTTP.Types.JSON | ||
( Address | ||
, ApiT (..) | ||
, Customer | ||
, CustomerList | ||
) | ||
import Control.Monad.IO.Class | ||
( liftIO | ||
) | ||
import Servant.Server | ||
( Handler | ||
) | ||
|
||
import qualified Cardano.Wallet.Deposit.IO as Wallet | ||
|
||
{----------------------------------------------------------------------------- | ||
HTTP Wallet endpoints | ||
------------------------------------------------------------------------------} | ||
{- NOTE [ApiT] | ||
The arguments and results of the 'Handler's defined in the present module | ||
are all wrapped in the 'ApiT' type constructor. | ||
The purpose of the 'ApiT' type constructor is to control the | ||
JSON encoding of the wrapped data type. | ||
Specifically, we for any data type @X@ that we define a separate package, | ||
we define instances such as 'FromJSON'@ (ApiT X)@ in the present package. | ||
In other words, defining the JSON encoding for data types is a concern | ||
of the @Cardano.Wallet.Deposit.HTTP.*@ modules; | ||
it's not a concern of the modules where the data type is originally defined. | ||
The JSONS instances for @ApiT@ can be implemented "by hand" | ||
or they can be derived automatically from the definition (using e.g. Generics). | ||
We plan on using FineTypes to generate the JSON encoding automatically. | ||
-} | ||
|
||
listCustomers | ||
:: Wallet.WalletInstance | ||
-> Handler (ApiT CustomerList) | ||
listCustomers w = | ||
liftIO $ ApiT <$> Wallet.listCustomers w | ||
|
||
createAddress | ||
:: Wallet.WalletInstance | ||
-> ApiT Customer | ||
-> Handler (ApiT Address) | ||
createAddress w a = | ||
liftIO $ ApiT <$> Wallet.createAddress (unApiT a) w |
38 changes: 38 additions & 0 deletions
38
lib/customer-deposit-wallet/http/Cardano/Wallet/Deposit/HTTP/Implementation.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
-- | | ||
-- Copyright: © 2024 Cardano Foundation | ||
-- License: Apache-2.0 | ||
-- | ||
-- Implementation of our HTTP API. | ||
-- | ||
module Cardano.Wallet.Deposit.HTTP.Implementation | ||
( api | ||
, implementation | ||
) | ||
where | ||
|
||
import Cardano.Wallet.Deposit.HTTP.Types.API | ||
( API | ||
) | ||
import Data.Proxy | ||
( Proxy (..) | ||
) | ||
import Servant | ||
( (:<|>) (..) | ||
) | ||
import Servant.Server | ||
( Server | ||
) | ||
|
||
import qualified Cardano.Wallet.Deposit.HTTP.Endpoints as HTTP | ||
import qualified Cardano.Wallet.Deposit.IO as Wallet | ||
|
||
{----------------------------------------------------------------------------- | ||
Types | ||
------------------------------------------------------------------------------} | ||
api :: Proxy API | ||
api = Proxy | ||
|
||
implementation :: Wallet.WalletInstance -> Server API | ||
implementation w = | ||
HTTP.listCustomers w | ||
:<|> HTTP.createAddress w |
39 changes: 39 additions & 0 deletions
39
lib/customer-deposit-wallet/http/Cardano/Wallet/Deposit/HTTP/Types/API.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{-# LANGUAGE DataKinds #-} | ||
{-# LANGUAGE TypeOperators #-} | ||
-- | | ||
-- Copyright: © 2024 Cardano Foundation | ||
-- License: Apache-2.0 | ||
-- | ||
-- Servant Type for our HTTP API. | ||
-- | ||
module Cardano.Wallet.Deposit.HTTP.Types.API | ||
( API | ||
) | ||
where | ||
|
||
import Cardano.Wallet.Deposit.HTTP.Types.JSON | ||
( Address | ||
, ApiT | ||
, Customer | ||
, CustomerList | ||
) | ||
import Servant.API | ||
( Capture | ||
, JSON | ||
, StdMethod (..) | ||
, Verb | ||
, (:<|>) | ||
, (:>) | ||
) | ||
|
||
{----------------------------------------------------------------------------- | ||
API | ||
------------------------------------------------------------------------------} | ||
|
||
type API = | ||
"customers" | ||
:> Verb 'GET 200 '[JSON] (ApiT CustomerList) | ||
:<|> | ||
"customers" | ||
:> Capture "customerId" (ApiT Customer) | ||
:> Verb 'PUT 200 '[JSON] (ApiT Address) |
104 changes: 104 additions & 0 deletions
104
lib/customer-deposit-wallet/http/Cardano/Wallet/Deposit/HTTP/Types/JSON.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
{-# LANGUAGE DerivingVia #-} | ||
{-# LANGUAGE FlexibleInstances #-} | ||
{-# LANGUAGE StandaloneDeriving #-} | ||
|
||
-- | | ||
-- Copyright: © 2024 Cardano Foundation | ||
-- License: Apache-2.0 | ||
-- | ||
-- Data types with a JSON schema. | ||
-- | ||
module Cardano.Wallet.Deposit.HTTP.Types.JSON | ||
( ApiT (..) | ||
|
||
-- * Re-exports | ||
, Address | ||
, Customer | ||
, CustomerList | ||
) | ||
where | ||
|
||
import Prelude | ||
|
||
import Cardano.Wallet.Deposit.HTTP.Types.JSON.Encoding | ||
( ViaText (..) | ||
, customOptions | ||
) | ||
import Cardano.Wallet.Deposit.Pure | ||
( Customer | ||
) | ||
import Cardano.Wallet.Deposit.Read | ||
( Address | ||
) | ||
import Data.Aeson | ||
( FromJSON (..) | ||
, ToJSON (..) | ||
, genericParseJSON | ||
, genericToJSON | ||
) | ||
import Data.Bifunctor | ||
( bimap | ||
, first | ||
) | ||
import Data.Text | ||
( Text | ||
) | ||
import Data.Text.Class | ||
( FromText (..) | ||
, getTextDecodingError | ||
) | ||
import Servant | ||
( FromHttpApiData (..) | ||
) | ||
|
||
import qualified Data.Text as T | ||
|
||
{----------------------------------------------------------------------------- | ||
Additional type definitions | ||
------------------------------------------------------------------------------} | ||
|
||
type CustomerList = [(Customer, Address)] | ||
|
||
{----------------------------------------------------------------------------- | ||
ApiT | ||
------------------------------------------------------------------------------} | ||
|
||
newtype ApiT a = ApiT {unApiT :: a} | ||
deriving (Eq, Ord, Show) | ||
|
||
{----------------------------------------------------------------------------- | ||
JSON encodings | ||
------------------------------------------------------------------------------} | ||
|
||
-- Address | ||
deriving via ViaText Address instance FromJSON (ApiT Address) | ||
deriving via ViaText Address instance ToJSON (ApiT Address) | ||
|
||
-- Customer | ||
instance FromHttpApiData (ApiT Customer) where | ||
parseUrlPiece = fmap ApiT . fromText' | ||
|
||
instance FromJSON (ApiT Customer) where | ||
parseJSON = fmap ApiT . parseJSON | ||
|
||
instance ToJSON (ApiT Customer) where | ||
toJSON = toJSON . unApiT | ||
|
||
-- | 'fromText' but with a simpler error type. | ||
fromText' :: FromText a => Text -> Either Text a | ||
fromText' = first (T.pack . getTextDecodingError) . fromText | ||
|
||
-- CustomerList | ||
type ApiCustomerList = [(ApiT Customer, ApiT Address)] | ||
|
||
toApiCustomerList :: ApiT CustomerList -> ApiCustomerList | ||
toApiCustomerList = fmap (bimap ApiT ApiT) . unApiT | ||
|
||
fromApiCustomerList :: ApiCustomerList -> ApiT CustomerList | ||
fromApiCustomerList = ApiT . fmap (bimap unApiT unApiT) | ||
|
||
instance FromJSON (ApiT CustomerList) where | ||
parseJSON = fmap fromApiCustomerList . genericParseJSON customOptions | ||
|
||
instance ToJSON (ApiT CustomerList) where | ||
toJSON = genericToJSON customOptions . toApiCustomerList |
Oops, something went wrong.