diff --git a/cardano-wallet.cabal b/cardano-wallet.cabal index 7c18bea6703..b6250bc5080 100644 --- a/cardano-wallet.cabal +++ b/cardano-wallet.cabal @@ -66,9 +66,10 @@ executable cardano-wallet-launcher build-depends: base , cardano-wallet-cli - , cardano-wallet-http-bridge , cardano-wallet-launcher + , directory , docopt + , filepath , fmt , process , say diff --git a/exe/launcher/Main.hs b/exe/launcher/Main.hs index 914e0037cc1..554b9d347f3 100644 --- a/exe/launcher/Main.hs +++ b/exe/launcher/Main.hs @@ -1,4 +1,5 @@ {-# LANGUAGE DataKinds #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE QuasiQuotes #-} module Main where @@ -14,12 +15,12 @@ import Cardano.Launcher , installSignalHandlers , launch ) -import Cardano.Wallet.HttpBridge.Environment - ( Network ) import Control.Concurrent ( threadDelay ) import Control.Monad ( when ) +import Data.Maybe + ( fromMaybe ) import Data.Text.Class ( FromText (..), ToText (..) ) import Data.Version @@ -29,21 +30,26 @@ import Fmt import Paths_cardano_wallet ( version ) import Say - ( sayErr ) + ( sayErr, sayString ) import System.Console.Docopt ( Arguments , Docopt , Option , docopt + , getArg , isPresent , longOption , parseArgsOrExit , shortOption ) +import System.Directory + ( createDirectory, doesDirectoryExist ) import System.Environment ( getArgs ) import System.Exit ( exitSuccess, exitWith ) +import System.FilePath + ( () ) import qualified Data.Text as T @@ -66,9 +72,10 @@ Usage: cardano-wallet-launcher --version Options: - --network testnet, staging, or mainnet [default: testnet] + --network testnet, staging, mainnet, or local [default: testnet] --wallet-server-port port used for serving the wallet API [default: 8090] --http-bridge-port port used for communicating with the http-bridge [default: 8080] + --state-dir write wallet state (blockchain and database) to this directory |] main :: IO () @@ -80,15 +87,17 @@ main = do putStrLn (showVersion version) exitSuccess - network <- args `parseArg` longOption "network" + let stateDir = args `getArg` (longOption "state-dir") + let network = fromMaybe "testnet" $ args `getArg` (longOption "network") bridgePort <- args `parseArg` longOption "http-bridge-port" walletPort <- args `parseArg` longOption "wallet-server-port" sayErr "Starting..." installSignalHandlers + maybe (pure ()) setupStateDir stateDir let commands = - [ nodeHttpBridgeOn bridgePort network - , walletOn walletPort bridgePort + [ nodeHttpBridgeOn stateDir bridgePort network + , walletOn stateDir walletPort bridgePort network ] sayErr $ fmt $ blockListF commands (ProcessHasExited name code) <- launch commands @@ -98,24 +107,33 @@ main = do parseArg :: FromText a => Arguments -> Option -> IO a parseArg = parseArgWith cli -nodeHttpBridgeOn :: Port "Node" -> Network -> Command -nodeHttpBridgeOn port net = Command - "cardano-http-bridge" - [ "start" - , "--port", T.unpack (toText port) - , "--template", T.unpack (toText net) - ] - (return ()) - Inherit - -walletOn :: Port "Wallet" -> Port "Node" -> Command -walletOn wp np = Command - "cardano-wallet" - [ "server" - , "--port", T.unpack (toText wp) - , "--bridge-port", T.unpack (toText np) - ] - (threadDelay oneSecond) - Inherit +nodeHttpBridgeOn :: Maybe FilePath -> Port "Node" -> String -> Command +nodeHttpBridgeOn stateDir port net = + Command "cardano-http-bridge" args (return ()) Inherit where + args = + [ "start" + , "--port", T.unpack (toText port) + , "--template", net + ] ++ networkArg + networkArg = maybe [] (\d -> ["--networks-dir", d]) stateDir + +walletOn :: Maybe FilePath -> Port "Wallet" -> Port "Node" -> String -> Command +walletOn stateDir wp np net = + Command "cardano-wallet" args (threadDelay oneSecond) Inherit + where + args = + [ "server" + , "--network", if net == "local" then "testnet" else net + , "--port", T.unpack (toText wp) + , "--bridge-port", T.unpack (toText np) + ] ++ dbArg + dbArg = maybe [] (\d -> ["--database", d "wallet.db"]) stateDir oneSecond = 1000000 + +setupStateDir :: FilePath -> IO () +setupStateDir dir = doesDirectoryExist dir >>= \case + True -> sayString $ "Using state directory: " ++ dir + False -> do + sayString $ "Creating state directory: " ++ dir + createDirectory dir diff --git a/exe/wallet/Main.hs b/exe/wallet/Main.hs index afd0b6066d4..5b14e32a585 100644 --- a/exe/wallet/Main.hs +++ b/exe/wallet/Main.hs @@ -97,6 +97,7 @@ import System.Console.Docopt , command , docopt , exitWithUsage + , getArg , isPresent , longOption , parseArgsOrExit @@ -110,7 +111,7 @@ import System.IO ( BufferMode (NoBuffering), hSetBuffering, stderr, stdout ) import qualified Cardano.Wallet.Api.Server as Server -import qualified Cardano.Wallet.DB.MVar as MVar +import qualified Cardano.Wallet.DB.Sqlite as Sqlite import qualified Cardano.Wallet.HttpBridge.Network as HttpBridge import qualified Cardano.Wallet.HttpBridge.Transaction as HttpBridge import qualified Data.Aeson as Aeson @@ -135,7 +136,7 @@ and can be run "offline". (e.g. 'generate mnemonic') ⚠️ Options are positional (--a --b is not equivalent to --b --a) ! ⚠️ Usage: - cardano-wallet server [--network=STRING] [--port=INT] [--bridge-port=INT] + cardano-wallet server [--network=STRING] [--port=INT] [--bridge-port=INT] [--database=FILE] cardano-wallet mnemonic generate [--size=INT] cardano-wallet wallet list [--port=INT] cardano-wallet wallet create [--port=INT] [--address-pool-gap=INT] @@ -154,6 +155,7 @@ Options: --size number of mnemonic words to generate [default: 15] --payment address to send to and amount to send separated by @: '@
' --network testnet, staging, or mainnet [default: testnet] + --database use this file for storing wallet state Examples: # Create a transaction and send 22 lovelace from wallet-id to specified address @@ -339,7 +341,8 @@ execHttpBridge args _ = do <- args `parseArg` longOption "port" (bridgePort :: Int) <- args `parseArg` longOption "bridge-port" - db <- MVar.newDBLayer + let dbFile = args `getArg` longOption "database" + (_, db) <- Sqlite.newDBLayer dbFile nw <- HttpBridge.newNetworkLayer @n bridgePort waitForConnection nw defaultRetryPolicy let tl = HttpBridge.newTransactionLayer @n