cardano-addresses-4.0.0: test/Command/Key/FromRecoveryPhraseSpec.hs
{-# LANGUAGE FlexibleContexts #-}
module Command.Key.FromRecoveryPhraseSpec
( spec
) where
import Prelude
import System.IO.Temp
( withSystemTempDirectory, writeTempFile )
import Test.Hspec
( Spec, SpecWith, it, shouldBe, shouldContain )
import Test.Utils
( cli, describeCmd )
spec :: Spec
spec = describeCmd [ "key", "from-recovery-phrase" ] $ do
specGolden "byron" defaultPhrase
"root_xsk1vzdkjk8txce80dwm5upjddrawv9l8mq2jyv6qqx2ylzu0yua8age295\
\s38lj9gune65g07w95ttlt5qq3qh67nx4euvj2cut7z6pente84au2qmjqqy8w9x\
\58z6f722j5twq860nhhmlq347wf0yp6wdkvq80h42"
specGolden "icarus" defaultPhrase
"root_xsk1qz497hekfxq0ftrzjh7sl0m9vseep44mrnmk2dkzawczwy7ghfgd3yp\
\maem5k7lcv782p4haa4kcwmdnks4776rkgrx9zn4h8am82dagca203x7fejp4x04\
\ty47he9rztj2lp46fwyzz3ad2yszwadjfnv76n80u"
specGolden "shelley" defaultPhrase
"root_xsk1qz497hekfxq0ftrzjh7sl0m9vseep44mrnmk2dkzawczwy7ghfgd3yp\
\maem5k7lcv782p4haa4kcwmdnks4776rkgrx9zn4h8am82dagca203x7fejp4x04\
\ty47he9rztj2lp46fwyzz3ad2yszwadjfnv76n80u"
specGolden "shared" defaultPhrase
"root_shared_xsk1qz497hekfxq0ftrzjh7sl0m9vseep44mrnmk2dkzawczwy7gh\
\fgd3ypmaem5k7lcv782p4haa4kcwmdnks4776rkgrx9zn4h8am82dagca203x7fej\
\p4x04ty47he9rztj2lp46fwyzz3ad2yszwadjfnvuedzh4"
specGoldenWithMnemonicPassphrase "shelley" defaultPhrase "from-mnemonic"
(unwords sndFactorPhrase) rootXPrvWithPassphrase
specGoldenWithMnemonicPassphrase "shelley" defaultPhrase "from-hex"
sndFactorPhraseHex rootXPrvWithPassphrase
specGoldenWithMnemonicPassphrase "shelley" defaultPhrase "from-base64"
sndFactorPhraseBase64 rootXPrvWithPassphrase
specGoldenWithMnemonicPassphrase "shelley" defaultPhrase "from-octets"
sndFactorPhraseOctets rootXPrvWithPassphrase
specGoldenWithMnemonicPassphrase "icarus" defaultPhrase "from-mnemonic"
(unwords sndFactorPhrase) rootXPrvWithPassphrase
specGoldenWithMnemonicPassphrase "icarus" defaultPhrase "from-hex"
sndFactorPhraseHex rootXPrvWithPassphrase
specGoldenWithMnemonicPassphrase "icarus" defaultPhrase "from-base64"
sndFactorPhraseBase64 rootXPrvWithPassphrase
specGoldenWithMnemonicPassphrase "icarus" defaultPhrase "from-octets"
sndFactorPhraseOctets rootXPrvWithPassphrase
specGoldenWithMnemonicPassphrase "shared" defaultPhrase "from-mnemonic"
(unwords sndFactorPhrase) rootXPrvSharedWithPassphrase
specGoldenWithMnemonicPassphrase "shared" defaultPhrase "from-hex"
sndFactorPhraseHex rootXPrvSharedWithPassphrase
specGoldenWithMnemonicPassphrase "shared" defaultPhrase "from-base64"
sndFactorPhraseBase64 rootXPrvSharedWithPassphrase
specGoldenWithMnemonicPassphrase "shared" defaultPhrase "from-octets"
sndFactorPhraseOctets rootXPrvSharedWithPassphrase
specInvalidStyle "patate" defaultPhrase
specInvalidStyle "💩" defaultPhrase
specInvalidPhrase "shelley" invalidPhrase
specGolden :: String -> [String] -> String -> SpecWith ()
specGolden style phrase want = it ("golden " <> style) $ do
out <- cli [ "key", "from-recovery-phrase", style ] (unwords phrase)
out `shouldBe` want
specInvalidStyle :: String -> [String] -> SpecWith ()
specInvalidStyle style phrase = it ("invalid style " <> style) $ do
(out, err) <- cli [ "key", "from-recovery-phrase", style ] (unwords phrase)
out `shouldBe` ""
err `shouldContain` "Unknown style; expecting one of"
err `shouldContain` "Usage:"
specInvalidPhrase :: String -> [String] -> SpecWith ()
specInvalidPhrase style phrase = it ("invalid phrase " <> unwords phrase) $ do
(out, err) <- cli [ "key", "from-recovery-phrase", style ] (unwords phrase)
out `shouldBe` ""
err `shouldContain` "Found an unknown word not present in the pre-defined dictionary."
specGoldenWithMnemonicPassphrase
:: String
-> [String]
-> String
-> String
-> String
-> SpecWith ()
specGoldenWithMnemonicPassphrase style phrase method sndfactor want =
it ("golden " <> style <> " from-file "<> method) $
withSystemTempDirectory "tmpdir" $ \dir -> do
filepath <- writeTempFile dir "passphrase" sndfactor
out <- cli [ "key", "from-recovery-phrase", style, "--passphrase"
, method, "--from-file", filepath] (unwords phrase)
out `shouldBe` want
defaultPhrase :: [String]
defaultPhrase =
[ "message", "mask", "aunt", "wheel", "ten"
, "maze", "between", "tomato", "slow", "analyst"
, "ladder", "such", "report", "capital", "produce"
]
invalidPhrase :: [String]
invalidPhrase =
replicate 9 "¯\\_(ツ)_/¯"
sndFactorPhrase :: [String]
sndFactorPhrase =
[ "test", "child", "burst", "immense", "armed"
, "parrot", "company", "walk", "dog"
]
--λ> let (Right m9) = mkSomeMnemonic @'[ 9, 12, 15 ] [ "test", "child", "burst", "immense", "armed", "parrot", "company", "walk", "dog" ]
--Right (SomeMnemonic (Mnemonic {mnemonicToEntropy = Entropy {entropyRaw = "\223\132\252{8\192\189@\203\167\180@", entropyChecksum = Checksum 4}, mnemonicToSentence = MnemonicSentence {mnemonicSentenceToListN = [WordIndex {unWordIndex = Offset 1788},WordIndex {unWordIndex = Offset 319},WordIndex {unWordIndex = Offset 246},WordIndex {unWordIndex = Offset 908},WordIndex {unWordIndex = Offset 94},WordIndex {unWordIndex = Offset 1283},WordIndex {unWordIndex = Offset 372},WordIndex {unWordIndex = Offset 1972},WordIndex {unWordIndex = Offset 516}]}}))
--λ> import qualified Data.ByteString as BS
--λ> import qualified Data.ByteArray as BA
--λ> let bytes = BA.convert $ someMnemonicToBytes m9 :: BS.ByteString
--λ> bytes
--"\223\132\252{8\192\189@\203\167\180@"
--λ> encode EBase16 bytes
--"df84fc7b38c0bd40cba7b440"
--λ> import qualified Data.Text.Encoding as T
--λ> import qualified Data.ByteArray.Encoding as BA
--λ> T.decodeUtf8 $ BA.convertToBase BA.Base64 bytes
--"34T8ezjAvUDLp7RA"
--λ> BS.unpack bytes
-- [223,132,252,123,56,192,189,64,203,167,180,64]
sndFactorPhraseHex :: String
sndFactorPhraseHex = "df84fc7b38c0bd40cba7b440"
sndFactorPhraseBase64 :: String
sndFactorPhraseBase64 = "34T8ezjAvUDLp7RA"
sndFactorPhraseOctets :: String
sndFactorPhraseOctets = "[223,132,252,123,56,192,189,64,203,167,180,64]"
rootXPrvWithPassphrase :: String
rootXPrvWithPassphrase =
"root_xsk1xpk2wzz7xsyhfxxvwraxnq2sps45ygfayrmn8kxjep4gl9jxgfg3tffp7z7w7ltd0\
\gw32wqhyk5c296u7m28l688n8n6v24hrp326kgzz6cgvkvvj2k0t34jkv6ze0d8vxxnavar4tz\
\gl96th9qhfayllsl4qsqq"
rootXPrvSharedWithPassphrase :: String
rootXPrvSharedWithPassphrase =
"root_shared_xsk1xpk2wzz7xsyhfxxvwraxnq2sps45ygfayrmn8kxjep4gl9jxgfg3tffp7z\
\7w7ltd0gw32wqhyk5c296u7m28l688n8n6v24hrp326kgzz6cgvkvvj2k0t34jkv6ze0d8vxxn\
\avar4tzgl96th9qhfayllsak74cf"