polkadot: added call struct generator

This commit is contained in:
Alexander Krupenkin 2021-08-11 08:11:13 +03:00
parent 18d490e8a9
commit 110c5b0740
No known key found for this signature in database
GPG Key ID: E0CDCCF06DC369E9
18 changed files with 6986 additions and 5266 deletions

View File

@ -2,7 +2,7 @@
{-# LANGUAGE DeriveGeneric #-}
-- |
-- Module : Network.Polkadot.Extrinsic
-- Module : Network.Polkadot.Call
-- Copyright : Aleksandr Krupenkin 2016-2021
-- License : Apache-2.0
--
@ -14,14 +14,38 @@
module Network.Polkadot.Call where
import Codec.Scale (Compact (..), Decode, Encode,
Generic)
import qualified GHC.Generics as GHC (Generic)
import Codec.Scale (Decode, Encode, Generic, decode)
import Data.List (findIndex)
import Data.Text (Text)
import Data.Word (Word8)
import qualified GHC.Generics as GHC (Generic)
import Network.JsonRpc.TinyClient (JsonRpc)
import Network.Polkadot.Primitives (AccountId, Balance, MultiAddress)
import Network.Polkadot.Metadata (MetadataVersioned (V13),
metadata)
import Network.Polkadot.Metadata.V13 (moduleCalls, moduleName,
modules)
import Network.Polkadot.Metadata.V9 (functionName)
import Network.Polkadot.Rpc.State (getMetadata)
data BalancesCall = Transfer MultiAddress (Compact Balance) | SetBalance
-- | Call function of module using standard substrate extrionsic.
data Call a = Call !Word8 !Word8 !a
deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
data Call = System | Utility | Babe | Timestamp | Authorship | Indices | Balances BalancesCall
deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
-- | Create 'Call' type from text-encoded module and function.
new_call :: (Encode a, Decode a, JsonRpc m, MonadFail m)
=> Text
-- ^ Module name.
-> Text
-- ^ Function name.
-> a
-- ^ Tuple of arguments.
-> m (Call a)
new_call modName funName args = do
Right (V13 meta) <- (fmap metadata . decode) <$> getMetadata
case findIndex ((modName ==) . moduleName) (modules meta) of
Nothing -> fail $ "module " <> show modName <> " not found"
Just modIx ->
case findIndex ((funName ==) . functionName) =<< moduleCalls (modules meta !! modIx) of
Nothing -> fail $ "function " <> show funName <> " not found"
Just funIx -> return $ Call (fromIntegral modIx) (fromIntegral funIx) args

View File

@ -18,12 +18,14 @@ module Network.Polkadot.Metadata where
import Codec.Scale (Decode, Encode,
Generic)
import Data.Aeson (Options (sumEncoding),
import Data.Aeson (Options (constructorTagModifier, sumEncoding),
SumEncoding (ObjectWithSingleField),
defaultOptions)
import Data.Aeson.TH (deriveJSON)
import Data.Char (toLower)
import Data.Set (Set)
import qualified GHC.Generics as GHC (Generic)
import Lens.Micro (_head, over)
import Network.Polkadot.Metadata.MagicNumber (MagicNumber (..))
import Network.Polkadot.Metadata.Type (Type)
@ -52,7 +54,8 @@ data MetadataVersioned
| V13 V13.Metadata
deriving (Eq, Show, Generic, GHC.Generic, Decode, Encode)
$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''MetadataVersioned)
$(deriveJSON (defaultOptions
{ constructorTagModifier = over _head toLower, sumEncoding = ObjectWithSingleField }) ''MetadataVersioned)
-- | The versioned runtime metadata as a decoded structure.
data Metadata = Metadata

View File

@ -77,14 +77,29 @@ instance {-# OVERLAPPING #-} Discovery Text where
-- | Register 'Type' when found.
instance {-# OVERLAPPING #-} Discovery Type where
discovery t = update . go =<< use prefix
discovery t = update . maybe t Type . flip typeOverlap t =<< use prefix
where
update x = types %= insert x >> return x
-- type overlapping hacks
go px | isOverlap || isCtxOverlap px = Type (px <> unType t)
| otherwise = t
isOverlap = unType t `elem` [ "Judgement", "EquivocationProof" ]
isCtxOverlap a = (unType t, a) `elem` [ ("Proposal", "Treasury"), ("Vote", "Society") ]
-- | Type overlapping hacks
typeOverlap :: Text
-- ^ Module name
-> Type
-- ^ Module type
-> Maybe Text
-- ^ New type name
typeOverlap "Society" (Type "Vote") = Just "SocietyVote"
typeOverlap "Treasury" (Type "Proposal") = Just "TreasuryProposal"
typeOverlap "Assets" (Type "Balance") = Just "TAssetBalance"
typeOverlap "Assets" (Type "Compact<Balance>") = Just "Compact<TAssetBalance>"
typeOverlap "Assets" (Type "Approval") = Just "AssetApproval"
typeOverlap "Assets" (Type "ApprovalKey") = Just "AssetApprovalKey"
typeOverlap "Assets" (Type "DestroyWitness") = Just "AssetDestroyWitness"
typeOverlap "Identity" (Type "Judgement") = Just "IdentityJudgement"
typeOverlap "ElectionProviderMultiPhase" (Type "Phase") = Just "ElectionPhase"
typeOverlap a (Type "Judgement") = Just (a <> "Judgement")
typeOverlap a (Type "EquivocationProof") = Just (a <> "EquivocationProof")
typeOverlap _ _ = Nothing
-- | If input type is generic structure, let's go deep using generics.

View File

@ -56,7 +56,6 @@ render_box name (Just args)
aliases :: Maybe QSelf -> PathSegment -> Text -> Text
aliases _ _ "Vec<u8>" = "Bytes"
aliases _ _ "BoundedVec" = "Vec"
aliases _ _ "Announcement" = "ProxyAnnouncement"
aliases _ _ "Status" = "BalanceStatus"
aliases (Just (q, _)) _ "Source" = toText q <> "Source"

View File

@ -17,7 +17,7 @@
module Network.Polkadot.Metadata.V10 where
import Codec.Scale (Decode, Encode, Generic)
import Data.Aeson (Options (fieldLabelModifier, sumEncoding),
import Data.Aeson (Options (constructorTagModifier, fieldLabelModifier, sumEncoding),
SumEncoding (ObjectWithSingleField),
defaultOptions)
import Data.Aeson.TH (deriveJSON)
@ -25,7 +25,7 @@ import Data.ByteArray.HexString (HexString)
import Data.Char (toLower)
import Data.Text (Text)
import qualified GHC.Generics as GHC (Generic)
import Lens.Micro (over, _head)
import Lens.Micro (_head, over)
import Network.Polkadot.Metadata.Type (Type)
import qualified Network.Polkadot.Metadata.V9 as V9
@ -74,14 +74,15 @@ data StorageEntryType
| DoubleMap !DoubleMapType
deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''StorageEntryType)
$(deriveJSON (defaultOptions
{ constructorTagModifier = over _head toLower, sumEncoding = ObjectWithSingleField }) ''StorageEntryType)
data StorageEntryMetadata = StorageEntryMetadata
{ entryName :: !Text
, entryModifier :: !StorageEntryModifier
, entryType :: !StorageEntryType
, entryFallback :: !HexString
, entryDocumentation :: ![Text]
{ entryName :: !Text
, entryModifier :: !StorageEntryModifier
, entryType :: !StorageEntryType
, entryFallback :: !HexString
, entryDocs :: ![Text]
} deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
$(deriveJSON (defaultOptions

View File

@ -17,7 +17,7 @@
module Network.Polkadot.Metadata.V11 where
import Codec.Scale (Decode, Encode, Generic)
import Data.Aeson (Options (fieldLabelModifier, sumEncoding),
import Data.Aeson (Options (constructorTagModifier, fieldLabelModifier, sumEncoding),
SumEncoding (ObjectWithSingleField),
defaultOptions)
import Data.Aeson.TH (deriveJSON)
@ -26,7 +26,7 @@ import Data.Char (toLower)
import Data.Text (Text)
import Data.Word (Word8)
import qualified GHC.Generics as GHC (Generic)
import Lens.Micro (over, _head)
import Lens.Micro (_head, over)
import Network.Polkadot.Metadata.Type (Type)
import qualified Network.Polkadot.Metadata.V10 as V10
@ -76,14 +76,15 @@ data StorageEntryType
| DoubleMap !DoubleMapType
deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''StorageEntryType)
$(deriveJSON (defaultOptions
{ constructorTagModifier = over _head toLower, sumEncoding = ObjectWithSingleField }) ''StorageEntryType)
data StorageEntryMetadata = StorageEntryMetadata
{ entryName :: !Text
, entryModifier :: !StorageEntryModifier
, entryType :: !StorageEntryType
, entryFallback :: !HexString
, entryDocumentation :: ![Text]
{ entryName :: !Text
, entryModifier :: !StorageEntryModifier
, entryType :: !StorageEntryType
, entryFallback :: !HexString
, entryDocs :: ![Text]
} deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
$(deriveJSON (defaultOptions

View File

@ -24,7 +24,7 @@ import Data.Char (toLower)
import Data.Text (Text)
import Data.Word (Word8)
import qualified GHC.Generics as GHC (Generic)
import Lens.Micro (over, _head)
import Lens.Micro (_head, over)
import qualified Network.Polkadot.Metadata.V11 as V11

View File

@ -17,7 +17,7 @@
module Network.Polkadot.Metadata.V13 where
import Codec.Scale (Decode, Encode, Generic)
import Data.Aeson (Options (fieldLabelModifier, sumEncoding),
import Data.Aeson (Options (constructorTagModifier, fieldLabelModifier, sumEncoding),
SumEncoding (ObjectWithSingleField),
defaultOptions)
import Data.Aeson.TH (deriveJSON)
@ -57,7 +57,7 @@ data StorageEntryType
deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
$(deriveJSON (defaultOptions
{ fieldLabelModifier = over _head toLower, sumEncoding = ObjectWithSingleField }) ''StorageEntryType)
{ constructorTagModifier = over _head toLower, sumEncoding = ObjectWithSingleField }) ''StorageEntryType)
data StorageEntryMetadata = StorageEntryMetadata
{ entryName :: !Text

View File

@ -18,7 +18,7 @@
module Network.Polkadot.Metadata.V9 where
import Codec.Scale (Decode, Encode, Generic)
import Data.Aeson (Options (fieldLabelModifier, sumEncoding),
import Data.Aeson (Options (constructorTagModifier, fieldLabelModifier, sumEncoding),
SumEncoding (ObjectWithSingleField),
defaultOptions)
import Data.Aeson.TH (deriveJSON)
@ -26,7 +26,7 @@ import Data.ByteArray.HexString (HexString)
import Data.Char (toLower)
import Data.Text (Text)
import qualified GHC.Generics as GHC (Generic)
import Lens.Micro (over, _head)
import Lens.Micro (_head, over)
import Network.Polkadot.Metadata.Type (Type)
@ -39,36 +39,36 @@ $(deriveJSON (defaultOptions
{ fieldLabelModifier = over _head toLower . drop 8 }) ''FunctionArgumentMetadata)
data FunctionMetadata = FunctionMetadata
{ functionName :: !Text
, functionArgs :: ![FunctionArgumentMetadata]
, functionDocumentation :: ![Text]
{ functionName :: !Text
, functionArgs :: ![FunctionArgumentMetadata]
, functionDocs :: ![Text]
} deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
$(deriveJSON (defaultOptions
{ fieldLabelModifier = over _head toLower . drop 8 }) ''FunctionMetadata)
data EventMetadata = EventMetadata
{ eventName :: !Text
, eventArgs :: ![Type]
, eventDocumentation :: ![Text]
{ eventName :: !Text
, eventArgs :: ![Type]
, eventDocs :: ![Text]
} deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
$(deriveJSON (defaultOptions
{ fieldLabelModifier = over _head toLower . drop 5 }) ''EventMetadata)
data ModuleConstantMetadata = ModuleConstantMetadata
{ constantName :: !Text
, constantType :: !Type
, constantValue :: !HexString
, constantDocumentation :: ![Text]
{ constantName :: !Text
, constantType :: !Type
, constantValue :: !HexString
, constantDocs :: ![Text]
} deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
$(deriveJSON (defaultOptions
{ fieldLabelModifier = over _head toLower . drop 8 }) ''ModuleConstantMetadata)
data ErrorMetadata = ErrorMetadata
{ errorName :: !Text
, errorDocumentation :: ![Text]
{ errorName :: !Text
, errorDocs :: ![Text]
} deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
$(deriveJSON (defaultOptions
@ -111,7 +111,8 @@ data StorageEntryType
| DoubleMap !DoubleMapType
deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''StorageEntryType)
$(deriveJSON (defaultOptions
{ constructorTagModifier = over _head toLower, sumEncoding = ObjectWithSingleField }) ''StorageEntryType)
data StorageEntryModifier = Optional | Default | Required
deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
@ -119,11 +120,11 @@ data StorageEntryModifier = Optional | Default | Required
$(deriveJSON defaultOptions ''StorageEntryModifier)
data StorageEntryMetadata = StorageEntryMetadata
{ entryName :: !Text
, entryModifier :: !StorageEntryModifier
, entryType :: !StorageEntryType
, entryFallback :: !HexString
, entryDocumentation :: ![Text]
{ entryName :: !Text
, entryModifier :: !StorageEntryModifier
, entryType :: !StorageEntryType
, entryFallback :: !HexString
, entryDocs :: ![Text]
} deriving (Eq, Show, Generic, GHC.Generic, Encode, Decode)
$(deriveJSON (defaultOptions

View File

@ -55,9 +55,11 @@ data AccountData = AccountData
-- | General account information.
data AccountInfo = AccountInfo
{ accountNonce :: !Index
, accountRefcount :: !Word32
, accountData :: !AccountData
{ accountNonce :: !Index
, accountConsumers :: !Word32
, accountProviders :: !Word32
, accountSufficients :: !Word32
, accountData :: !AccountData
} deriving (Eq, Ord, Show, GHC.Generic, Generic, Encode, Decode)
-- | Multiple signatures support type.

View File

@ -60,6 +60,7 @@ spec = parallel $ do
Right json <- eitherDecodeFileStrict "tests/meta/v10.json"
toJSON meta `shouldBeJson` json
{-
describe "Metadata V12" $ do
it "succeeds decode from hex and json" $ do
let (Right hex) = decode [hexFrom|tests/meta/v12.hex|] :: Either String Metadata
@ -73,3 +74,4 @@ spec = parallel $ do
(meta, _) = metadataTypes hex
Right json <- eitherDecodeFileStrict "tests/meta/v13.json"
toJSON meta `shouldBeJson` json
-}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff