module Main where
import Control.Applicative (optional, (<**>))
import Control.Monad ((>=>))
import Data.ByteString.Char8 (unpack)
import Data.List (isPrefixOf, sort)
import Data.Maybe (listToMaybe, mapMaybe)
import Options.Applicative (
ParserInfo,
execParser,
help,
helper,
info,
long,
progDesc,
short,
strOption,
)
import Servant.API (BasicAuthData (..))
import System.Process (readProcess)
import Bitcoin.Core.Regtest (
NodeHandle,
nodeAuth,
nodePort,
withBitcoind,
)
opts :: ParserInfo (Maybe FilePath)
opts = info (outputOpt <**> helper) $ progDesc "Create a representation of the bitcoind rpc command set"
where
outputOpt =
optional . strOption $
short 'o' <> long "output" <> help "Omitting this argument outputs to stdout"
main :: IO ()
main = do
outputFile <- execParser opts
mapM_ (`writeFile` mempty) outputFile
let writeOutput = maybe putStrLn appendFile outputFile
withBitcoind 8330 $ \h -> do
rpcCommands <- parseHelpText <$> bitcoinCli h ["help"]
writeOutput $ unlines rpcCommands
mapM_ (getHelpText h >=> writeOutput) rpcCommands
where
getHelpText h c = bitcoinCli h ["help", c]
-- | Compute the sorted list of available RPC commands
parseHelpText :: String -> [String]
parseHelpText = sort . mapMaybe (listToMaybe . words) . filter isRpc . lines
where
isRpc = not . isPrefixOf "="
bitcoinCli :: NodeHandle -> [String] -> IO String
bitcoinCli h args =
readProcess "bitcoin-cli" (setupArgs <> args) mempty
where
setupArgs =
[ "-rpcport=" <> show (nodePort h)
, "-rpcuser=" <> (unpack . basicAuthUsername . nodeAuth) h
, "-rpcpassword=" <> (unpack . basicAuthPassword . nodeAuth) h
]