packages feed

bitcoin-address-0.1: lib/Bitcoin/Address/Settings.hs

{-# LANGUAGE StrictData #-}
{-# OPTIONS_HADDOCK prune #-}

-- | This module exports settings for different Bitcoin networks.
module Bitcoin.Address.Settings
  ( -- * Settings
    Settings(..)
    -- ** PrefixP2PKH
  , PrefixP2PKH(..)
    -- ** PrefixP2SH
  , PrefixP2SH(..)
    -- ** PrefixSegWit
  , PrefixSegWit
  , prefixSegWit
  , unPrefixSegWit
  , prefixSegWitHRP
  ) where

import qualified Codec.Binary.Bech32 as Bech32
import qualified Data.ByteString as B
import qualified Data.ByteString.Builder as BB
import qualified Data.ByteString.Lazy.Char8 as BL8
import qualified Data.Text.Encoding as T
import Data.Word

import Bitcoin.Address.Internal (hush)

--------------------------------------------------------------------------------

-- | Bitcoin network settings
--
-- For examples, see 'Bitcoin.Address.btc' or 'Bitcoin.Address.btcTestnet' in
-- "Bitcoin.Address".
data Settings = Settings
  { settings_prefixP2PKH :: PrefixP2PKH
  , settings_prefixP2SH :: PrefixP2SH
  , settings_prefixSegWit :: PrefixSegWit
  } deriving (Eq, Show)

--------------------------------------------------------------------------------

-- | The byte prefix used in 'P2PKH' addresses.
newtype PrefixP2PKH = PrefixP2PKH { unPrefixP2PKH :: Word8 }
  deriving newtype (Eq, Ord, Show)

--------------------------------------------------------------------------------

-- | The byte prefix used in 'P2SH' addresses.
newtype PrefixP2SH = PrefixP2SH { unPrefixP2SH :: Word8 }
  deriving newtype (Eq, Ord, Show)

--------------------------------------------------------------------------------

-- | The Human Readable Part of a 'P2WPKH' or 'P2WSH'
-- address (e.g., the “bc” in “bc1…”)
newtype PrefixSegWit = PrefixSegWit Bech32.HumanReadablePart
  deriving newtype (Eq)

instance Ord PrefixSegWit where
  compare a b = compare (unPrefixSegWit a) (unPrefixSegWit b)

instance Show PrefixSegWit where
  showsPrec n p = showParen (n > 10) $
    showString "PrefixSegWit " .
    mappend (BL8.unpack (BB.toLazyByteString
               (BB.byteStringHex (unPrefixSegWit p))))

prefixSegWitHRP :: PrefixSegWit -> Bech32.HumanReadablePart
prefixSegWitHRP (PrefixSegWit hrp) = hrp

-- | Obtain the Bech32 Human Readable Part inside 'PrefixSegWit'.
unPrefixSegWit :: PrefixSegWit -> B.ByteString
unPrefixSegWit (PrefixSegWit hrp) =
  T.encodeUtf8 (Bech32.humanReadablePartToText hrp)

-- | Construct a 'PrefixSegWit' from the Bech32 Human Readable Part.
prefixSegWit :: B.ByteString -> Maybe PrefixSegWit
prefixSegWit b = do
  t <- hush (T.decodeUtf8' b)
  PrefixSegWit <$> hush (Bech32.humanReadablePartFromText t)