diff --git a/lib/customer-deposit-wallet/http/Cardano/Wallet/Deposit/HTTP/Server.hs b/lib/customer-deposit-wallet/http/Cardano/Wallet/Deposit/HTTP/Server.hs index fa936209323..e16def75ebe 100644 --- a/lib/customer-deposit-wallet/http/Cardano/Wallet/Deposit/HTTP/Server.hs +++ b/lib/customer-deposit-wallet/http/Cardano/Wallet/Deposit/HTTP/Server.hs @@ -68,25 +68,30 @@ api :: Proxy API api = Proxy server - :: Tracer IO String + :: Tracer IO () + -- ^ Tracer for wallet tip changes + -> Tracer IO String -> FilePath -> WalletBootEnv IO -> WalletResource -> Server API -server tr dbDir wb r = +server wtc tr dbDir wb r = listCustomerH r :<|> queryAddressH r - :<|> createWalletViaMnemonic tr dbDir wb r - :<|> createWalletViaXPub tr dbDir wb r + :<|> createWalletViaMnemonic wtc tr dbDir wb r + :<|> createWalletViaXPub wtc tr dbDir wb r createWalletViaMnemonic - :: Tracer IO String + :: Tracer IO () + -- ^ Tracer for wallet tip changes + -> Tracer IO String -> FilePath -> WalletBootEnv IO -> WalletResource -> PostWalletViaMnemonic -> Handler NoContent createWalletViaMnemonic + wtc tracer dir boot @@ -99,6 +104,7 @@ createWalletViaMnemonic initWallet :: WalletResourceM () initWallet = REST.initWallet + wtc tracer boot dir @@ -107,13 +113,16 @@ createWalletViaMnemonic onlyOnWalletIntance resource initWallet $> NoContent createWalletViaXPub - :: Tracer IO String + :: Tracer IO () + -- ^ Tracer for wallet tip changes + -> Tracer IO String -> FilePath -> WalletBootEnv IO -> WalletResource -> PostWalletViaXPub -> Handler NoContent createWalletViaXPub + wtc tracer dir boot @@ -130,6 +139,7 @@ createWalletViaXPub Right credentials -> Right <$> REST.initWallet + wtc tracer boot dir diff --git a/lib/customer-deposit-wallet/rest/Cardano/Wallet/Deposit/REST.hs b/lib/customer-deposit-wallet/rest/Cardano/Wallet/Deposit/REST.hs index 5bc16a39b30..fa79b7cc535 100644 --- a/lib/customer-deposit-wallet/rest/Cardano/Wallet/Deposit/REST.hs +++ b/lib/customer-deposit-wallet/rest/Cardano/Wallet/Deposit/REST.hs @@ -337,18 +337,20 @@ createTheDepositWalletOnDisk _tr dir credentials users action = do -- | Load an existing wallet from disk. loadWallet - :: WalletIO.WalletBootEnv IO + :: Tracer IO () + -- ^ Tracer for wallet tip changes + -> WalletIO.WalletBootEnv IO -- ^ Environment for the wallet -> FilePath -- ^ Path to the wallet database directory -> WalletResourceM () -loadWallet bootEnv dir = do +loadWallet wtc bootEnv dir = do let action :: (WalletIO.WalletInstance -> IO b) -> IO (Either ErrDatabase b) action f = findTheDepositWalletOnDisk bootEnv dir $ \case Right wallet -> Right - <$> WalletIO.withWalletLoad + <$> WalletIO.withWalletLoad wtc (WalletIO.WalletEnv bootEnv wallet) f Left e -> pure $ Left $ ErrLoadingDatabase e @@ -360,7 +362,9 @@ loadWallet bootEnv dir = do -- | Initialize a new wallet from an 'XPub'. initWallet - :: Tracer IO String + :: Tracer IO () + -- ^ Tracer for wallet tip changes + -> Tracer IO String -- ^ Tracer for logging -> WalletIO.WalletBootEnv IO -- ^ Environment for the wallet @@ -371,13 +375,13 @@ initWallet -> Word31 -- ^ Max number of users ? -> WalletResourceM () -initWallet tr bootEnv dir credentials users = do +initWallet wtc tr bootEnv dir credentials users = do let action :: (WalletIO.WalletInstance -> IO b) -> IO (Either ErrDatabase b) action f = createTheDepositWalletOnDisk tr dir credentials users $ \case Just wallet -> do fmap Right - $ WalletIO.withWalletInit + $ WalletIO.withWalletInit wtc (WalletIO.WalletEnv bootEnv wallet) credentials users diff --git a/lib/customer-deposit-wallet/rest/Cardano/Wallet/Deposit/REST/Start.hs b/lib/customer-deposit-wallet/rest/Cardano/Wallet/Deposit/REST/Start.hs index c2926763272..89236c97bf6 100644 --- a/lib/customer-deposit-wallet/rest/Cardano/Wallet/Deposit/REST/Start.hs +++ b/lib/customer-deposit-wallet/rest/Cardano/Wallet/Deposit/REST/Start.hs @@ -49,17 +49,19 @@ lg :: (MonadIO m, Show a) => Tracer IO String -> String -> a -> m () lg tr p x = liftIO $ traceWith tr $ p <> ": " <> show x loadDepositWalletFromDisk - :: Tracer IO String + :: Tracer IO () + -- ^ Tracer for wallet tip changes + -> Tracer IO String -> FilePath -> WalletBootEnv IO -> WalletResource -> IO () -loadDepositWalletFromDisk tr dir env resource = do +loadDepositWalletFromDisk wtc tr dir env resource = do result <- flip runWalletResourceM resource $ do test <- liftIO $ walletExists dir when test $ do lg tr "Loading wallet from" dir - loadWallet env dir + loadWallet wtc env dir lg tr "Wallet loaded from" dir pure test case result of diff --git a/lib/customer-deposit-wallet/src/Cardano/Wallet/Deposit/IO.hs b/lib/customer-deposit-wallet/src/Cardano/Wallet/Deposit/IO.hs index 26a81299d9b..4ff73ddfd45 100644 --- a/lib/customer-deposit-wallet/src/Cardano/Wallet/Deposit/IO.hs +++ b/lib/customer-deposit-wallet/src/Cardano/Wallet/Deposit/IO.hs @@ -90,6 +90,7 @@ import Cardano.Wallet.Network.Checkpoints.Policy import Control.Tracer ( Tracer , contramap + , traceWith ) import Data.Bifunctor ( first @@ -175,12 +176,14 @@ readWalletState WalletInstance{walletState} = -- | Initialize a new wallet in the given environment. withWalletInit - :: WalletEnv IO + :: Tracer IO () -- wallet tip changes + -> WalletEnv IO -> Credentials -> Word31 -> (WalletInstance -> IO a) -> IO a withWalletInit + wtc env@WalletEnv { bootEnv = WalletBootEnv{genesisData} , .. @@ -194,23 +197,26 @@ withWalletInit credentials knownCustomerCount genesisData - withWalletDBVar env walletState action + withWalletDBVar wtc env walletState action -- | Load an existing wallet from the given environment. withWalletLoad - :: WalletEnv IO + :: Tracer IO () -- wallet tip changes + -> WalletEnv IO -> (WalletInstance -> IO a) -> IO a -withWalletLoad env@WalletEnv{..} action = do +withWalletLoad wtc env@WalletEnv{..} action = do walletState <- DBVar.loadDBVar store - withWalletDBVar env walletState action + withWalletDBVar wtc env walletState action withWalletDBVar - :: WalletEnv IO + :: Tracer IO () -- wallet tip changes + -> WalletEnv IO -> DBVar.DBVar IO Wallet.DeltaWalletState -> (WalletInstance -> IO a) -> IO a withWalletDBVar + wtc env@WalletEnv{bootEnv = WalletBootEnv{logger, networkEnv}} walletState action = do @@ -228,7 +234,7 @@ withWalletDBVar [ walletTip , Read.GenesisPoint ] - , rollForward = rollForward w + , rollForward = rollForward w wtc , rollBackward = rollBackward w } @@ -294,10 +300,11 @@ getAllDeposits w i = rollForward :: WalletInstance + -> Tracer IO () -- wallet tip changes -> NonEmpty (Read.EraValue Read.Block) -> tip -> IO () -rollForward w blocks _nodeTip = do +rollForward w wtc blocks _nodeTip = do timeFromSlot <- slotResolver w onWalletState w $ Delta.update @@ -305,6 +312,7 @@ rollForward w blocks _nodeTip = do . Wallet.rollForwardMany timeFromSlot blocks + traceWith wtc () x <- readWalletState w x `seq` pure () diff --git a/lib/customer-deposit-wallet/test/scenario/Test/Scenario/Wallet/Deposit/Exchanges.lhs.md b/lib/customer-deposit-wallet/test/scenario/Test/Scenario/Wallet/Deposit/Exchanges.lhs.md index 080684b7079..1d22927004d 100644 --- a/lib/customer-deposit-wallet/test/scenario/Test/Scenario/Wallet/Deposit/Exchanges.lhs.md +++ b/lib/customer-deposit-wallet/test/scenario/Test/Scenario/Wallet/Deposit/Exchanges.lhs.md @@ -43,6 +43,9 @@ import Cardano.Wallet.Deposit.Read , TxId , lessOrEqual ) +import Control.Tracer + ( nullTracer + ) import Test.Scenario.Blockchain ( ScenarioEnv , ada @@ -81,7 +84,7 @@ scenarioRestore :: XPub -> WalletEnv IO -> IO () scenarioRestore xpub env = do let knownCustomerCount = 127 - Wallet.withWalletInit env (XPubCredentials xpub) knownCustomerCount $ \w -> do + Wallet.withWalletInit nullTracer env (XPubCredentials xpub) knownCustomerCount $ \w -> do value <- Wallet.availableBalance w assert $ value == ada 0 ``` @@ -92,7 +95,7 @@ In order to load the wallet state from a database file and resume operation from scenarioStart :: WalletEnv IO -> IO () scenarioStart env = - Wallet.withWalletLoad env $ \w -> do + Wallet.withWalletLoad nullTracer env $ \w -> do value <- Wallet.availableBalance w assert $ value == ada 0 ``` diff --git a/lib/customer-deposit-wallet/test/scenario/Test/Scenario/Wallet/Deposit/Run.hs b/lib/customer-deposit-wallet/test/scenario/Test/Scenario/Wallet/Deposit/Run.hs index ca440b7a038..ea0e8193178 100644 --- a/lib/customer-deposit-wallet/test/scenario/Test/Scenario/Wallet/Deposit/Run.hs +++ b/lib/customer-deposit-wallet/test/scenario/Test/Scenario/Wallet/Deposit/Run.hs @@ -18,6 +18,9 @@ import Cardano.Crypto.Wallet import Cardano.Wallet.Deposit.Pure.State.Creation ( Credentials (..) ) +import Control.Tracer + ( nullTracer + ) import Test.Hspec ( SpecWith , describe @@ -62,6 +65,7 @@ scenarios = do it "1. Assign an address to a customer ID" $ \env -> do withWalletEnvMock env $ \walletEnv -> Wallet.withWalletInit + nullTracer walletEnv (XPubCredentials $ freshXPub 1) 32 @@ -69,13 +73,15 @@ scenarios = do it "4. Create payments to a different wallet" $ \env -> do withWalletEnvMock env $ \walletEnv -> - Wallet.withWalletInit walletEnv (XPubCredentials xpub) 32 + Wallet.withWalletInit nullTracer + walletEnv (XPubCredentials xpub) 32 $ Exchanges.scenarioCreatePayment xprv env mockAddress describe "Temporary tests" $ do it "Wallet receives funds that are sent to customer address" $ \env -> do withWalletEnvMock env $ \walletEnv -> Wallet.withWalletInit + nullTracer walletEnv (XPubCredentials $ freshXPub 0) 8 diff --git a/lib/customer-deposit-wallet/test/unit/Cardano/Wallet/Deposit/RESTSpec.hs b/lib/customer-deposit-wallet/test/unit/Cardano/Wallet/Deposit/RESTSpec.hs index c8f7ee64273..76d394b15d3 100644 --- a/lib/customer-deposit-wallet/test/unit/Cardano/Wallet/Deposit/RESTSpec.hs +++ b/lib/customer-deposit-wallet/test/unit/Cardano/Wallet/Deposit/RESTSpec.hs @@ -120,7 +120,7 @@ withInitializedWallet -> WalletResourceM a -> IO (Either ErrWalletResource a) withInitializedWallet dir f = withWallet $ do - initWallet nullTracer fakeBootEnv dir credentials 0 + initWallet nullTracer nullTracer fakeBootEnv dir credentials 0 letItInitialize f @@ -129,7 +129,7 @@ withLoadedWallet -> WalletResourceM a -> IO (Either ErrWalletResource a) withLoadedWallet dir f = withWallet $ do - loadWallet fakeBootEnv dir + loadWallet nullTracer fakeBootEnv dir letItInitialize f diff --git a/lib/exe/lib/Cardano/Wallet/Application.hs b/lib/exe/lib/Cardano/Wallet/Application.hs index 7fdb3048512..7946d5adfa6 100644 --- a/lib/exe/lib/Cardano/Wallet/Application.hs +++ b/lib/exe/lib/Cardano/Wallet/Application.hs @@ -188,6 +188,7 @@ import Cardano.Wallet.UI.Common.Layer , UILayer , oobMessages , sourceOfNewTip + , walletTipChanges ) import Control.Exception.Extra ( handle @@ -208,6 +209,7 @@ import Control.Monad.Trans.Except ) import Control.Tracer ( Tracer (..) + , nullTracer , traceWith ) import Data.Function @@ -425,15 +427,16 @@ serveWallet "deposit-wallet" Just databaseDir' -> pure databaseDir' resource <- ContT withResource + ui <- Ui.withUILayer 1 resource liftIO $ loadDepositWalletFromDisk + (walletTipChanges >$< oobMessages ui) ( DepositApplicationLog >$< applicationTracer ) databaseDir' bootEnv resource - ui <- Ui.withUILayer 1 resource REST.onResourceChange ( \_ -> do traceWith (oobMessages ui) @@ -471,6 +474,7 @@ serveWallet resource <- ContT withResource liftIO $ loadDepositWalletFromDisk + nullTracer ( DepositApplicationLog >$< applicationTracer ) @@ -633,6 +637,7 @@ serveWallet application = Server.serve api $ Deposit.server + nullTracer (DepositApplicationLog >$< applicationTracer) databaseDir' bootEnv @@ -668,6 +673,7 @@ serveWallet application = Server.serve api $ DepositUi.serveUI + (walletTipChanges >$< oobMessages ui) (DepositUIApplicationLog >$< applicationTracer) ui bootEnv diff --git a/lib/ui/cardano-wallet-ui.cabal b/lib/ui/cardano-wallet-ui.cabal index fa47ce86b6c..5964b678622 100644 --- a/lib/ui/cardano-wallet-ui.cabal +++ b/lib/ui/cardano-wallet-ui.cabal @@ -94,6 +94,7 @@ library Cardano.Wallet.UI.Deposit.Server.Payments.Page Cardano.Wallet.UI.Deposit.Server.Wallet Cardano.Wallet.UI.Deposit.Types.Payments + Cardano.Wallet.UI.Deposit.Types.Wallet Cardano.Wallet.UI.Lib.Discretization Cardano.Wallet.UI.Lib.ListOf Cardano.Wallet.UI.Lib.Pagination.Map @@ -180,16 +181,16 @@ test-suite unit , cardano-crypto , cardano-wallet-read , cardano-wallet-ui - , contra-tracer , containers + , contra-tracer + , customer-deposit-wallet + , customer-deposit-wallet:rest , hspec , mtl , QuickCheck - , text , temporary + , text , time - , customer-deposit-wallet:rest - , customer-deposit-wallet:customer-deposit-wallet build-tool-depends: hspec-discover:hspec-discover type: exitcode-stdio-1.0 diff --git a/lib/ui/src/Cardano/Wallet/UI/Common/Layer.hs b/lib/ui/src/Cardano/Wallet/UI/Common/Layer.hs index e0177a95b96..b8626ce7c7e 100644 --- a/lib/ui/src/Cardano/Wallet/UI/Common/Layer.hs +++ b/lib/ui/src/Cardano/Wallet/UI/Common/Layer.hs @@ -13,6 +13,7 @@ module Cardano.Wallet.UI.Common.Layer , stateL , sseEnabled , sourceOfNewTip + , walletTipChanges ) where @@ -124,6 +125,9 @@ data SessionLayer s = SessionLayer messageOfPush :: Push -> Message messageOfPush (Push x) = Message x mempty +walletTipChanges :: () -> Push +walletTipChanges _ = Push "wallet-tip" + -- | Create a session layer giver the state and the server-sent events channel. mkSession :: TVar (State s) -> TChan Message -> SessionLayer s mkSession var sseChan = @@ -170,7 +174,12 @@ mkUILayer -> UILayer s mkUILayer throttling oobChan sessions' s0 = UILayer{..} where - oobMessages = Tracer $ atomically . writeTChan oobChan . messageOfPush + oobMessages = + Tracer + $ throttling + . atomically + . writeTChan oobChan + . messageOfPush sessions sid = do sids <- readTVarIO sessions' case Map.lookup sid sids of diff --git a/lib/ui/src/Cardano/Wallet/UI/Deposit/API.hs b/lib/ui/src/Cardano/Wallet/UI/Deposit/API.hs index 3f81be5e3b8..a93e1240e82 100644 --- a/lib/ui/src/Cardano/Wallet/UI/Deposit/API.hs +++ b/lib/ui/src/Cardano/Wallet/UI/Deposit/API.hs @@ -244,6 +244,9 @@ type Data = :<|> "payments" :> "reset" :> SessionedHtml Post + :<|> "wallet" + :> "status" + :> SessionedHtml Get type Home = SessionedHtml Get @@ -300,6 +303,7 @@ modalLink :: Maybe Text -> Maybe Text -> Link paymentsSignLink :: Link paymentsSubmitLink :: Link paymentsResetLink :: Link +walletStatusLink :: Link homePageLink :<|> aboutPageLink :<|> networkPageLink @@ -339,5 +343,6 @@ homePageLink :<|> modalLink :<|> paymentsSignLink :<|> paymentsSubmitLink - :<|> paymentsResetLink = + :<|> paymentsResetLink + :<|> walletStatusLink = allLinks (Proxy @UI) diff --git a/lib/ui/src/Cardano/Wallet/UI/Deposit/Handlers/Wallet.hs b/lib/ui/src/Cardano/Wallet/UI/Deposit/Handlers/Wallet.hs index 069db286ca8..bfc06d0a9d9 100644 --- a/lib/ui/src/Cardano/Wallet/UI/Deposit/Handlers/Wallet.hs +++ b/lib/ui/src/Cardano/Wallet/UI/Deposit/Handlers/Wallet.hs @@ -1,10 +1,16 @@ {-# LANGUAGE NamedFieldPuns #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} + +{-# HLINT ignore "Redundant <$>" #-} module Cardano.Wallet.UI.Deposit.Handlers.Wallet where import Prelude +import Cardano.Wallet.Deposit.IO.Network.Type + ( NetworkEnv (slotToUTCTime) + ) import Cardano.Wallet.Deposit.Pure ( Credentials , Customer @@ -14,9 +20,15 @@ import Cardano.Wallet.Deposit.Pure.State.Creation , credentialsFromEncodedXPub , credentialsFromMnemonics ) +import Cardano.Wallet.Deposit.Read + ( slotFromChainPoint + ) import Cardano.Wallet.Deposit.REST ( WalletResource , WalletResourceM + , availableBalance + , getWalletTip + , networkTag ) import Cardano.Wallet.Deposit.REST.Wallet.Create ( PostWalletViaMnemonic (..) @@ -33,6 +45,9 @@ import Cardano.Wallet.UI.Deposit.Handlers.Lib import Cardano.Wallet.UI.Deposit.Html.Pages.Wallet ( WalletPresent ) +import Cardano.Wallet.UI.Deposit.Types.Wallet + ( Status (..) + ) import Control.Monad.Trans ( MonadIO (..) ) @@ -46,7 +61,9 @@ getWallet :: SessionLayer WalletResource -> (WalletPresent -> html) -- success report -> Handler html -getWallet layer render = render <$> walletPresence layer +getWallet layer render = do + presence <- walletPresence layer + pure $ render presence initWalletWithXPub :: SessionLayer WalletResource @@ -116,3 +133,22 @@ deleteWalletHandler -> Handler html deleteWalletHandler layer deleteWallet alert render = catchRunWalletResourceHtml layer alert render deleteWallet + +getStatusRest :: NetworkEnv IO x -> WalletResourceM Status +getStatusRest nenv = do + tip <- getWalletTip + slotToTime <- liftIO $ slotToUTCTime nenv + Status + <$> pure tip + <*> pure (slotToTime $ slotFromChainPoint tip) + <*> availableBalance + <*> networkTag +getStatus + :: NetworkEnv IO x + -> SessionLayer WalletResource + -> (BL.ByteString -> html) + -> (Status -> html) + -> Handler html +getStatus nenv layer alert render = do + catchRunWalletResourceHtml layer alert id $ do + render <$> getStatusRest nenv diff --git a/lib/ui/src/Cardano/Wallet/UI/Deposit/Html/Common.hs b/lib/ui/src/Cardano/Wallet/UI/Deposit/Html/Common.hs index f8ae51d84a4..958ceb515fd 100644 --- a/lib/ui/src/Cardano/Wallet/UI/Deposit/Html/Common.hs +++ b/lib/ui/src/Cardano/Wallet/UI/Deposit/Html/Common.hs @@ -13,6 +13,8 @@ module Cardano.Wallet.UI.Deposit.Html.Common , valueH , lovelaceH , modalElementH + , chainPointToSlotH + , networkTagH ) where @@ -22,12 +24,14 @@ import Cardano.Wallet.Deposit.Pure.API.TxHistory ( DownTime ) import Cardano.Wallet.Deposit.Read - ( Slot + ( NetworkTag (..) + , Slot , TxId , WithOrigin (..) ) import Cardano.Wallet.Read - ( Coin (..) + ( ChainPoint (..) + , Coin (..) , SlotNo (..) , Value (..) , hashFromTxId @@ -94,6 +98,20 @@ slotH = \case Origin -> "Origin" At (SlotNo s) -> toHtml $ show s +chainPointToSlotH + :: ChainPoint + -> Html () +chainPointToSlotH cp = case cp of + GenesisPoint -> toHtml ("Genesis" :: Text) + BlockPoint (SlotNo n) _ -> toHtml $ show n + +networkTagH :: NetworkTag -> Html () +networkTagH = toHtml . showTag + +showTag :: NetworkTag -> Text +showTag MainnetTag = "Mainnet" +showTag TestnetTag = "Testnet" + txIdH :: TxId -> Html () txIdH txId = truncatableText WithCopy ("tx-id-text-" <> toText (take 16 h)) diff --git a/lib/ui/src/Cardano/Wallet/UI/Deposit/Html/Pages/Addresses/Transactions.hs b/lib/ui/src/Cardano/Wallet/UI/Deposit/Html/Pages/Addresses/Transactions.hs index 113e459d44e..7d214c273c1 100644 --- a/lib/ui/src/Cardano/Wallet/UI/Deposit/Html/Pages/Addresses/Transactions.hs +++ b/lib/ui/src/Cardano/Wallet/UI/Deposit/Html/Pages/Addresses/Transactions.hs @@ -139,7 +139,7 @@ customerHistoryH params@TransactionHistoryParams{..} txs = when txHistorySlot $ thEnd (Just 7) "Slot" when txHistoryUTC - $ thEnd (Just 9) "Time" + $ thEnd (Just 10) "Time" when txHistoryReceived $ thEnd (Just 7) "Deposit" when txHistorySpent @@ -295,7 +295,8 @@ transactionsElementH now origin = do $ do i_ [class_ "bi bi-gear"] mempty div_ $ do - div_ [class_ "d-flex justify-content-end"] + div_ + [class_ "d-flex justify-content-end"] toggle div_ [class_ "mt-1"] $ transactionsViewControls now origin diff --git a/lib/ui/src/Cardano/Wallet/UI/Deposit/Html/Pages/Wallet.hs b/lib/ui/src/Cardano/Wallet/UI/Deposit/Html/Pages/Wallet.hs index 83f3edd2bd0..b900997dd50 100644 --- a/lib/ui/src/Cardano/Wallet/UI/Deposit/Html/Pages/Wallet.hs +++ b/lib/ui/src/Cardano/Wallet/UI/Deposit/Html/Pages/Wallet.hs @@ -55,6 +55,17 @@ import Cardano.Wallet.UI.Deposit.API , walletMnemonicLink , walletPostMnemonicLink , walletPostXPubLink + , walletStatusLink + ) +import Cardano.Wallet.UI.Deposit.Html.Common + ( chainPointToSlotH + , networkTagH + , timeH + , valueH + , withOriginH + ) +import Cardano.Wallet.UI.Deposit.Types.Wallet + ( Status (..) ) import Cardano.Wallet.UI.Type ( WHtml @@ -149,20 +160,39 @@ deleteWalletModalH = "Cancel" } -walletElementH :: (BL.ByteString -> Html ()) -> WalletPresent -> Html () -walletElementH alert = \case +walletStatusH :: Status -> Html () +walletStatusH status = do + box "Status" mempty + $ record (Just 13) Full Striped + $ do + simpleField "Tip Slot" $ do + chainPointToSlotH $ tip status + simpleField "Tip Time" $ do + maybe mempty (withOriginH timeH) (tipTime status) + simpleField "Balance" $ valueH $ balance status + simpleField "Network" $ networkTagH $ network status + +walletElementH + :: (BL.ByteString -> Html ()) + -> WalletPresent + -> Html () +walletElementH alert presence = case presence of WalletPresent (WalletPublicIdentity xpub customers) -> do + div_ [class_ "row mt-2 gx-0"] + $ sseH walletStatusLink "wallet-status" ["wallet-tip"] div_ [class_ "row mt-2 gx-0"] $ do - box "Wallet Public Identity" mempty $ - record (Just 13) Full Striped $ do + box "Public Identity" mempty + $ record (Just 13) Full Striped + $ do simpleField "Extended Public Key" $ pubKeyH xpub simpleField "Tracked Addresses" $ div_ [class_ "d-flex justify-content-end align-items-center"] $ toHtml $ toText customers div_ [class_ "row mt-2 gx-0"] $ do - box "Wallet Management" mempty - $ div_ [class_ "d-flex justify-content-end align-items-center"] + box "Management" mempty + $ div_ + [class_ "d-flex justify-content-end align-items-center"] deleteWalletButtonH div_ [id_ "delete-result"] mempty WalletAbsent -> runWHtml Deposit $ do diff --git a/lib/ui/src/Cardano/Wallet/UI/Deposit/Server.hs b/lib/ui/src/Cardano/Wallet/UI/Deposit/Server.hs index 1b71e0cc86a..03e77aee736 100644 --- a/lib/ui/src/Cardano/Wallet/UI/Deposit/Server.hs +++ b/lib/ui/src/Cardano/Wallet/UI/Deposit/Server.hs @@ -18,7 +18,7 @@ import Cardano.Wallet.Api.Types ( ApiWalletMode (..) ) import Cardano.Wallet.Deposit.IO - ( WalletBootEnv + ( WalletBootEnv (networkEnv) ) import Cardano.Wallet.Deposit.REST ( WalletResource @@ -126,6 +126,7 @@ import Cardano.Wallet.UI.Deposit.Server.Wallet , servePostMnemonicWallet , servePostXPubWallet , serveWalletPage + , serveWalletStatus ) import Control.Monad.Trans ( MonadIO (..) @@ -157,7 +158,9 @@ import qualified Data.ByteString.Lazy as BL serveUI :: forall n . HasSNetworkId n - => Tracer IO String + => Tracer IO () + -- ^ Tracer for wallet tip changes + -> Tracer IO String -> UILayer WalletResource -> WalletBootEnv IO -> FilePath @@ -166,7 +169,7 @@ serveUI -> NetworkLayer IO Read.ConsensusBlock -> BlockchainSource -> Server UI -serveUI tr ul env dbDir config nid nl bs = +serveUI wtc tr ul env dbDir config nid nl bs = serveTabPage ul config Wallet :<|> serveTabPage ul config About :<|> serveTabPage ul config Network @@ -182,8 +185,8 @@ serveUI tr ul env dbDir config nid nl bs = :<|> serveFavicon :<|> serveMnemonic :<|> serveWalletPage ul - :<|> servePostMnemonicWallet tr env dbDir ul - :<|> servePostXPubWallet tr env dbDir ul + :<|> servePostMnemonicWallet wtc tr env dbDir ul + :<|> servePostXPubWallet wtc tr env dbDir ul :<|> serveDeleteWallet ul dbDir :<|> serveDeleteWalletModal ul :<|> serveGetAddress ul @@ -207,6 +210,7 @@ serveUI tr ul env dbDir config nid nl bs = :<|> servePaymentsSign ul :<|> servePaymentsSubmit ul :<|> servePaymentsReset ul + :<|> serveWalletStatus (networkEnv env) ul serveModal :: UILayer WalletResource diff --git a/lib/ui/src/Cardano/Wallet/UI/Deposit/Server/Wallet.hs b/lib/ui/src/Cardano/Wallet/UI/Deposit/Server/Wallet.hs index 4c8d863b4e3..1bf72a71888 100644 --- a/lib/ui/src/Cardano/Wallet/UI/Deposit/Server/Wallet.hs +++ b/lib/ui/src/Cardano/Wallet/UI/Deposit/Server/Wallet.hs @@ -13,11 +13,18 @@ import Prelude import Cardano.Wallet.Deposit.IO ( WalletBootEnv ) +import Cardano.Wallet.Deposit.IO.Network.Type + ( NetworkEnv + ) import Cardano.Wallet.Deposit.REST ( WalletResource , deleteWallet , initWallet ) +import Cardano.Wallet.Deposit.REST.Wallet.Create + ( PostWalletViaMnemonic + , PostWalletViaXPub + ) import Cardano.Wallet.UI.Common.Handlers.Session ( withSessionLayer ) @@ -45,6 +52,7 @@ import Cardano.Wallet.UI.Cookies ) import Cardano.Wallet.UI.Deposit.Handlers.Wallet ( deleteWalletHandler + , getStatus , getWallet , postMnemonicWallet , postXPubWallet @@ -52,6 +60,7 @@ import Cardano.Wallet.UI.Deposit.Handlers.Wallet import Cardano.Wallet.UI.Deposit.Html.Pages.Wallet ( deleteWalletModalH , walletElementH + , walletStatusH ) import Cardano.Wallet.UI.Deposit.Server.Lib ( alert @@ -70,11 +79,6 @@ import Servant ( Handler ) -import Cardano.Wallet.Deposit.REST.Wallet.Create - ( PostWalletViaMnemonic - , PostWalletViaXPub - ) - serveMnemonic :: Maybe Bool -> Maybe RequestCookies @@ -89,37 +93,42 @@ serveWalletPage -> Maybe RequestCookies -> Handler (CookieResponse RawHtml) serveWalletPage ul = withSessionLayer ul $ \layer -> do - getWallet layer (renderSmoothHtml . walletElementH alertH) + getWallet layer $ \presence -> + renderSmoothHtml $ walletElementH alertH presence servePostMnemonicWallet - :: Tracer IO String + :: Tracer IO () + -- ^ Tracer for wallet tip changes + -> Tracer IO String -> WalletBootEnv IO -> FilePath -> UILayer WalletResource -> PostWalletViaMnemonic -> Maybe RequestCookies -> Handler (CookieResponse RawHtml) -servePostMnemonicWallet tr env dbDir ul request = +servePostMnemonicWallet wtc tr env dbDir ul request = withSessionLayer ul $ \layer -> do postMnemonicWallet layer initWallet' alert ok request where ok _ = renderHtml . rogerH @Text $ "ok" - initWallet' = initWallet tr env dbDir + initWallet' = initWallet wtc tr env dbDir servePostXPubWallet - :: Tracer IO String + :: Tracer IO () + -- ^ Tracer for wallet tip changes + -> Tracer IO String -> WalletBootEnv IO -> FilePath -> UILayer WalletResource -> PostWalletViaXPub -> Maybe RequestCookies -> Handler (CookieResponse RawHtml) -servePostXPubWallet tr env dbDir ul request = +servePostXPubWallet wtc tr env dbDir ul request = withSessionLayer ul $ \layer -> do postXPubWallet layer initWallet' alert ok request where ok _ = renderHtml . rogerH @Text $ "ok" - initWallet' = initWallet tr env dbDir + initWallet' = initWallet wtc tr env dbDir serveDeleteWallet :: UILayer WalletResource @@ -137,3 +146,11 @@ serveDeleteWalletModal -> Handler (CookieResponse RawHtml) serveDeleteWalletModal ul = withSessionLayer ul $ \_ -> pure $ renderSmoothHtml deleteWalletModalH + +serveWalletStatus + :: NetworkEnv IO x + -> UILayer WalletResource + -> Maybe RequestCookies + -> Handler (CookieResponse RawHtml) +serveWalletStatus nenv ul = withSessionLayer ul $ \l -> + renderHtml <$> getStatus nenv l alertH walletStatusH diff --git a/lib/ui/src/Cardano/Wallet/UI/Deposit/Types/Wallet.hs b/lib/ui/src/Cardano/Wallet/UI/Deposit/Types/Wallet.hs new file mode 100644 index 00000000000..f15c2db9980 --- /dev/null +++ b/lib/ui/src/Cardano/Wallet/UI/Deposit/Types/Wallet.hs @@ -0,0 +1,23 @@ +module Cardano.Wallet.UI.Deposit.Types.Wallet + ( Status (..) + ) +where + +import Prelude + +import Cardano.Wallet.Deposit.Read + ( ChainPoint + , NetworkTag + , Value + , WithOrigin + ) +import Data.Time + ( UTCTime + ) + +data Status = Status + { tip :: ChainPoint + , tipTime :: Maybe (WithOrigin UTCTime) + , balance :: Value + , network :: NetworkTag + } diff --git a/lib/ui/test/unit/Cardano/Wallet/UI/Deposit/Html/Pages/Payments/PageSpec.hs b/lib/ui/test/unit/Cardano/Wallet/UI/Deposit/Html/Pages/Payments/PageSpec.hs index 16f8aea1398..7067cadb6cd 100644 --- a/lib/ui/test/unit/Cardano/Wallet/UI/Deposit/Html/Pages/Payments/PageSpec.hs +++ b/lib/ui/test/unit/Cardano/Wallet/UI/Deposit/Html/Pages/Payments/PageSpec.hs @@ -119,7 +119,7 @@ withInitializedWallet f = withSystemTempDirectory "wallet-ui" $ \dir -> do bootEnv <- fakeBootEnv withWallet $ do - initWallet nullTracer bootEnv dir credentials 1 + initWallet nullTracer nullTracer bootEnv dir credentials 1 letItInitialize fundTheWallet (networkEnv bootEnv) f