View on GitHub
File Changes
    , MnemonicWordsError(..)
    , ValidEntropySize
    , ValidChecksumSize
+
    , ValidMnemonicSentence
    , ConsistentEntropy
    , CheckSumBits
    , EntropySize
    , unsafeRunExceptT
    , unsafeXPrv
    , unsafeMkMnemonic
+
    , unsafeMkEntropy
+
    , unsafeSomeMnemonicFromEntropy
    , unsafeDeserialiseCbor
    , unsafeBech32DecodeFile
    , unsafeBech32Decode
    ( XPrv )
import Cardano.Wallet.Api.Types
    ( DecodeAddress (..) )
+
import Cardano.Wallet.Primitive.AddressDerivation
+
    ( SomeMnemonic (..) )
import Cardano.Wallet.Primitive.Mnemonic
-
    ( ConsistentEntropy, EntropySize, Mnemonic, mkMnemonic )
+
    ( ConsistentEntropy
+
    , Entropy
+
    , EntropySize
+
    , Mnemonic
+
    , MnemonicWords
+
    , ValidChecksumSize
+
    , ValidEntropySize
+
    , ValidMnemonicSentence
+
    , entropyToMnemonic
+
    , mkEntropy
+
    , mkMnemonic
+
    )
import Cardano.Wallet.Primitive.Types
    ( Address )
import Control.Monad
    ( ByteString )
import Data.Char
    ( isHexDigit )
+
import Data.Proxy
+
    ( Proxy )
import Data.Text
    ( Text )
import Data.Text.Class
    snd
    (CBOR.deserialiseFromBytes decoder bytes)

                      
+
unsafeMkEntropy
+
    :: forall ent csz.
+
        ( HasCallStack
+
        , ValidEntropySize ent
+
        , ValidChecksumSize ent csz
+
        )
+
    => ByteString
+
    -> Entropy ent
+
unsafeMkEntropy = either (error . show) id . mkEntropy
+

                      
+
unsafeSomeMnemonicFromEntropy
+
    :: forall mw ent csz.
+
        ( HasCallStack
+
        , ValidEntropySize ent
+
        , ValidChecksumSize ent csz
+
        , ValidMnemonicSentence mw
+
        , ent ~ EntropySize mw
+
        , mw ~ MnemonicWords ent
+
        )
+
    => Proxy mw
+
    -> ByteString
+
    -> SomeMnemonic
+
unsafeSomeMnemonicFromEntropy _ = SomeMnemonic
+
    . entropyToMnemonic
+
    . unsafeMkEntropy @ent
+

                      
-- | Load the data part of a bech32-encoded string from file. These files often
-- come from @[email protected] Only the first line of the file is read.
unsafeBech32DecodeFile :: HasCallStack => FilePath -> IO BL.ByteString
    , mkSeqState
    )
import Cardano.Wallet.Primitive.Mnemonic
-
    ( EntropySize, entropyToMnemonic, genEntropy, mkEntropy )
+
    ( EntropySize, entropyToMnemonic, genEntropy )
import Cardano.Wallet.Primitive.Model
    ( Wallet, initWallet, unsafeInitWallet )
import Cardano.Wallet.Primitive.Types
    , fromFlatSlot
    )
import Cardano.Wallet.Unsafe
-
    ( unsafeRunExceptT )
+
    ( unsafeRunExceptT, unsafeSomeMnemonicFromEntropy )
import Control.DeepSeq
    ( NFData (..), force )
import Control.Exception
    ( ByteString )
import Data.Functor
    ( ($>) )
+
import Data.Proxy
+
    ( Proxy (..) )
import Data.Quantity
    ( Quantity (..) )
import Data.Time.Clock.System
initDummyState =
    mkSeqState (xprv, mempty) defaultAddressPoolGap
  where
-
    mnemonic = unsafePerformIO $
-
        SomeMnemonic
-
        . entropyToMnemonic @15
+
    mnemonic = unsafePerformIO
+
        $ SomeMnemonic . entropyToMnemonic @15
        <$> genEntropy @(EntropySize 15)
    xprv = generateKeyFromSeed (mnemonic, Nothing) mempty

                      
ourAccount :: ShelleyKey 'AccountK XPub
ourAccount = publicKey $ unsafeGenerateKeyFromSeed (seed, Nothing) mempty
  where
-
    seed = SomeMnemonic $ entropyToMnemonic @15 ent
-
    ent = either (error . show) id $ mkEntropy $ BS.replicate 32 0
+
    seed = unsafeSomeMnemonicFromEntropy (Proxy @15) (BS.replicate 32 0)

                      
rewardAccount :: ShelleyKey 'AddressK XPub
rewardAccount = publicKey $ unsafeGenerateKeyFromSeed (seed, Nothing) mempty
  where
-
    seed = SomeMnemonic $ entropyToMnemonic @15 ent
-
    ent = either (error . show) id $ mkEntropy $ BS.replicate 32 0
+
    seed = unsafeSomeMnemonicFromEntropy (Proxy @15) (BS.replicate 32 0)

                      
-- | Make a prefixed bytestring for use as a Hash or Address.
label :: Show n => String -> n -> B8.ByteString
    , arbitrarySizedBoundedIntegral
    , choose
    , elements
+
    , frequency
    , generate
    , genericShrink
    , liftArbitrary
  where
    genRootKeysSeq :: Gen (ShelleyKey 'RootK XPrv)
    genRootKeysSeq = do
-
        (s, g, e) <- (,,)
-
            <$> (SomeMnemonic <$> genMnemonic @12)
-
            <*> (SomeMnemonic <$> genMnemonic @12)
-
            <*> genPassphrase @"encryption" (0, 16)
-
        return $ Seq.generateKeyFromSeed (s, Just g) e
+
        s <- (SomeMnemonic <$> genMnemonic @12)
+
        g <- frequency
+
                [ (1, return Nothing)
+
                , (3, Just . SomeMnemonic <$> genMnemonic @12)
+
                ]
+
        e <- genPassphrase @"encryption" (0, 16)
+
        return $ Seq.generateKeyFromSeed (s, g) e
{-# NOINLINE rootKeysSeq #-}

                      
arbitrarySeqAccount
    ( ConsistentEntropy, EntropySize, mkMnemonic )
import Cardano.Wallet.Primitive.Types
    ( Address )
+
import Cardano.Wallet.Unsafe
+
    ( unsafeSomeMnemonicFromEntropy )
import Control.Monad
    ( forM_ )
+
import Data.Proxy
+
    ( Proxy (..) )
import Data.Text
    ( Text )
import Test.Hspec
spec :: Spec
spec = do
    describe "Golden Tests - Icarus' style addresses" $ do
+
        let seed0 = unsafeSomeMnemonicFromEntropy (Proxy @15)
+
                "4\175\242L\184\243\191 \169]\171 \207\r\v\233\NUL~&\ETB"
+

                      
+
        goldenAddressGeneration $ GoldenAddressGeneration
+
            seed0 (toEnum 0x80000000) UTxOExternal (toEnum 0x00000000)
+
            "Ae2tdPwUPEZGQVrA6qKreDzdtYxcWMMrpTFYCpFcuJfhJBEfoeiuW4MtaXZ"
+

                      
+
        goldenAddressGeneration $ GoldenAddressGeneration
+
            seed0 (toEnum 0x80000000) UTxOExternal (toEnum 0x0000000E)
+
            "Ae2tdPwUPEZDLWQQEBR1UW7HeXJVaqUnuw8DUFu52TDWCJbxbkCyQYyxckP"
+

                      
+
        goldenAddressGeneration $ GoldenAddressGeneration
+
            seed0 (toEnum 0x8000000E) UTxOInternal (toEnum 0x0000002A)
+
            "Ae2tdPwUPEZFRbyhz3cpfC2CumGzNkFBN2L42rcUc2yjQpEkxDbkPodpMAi"
        let (Right seed1) = fromMnemonic @'[12]
              [ "ghost", "buddy", "neutral", "broccoli", "face", "rack"
              , "relief", "odor", "swallow", "real", "once", "ecology"
    , shrinkPool
    )
import Cardano.Wallet.Primitive.Mnemonic
-
    ( entropyToMnemonic, mkEntropy )
+
    ( entropyToMnemonic )
import Cardano.Wallet.Primitive.Types
    ( Address (..), ShowFmt (..) )
+
import Cardano.Wallet.Unsafe
+
    ( unsafeMkEntropy, unsafeSomeMnemonicFromEntropy )
import Control.Monad
    ( forM, forM_, unless )
import Control.Monad.IO.Class
prop_genChangeGap g =
    property prop
  where
-
    Right mw = SomeMnemonic . entropyToMnemonic @12 <$> mkEntropy "0000000000000000"
+
    mw = SomeMnemonic
+
        $ entropyToMnemonic @12
+
        $ unsafeMkEntropy "0000000000000000"
    key = Shelley.unsafeGenerateKeyFromSeed (mw, Nothing) mempty
    s0 = mkSeqState (key, mempty) g
    prop =
prop_lookupDiscovered (s0, addr) =
    let (ours, s) = isOurs addr s0 in ours ==> prop s
  where
-
    Right mw = SomeMnemonic . entropyToMnemonic @12 <$> mkEntropy "0000000000000000"
+
    mw = unsafeSomeMnemonicFromEntropy (Proxy @12) "0000000000000000"
    key = Shelley.unsafeGenerateKeyFromSeed (mw, Nothing) mempty
    prop s = monadicIO $ liftIO $ do
        unless (isJust $ isOwned s (key, mempty) addr) $ do
instance Show Key where show (Key proxy) = show (typeRep proxy)

                      
dummyMnemonic :: SomeMnemonic
-
dummyMnemonic = either (error . show) id $
-
    SomeMnemonic . entropyToMnemonic @12 <$> mkEntropy (BS.pack $ replicate 16 0)
+
dummyMnemonic =
+
    unsafeSomeMnemonicFromEntropy (Proxy @12) (BS.pack $ replicate 16 0)
import Prelude

                      
import Cardano.Wallet.Primitive.AddressDerivation
-
    ( Depth (..), SomeMnemonic (..), WalletKey (..), XPrv, digest, publicKey )
+
    ( Depth (..), WalletKey (..), XPrv, digest, publicKey )
import Cardano.Wallet.Primitive.AddressDerivation.Shelley
    ( ShelleyKey (..), generateKeyFromSeed )
-
import Cardano.Wallet.Primitive.Mnemonic
-
    ( entropyToMnemonic, mkEntropy )
import Cardano.Wallet.Primitive.Types
    ( ActiveSlotCoefficient (..)
    , Address (..)
    , wholeRange
    )
import Cardano.Wallet.Unsafe
-
    ( unsafeFromHex )
+
    ( unsafeFromHex, unsafeSomeMnemonicFromEntropy )
import Control.DeepSeq
    ( deepseq )
import Control.Exception

                      
    describe "Buildable" $ do
        it "WalletId" $ do
-
            let mw = either (error . show) id
-
                    $ SomeMnemonic
-
                    . entropyToMnemonic @12
-
                    <$> mkEntropy "0000000000000000"
+
            let mw = unsafeSomeMnemonicFromEntropy (Proxy @12)
+
                    "0000000000000000"
            let xprv = generateKeyFromSeed
                    (mw, Nothing) mempty :: ShelleyKey 'RootK XPrv
            let wid = WalletId $ digest $ publicKey xprv
    , NetworkDiscriminantVal
    , Passphrase (..)
    , PaymentAddress (..)
-
    , SomeMnemonic (..)
    , XPrv
    , networkDiscriminantVal
    , paymentAddress
    ( ShelleyKey )
import Cardano.Wallet.Primitive.CoinSelection
    ( CoinSelection (..) )
-
import Cardano.Wallet.Primitive.Mnemonic
-
    ( EntropySize, entropyToMnemonic, mkEntropy )
import Cardano.Wallet.Primitive.Types
    ( Address (..)
    , Coin (..)
import Cardano.Wallet.Transaction
    ( ErrMkTx (..), TransactionLayer (..) )
import Cardano.Wallet.Unsafe
-
    ( unsafeFromHex )
+
    ( unsafeFromHex, unsafeSomeMnemonicFromEntropy )
import Data.ByteArray.Encoding
    ( Base (Base16), convertToBase )
import Data.ByteString
    )
  where
    pwd = mempty
-
    seed = SomeMnemonic $ entropyToMnemonic @12 ent
-
    ent = either (error . show) id $ mkEntropy @(EntropySize 12) bytes
+
    seed = unsafeSomeMnemonicFromEntropy (Proxy @12) bytes

                      
xprvRndFromSeed
    :: ByteString
  where
    pwd = mempty
    derPath = (minBound, minBound)
-
    seed = SomeMnemonic $ entropyToMnemonic ent
-
    ent = either (error . show) id $ mkEntropy @(EntropySize 12) bytes
+
    seed = unsafeSomeMnemonicFromEntropy (Proxy @12) bytes

                      
mkKeystore :: Ord k => [(k,v)] -> (k -> Maybe v)
mkKeystore pairs k =