{-# LANGUAGE GeneralizedNewtypeDeriving #-} module Network.EasyBitcoin.BitcoinUnits ( btc , mBTC , satoshis , asBtc , asMbtc , asSatoshis , showAsBtc , showAsMbtc , showAsSatoshis , BTC() )where import Network.EasyBitcoin.NetworkParams import Network.EasyBitcoin.Internal.InstanciationHelpers import Control.Arrow(first) import Control.Applicative((<$>)) -- | Bitcoins are represented internally as an integer value, but showed and read as a decimal values. -- When importing them, extra significative digits will be silently dropped. newtype BTC a = Satoshis Int deriving (Eq,Ord,Num) btc :: Double -> BTC net btc x = Satoshis $ round (x*100000000) mBTC :: Double -> BTC net mBTC x = Satoshis $ round (x*100000) satoshis :: Int -> BTC net satoshis = Satoshis asBtc :: BTC net -> Double asBtc (Satoshis x) = fromIntegral x/100000000 asMbtc :: BTC net -> Double asMbtc (Satoshis x) = fromIntegral x /100000 asSatoshis :: BTC net -> Int asSatoshis (Satoshis x) = x showAsBtc :: BTC net -> String showAsBtc (Satoshis x) = let str = reverse (show x) ++ replicate 9 '0' (smallers,biggers) = splitAt 8 str in if all (=='0') biggers then "0." ++ reverse smallers else dropWhile (=='0') $ reverse biggers ++ "." ++ reverse smallers showAsMbtc :: BTC net -> String showAsMbtc (Satoshis x) = let str = reverse (show x) ++ replicate 6 '0' (smallers,biggers) = splitAt 5 str in if all (=='0') biggers then "0." ++ reverse smallers else dropWhile (=='0') $ reverse biggers ++ "." ++ reverse smallers showAsSatoshis :: BTC net -> String showAsSatoshis = show.asSatoshis instance Show (BTC a) where show = showAsBtc instance Read (BTC a) where readsPrec n str = first btc <$> (readsPrec n str:: [(Double,String)])