{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Network.Polkadot.Extrinsic.Unchecked
( UncheckedExtrinsic (..)
, new_unsigned
, new_signed
, sign_extrinsic
) where
import Codec.Scale (encode)
import Codec.Scale.Class (Decode (..),
Encode (..))
import Control.Arrow ((&&&))
import Control.Monad (when)
import Data.Bits (clearBit, setBit,
testBit)
import Data.ByteArray.HexString (HexString)
import Data.ByteString (ByteString)
import Data.Word (Word8)
import Network.JsonRpc.TinyClient (JsonRpc)
import Network.Polkadot.Crypto (MultiPair (..))
import Network.Polkadot.Extrinsic.Payload (sign_payload)
import Network.Polkadot.Extrinsic.SignedExtension (SignedExtension)
extrinsic_version :: Word8
extrinsic_version :: Word8
extrinsic_version = Word8
4
data UncheckedExtrinsic c a s e
= UncheckedExtrinsic
{ forall c a s e. UncheckedExtrinsic c a s e -> Maybe (a, s, e)
extrinsicSignature :: !(Maybe (a, s, e))
, forall c a s e. UncheckedExtrinsic c a s e -> c
extrinsicFunction :: !c
}
instance Encode c => Show (UncheckedExtrinsic c a b c) where
show :: UncheckedExtrinsic c a b c -> String
show (UncheckedExtrinsic Maybe (a, b, c)
_ c
call) = String
"UncheckedExtrinsic " String -> ShowS
forall a. [a] -> [a] -> [a]
++ HexString -> String
forall a. Show a => a -> String
show HexString
encoded
where
encoded :: HexString
encoded :: HexString
encoded = c -> HexString
forall a ba. (Encode a, ByteArray ba) => a -> ba
encode c
call
instance (Encode c, Encode a, Encode s, Encode e) => Encode (UncheckedExtrinsic c a s e) where
put :: Putter (UncheckedExtrinsic c a s e)
put UncheckedExtrinsic c a s e
xt = Putter ByteString
forall a. Encode a => Putter a
put ByteString
encoded
where
encoded :: ByteString
encoded :: ByteString
encoded = case UncheckedExtrinsic c a s e
xt of
UncheckedExtrinsic Maybe (a, s, e)
Nothing c
call
-> Word8 -> ByteString
forall a ba. (Encode a, ByteArray ba) => a -> ba
encode Word8
extrinsic_version ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> c -> ByteString
forall a ba. (Encode a, ByteArray ba) => a -> ba
encode c
call
UncheckedExtrinsic (Just (a, s, e)
s) c
call
-> Word8 -> ByteString
forall a ba. (Encode a, ByteArray ba) => a -> ba
encode (Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
setBit Word8
extrinsic_version Int
7) ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> (a, s, e) -> ByteString
forall a ba. (Encode a, ByteArray ba) => a -> ba
encode (a, s, e)
s ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> c -> ByteString
forall a ba. (Encode a, ByteArray ba) => a -> ba
encode c
call
instance (Decode c, Decode a, Decode s, Decode e) => Decode (UncheckedExtrinsic c a s e) where
get :: Get (UncheckedExtrinsic c a s e)
get = do
([()]
_v :: [()]) <- Get [()]
forall a. Decode a => Get a
get
(Bool
signed, Word8
version) <- ((Word8 -> Int -> Bool) -> Int -> Word8 -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word8 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Int
7 (Word8 -> Bool) -> (Word8 -> Word8) -> Word8 -> (Bool, Word8)
forall b c c'. (b -> c) -> (b -> c') -> b -> (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& (Word8 -> Int -> Word8) -> Int -> Word8 -> Word8
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
clearBit Int
7) (Word8 -> (Bool, Word8)) -> Get Word8 -> Get (Bool, Word8)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
forall a. Decode a => Get a
get
Bool -> Get () -> Get ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word8
version Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
extrinsic_version) (Get () -> Get ()) -> Get () -> Get ()
forall a b. (a -> b) -> a -> b
$ String -> Get ()
forall a. String -> Get a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"bad version"
Maybe (a, s, e) -> c -> UncheckedExtrinsic c a s e
forall c a s e. Maybe (a, s, e) -> c -> UncheckedExtrinsic c a s e
UncheckedExtrinsic
(Maybe (a, s, e) -> c -> UncheckedExtrinsic c a s e)
-> Get (Maybe (a, s, e)) -> Get (c -> UncheckedExtrinsic c a s e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (if Bool
signed then ((a, s, e) -> Maybe (a, s, e))
-> Get (a, s, e) -> Get (Maybe (a, s, e))
forall a b. (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, s, e) -> Maybe (a, s, e)
forall a. a -> Maybe a
Just Get (a, s, e)
forall a. Decode a => Get a
get else Maybe (a, s, e) -> Get (Maybe (a, s, e))
forall a. a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (a, s, e)
forall a. Maybe a
Nothing)
Get (c -> UncheckedExtrinsic c a s e)
-> Get c -> Get (UncheckedExtrinsic c a s e)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get c
forall a. Decode a => Get a
get
new_signed :: c -> a -> s -> e -> UncheckedExtrinsic c a s e
new_signed :: forall c a s e. c -> a -> s -> e -> UncheckedExtrinsic c a s e
new_signed c
call a
address s
sig e
extra = Maybe (a, s, e) -> c -> UncheckedExtrinsic c a s e
forall c a s e. Maybe (a, s, e) -> c -> UncheckedExtrinsic c a s e
UncheckedExtrinsic ((a, s, e) -> Maybe (a, s, e)
forall a. a -> Maybe a
Just (a
address, s
sig, e
extra)) c
call
new_unsigned :: f -> UncheckedExtrinsic f a b c
new_unsigned :: forall f a b c. f -> UncheckedExtrinsic f a b c
new_unsigned = Maybe (a, b, c) -> f -> UncheckedExtrinsic f a b c
forall c a s e. Maybe (a, s, e) -> c -> UncheckedExtrinsic c a s e
UncheckedExtrinsic Maybe (a, b, c)
forall a. Maybe a
Nothing
sign_extrinsic :: (MultiPair a, Encode c, SignedExtension e, JsonRpc m)
=> a
-> c
-> e
-> m (UncheckedExtrinsic c (MultiAddress a) (MultiSignature a) e)
sign_extrinsic :: forall a c e (m :: * -> *).
(MultiPair a, Encode c, SignedExtension e, JsonRpc m) =>
a
-> c
-> e
-> m (UncheckedExtrinsic c (MultiAddress a) (MultiSignature a) e)
sign_extrinsic a
a c
c e
e = do
MultiSignature a
sig <- a -> Payload c e -> m (MultiSignature a)
forall a c e (m :: * -> *).
(MultiPair a, Encode c, SignedExtension e, JsonRpc m) =>
a -> Payload c e -> m (MultiSignature a)
sign_payload a
a (c
c, e
e)
UncheckedExtrinsic c (MultiAddress a) (MultiSignature a) e
-> m (UncheckedExtrinsic c (MultiAddress a) (MultiSignature a) e)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (UncheckedExtrinsic c (MultiAddress a) (MultiSignature a) e
-> m (UncheckedExtrinsic c (MultiAddress a) (MultiSignature a) e))
-> UncheckedExtrinsic c (MultiAddress a) (MultiSignature a) e
-> m (UncheckedExtrinsic c (MultiAddress a) (MultiSignature a) e)
forall a b. (a -> b) -> a -> b
$ c
-> MultiAddress a
-> MultiSignature a
-> e
-> UncheckedExtrinsic c (MultiAddress a) (MultiSignature a) e
forall c a s e. c -> a -> s -> e -> UncheckedExtrinsic c a s e
new_signed c
c (a -> MultiAddress a
forall a. MultiPair a => a -> MultiAddress a
multi_address a
a) MultiSignature a
sig e
e