Skip to content

Commit

Permalink
Add Cardano.Wallet.Deposit.REST module
Browse files Browse the repository at this point in the history
  • Loading branch information
HeinrichApfelmus authored and paolino committed Sep 5, 2024
1 parent be751bf commit ae3a5b0
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/customer-deposit-wallet/customer-deposit-wallet.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ library
Cardano.Wallet.Deposit.Pure.UTxOHistory
Cardano.Wallet.Deposit.Pure.Submissions
Cardano.Wallet.Deposit.Read
Cardano.Wallet.Deposit.REST
Cardano.Wallet.Deposit.Write

test-suite scenario
Expand Down
185 changes: 185 additions & 0 deletions lib/customer-deposit-wallet/src/Cardano/Wallet/Deposit/REST.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
{-|
Copyright: © 2024 Cardano Foundation
License: Apache-2.0
'IO'-based interface to the Deposit Wallet
where the wallet is treated as a mutable resource (~ REST).
This interface can be mapped one-to-one to a HTTP interface.
-}
module Cardano.Wallet.Deposit.REST
(
-- * Types
, WalletResource
, withWalletResource

, WalletResourceM
, runWalletResourceM

-- * Operations
-- ** Initialization
, putWallet

-- ** Mapping between customers and addresses
, listCustomers
, createAddress

-- ** Reading from the blockchain
, getWalletTip
, availableBalance
, getCustomerHistory
, getCustomerHistories

-- ** Writing to the blockchain
, createPayment
, getBIP32PathsForOwnedInputs
, signTxBody
) where

import Prelude

import Cardano.Crypto.Wallet
( XPub
)
import Cardano.Wallet.Address.BIP32
( BIP32Path
)
import Cardano.Wallet.Deposit.Pure
( Customer
, WalletState
, Word31
)
import Cardano.Wallet.Deposit.Read
( Address
)
import Control.Monad.Trans.Except
( ExceptT (..)
, runExceptT
)
import Control.Monad.Trans.Reader
( ReaderT (..)
)
import Data.Bifunctor
( first
)

import qualified Cardano.Wallet.Deposit.IO as WalletIO
import qualified Cardano.Wallet.Deposit.Read as Read
import qualified Cardano.Wallet.Deposit.Resource as Resource
import qualified Cardano.Wallet.Deposit.Write as Write

{-----------------------------------------------------------------------------
Types
------------------------------------------------------------------------------}
-- | Mutable resource that may hold a 'WalletInstance'.
type WalletResource = Resource.Resource WalletIO.WalletInstance

{-
-- Find the resource from the file system
-- or create a new one.
-- withWalletInit
-- withWalletLoad
-- | Load an existing wallet from the given environment.
withWalletLoad
:: WalletEnv IO
-> (WalletInstance -> IO a)
-> IO a
withWalletLoad = undefined
-}

-- | Create a 'WalletResource'.
withWalletResource
:: WalletIO.WalletEnv IO
-> (WalletResource -> IO b)
-> IO b
withWalletResource _env = Resource.withResource

-- | Error indicating that the 'WalletResource' does not hold a wallet.
newtype ErrNoWallet
= ErrNoWallet Resource.NotInitialized
deriving (Eq, Ord, Show)

-- | Monad for acting on a 'WalletResource'.
type WalletResourceM = ReaderT WalletResource (ExcepT ErrNoWallet IO)

runWalletResourceM
:: WalletResourceM a
-> WalletResource -> IO (Either ErrNoWallet a)
runWalletResourceM action resource =
runExceptT (runReaderT action resource)

-- | Run an 'IO' function on the 'WalletInstance'.
onWalletInstance
:: (WalletInstance -> IO a)
-> WalletResourceM a
onWalletInstance action = ReaderT $ \resource -> ExceptT $
first ErrNoWallet <$> Resource.onResource action resource

-- | Error indicating that the 'WalletResource' already holds a wallet.
data ErrWalletAlreadyExits
= ErrWalletAlreadyExitsOrVanished
deriving (Eq, Ord, Show)

-- | Initialize a new wallet if none existed before.
putWallet
:: XPub
-> Word31
-> WalletResource -> IO (Either ErrWalletAlreadyExits ())
putWallet xpub knownCustomerCount resource =
first (const ErrWalletAlreadyExitsOrVanished)
<$> Resource.putResource
(WalletIO.withWalletInit xpub knownCustomerCount)
resource

{-----------------------------------------------------------------------------
Operations
------------------------------------------------------------------------------}
listCustomers
:: WalletResourceM [(Customer, Address)]
listCustomers = onWalletInstance WalletIO.listCustomers

createAddress
:: Customer
-> WalletResourceM Address
createAddress = onWalletInstance . WalletIO.createAddress

{-----------------------------------------------------------------------------
Operations
Reading from the blockchain
------------------------------------------------------------------------------}
getWalletTip :: WalletResourceM Read.ChainPoint
getWalletTip = onWalletInstance WalletIO.getWalletTip

availableBalance :: WalletResourceM Read.Value
availableBalance = onWalletInstance WalletIO.availableBalance

getCustomerHistory
:: Customer
-> WalletResourceM [Wallet.TxSummary]
getCustomerHistory = onWalletInstance . WalletIO.getCustomerHistory

getCustomerHistories
:: (Read.ChainPoint, Read.ChainPoint)
-> WalletResourceM (Map.Map Customer Wallet.ValueTransfer)
getCustomerHistories = onWalletInstance . WalletIO.getCustomerHistories

{-----------------------------------------------------------------------------
Operations
Writing to blockchain
------------------------------------------------------------------------------}

createPayment
:: [(Address, Read.Value)]
-> WalletResourceM (Maybe Write.TxBody)
createPayment = onWalletInstance . WalletIO.createPayment

getBIP32PathsForOwnedInputs
:: Write.TxBody
-> WalletResourceM [BIP32Path]
getBIP32PathsForOwnedInputs =
onWalletInstance . WalletIO.getBIP32PathsForOwnedInputs

signTxBody
:: Write.TxBody
-> WalletResourceM (Maybe Write.Tx)
signTxBody = onWalletInstance . WalletIO.signTxBody

0 comments on commit ae3a5b0

Please sign in to comment.