1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
//! ⚠️ This project is heavily work-in-progress and not ready for production => **API breakage expected!** //! //! Gekko offers utilities to parse substrate metadata, generate the //! corresponding Rust interfaces, create transactions and the ability to //! encode/decode those transaction. //! //! The project is split into multiple crates, although all functionality can be //! exposed by just using `gekko`. //! * `gekko` - Contains runtime interfaces to interact with Kusama, Polkadot //! and Westend, including creating transactions. //! * `gekko-metadata` - Utilities to parse and process substrate metadata. //! * Can also be enabled in `gekko` with the `"metadata"` feature. //! * `gekko-generator` - Macro to generate Rust interfaces during compile time //! based on the the parsed substrate metadata. //! * Can also be enabled in `gekko` with the `"generator"` feature. //! //! # Interacting with the runtime //! //! Gekko exposes multiple interfaces to interact with Kusama/Polkadot, such as //! extrinsics, storage entires, events, constants and errors. //! //! ### Disclaimer about types //! //! This library makes no assumptions about parameter types and must be //! specified manually as generic types. Each field contains a type description //! which can serve as a hint on what type is being expected, as provided by the //! runtime meatadata. See the [`common`] module for common types which can be //! used. //! //! ## Extrinsics. //! //! Transactions can be created by using a transaction builder from the //! [`transaction`] module. The transaction formats are versioned, reflecting //! the changes during Substrates history. Unless you're working with historic //! data, you probably want the latest version. //! //! Extrinsics can chosen from the [`runtime`] module and constructed //! accordingly. Take a look at the [`common`] module which contains utilities //! for creating transaction. //! //! ### Example //! //! ``` //! use gekko::common::*; //! use gekko::transaction::*; //! use gekko::runtime::polkadot::extrinsics::balances::TransferKeepAlive; //! //! // In this example, a random key is generated. You probably want to *import* one. //! let (keypair, _) = KeyPairBuilder::<Sr25519>::generate(); //! let currency = BalanceBuilder::new(Currency::Polkadot); //! //! // The destination address. //! let destination = //! AccountId::from_ss58_address("12eDex4amEwj39T7Wz4Rkppb68YGCDYKG9QHhEhHGtNdDy7D") //! .unwrap(); //! //! // Send 50 DOT to the destination. //! let call = TransferKeepAlive { //! dest: destination, //! value: currency.balance(50), //! }; //! //! // Transaction fee. //! let payment = currency.balance_as_metric(Metric::Milli, 10).unwrap(); //! //! // Build the final transaction. //! let transaction: PolkadotSignedExtrinsic<_> = SignedTransactionBuilder::new() //! .signer(keypair) //! .call(call) //! .nonce(0) //! .payment(payment) //! .network(Network::Polkadot) //! .spec_version(9050) //! .build() //! .unwrap(); //! ``` //! //! # Parsing Metadata //! //! Gekko offers utilities that allow you to search for specific extrinsics or //! to iterate through all of those. //! //! ## Example //! //! ```no_run //! use gekko::metadata::*; //! //! // Parse runtime metadata //! let content = std::fs::read_to_string("metadata_kusama_9080.hex").unwrap(); //! let data = parse_hex_metadata(content).unwrap().into_inner(); //! //! // Get information about the extrinsic. //! let extr = data //! .find_module_extrinsic("Balances", "transfer_keep_alive") //! .unwrap(); //! //! assert_eq!(extr.module_id, 4); //! assert_eq!(extr.dispatch_id, 3); //! assert_eq!( //! extr.args, //! vec![ //! ("dest", "<T::Lookup as StaticLookup>::Source"), //! ("value", "Compact<T::Balance>"), //! ] //! ); //! ``` //! //! A macro available in `gekko::generator` will parse the metadata //! automatically for you and generate the Rust interfaces at compile time. pub use runtime::*; #[cfg(feature = "dumps")] /// Raw Kusama and Polkadot runtime metadata dumps. pub mod dumps { pub use gekko_metadata::*; } #[cfg(feature = "generator")] /// Substrate runtime metadata generator for creating Rust interfaces. pub mod generator { pub use gekko_generator::*; } #[cfg(feature = "metadata")] /// Utilities for parsing substrate runtime metadata. pub mod metadata { pub use gekko_metadata::*; } pub mod transaction; // TODO: Rename to "primitives"? pub mod common; /// Types and interfaces to interact with runtimes. pub mod runtime { pub mod polkadot { pub use latest::*; /// The latest runtime types and interfaces. mod latest { /// The latest spec version. pub const SPEC_VERSION: u32 = 9050; #[gekko_generator::parse_from_hex_file("dumps/metadata_polkadot_9050.hex")] struct A; } } pub mod kusama { pub use latest::*; /// The latest runtime types and interfaces. mod latest { /// The latest spec version. pub const SPEC_VERSION: u32 = 9080; #[gekko_generator::parse_from_hex_file("dumps/metadata_kusama_9080.hex")] struct A; } } } pub type Result<T> = std::result::Result<T, Error>; #[derive(Debug, Clone)] pub enum Error { BuilderMissingField(&'static str), } /// Convenience function for crate internals. // TODO: Move this to `common::crypto` fn blake2b<T: AsRef<[u8]>>(payload: T) -> [u8; 32] { let mut hash = [0; 32]; hash.copy_from_slice(blake2_rfc::blake2b::blake2b(32, &[], payload.as_ref()).as_bytes()); hash }