{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Haskoin.Address (
Address (..),
isPubKeyAddress,
isScriptAddress,
isWitnessAddress,
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.Crypto
import Haskoin.Data
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 Hash160
k) = do
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
0x00
Hash160 -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
k
serialize (ScriptAddress Hash160
s) = do
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
0x01
Hash160 -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
s
serialize (WitnessPubKeyAddress Hash160
h) = do
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
0x02
Hash160 -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash160
h
serialize (WitnessScriptAddress Hash256
s) = do
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
0x03
Hash256 -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize Hash256
s
serialize (WitnessAddress Word8
v ByteString
d) = do
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
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
Word8
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
Word8
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
Word8
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
Word8
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
Word8
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)
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
$
Text
"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 Address
_ = Bool
False
isScriptAddress :: Address -> Bool
isScriptAddress :: Address -> Bool
isScriptAddress ScriptAddress{} = Bool
True
isScriptAddress Address
_ = Bool
False
isWitnessPubKeyAddress :: Address -> Bool
isWitnessPubKeyAddress :: Address -> Bool
isWitnessPubKeyAddress WitnessPubKeyAddress{} = Bool
True
isWitnessPubKeyAddress Address
_ = Bool
False
isWitnessScriptAddress :: Address -> Bool
isWitnessScriptAddress :: Address -> Bool
isWitnessScriptAddress WitnessScriptAddress{} = Bool
True
isWitnessScriptAddress Address
_ = Bool
False
isWitnessAddress :: Address -> Bool
isWitnessAddress :: Address -> Bool
isWitnessAddress WitnessAddress{} = Bool
True
isWitnessAddress Address
_ = Bool
False
addrToJSON :: Network -> Address -> Value
addrToJSON :: Network -> Address -> Value
addrToJSON Network
net 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 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 Network
net =
String -> (Text -> Parser Address) -> Value -> Parser Address
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"address" ((Text -> Parser Address) -> Value -> Parser Address)
-> (Text -> Parser Address) -> Value -> Parser Address
forall a b. (a -> b) -> a -> b
$ \Text
t ->
case Network -> Text -> Maybe Address
textToAddr Network
net Text
t of
Maybe Address
Nothing -> String -> Parser Address
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"could not decode address"
Just 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 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 Word8
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 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 Word8
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 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 Word8
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 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 Word8
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 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 Network
net 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 Network
net Text
txt = do
(Word8
ver, ByteString
bs) <- Network -> Text -> Maybe (Word8, ByteString)
cashAddrDecode Network
net Text
txt
case Word8
ver of
Word8
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)
Word8
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)
Word8
_ -> Maybe Address
forall a. Maybe a
Nothing
bech32ToAddr :: Network -> Text -> Maybe Address
bech32ToAddr :: Network -> Text -> Maybe Address
bech32ToAddr Network
net Text
txt = do
Text
hrp <- Network -> Maybe Text
getBech32Prefix Network
net
(Word8
ver, 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
Word8
0 -> case ByteString -> Int
B.length ByteString
bs of
Int
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)
Int
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)
Int
_ -> Maybe Address
forall a. Maybe a
Nothing
Word8
_ -> 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 Network
net 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 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 Word8
x 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 String
"Does not recognize address prefix"
base58put :: MonadPut m => Network -> Address -> m ()
base58put :: Network -> Address -> m ()
base58put Network
net (PubKeyAddress 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 Network
net (ScriptAddress 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 Network
_ Address
_ = String -> m ()
forall a. HasCallStack => String -> a
error String
"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 Hash160
h -> Hash160 -> ScriptOutput
PayPKHash Hash160
h
ScriptAddress Hash160
h -> Hash160 -> ScriptOutput
PayScriptHash Hash160
h
WitnessPubKeyAddress Hash160
h -> Hash160 -> ScriptOutput
PayWitnessPKHash Hash160
h
WitnessScriptAddress Hash256
h -> Hash256 -> ScriptOutput
PayWitnessScriptHash Hash256
h
WitnessAddress Word8
v 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 String
"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 String
"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 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 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 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 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 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 Word8
v 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
ScriptOutput
_ -> Maybe Address
forall a. Maybe a
Nothing
inputAddress :: ScriptInput -> Maybe Address
inputAddress :: ScriptInput -> Maybe Address
inputAddress =
\case
(RegularInput (SpendPKHash TxSignature
_ 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 SimpleInput
_ 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
ScriptInput
_ -> Maybe Address
forall a. Maybe a
Nothing