{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Haskoin.Address
(
Address(..)
, isPubKeyAddress
, isScriptAddress
, isWitnessPubKeyAddress
, isWitnessScriptAddress
, addrToText
, textToAddr
, bech32ToAddr
, cashToAddr
, base58ToAddr
, addrToJSON
, addrToEncoding
, addrFromJSON
, pubKeyAddr
, pubKeyWitnessAddr
, pubKeyCompatWitnessAddr
, p2pkhAddr
, p2wpkhAddr
, p2shAddr
, p2wshAddr
, inputAddress
, outputAddress
, addressToScript
, addressToScriptBS
, addressToOutput
, payToScriptAddress
, payToWitnessScriptAddress
, payToNestedScriptAddress
, scriptToAddress
, scriptToAddressBS
, module Haskoin.Address.Base58
, module Haskoin.Address.Bech32
, module Haskoin.Address.CashAddr
) where
import Control.Applicative
import Control.Arrow (second)
import Control.DeepSeq
import Control.Monad
import Data.Aeson as A
import Data.Aeson.Encoding as A
import Data.Aeson.Types
import Data.Binary (Binary (..))
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Bytes.Get
import Data.Bytes.Put
import Data.Bytes.Serial
import Data.Hashable
import Data.Maybe
import Data.Serialize (Serialize (..))
import Data.Text (Text)
import qualified Data.Text as T
import Data.Word (Word8)
import GHC.Generics (Generic)
import Haskoin.Address.Base58
import Haskoin.Address.Bech32
import Haskoin.Address.CashAddr
import Haskoin.Constants
import Haskoin.Crypto
import Haskoin.Keys.Common
import Haskoin.Script
import Haskoin.Util
data Address
= PubKeyAddress
{ Address -> Hash160
getAddrHash160 :: !Hash160
}
| ScriptAddress
{ getAddrHash160 :: !Hash160
}
| WitnessPubKeyAddress
{ getAddrHash160 :: !Hash160
}
| WitnessScriptAddress
{ Address -> Hash256
getAddrHash256 :: !Hash256
}
| WitnessAddress
{ Address -> Word8
getAddrVersion :: !Word8
, Address -> ByteString
getAddrData :: !ByteString
}
deriving
(Address -> Address -> Bool
(Address -> Address -> Bool)
-> (Address -> Address -> Bool) -> Eq Address
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Address -> Address -> Bool
$c/= :: Address -> Address -> Bool
== :: Address -> Address -> Bool
$c== :: Address -> Address -> Bool
Eq, Eq Address
Eq Address =>
(Address -> Address -> Ordering)
-> (Address -> Address -> Bool)
-> (Address -> Address -> Bool)
-> (Address -> Address -> Bool)
-> (Address -> Address -> Bool)
-> (Address -> Address -> Address)
-> (Address -> Address -> Address)
-> Ord Address
Address -> Address -> Bool
Address -> Address -> Ordering
Address -> Address -> Address
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Address -> Address -> Address
$cmin :: Address -> Address -> Address
max :: Address -> Address -> Address
$cmax :: Address -> Address -> Address
>= :: Address -> Address -> Bool
$c>= :: Address -> Address -> Bool
> :: Address -> Address -> Bool
$c> :: Address -> Address -> Bool
<= :: Address -> Address -> Bool
$c<= :: Address -> Address -> Bool
< :: Address -> Address -> Bool
$c< :: Address -> Address -> Bool
compare :: Address -> Address -> Ordering
$ccompare :: Address -> Address -> Ordering
$cp1Ord :: Eq Address
Ord, (forall x. Address -> Rep Address x)
-> (forall x. Rep Address x -> Address) -> Generic Address
forall x. Rep Address x -> Address
forall x. Address -> Rep Address x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Address x -> Address
$cfrom :: forall x. Address -> Rep Address x
Generic, Int -> Address -> ShowS
[Address] -> ShowS
Address -> String
(Int -> Address -> ShowS)
-> (Address -> String) -> ([Address] -> ShowS) -> Show Address
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Address] -> ShowS
$cshowList :: [Address] -> ShowS
show :: Address -> String
$cshow :: Address -> String
showsPrec :: Int -> Address -> ShowS
$cshowsPrec :: Int -> Address -> ShowS
Show, ReadPrec [Address]
ReadPrec Address
Int -> ReadS Address
ReadS [Address]
(Int -> ReadS Address)
-> ReadS [Address]
-> ReadPrec Address
-> ReadPrec [Address]
-> Read Address
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Address]
$creadListPrec :: ReadPrec [Address]
readPrec :: ReadPrec Address
$creadPrec :: ReadPrec Address
readList :: ReadS [Address]
$creadList :: ReadS [Address]
readsPrec :: Int -> ReadS Address
$creadsPrec :: Int -> ReadS Address
Read, Int -> Address -> Int
Address -> Int
(Int -> Address -> Int) -> (Address -> Int) -> Hashable Address
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Address -> Int
$chash :: Address -> Int
hashWithSalt :: Int -> Address -> Int
$chashWithSalt :: Int -> Address -> Int
Hashable, Address -> ()
(Address -> ()) -> NFData Address
forall a. (a -> ()) -> NFData a
rnf :: Address -> ()
$crnf :: Address -> ()
NFData)
instance Serial Address where
serialize :: Address -> m ()
serialize (PubKeyAddress k :: Hash160
k) = do
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x00
Hash160 -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
k
serialize (ScriptAddress s :: Hash160
s) = do
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x01
Hash160 -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
s
serialize (WitnessPubKeyAddress h :: Hash160
h) = do
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x02
Hash160 -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h
serialize (WitnessScriptAddress s :: Hash256
s) = do
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x03
Hash256 -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash256
s
serialize (WitnessAddress v :: Word8
v d :: ByteString
d) = do
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x04
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
v
Word64 -> m ()
forall (m :: * -> *). MonadPut m => Word64 -> m ()
putWord64be (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
d))
ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putByteString ByteString
d
deserialize :: m Address
deserialize =
m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8 m Word8 -> (Word8 -> m Address) -> m Address
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
0x00 -> Hash160 -> Address
PubKeyAddress (Hash160 -> Address) -> m Hash160 -> m Address
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Hash160
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
0x01 -> Hash160 -> Address
ScriptAddress (Hash160 -> Address) -> m Hash160 -> m Address
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Hash160
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
0x02 -> Hash160 -> Address
WitnessPubKeyAddress (Hash160 -> Address) -> m Hash160 -> m Address
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Hash160
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
0x03 -> Hash256 -> Address
WitnessScriptAddress (Hash256 -> Address) -> m Hash256 -> m Address
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Hash256
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
0x04 -> Word8 -> ByteString -> Address
WitnessAddress (Word8 -> ByteString -> Address)
-> m Word8 -> m (ByteString -> Address)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8 m (ByteString -> Address) -> m ByteString -> m Address
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
(Int -> m ByteString
forall (m :: * -> *). MonadGet m => Int -> m ByteString
getByteString (Int -> m ByteString) -> (Word64 -> Int) -> Word64 -> m ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> m ByteString) -> m Word64 -> m ByteString
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m Word64
forall (m :: * -> *). MonadGet m => m Word64
getWord64be)
b :: Word8
b -> String -> m Address
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> m Address) -> (Text -> String) -> Text -> m Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack (Text -> m Address) -> Text -> m Address
forall a b. (a -> b) -> a -> b
$
"Could not decode address type byte: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
ByteString -> Text
encodeHex (Word8 -> ByteString
B.singleton Word8
b)
instance Serialize Address where
put :: Putter Address
put = Putter Address
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
get :: Get Address
get = Get Address
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
instance Binary Address where
put :: Address -> Put
put = Address -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
get :: Get Address
get = Get Address
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
isPubKeyAddress :: Address -> Bool
isPubKeyAddress :: Address -> Bool
isPubKeyAddress PubKeyAddress {} = Bool
True
isPubKeyAddress _ = Bool
False
isScriptAddress :: Address -> Bool
isScriptAddress :: Address -> Bool
isScriptAddress ScriptAddress {} = Bool
True
isScriptAddress _ = Bool
False
isWitnessPubKeyAddress :: Address -> Bool
isWitnessPubKeyAddress :: Address -> Bool
isWitnessPubKeyAddress WitnessPubKeyAddress {} = Bool
True
isWitnessPubKeyAddress _ = Bool
False
isWitnessScriptAddress :: Address -> Bool
isWitnessScriptAddress :: Address -> Bool
isWitnessScriptAddress WitnessScriptAddress {} = Bool
True
isWitnessScriptAddress _ = Bool
False
isWitnessAddress :: Address -> Bool
isWitnessAddress :: Address -> Bool
isWitnessAddress WitnessAddress {} = Bool
True
isWitnessAddress _ = Bool
False
addrToJSON :: Network -> Address -> Value
addrToJSON :: Network -> Address -> Value
addrToJSON net :: Network
net a :: Address
a = Maybe Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Network -> Address -> Maybe Text
addrToText Network
net Address
a)
addrToEncoding :: Network -> Address -> Encoding
addrToEncoding :: Network -> Address -> Encoding
addrToEncoding net :: Network
net = Encoding -> (Text -> Encoding) -> Maybe Text -> Encoding
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Encoding
null_ Text -> Encoding
forall a. Text -> Encoding' a
text (Maybe Text -> Encoding)
-> (Address -> Maybe Text) -> Address -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Network -> Address -> Maybe Text
addrToText Network
net
addrFromJSON :: Network -> Value -> Parser Address
addrFromJSON :: Network -> Value -> Parser Address
addrFromJSON net :: Network
net =
String -> (Text -> Parser Address) -> Value -> Parser Address
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText "address" ((Text -> Parser Address) -> Value -> Parser Address)
-> (Text -> Parser Address) -> Value -> Parser Address
forall a b. (a -> b) -> a -> b
$ \t :: Text
t ->
case Network -> Text -> Maybe Address
textToAddr Network
net Text
t of
Nothing -> String -> Parser Address
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "could not decode address"
Just x :: Address
x -> Address -> Parser Address
forall (m :: * -> *) a. Monad m => a -> m a
return Address
x
addrToText :: Network -> Address -> Maybe Text
addrToText :: Network -> Address -> Maybe Text
addrToText net :: Network
net a :: Address
a@PubKeyAddress {getAddrHash160 :: Address -> Hash160
getAddrHash160 = Hash160
h}
| Maybe Text -> Bool
forall a. Maybe a -> Bool
isNothing (Network -> Maybe Text
getCashAddrPrefix Network
net) =
Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> (Put -> Text) -> Put -> Maybe Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
encodeBase58Check (ByteString -> Text) -> (Put -> ByteString) -> Put -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutS (Put -> Maybe Text) -> Put -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Network -> Putter Address
forall (m :: * -> *). MonadPut m => Network -> Address -> m ()
base58put Network
net Address
a
| Bool
otherwise = Network -> Word8 -> ByteString -> Maybe Text
cashAddrEncode Network
net 0 (Put -> ByteString
runPutS (Put -> ByteString) -> Put -> ByteString
forall a b. (a -> b) -> a -> b
$ Hash160 -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h)
addrToText net :: Network
net a :: Address
a@ScriptAddress {getAddrHash160 :: Address -> Hash160
getAddrHash160 = Hash160
h}
| Maybe Text -> Bool
forall a. Maybe a -> Bool
isNothing (Network -> Maybe Text
getCashAddrPrefix Network
net) =
Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> (Put -> Text) -> Put -> Maybe Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
encodeBase58Check (ByteString -> Text) -> (Put -> ByteString) -> Put -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutS (Put -> Maybe Text) -> Put -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Network -> Putter Address
forall (m :: * -> *). MonadPut m => Network -> Address -> m ()
base58put Network
net Address
a
| Bool
otherwise =
Network -> Word8 -> ByteString -> Maybe Text
cashAddrEncode Network
net 1 (Put -> ByteString
runPutS (Put -> ByteString) -> Put -> ByteString
forall a b. (a -> b) -> a -> b
$ Hash160 -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h)
addrToText net :: Network
net WitnessPubKeyAddress {getAddrHash160 :: Address -> Hash160
getAddrHash160 = Hash160
h} = do
Text
hrp <- Network -> Maybe Text
getBech32Prefix Network
net
Text -> Word8 -> Data -> Maybe Text
segwitEncode Text
hrp 0 (ByteString -> Data
B.unpack (Put -> ByteString
runPutS (Put -> ByteString) -> Put -> ByteString
forall a b. (a -> b) -> a -> b
$ Hash160 -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h))
addrToText net :: Network
net WitnessScriptAddress {getAddrHash256 :: Address -> Hash256
getAddrHash256 = Hash256
h} = do
Text
hrp <- Network -> Maybe Text
getBech32Prefix Network
net
Text -> Word8 -> Data -> Maybe Text
segwitEncode Text
hrp 0 (ByteString -> Data
B.unpack (Put -> ByteString
runPutS (Put -> ByteString) -> Put -> ByteString
forall a b. (a -> b) -> a -> b
$ Hash256 -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash256
h))
addrToText net :: Network
net WitnessAddress {getAddrVersion :: Address -> Word8
getAddrVersion = Word8
v, getAddrData :: Address -> ByteString
getAddrData = ByteString
d} = do
Text
hrp <- Network -> Maybe Text
getBech32Prefix Network
net
Text -> Word8 -> Data -> Maybe Text
segwitEncode Text
hrp Word8
v (ByteString -> Data
B.unpack ByteString
d)
textToAddr :: Network -> Text -> Maybe Address
textToAddr :: Network -> Text -> Maybe Address
textToAddr net :: Network
net txt :: Text
txt =
Network -> Text -> Maybe Address
cashToAddr Network
net Text
txt Maybe Address -> Maybe Address -> Maybe Address
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Network -> Text -> Maybe Address
bech32ToAddr Network
net Text
txt Maybe Address -> Maybe Address -> Maybe Address
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Network -> Text -> Maybe Address
base58ToAddr Network
net Text
txt
cashToAddr :: Network -> Text -> Maybe Address
cashToAddr :: Network -> Text -> Maybe Address
cashToAddr net :: Network
net txt :: Text
txt = do
(ver :: Word8
ver, bs :: ByteString
bs) <- Network -> Text -> Maybe (Word8, ByteString)
cashAddrDecode Network
net Text
txt
case Word8
ver of
0 -> Hash160 -> Address
PubKeyAddress (Hash160 -> Address) -> Maybe Hash160 -> Maybe Address
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either String Hash160 -> Maybe Hash160
forall a b. Either a b -> Maybe b
eitherToMaybe (Get Hash160 -> ByteString -> Either String Hash160
forall a. Get a -> ByteString -> Either String a
runGetS Get Hash160
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize ByteString
bs)
1 -> Hash160 -> Address
ScriptAddress (Hash160 -> Address) -> Maybe Hash160 -> Maybe Address
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either String Hash160 -> Maybe Hash160
forall a b. Either a b -> Maybe b
eitherToMaybe (Get Hash160 -> ByteString -> Either String Hash160
forall a. Get a -> ByteString -> Either String a
runGetS Get Hash160
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize ByteString
bs)
_ -> Maybe Address
forall a. Maybe a
Nothing
bech32ToAddr :: Network -> Text -> Maybe Address
bech32ToAddr :: Network -> Text -> Maybe Address
bech32ToAddr net :: Network
net txt :: Text
txt = do
Text
hrp <- Network -> Maybe Text
getBech32Prefix Network
net
(ver :: Word8
ver, bs :: ByteString
bs) <- (Data -> ByteString) -> (Word8, Data) -> (Word8, ByteString)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second Data -> ByteString
B.pack ((Word8, Data) -> (Word8, ByteString))
-> Maybe (Word8, Data) -> Maybe (Word8, ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Text -> Maybe (Word8, Data)
segwitDecode Text
hrp Text
txt
case Word8
ver of
0 -> case ByteString -> Int
B.length ByteString
bs of
20 -> Hash160 -> Address
WitnessPubKeyAddress (Hash160 -> Address) -> Maybe Hash160 -> Maybe Address
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either String Hash160 -> Maybe Hash160
forall a b. Either a b -> Maybe b
eitherToMaybe (Get Hash160 -> ByteString -> Either String Hash160
forall a. Get a -> ByteString -> Either String a
runGetS Get Hash160
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize ByteString
bs)
32 -> Hash256 -> Address
WitnessScriptAddress (Hash256 -> Address) -> Maybe Hash256 -> Maybe Address
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either String Hash256 -> Maybe Hash256
forall a b. Either a b -> Maybe b
eitherToMaybe (Get Hash256 -> ByteString -> Either String Hash256
forall a. Get a -> ByteString -> Either String a
runGetS Get Hash256
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize ByteString
bs)
_ -> Maybe Address
forall a. Maybe a
Nothing
_ -> Address -> Maybe Address
forall a. a -> Maybe a
Just (Address -> Maybe Address) -> Address -> Maybe Address
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString -> Address
WitnessAddress Word8
ver ByteString
bs
base58ToAddr :: Network -> Text -> Maybe Address
base58ToAddr :: Network -> Text -> Maybe Address
base58ToAddr net :: Network
net txt :: Text
txt =
Either String Address -> Maybe Address
forall a b. Either a b -> Maybe b
eitherToMaybe (Either String Address -> Maybe Address)
-> (ByteString -> Either String Address)
-> ByteString
-> Maybe Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Get Address -> ByteString -> Either String Address
forall a. Get a -> ByteString -> Either String a
runGetS (Network -> Get Address
forall (m :: * -> *). MonadGet m => Network -> m Address
base58get Network
net) (ByteString -> Maybe Address) -> Maybe ByteString -> Maybe Address
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Text -> Maybe ByteString
decodeBase58Check Text
txt
base58get :: MonadGet m => Network -> m Address
base58get :: Network -> m Address
base58get net :: Network
net = do
Word8
pfx <- m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8
Hash160
addr <- m Hash160
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
Word8 -> Hash160 -> m Address
forall (m :: * -> *). MonadFail m => Word8 -> Hash160 -> m Address
f Word8
pfx Hash160
addr
where
f :: Word8 -> Hash160 -> m Address
f x :: Word8
x a :: Hash160
a
| Word8
x Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Network -> Word8
getAddrPrefix Network
net = Address -> m Address
forall (m :: * -> *) a. Monad m => a -> m a
return (Address -> m Address) -> Address -> m Address
forall a b. (a -> b) -> a -> b
$ Hash160 -> Address
PubKeyAddress Hash160
a
| Word8
x Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Network -> Word8
getScriptPrefix Network
net = Address -> m Address
forall (m :: * -> *) a. Monad m => a -> m a
return (Address -> m Address) -> Address -> m Address
forall a b. (a -> b) -> a -> b
$ Hash160 -> Address
ScriptAddress Hash160
a
| Bool
otherwise = String -> m Address
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "Does not recognize address prefix"
base58put :: MonadPut m => Network -> Address -> m ()
base58put :: Network -> Address -> m ()
base58put net :: Network
net (PubKeyAddress h :: Hash160
h) = do
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 (Network -> Word8
getAddrPrefix Network
net)
Hash160 -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h
base58put net :: Network
net (ScriptAddress h :: Hash160
h) = do
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 (Network -> Word8
getScriptPrefix Network
net)
Hash160 -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h
base58put _ _ = String -> m ()
forall a. HasCallStack => String -> a
error "Cannot serialize this address as Base58"
pubKeyAddr :: PubKeyI -> Address
pubKeyAddr :: PubKeyI -> Address
pubKeyAddr = Hash160 -> Address
PubKeyAddress (Hash160 -> Address) -> (PubKeyI -> Hash160) -> PubKeyI -> Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Hash160
forall b. ByteArrayAccess b => b -> Hash160
addressHash (ByteString -> Hash160)
-> (PubKeyI -> ByteString) -> PubKeyI -> Hash160
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutS (Put -> ByteString) -> (PubKeyI -> Put) -> PubKeyI -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PubKeyI -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
p2pkhAddr :: Hash160 -> Address
p2pkhAddr :: Hash160 -> Address
p2pkhAddr = Hash160 -> Address
PubKeyAddress
pubKeyWitnessAddr :: PubKeyI -> Address
pubKeyWitnessAddr :: PubKeyI -> Address
pubKeyWitnessAddr = Hash160 -> Address
WitnessPubKeyAddress (Hash160 -> Address) -> (PubKeyI -> Hash160) -> PubKeyI -> Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Hash160
forall b. ByteArrayAccess b => b -> Hash160
addressHash (ByteString -> Hash160)
-> (PubKeyI -> ByteString) -> PubKeyI -> Hash160
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Put -> ByteString
runPutS (Put -> ByteString) -> (PubKeyI -> Put) -> PubKeyI -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PubKeyI -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
pubKeyCompatWitnessAddr :: PubKeyI -> Address
pubKeyCompatWitnessAddr :: PubKeyI -> Address
pubKeyCompatWitnessAddr =
Hash160 -> Address
p2shAddr (Hash160 -> Address) -> (PubKeyI -> Hash160) -> PubKeyI -> Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
ByteString -> Hash160
forall b. ByteArrayAccess b => b -> Hash160
addressHash (ByteString -> Hash160)
-> (PubKeyI -> ByteString) -> PubKeyI -> Hash160
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
ScriptOutput -> ByteString
encodeOutputBS (ScriptOutput -> ByteString)
-> (PubKeyI -> ScriptOutput) -> PubKeyI -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
Hash160 -> ScriptOutput
PayWitnessPKHash (Hash160 -> ScriptOutput)
-> (PubKeyI -> Hash160) -> PubKeyI -> ScriptOutput
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
ByteString -> Hash160
forall b. ByteArrayAccess b => b -> Hash160
addressHash (ByteString -> Hash160)
-> (PubKeyI -> ByteString) -> PubKeyI -> Hash160
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
Put -> ByteString
runPutS (Put -> ByteString) -> (PubKeyI -> Put) -> PubKeyI -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
PubKeyI -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
p2wpkhAddr :: Hash160 -> Address
p2wpkhAddr :: Hash160 -> Address
p2wpkhAddr = Hash160 -> Address
WitnessPubKeyAddress
p2shAddr :: Hash160 -> Address
p2shAddr :: Hash160 -> Address
p2shAddr = Hash160 -> Address
ScriptAddress
p2wshAddr :: Hash256 -> Address
p2wshAddr :: Hash256 -> Address
p2wshAddr = Hash256 -> Address
WitnessScriptAddress
payToScriptAddress :: ScriptOutput -> Address
payToScriptAddress :: ScriptOutput -> Address
payToScriptAddress = Hash160 -> Address
p2shAddr (Hash160 -> Address)
-> (ScriptOutput -> Hash160) -> ScriptOutput -> Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Hash160
forall b. ByteArrayAccess b => b -> Hash160
addressHash (ByteString -> Hash160)
-> (ScriptOutput -> ByteString) -> ScriptOutput -> Hash160
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> ByteString
encodeOutputBS
payToWitnessScriptAddress :: ScriptOutput -> Address
payToWitnessScriptAddress :: ScriptOutput -> Address
payToWitnessScriptAddress = Hash256 -> Address
p2wshAddr (Hash256 -> Address)
-> (ScriptOutput -> Hash256) -> ScriptOutput -> Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Hash256
forall b. ByteArrayAccess b => b -> Hash256
sha256 (ByteString -> Hash256)
-> (ScriptOutput -> ByteString) -> ScriptOutput -> Hash256
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> ByteString
encodeOutputBS
payToNestedScriptAddress :: ScriptOutput -> Address
payToNestedScriptAddress :: ScriptOutput -> Address
payToNestedScriptAddress =
Hash160 -> Address
p2shAddr (Hash160 -> Address)
-> (ScriptOutput -> Hash160) -> ScriptOutput -> Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Hash160
forall b. ByteArrayAccess b => b -> Hash160
addressHash (ByteString -> Hash160)
-> (ScriptOutput -> ByteString) -> ScriptOutput -> Hash160
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> ByteString
encodeOutputBS (ScriptOutput -> ByteString)
-> (ScriptOutput -> ScriptOutput) -> ScriptOutput -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script -> ScriptOutput
toP2WSH (Script -> ScriptOutput)
-> (ScriptOutput -> Script) -> ScriptOutput -> ScriptOutput
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> Script
encodeOutput
addressToOutput :: Address -> ScriptOutput
addressToOutput :: Address -> ScriptOutput
addressToOutput =
\case
PubKeyAddress h :: Hash160
h -> Hash160 -> ScriptOutput
PayPKHash Hash160
h
ScriptAddress h :: Hash160
h -> Hash160 -> ScriptOutput
PayScriptHash Hash160
h
WitnessPubKeyAddress h :: Hash160
h -> Hash160 -> ScriptOutput
PayWitnessPKHash Hash160
h
WitnessScriptAddress h :: Hash256
h -> Hash256 -> ScriptOutput
PayWitnessScriptHash Hash256
h
WitnessAddress v :: Word8
v d :: ByteString
d -> Word8 -> ByteString -> ScriptOutput
PayWitness Word8
v ByteString
d
addressToScript :: Address -> Script
addressToScript :: Address -> Script
addressToScript = ScriptOutput -> Script
encodeOutput (ScriptOutput -> Script)
-> (Address -> ScriptOutput) -> Address -> Script
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Address -> ScriptOutput
addressToOutput
addressToScriptBS :: Address -> ByteString
addressToScriptBS :: Address -> ByteString
addressToScriptBS = Put -> ByteString
runPutS (Put -> ByteString) -> Putter Address -> Address -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize (Script -> Put) -> (Address -> Script) -> Putter Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Address -> Script
addressToScript
scriptToAddress :: Script -> Either String Address
scriptToAddress :: Script -> Either String Address
scriptToAddress =
String -> Maybe Address -> Either String Address
forall b a. b -> Maybe a -> Either b a
maybeToEither "Could not decode address" (Maybe Address -> Either String Address)
-> (ScriptOutput -> Maybe Address)
-> ScriptOutput
-> Either String Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> Maybe Address
outputAddress (ScriptOutput -> Either String Address)
-> (Script -> Either String ScriptOutput)
-> Script
-> Either String Address
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Script -> Either String ScriptOutput
decodeOutput
scriptToAddressBS :: ByteString -> Either String Address
scriptToAddressBS :: ByteString -> Either String Address
scriptToAddressBS =
String -> Maybe Address -> Either String Address
forall b a. b -> Maybe a -> Either b a
maybeToEither "Could not decode address" (Maybe Address -> Either String Address)
-> (ScriptOutput -> Maybe Address)
-> ScriptOutput
-> Either String Address
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScriptOutput -> Maybe Address
outputAddress (ScriptOutput -> Either String Address)
-> (ByteString -> Either String ScriptOutput)
-> ByteString
-> Either String Address
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< ByteString -> Either String ScriptOutput
decodeOutputBS
outputAddress :: ScriptOutput -> Maybe Address
outputAddress :: ScriptOutput -> Maybe Address
outputAddress =
\case
PayPKHash h :: Hash160
h -> Address -> Maybe Address
forall a. a -> Maybe a
Just (Address -> Maybe Address) -> Address -> Maybe Address
forall a b. (a -> b) -> a -> b
$ Hash160 -> Address
PubKeyAddress Hash160
h
PayScriptHash h :: Hash160
h -> Address -> Maybe Address
forall a. a -> Maybe a
Just (Address -> Maybe Address) -> Address -> Maybe Address
forall a b. (a -> b) -> a -> b
$ Hash160 -> Address
ScriptAddress Hash160
h
PayPK k :: PubKeyI
k -> Address -> Maybe Address
forall a. a -> Maybe a
Just (Address -> Maybe Address) -> Address -> Maybe Address
forall a b. (a -> b) -> a -> b
$ PubKeyI -> Address
pubKeyAddr PubKeyI
k
PayWitnessPKHash h :: Hash160
h -> Address -> Maybe Address
forall a. a -> Maybe a
Just (Address -> Maybe Address) -> Address -> Maybe Address
forall a b. (a -> b) -> a -> b
$ Hash160 -> Address
WitnessPubKeyAddress Hash160
h
PayWitnessScriptHash h :: Hash256
h -> Address -> Maybe Address
forall a. a -> Maybe a
Just (Address -> Maybe Address) -> Address -> Maybe Address
forall a b. (a -> b) -> a -> b
$ Hash256 -> Address
WitnessScriptAddress Hash256
h
PayWitness v :: Word8
v d :: ByteString
d -> Address -> Maybe Address
forall a. a -> Maybe a
Just (Address -> Maybe Address) -> Address -> Maybe Address
forall a b. (a -> b) -> a -> b
$ Word8 -> ByteString -> Address
WitnessAddress Word8
v ByteString
d
_ -> Maybe Address
forall a. Maybe a
Nothing
inputAddress :: ScriptInput -> Maybe Address
inputAddress :: ScriptInput -> Maybe Address
inputAddress =
\case
(RegularInput (SpendPKHash _ key :: PubKeyI
key)) -> Address -> Maybe Address
forall a. a -> Maybe a
Just (Address -> Maybe Address) -> Address -> Maybe Address
forall a b. (a -> b) -> a -> b
$ PubKeyI -> Address
pubKeyAddr PubKeyI
key
(ScriptHashInput _ rdm :: ScriptOutput
rdm) -> Address -> Maybe Address
forall a. a -> Maybe a
Just (Address -> Maybe Address) -> Address -> Maybe Address
forall a b. (a -> b) -> a -> b
$ ScriptOutput -> Address
payToScriptAddress ScriptOutput
rdm
_ -> Maybe Address
forall a. Maybe a
Nothing