From 97ed9b61d6f36d0684bf5a3fee420b2102a0fb35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=92=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=B8=D0=BC=D0=B8=D1=80=D0=BE=D0=B2?= <32911557+vladimirovmm@users.noreply.github.com> Date: Tue, 15 Feb 2022 20:28:31 +0500 Subject: [PATCH] [v1.6] $ dove deploy [FILE_NAME|PATH] [OPTIONS] (#212) * rebase master * rebase master * fix * debug comments removed * subxt client * $ dove deploy * README.md + hints * Updating the comment * rename PublishParamsCmd => NodeAccessParams * build.rs: debugging mode * Revert "build.rs: debugging mode" This reverts commit 7594eae07aa3544c9b14f0fe2e10149e25b1e552. * [test] $ dove deploy --- Cargo.lock | 44 + Cargo.toml | 2 + README.md | 37 +- dove/Cargo.toml | 1 + dove/src/cmd/deploy.rs | 179 +- dove/src/cmd/key.rs | 4 +- dove/src/lib.rs | 2 + dove/src/publish.rs | 200 ++ dove/src/wallet_key.rs | 2 +- dove/tests/test_cmd_dove_deploy.rs | 46 + pontem/client/Cargo.toml | 19 + pontem/client/build.rs | 19 + pontem/client/src/lib.rs | 223 ++ pontem/hash_project/Cargo.toml | 18 + pontem/hash_project/src/lib.rs | 106 + pontem/pontemapi/Cargo.lock | 3021 ++++++++++++++++++++++++ pontem/pontemapi/Cargo.toml | 23 + pontem/pontemapi/metadata/pontem.scale | Bin 0 -> 111486 bytes pontem/pontemapi/src/lib.rs | 603 +++++ 19 files changed, 4491 insertions(+), 58 deletions(-) create mode 100644 dove/src/publish.rs create mode 100644 dove/tests/test_cmd_dove_deploy.rs create mode 100644 pontem/client/Cargo.toml create mode 100644 pontem/client/build.rs create mode 100644 pontem/client/src/lib.rs create mode 100644 pontem/hash_project/Cargo.toml create mode 100644 pontem/hash_project/src/lib.rs create mode 100644 pontem/pontemapi/Cargo.lock create mode 100644 pontem/pontemapi/Cargo.toml create mode 100644 pontem/pontemapi/metadata/pontem.scale create mode 100644 pontem/pontemapi/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index bc2871dd..3695755c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -704,6 +704,7 @@ dependencies = [ "move-vm-types", "once_cell", "pontem", + "pontem-client", "rand 0.7.3", "regex", "reqwest", @@ -1057,6 +1058,16 @@ dependencies = [ "tracing-futures", ] +[[package]] +name = "hash_project" +version = "0.1.0" +dependencies = [ + "anyhow", + "log", + "sha256", + "toml", +] + [[package]] name = "hashbrown" version = "0.11.2" @@ -1417,6 +1428,16 @@ version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" +[[package]] +name = "libloading" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +dependencies = [ + "cfg-if 1.0.0", + "winapi 0.3.9", +] + [[package]] name = "linked-hash-map" version = "0.5.4" @@ -2750,6 +2771,19 @@ dependencies = [ "rust-base58", ] +[[package]] +name = "pontem-client" +version = "0.15.0" +dependencies = [ + "anyhow", + "env_logger", + "hash_project", + "libloading", + "log", + "rand 0.8.4", + "url", +] + [[package]] name = "ppv-lite86" version = "0.2.16" @@ -3357,6 +3391,16 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "sha256" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e84a7f596c081d359de5e06a83877138bc3c4483591e1af1916e1472e6e146e" +dependencies = [ + "hex", + "sha2", +] + [[package]] name = "sha3" version = "0.9.1" diff --git a/Cargo.toml b/Cargo.toml index 0d230fb0..c3a841ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,9 @@ members = [ "dove", "lang", "common/git-hash", + "pontem/client" ] +exclude = [ "pontem/hash_project", "pontem/pontemapi"] [profile.release] lto = "thin" diff --git a/README.md b/README.md index 9a9048ae..8f56bc33 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ cargo install --path ./dove dove -h ``` -##### Create new project: +## Create new project: ```shell script dove new first_project @@ -36,7 +36,7 @@ dove new first_project This command will create `first_project/` directory with special `Move.toml` manifest file and `sources/` directory for Move source code. -##### Build project: +## Build project: ```shell script dove build @@ -60,7 +60,7 @@ The contents of the directories will be deleted: - `/build` - `~/.move/` -### Pallet Transactions +## Pallet Transactions Command `call` allows you to create transactions for Polkadot chain with [Move Pallete](https://github.com/pontem-network/sp-move) on board. @@ -130,10 +130,11 @@ Migrated inside Dove, see help: dove run --help ``` -### Manage wallet keys +## Manage wallet keys Command `key` allows you to save the secret keys to the wallet on your computer and access them under an alias. -Saved key can be used when publishing a module `$ dove deploy module --account ...` or package `$ dove deploy package --account ...`, as well as when execute a transaction `$ dove call --account ...`. +Saved key can be used when publishing a module or bundle `$ dove deploy --account ...`, +as well as when execute a transaction `$ dove call --account ...`. Keys are stored on your computer in the `~/.move/` directory. Before saving, they are encrypted with the aes + password. #### Adding a key: @@ -169,6 +170,32 @@ Deleting all saved keys: dove key delete --all ``` +## Publishing a module or package + +```bash +$ dove deploy [FILE_NAME|PATH_TO_FILE] [OPTIONS] +``` +### Input parameters +- [FILE_NAME] - Name of module or package to be published. +- [PATH_TO_FILE] - Path to the file to be published. Expected file extension: + - `pac` bundle + - `mv` module + - `mvt` transaction +- `-g` / `--gas` Limitation of gas consumption per operation. A positive integer is expected +- `-u` / `--url` The url of the substrate node to query [default: ws://localhost:9944]. HTTP, HTTPS, WS protocols are supported. It is recommended to use WS. When using HTTP or HTTPS, you cannot get the publication status. +- `--account` Account from whom to publish. Address or test account name or name wallet key. Example: //Alice, alice, bob, NAME_WALLET_KEY... or 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY. When used in combination with `--secret` is ignored. +- `-s` / `--secret` Secret phrase. If a secret phrase is specified, you do not need to specify. +- `modules_exclude` Names of modules to exclude from the package process. + +### Examples: +```bash +dove deploy +dove deploy PACKAGE_NAME --account WALLET_KEY --gas 300 +dove deploy PACKAGE_NAME --secret --url ws://127.0.0.1:9944 --gas 400 --modules_exclude MODULE_NAME_1 MODULE_NAME_2 .. +dove deploy MODULE_NAME --secret --url https://127.0.0.1:9933 --gas 400 +dove deploy PATH/TO/FILE --account //Alice --gas 300 +``` + ## LICENSE [LICENSE](/LICENSE) diff --git a/dove/Cargo.toml b/dove/Cargo.toml index 76f355f9..8275a285 100644 --- a/dove/Cargo.toml +++ b/dove/Cargo.toml @@ -13,6 +13,7 @@ edition = "2021" # LOCAL git-hash = { path = "../common/git-hash" } lang = { path = "../lang" } +pontem-client = { path = "../pontem/client" } # DIEM move-core-types = { git = "https://github.com/pontem-network/move.git", branch = "release-1.6" } diff --git a/dove/src/cmd/deploy.rs b/dove/src/cmd/deploy.rs index e8addd8b..ca10c215 100644 --- a/dove/src/cmd/deploy.rs +++ b/dove/src/cmd/deploy.rs @@ -1,26 +1,41 @@ use core::mem; use std::collections::HashMap; use std::fs; -use std::ffi::OsStr; +use std::str::FromStr; use std::fs::remove_file; use std::path::{PathBuf, Path}; + use anyhow::Error; use structopt::StructOpt; +use serde::{Serialize, Deserialize}; use anyhow::Result; +use itertools::Itertools; + use move_binary_format::access::ModuleAccess; use move_binary_format::CompiledModule; - use move_cli::Command as MoveCommand; use move_cli::package::cli::PackageCommand; use move_cli::run_cli; use move_core_types::language_storage::ModuleId; use crate::context::Context; -use serde::{Serialize, Deserialize}; +use crate::publish::{NodeAccessParams, Publish}; -#[derive(StructOpt, Debug, Default)] +#[derive(StructOpt, Debug)] #[structopt(setting(structopt::clap::AppSettings::ColoredHelp))] +#[structopt(usage = "dove deploy [FILE_NAME|PATH] [OPTIONS] + Examples: + $ dove deploy + $ dove deploy PACKAGE_NAME --account WALLET_KEY --gas 300 + $ dove deploy PACKAGE_NAME --secret --url ws://127.0.0.1:9944 --gas 400 --modules_exclude MODULE_NAME_1 MODULE_NAME_2 .. + $ dove deploy MODULE_NAME --secret --url https://127.0.0.1:9933 --gas 400 + $ dove deploy PATH/TO/FILE --account //Alice --gas 300 +")] pub struct Deploy { + #[structopt(help = "Module/Bundle name or path")] + file: Option, + + // * Only for bundle // Names of modules to exclude from the package process. // Modules are taken from the /build//bytecode_modules directory. // The names are case-insensitive and can be specified with an extension.mv or without it. @@ -31,12 +46,8 @@ pub struct Deploy { )] modules_exclude: Vec, - #[structopt( - help = "File name of the resulting .pac file.", - short = "o", - long = "output" - )] - output: Option, + #[structopt(flatten)] + request: NodeAccessParams, } impl Deploy { @@ -47,19 +58,18 @@ impl Deploy { // packaging of modules self.bundle_modules_into_pac(ctx)?; - Ok(()) + if !self.request.need_to_publish() { + return Ok(()); + } + + // Publish a bundle or module to a node + self.publish(ctx) } -} -impl Deploy { fn bundle_modules_into_pac(&self, ctx: &Context) -> Result<()> { // Path to the output file let output_file_path = ctx - .bundles_output_path( - self.output - .as_deref() - .unwrap_or_else(|| ctx.manifest.package.name.as_str()), - )? + .bundles_output_path(ctx.manifest.package.name.as_str())? .with_extension("pac"); if output_file_path.exists() { remove_file(&output_file_path)?; @@ -96,41 +106,26 @@ impl Deploy { ); Ok(()) } -} -/// Return file paths from ./PROJECT_FOLDER/build/PROJECT_NAME/bytecode_modules -/// Only with the .mv extension -fn get_bytecode_modules_path(project_dir: &Path, project_name: &str) -> Result> { - let path = project_dir - .join("build") - .join(project_name) - .join("bytecode_modules"); - if !path.exists() { - return Ok(Vec::new()); - } + /// Publish a bundle or module to a node + fn publish(&self, ctx: &Context) -> Result<()> { + let file_name = self + .file + .as_ref() + .ok_or(anyhow!("File name not specified"))?; - let list = fs::read_dir(path)? - .map(|res| res.map(|e| e.path())) - .collect::, _>>() - .map(|list| { - list.into_iter() - .filter(|path| path.is_file() && path.extension() == Some(OsStr::new("mv"))) - .collect::>() - })?; - Ok(list) -} + let file_path = if let Some(path) = str_to_path(file_name) { + path + } else { + search_by_file_name(&ctx.project_root_dir, file_name)? + }; -pub fn run_dove_package_build(ctx: &mut Context) -> Result<()> { - let build_cmd = MoveCommand::Package { - cmd: PackageCommand::Build {}, - }; - run_cli( - ctx.native_functions.clone(), - &ctx.cost_table, - &ctx.error_descriptions, - &ctx.move_args, - &build_cmd, - ) + Publish::try_from((&self.request, file_path))? + .apply() + .map(|address| { + println!("Address: {}", address); + }) + } } #[derive(Serialize, Deserialize, Debug, Default)] @@ -193,3 +188,87 @@ impl ModulePackage { bcs::to_bytes(&self).map_err(|err| err.into()) } } + +/// Return file paths from ./PROJECT_FOLDER/build/PROJECT_NAME/bytecode_modules +/// Only with the .mv extension +fn get_bytecode_modules_path(project_dir: &Path, project_name: &str) -> Result> { + let path = project_dir + .join("build") + .join(project_name) + .join("bytecode_modules"); + if !path.exists() { + return Ok(Vec::new()); + } + + search_by_extension(&path, &["mv"]) +} + +pub fn run_dove_package_build(ctx: &mut Context) -> Result<()> { + let build_cmd = MoveCommand::Package { + cmd: PackageCommand::Build {}, + }; + run_cli( + ctx.native_functions.clone(), + &ctx.cost_table, + &ctx.error_descriptions, + &ctx.move_args, + &build_cmd, + ) +} + +#[inline] +fn str_to_path(path: &str) -> Option { + PathBuf::from_str(path) + .ok() + .and_then(|path| path.canonicalize().ok()) +} + +/// Recursive file search by extension list +fn search_by_extension(path: &Path, list_extension: &[&str]) -> Result> { + let list = fs::read_dir(path)? + .map(|res| res.map(|e| e.path())) + .collect::, _>>()? + .into_iter() + .filter_map(|path| { + if path.is_dir() { + search_by_extension(&path, list_extension).ok() + } else if path.is_file() { + let ext = path + .extension() + .and_then(|t| t.to_str()) + .unwrap_or_default(); + if list_extension.contains(&ext) { + Some(vec![path]) + } else { + None + } + } else { + None + } + }) + .flatten() + .collect::>(); + Ok(list) +} + +fn search_by_file_name(path_project: &Path, file_name: &str) -> Result { + let mut list: Vec = search_by_extension(path_project, &["mv", "mvt", "pac"])? + .into_iter() + .filter(|path| { + let name_ext = path.file_name().and_then(|name| name.to_str()); + let name = path.file_stem().and_then(|name| name.to_str()); + name_ext == Some(file_name) || name == Some(file_name) + }) + .collect(); + if list.is_empty() { + bail!(r#"File named "{}" not found"#, file_name); + } else if list.len() > 1 { + let paths_string: String = list.iter().map(|path| path.display()).join("\n"); + bail!( + r"Found more than one file named {:?}\nSpecify the full path to the file\n{}", + file_name, + paths_string + ) + } + Ok(list.remove(0)) +} diff --git a/dove/src/cmd/key.rs b/dove/src/cmd/key.rs index 7d4b08a2..ef290a62 100644 --- a/dove/src/cmd/key.rs +++ b/dove/src/cmd/key.rs @@ -74,7 +74,7 @@ impl Key { fn add(alias: &str, without_password: bool) -> Result<()> { let alias = wallet_key::valid_alias(alias)?; - if wallet_key::isset(&alias) { + if wallet_key::existence(&alias) { bail!(r#"A key with name "{}" already exists"#, alias); } @@ -124,7 +124,7 @@ fn read_password() -> Result { Ok(password) } -fn cli_entering_a_secret_phrase() -> Result { +pub fn cli_entering_a_secret_phrase() -> Result { println!("Please enter secret phrase:"); let key_phrase = cli_read_line()?; diff --git a/dove/src/lib.rs b/dove/src/lib.rs index e304da84..76483adb 100644 --- a/dove/src/lib.rs +++ b/dove/src/lib.rs @@ -33,6 +33,8 @@ pub mod natives; /// To work with stored access keys pub mod wallet_key; +pub mod publish; + /// Get the location of the ".move" directory. /// Default: ~/.move/ /// If the directory "~/.move/" does not exist, it will be created. diff --git a/dove/src/publish.rs b/dove/src/publish.rs new file mode 100644 index 00000000..3b39263b --- /dev/null +++ b/dove/src/publish.rs @@ -0,0 +1,200 @@ +use std::path::PathBuf; + +use anyhow::Error; +use structopt::StructOpt; +use anyhow::Result; +use url::Url; + +use pontem_client::PontemClient; +use crate::cmd::key::cli_entering_a_secret_phrase; +use crate::wallet_key; +use crate::wallet_key::WalletKey; + +#[derive(StructOpt, Debug)] +#[structopt(setting(structopt::clap::AppSettings::ColoredHelp))] +pub struct NodeAccessParams { + /// Account from whom to publish. Address or test account name or name secret key. + /// Example: //Alice, alice, bob, NAME_WALLET_KEY... or 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + #[structopt(long = "account")] + account: Option, + + /// Secret phrase. + /// If a secret phrase is specified, you do not need to specify an account + #[structopt(long = "secret", short)] + secret_phrase: bool, + + /// The url of the substrate node to query + #[structopt( + long = "url", + short, + parse(try_from_str), + default_value = "ws://localhost:9944" + )] + url_to_node: Url, + + /// Limitation of gas consumption per operation + #[structopt(long = "gas", short)] + gas_limit: Option, +} + +impl NodeAccessParams { + pub fn need_to_publish(&self) -> bool { + self.account.is_some() || self.secret_phrase + } +} + +pub struct Publish { + /// Client for connecting to "Pontem" + client: PontemClient, + + /// Path to the file to be published + file_path: PathBuf, + + /// Limitation of gas consumption per operation + gas_limit: u64, + + /// Access type - by secret phrase or through a test account + access: AccessType, +} + +impl Publish { + pub fn apply(&self) -> Result { + match self.file_type()? { + FileType::Module => match &self.access { + AccessType::SecretPhrase(secret) => self.client.tx_mvm_publish_module( + self.file_path_as_str()?, + self.gas_limit, + secret, + ), + AccessType::TestAccount(test_account) => self.client.tx_mvm_publish_module_dev( + self.file_path_as_str()?, + self.gas_limit, + test_account, + ), + }, + FileType::Bundle => match &self.access { + AccessType::SecretPhrase(secret) => self.client.tx_mvm_publish_package( + self.file_path_as_str()?, + self.gas_limit, + secret, + ), + AccessType::TestAccount(test_account) => self.client.tx_mvm_publish_package_dev( + self.file_path_as_str()?, + self.gas_limit, + test_account, + ), + }, + FileType::TX => match &self.access { + AccessType::SecretPhrase(secret) => { + self.client + .tx_mvm_execute(self.file_path_as_str()?, self.gas_limit, secret) + } + AccessType::TestAccount(test_account) => self.client.tx_mvm_execute_dev( + self.file_path_as_str()?, + self.gas_limit, + test_account, + ), + }, + } + } +} + +/// PublishParamsCmd - Connection parameters +/// PathBuf - The path to the file to be published (*.mvt, *.mv, *.pac) +impl TryFrom<(&NodeAccessParams, PathBuf)> for Publish { + type Error = Error; + + fn try_from(value: (&NodeAccessParams, PathBuf)) -> std::result::Result { + let (params, file_path) = value; + let gas_limit = params + .gas_limit + .ok_or(anyhow!("Please specify gas limit"))?; + let mut url_to_node = params.url_to_node.clone(); + + let access = if params.secret_phrase { + // Request secret phrases + let secret = cli_entering_a_secret_phrase()?; + AccessType::SecretPhrase(secret) + } else if let Some(test_account_or_name_key) = ¶ms.account { + match cli_name_to_key(test_account_or_name_key)? { + Some(WalletKey { + secret_phrase, + node_address, + }) => { + url_to_node = node_address; + AccessType::SecretPhrase(secret_phrase) + } + None => AccessType::TestAccount(test_account_or_name_key.to_owned()), + } + } else { + bail!("Specify name of key or name of test account or secret phrase") + }; + + let client = PontemClient::new(url_to_node.as_str())?; + + Ok(Publish { + client, + access, + gas_limit, + file_path, + }) + } +} + +impl Publish { + fn file_type(&self) -> Result { + let ext = self + .file_path + .extension() + .and_then(|ext| ext.to_str()) + .unwrap_or_default() + .to_string(); + + Ok(match ext.as_str() { + "pac" => FileType::Bundle, + "mv" => FileType::Module, + "mvt" => FileType::TX, + _ => bail!( + "pac or mv extension was expected\n{}", + self.file_path.display() + ), + }) + } + + fn file_path_as_str(&self) -> Result<&str> { + self.file_path + .to_str() + .ok_or(anyhow!("Error converting path to string")) + } +} + +/// Access type - by secret phrase or through a test account +enum AccessType { + SecretPhrase(String), + TestAccount(String), +} + +enum FileType { + Bundle, + Module, + TX, +} + +/// Checking for a key with this name and getting the content +fn cli_name_to_key(key_name: &str) -> Result> { + // Checking for a saved key with this name + if !wallet_key::existence(key_name) { + return Ok(None); + } + + // Trying to get secret phrases without a password + let mut phrase = wallet_key::get(key_name, None); + if phrase.is_err() { + // Password required + println!("Please enter password for key:"); + let password = rpassword::read_password()?.trim().to_string(); + phrase = + wallet_key::get(key_name, Some(&password)).map_err(|_| anyhow!("Invalid password")) + } + phrase.map(Some) +} diff --git a/dove/src/wallet_key.rs b/dove/src/wallet_key.rs index d2e33175..99df0baf 100644 --- a/dove/src/wallet_key.rs +++ b/dove/src/wallet_key.rs @@ -68,7 +68,7 @@ pub fn get(alias: &str, password: Option<&str>) -> Result { /// Check if there is a secret phrase with this alias /// ~/.move/.key #[inline] -pub fn isset(alias: &str) -> bool { +pub fn existence(alias: &str) -> bool { path(alias).map_or(false, |path| path.exists()) } diff --git a/dove/tests/test_cmd_dove_deploy.rs b/dove/tests/test_cmd_dove_deploy.rs new file mode 100644 index 00000000..4ee5b1c6 --- /dev/null +++ b/dove/tests/test_cmd_dove_deploy.rs @@ -0,0 +1,46 @@ +mod helpers; + +use std::fs; +use std::io::Read; +use helpers::{delete_project, dove, new_demo_project}; + +/// Build a project and package +/// $ dove deploy --modules_exclude Demo1v Demo2v +#[test] +fn test_cmd_dove_deploy() { + let project_name = "project_deploy"; + let project_path = new_demo_project(project_name).unwrap(); + + dove( + &["deploy", "--modules_exclude", "Demo1v", "Demo2v"], + &project_path, + ) + .unwrap(); + + let mut content = Vec::new(); + fs::File::open( + project_path + .join("build") + .join("for_tests") + .join("bundles") + .join("for_tests.pac"), + ) + .unwrap() + .read_to_end(&mut content) + .unwrap(); + + assert!(find_u8(&content, b"Demo3v")); + assert!(!find_u8(&content, b"Demo2v")); + assert!(!find_u8(&content, b"Demo1v")); + assert!(!find_u8(&content, b"main")); + + delete_project(&project_path).unwrap(); +} + +fn find_u8(source: &[u8], need: &[u8]) -> bool { + source.iter().enumerate().any(|(pos, _)| { + need.iter() + .enumerate() + .all(|(index, byte)| Some(byte) == source.get(index + pos)) + }) +} diff --git a/pontem/client/Cargo.toml b/pontem/client/Cargo.toml new file mode 100644 index 00000000..2402a2b2 --- /dev/null +++ b/pontem/client/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "pontem-client" +version = "0.15.0" +edition = "2021" + +# the script for building the library "subxt" +build = "build.rs" + +[dependencies] +anyhow = "1.0" +libloading = ">=0.6" +rand = ">=0.3" +url = ">=2" +# +hash_project = { path = "../hash_project" } + +[dev-dependencies] +env_logger = "0.9" +log = "0.4" diff --git a/pontem/client/build.rs b/pontem/client/build.rs new file mode 100644 index 00000000..aedfde33 --- /dev/null +++ b/pontem/client/build.rs @@ -0,0 +1,19 @@ +use std::path::PathBuf; + +fn main() { + println!(r#"Building: pontemapi"#); + + let lib_path = PathBuf::from("../pontemapi").canonicalize().unwrap(); + let result = std::process::Command::new("cargo") + .args(["build", "--release"]) + .current_dir(&lib_path) + .output() + .unwrap(); + + if result.status.code() != Some(0) { + let error = String::from_utf8(result.stderr).unwrap_or_default(); + println!("Error: {}", error); + panic!(r#"Failed to create "pontemapi" library"#); + } + println!(r#"Building of the "pontempi" library is completed"#) +} diff --git a/pontem/client/src/lib.rs b/pontem/client/src/lib.rs new file mode 100644 index 00000000..7f709600 --- /dev/null +++ b/pontem/client/src/lib.rs @@ -0,0 +1,223 @@ +use std::fs; +use anyhow::{Error, Result}; +use libloading::Library; +use url::Url; + +/// Path to the compiled library +#[cfg(target_os = "linux")] +const LIB_PONTEMAPI: &[u8] = include_bytes!("../../pontemapi/target/release/libpontemapi.so"); + +/// Path to the compiled library +#[cfg(target_os = "macos")] +const LIB_PONTEMAPI: &[u8] = include_bytes!("../../pontemapi/target/release/libpontemapi.dylib"); + +/// Path to the compiled library +#[cfg(target_os = "windows")] +const LIB_PONTEMAPI: &[u8] = include_bytes!("../../pontemapi/target/release/libpontemapi.dll"); + +/// Library Version pontemapi +#[cfg(not(doc))] +const LIB_VERSION: &str = hash_project::version!("pontem/pontemapi"); + +/// Docgen is launched from the current directory +#[cfg(doc)] +const LIB_VERSION: &str = hash_project::version!("../pontemapi"); + +/// Type of function from the library +type FnInterface = unsafe fn(&str, &str, u64, &str) -> Result; + +/// Client for publishing module, bundle, transactions to node +pub struct PontemClient { + lib: Library, + /// url: Node address. ws://127.0.0.1:9944 + url: Url, +} + +impl PontemClient { + /// Creating a temporary library file and initializing the library + /// url: Node address. ws://127.0.0.1:9944 + pub fn new(url: &str) -> Result { + let url = Url::parse(url)?; + let lib = PontemClient::load()?; + + Ok(PontemClient { lib, url }) + } + + /// Publishing the module. + /// package_path: The path to the module file. PATH/TO/MODULE/FILE.mv + /// gas: Gas limit for transaction execution. + /// key_phrase: secret keyphrase + pub fn tx_mvm_publish_module( + &self, + module_path: &str, + gas: u64, + key_phrase: &str, + ) -> Result { + unsafe { + let func: libloading::Symbol = self.lib.get(b"tx_mvm_publish_module")?; + func(module_path, self.url.as_str(), gas, key_phrase) + } + } + + /// (DEV) Publishing the module. + /// package_path: The path to the module file. PATH/TO/MODULE/FILE.mv + /// gas: Gas limit for transaction execution. + /// signer: alias or ss58 address of the test account. //Alice, alice, bob... or 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + pub fn tx_mvm_publish_module_dev( + &self, + module_path: &str, + gas: u64, + signer: &str, + ) -> Result { + unsafe { + let func: libloading::Symbol = + self.lib.get(b"tx_mvm_publish_module_dev")?; + func(module_path, self.url.as_str(), gas, signer) + } + } + + /// Transaction execution + /// transaction_path: The path to the transaction file. PATH/TO/TRANSACTION/FILE.mv + /// gas: Gas limit for transaction execution. + /// key_phrase: secret keyphrase + pub fn tx_mvm_execute( + &self, + transaction_path: &str, + gas: u64, + key_phrase: &str, + ) -> Result { + unsafe { + let func: libloading::Symbol = self.lib.get(b"tx_mvm_execute")?; + func(transaction_path, self.url.as_str(), gas, key_phrase) + } + } + + /// (DEV) Transaction execution + /// transaction_path: The path to the transaction file. PATH/TO/TRANSACTION/FILE.mv + /// gas: Gas limit for transaction execution. + /// test_account: alias or ss58 address of the test account. //Alice, alice, bob... or 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + pub fn tx_mvm_execute_dev( + &self, + transaction_path: &str, + gas: u64, + test_account: &str, + ) -> Result { + unsafe { + let func: libloading::Symbol = self.lib.get(b"tx_mvm_execute_dev")?; + func(transaction_path, self.url.as_str(), gas, test_account) + } + } + + /// Publishing the package + /// package_path: The path to the package file. PATH/TO/PACKAGE/FILE.mv + /// gas: Gas limit for transaction execution. + /// key_phrase: secret keyphrase + pub fn tx_mvm_publish_package( + &self, + package_path: &str, + gas: u64, + key_phrase: &str, + ) -> Result { + unsafe { + let func: libloading::Symbol = + self.lib.get(b"tx_mvm_publish_package")?; + func(package_path, self.url.as_str(), gas, key_phrase) + } + } + + /// (DEV) Publishing the package + /// package_path: The path to the package file. PATH/TO/PACKAGE/FILE.mv + /// gas: Gas limit for transaction execution. + /// signer: alias or ss58 address of the test account. //Alice, alice, bob... or 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + pub fn tx_mvm_publish_package_dev( + &self, + package_path: &str, + gas: u64, + signer: &str, + ) -> Result { + unsafe { + let func: libloading::Symbol = + self.lib.get(b"tx_mvm_publish_package_dev")?; + func(package_path, self.url.as_str(), gas, signer) + } + } + + /// Library Version + pub fn version(&self) -> Result { + let result = unsafe { + let func: libloading::Symbol String> = self.lib.get(b"version")?; + func() + }; + Ok(result) + } + + /// Create a library in a temporary folder + /// /libpontemapi.so + fn load() -> Result { + let name_file = format!("libpontemapi_{}", LIB_VERSION); + let path = std::env::temp_dir().join(name_file); + if !path.exists() { + fs::write(&path, LIB_PONTEMAPI)?; + } + let lib = unsafe { libloading::Library::new(path.as_os_str())? }; + Ok(lib) + } +} + +impl Default for PontemClient { + fn default() -> Self { + PontemClient::new("ws://127.0.0.1:9944").unwrap() + } +} + +#[cfg(test)] +mod tests { + use log::debug; + use crate::PontemClient; + + #[test] + fn test_version() { + let version = PontemClient::default().version().unwrap(); + println!("version: {}", &version); + } + + #[test] + #[ignore] + fn test_tx_mvm_publish_module_dev() { + env_logger::init(); + + let client = PontemClient::default(); + let result = client + .tx_mvm_publish_module_dev("../pontemapi/Alice_Store.mv", 100, "//Alice") + .unwrap(); + debug!("result: {}", result); + } + + #[test] + #[ignore] + fn test_tx_mvm_execute_dev() { + env_logger::init(); + + let client = PontemClient::default(); + let result = client + .tx_mvm_execute_dev("../pontemapi/Alice_Main.mvt", 100, "alice") + .unwrap(); + debug!("result: {}", result); + } + + #[test] + #[ignore] + fn test_tx_mvm_publish_package_dev() { + env_logger::init(); + + let client = PontemClient::default(); + let result = client + .tx_mvm_publish_package_dev( + "../pontemapi/Alice_Store.pac", + 1000, + "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + ) + .unwrap(); + debug!("result: {}", result); + } +} diff --git a/pontem/hash_project/Cargo.toml b/pontem/hash_project/Cargo.toml new file mode 100644 index 00000000..994c960b --- /dev/null +++ b/pontem/hash_project/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "hash_project" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[workspace] + +[dependencies] +anyhow = "1.0" +sha256 = "1.0" +log = "0.4" +toml = "0.5" + +[dev-dependencies] +env_logger = "0.9" \ No newline at end of file diff --git a/pontem/hash_project/src/lib.rs b/pontem/hash_project/src/lib.rs new file mode 100644 index 00000000..9589b064 --- /dev/null +++ b/pontem/hash_project/src/lib.rs @@ -0,0 +1,106 @@ +use std::path::{Path, PathBuf}; +use std::str::FromStr; +use std::fs; +use proc_macro::TokenStream; +use anyhow::{Result}; +use log::debug; +use toml::Value; + +/// Get the project version and a short hash +#[proc_macro] +pub fn version(item: TokenStream) -> TokenStream { + let params = item.to_string(); + let path = params.trim_matches('"'); + let full_version = version_with_shorthash(path).unwrap(); + format!(r#""{}""#, &full_version).parse().unwrap() +} + +/// Get the project version and a short hash +fn version_with_shorthash(project_path: &str) -> Result { + debug!("project_path: {}", project_path); + debug!( + "current_path: {}", + PathBuf::from_str(".")?.canonicalize()?.display() + ); + + let path = PathBuf::from_str(project_path)?.canonicalize()?; + debug!("path: {}", path.display()); + + let full_hash = hash_project(&path)?; + debug!("long hash: {}", &full_hash); + + let short_hash = &full_hash[..8]; + debug!("short hash: {}", short_hash); + + let version = version_project(&path)?; + debug!("Version: {}", &version); + + Ok(format!("{}_{}", version, short_hash)) +} + +/// Full project hash +fn hash_project(path: &Path) -> Result { + let files = project_files(&path)?; + + let hash = files + .iter() + .filter_map(|path| sha256::digest_file(&path).ok()) + .collect::>() + .join(""); + Ok(sha256::digest_bytes(hash.as_bytes())) +} + +fn version_project(path: &Path) -> Result { + let file = fs::read_to_string(path.join("Cargo.toml"))?.parse::()?; + + Ok(file + .as_table() + .and_then(|value| value.get("package")) + .and_then(|value| value.get("version")) + .and_then(|value| value.as_str().map(|v| v.to_string())) + .unwrap_or("0.0.0".to_string())) +} + +/// List of project files +fn project_files(path: &Path) -> Result> { + let result: Vec = fs::read_dir(&path)? + .filter_map(|path| path.ok()) + .map(|path| path.path()) + .filter_map(|path| { + if path.is_dir() { + let name = path.file_name()?.to_str()?; + if ["target", "debug", "release", ".idea"].contains(&name) { + None + } else { + project_files(&path).ok() + } + } else if path.is_file() { + let ext = path.extension()?.to_str()?; + if ["rs", "toml", "lock"].contains(&ext) { + Some(vec![path]) + } else { + None + } + } else { + None + } + }) + .flatten() + .collect(); + + Ok(result) +} + +#[cfg(test)] +mod tests { + use log::debug; + use crate::{version_with_shorthash}; + + #[test] + fn test_version_with_shorthash() { + env_logger::init(); + + let version = version_with_shorthash("../pontemapi").unwrap(); + debug!("{:?}", version); + } +} diff --git a/pontem/pontemapi/Cargo.lock b/pontem/pontemapi/Cargo.lock new file mode 100644 index 00000000..6b4ebe83 --- /dev/null +++ b/pontem/pontemapi/Cargo.lock @@ -0,0 +1,3021 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.4", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "async-trait" +version = "0.1.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "backtrace" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "beef" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bed554bd50246729a1ec158d08aa3235d1b69d94ad120ebe187e28894787e736" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitvec" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +dependencies = [ + "arrayvec 0.4.12", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.5", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "bumpalo" +version = "3.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" + +[[package]] +name = "byte-slice-cast" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d30c751592b77c499e7bce34d99d67c2c11bdc0574e9a488ddade14150a4698" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chameleon" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12bd83544cd11113170ce1eee45383928f3f720bc8b305af18c2a3da3547e1ae" + +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "winapi", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array 0.14.5", + "subtle", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array 0.14.5", + "subtle", +] + +[[package]] +name = "curve25519-dalek" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" +dependencies = [ + "byteorder", + "digest 0.8.1", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "darling" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.5", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "dyn-clonable" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" +dependencies = [ + "dyn-clonable-impl", + "dyn-clone", +] + +[[package]] +name = "dyn-clonable-impl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + +[[package]] +name = "ed25519" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74e1069e39f1454367eb2de793ed062fac4c35c2934b76a81d90dd9abcd28816" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "environmental" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b91989ae21441195d7d9b9993a2f9295c7e1a8c96255d8b729accddc124797" + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.4", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "frame-metadata" +version = "14.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ed5e5c346de62ca5c184b4325a6600d1eaca210666e4606fe4e449574978d0" +dependencies = [ + "cfg-if", + "parity-scale-codec", + "scale-info", + "serde", +] + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "futures" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-executor" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" + +[[package]] +name = "futures-macro" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" + +[[package]] +name = "h2" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f1f717ddc7b2ba36df7e871fd88db79326551d3d6f1fc406fbfd28b582ff8e" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hash-db" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hash_project" +version = "0.1.0" +dependencies = [ + "anyhow", + "log", + "sha256", + "toml", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac 0.8.0", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "digest 0.9.0", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array 0.14.5", + "hmac 0.8.1", +] + +[[package]] +name = "http" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.1", +] + +[[package]] +name = "http-body" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa 0.4.8", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" +dependencies = [ + "http", + "hyper", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", + "webpki-roots", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "indexmap" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "integer-sqrt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "js-sys" +version = "0.3.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpsee" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5b02d34b7d70caa454dcf79914d70d9ef6edecef84b9261f499a9f3521b7935" +dependencies = [ + "jsonrpsee-http-client", + "jsonrpsee-proc-macros", + "jsonrpsee-types", + "jsonrpsee-utils", + "jsonrpsee-ws-client", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea17b6d6da182fc4b293e0bebea5cc72e194d9392f485fb4051488af3edd1cd" +dependencies = [ + "async-trait", + "fnv", + "hyper", + "hyper-rustls", + "jsonrpsee-types", + "jsonrpsee-utils", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-proc-macros" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfdf283c6c3403ce9969700177bbcf35a695576fc2d993f38ab32a690631a96" +dependencies = [ + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d822e0fc7be95e5085da5d61508bf5e3d5c1614dd235402086ec5c1cb15bdfa" +dependencies = [ + "anyhow", + "async-trait", + "beef", + "futures-channel", + "futures-util", + "hyper", + "serde", + "serde_json", + "soketto", + "thiserror", + "tracing", +] + +[[package]] +name = "jsonrpsee-utils" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e722316d556c5228624fb1cc7ea672f6ed163e60183e93f11d3ee979417331cb" +dependencies = [ + "arrayvec 0.7.2", + "beef", + "futures-util", + "hyper", + "jsonrpsee-types", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "664d2c9443cb1171e2414c66e0f0b44040eb2cff073455a0d168984eee178159" +dependencies = [ + "async-trait", + "fnv", + "futures", + "http", + "jsonrpsee-types", + "pin-project", + "rustls-native-certs", + "serde", + "serde_json", + "soketto", + "thiserror", + "tokio", + "tokio-rustls", + "tokio-util", + "tracing", + "webpki-roots", +] + +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "lock_api" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memory-db" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de006e09d04fc301a5f7e817b75aa49801c4479a8af753764416b085337ddcc5" +dependencies = [ + "hash-db", + "hashbrown", + "parity-util-mem", +] + +[[package]] +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" + +[[package]] +name = "merlin" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "mio" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "parity-scale-codec" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" +dependencies = [ + "arrayvec 0.7.2", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" +dependencies = [ + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parity-util-mem" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f4cb4e169446179cbc6b8b6320cc9fca49bd2e94e8db25f25f200a8ea774770" +dependencies = [ + "cfg-if", + "hashbrown", + "impl-trait-for-tuples", + "parity-util-mem-derive", + "parking_lot", + "primitive-types", + "winapi", +] + +[[package]] +name = "parity-util-mem-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" +dependencies = [ + "proc-macro2", + "syn", + "synstructure", +] + +[[package]] +name = "parity-wasm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "paste" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac 0.8.0", +] + +[[package]] +name = "pbkdf2" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" +dependencies = [ + "crypto-mac 0.11.1", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pin-project" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pontemapi" +version = "0.15.0" +dependencies = [ + "anyhow", + "hash_project", + "hex", + "log", + "parity-scale-codec", + "sp-core", + "sp-keyring", + "subxt", + "tokio", + "url", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "primitive-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.4", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "ref-cast" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustls" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca9ebdfa27d3fc180e42879037b5338ab1c040c06affd00d8338598e7800943" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" +dependencies = [ + "base64 0.13.0", +] + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "scale-info" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c55b744399c25532d63a0d2789b109df8d46fc93752d46b0782991a931a782f" +dependencies = [ + "bitvec", + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", + "serde", +] + +[[package]] +name = "scale-info-derive" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baeb2780690380592f86205aa4ee49815feb2acad8c2f59e6dd207148c3f1fcd" +dependencies = [ + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "schannel" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +dependencies = [ + "lazy_static", + "winapi", +] + +[[package]] +name = "schnorrkel" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "curve25519-dalek 2.1.3", + "getrandom 0.1.16", + "merlin", + "rand 0.7.3", + "rand_core 0.5.1", + "sha2 0.8.2", + "subtle", + "zeroize", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0486718e92ec9a68fbed73bb5ef687d71103b142595b406835649bebd33f72c7" + +[[package]] +name = "serde" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" +dependencies = [ + "itoa 1.0.1", + "ryu", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sha256" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e84a7f596c081d359de5e06a83877138bc3c4483591e1af1916e1472e6e146e" +dependencies = [ + "hex", + "sha2 0.9.9", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signature" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f054c6c1a6e95179d6f23ed974060dcefb2d9388bb7256900badad682c499de4" + +[[package]] +name = "slab" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" + +[[package]] +name = "smallvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" + +[[package]] +name = "socket2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.0", + "bytes", + "futures", + "httparse", + "log", + "rand 0.8.4", + "sha-1", +] + +[[package]] +name = "sp-application-crypto" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-std", +] + +[[package]] +name = "sp-arithmetic" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "scale-info", + "serde", + "sp-debug-derive", + "sp-std", + "static_assertions", +] + +[[package]] +name = "sp-core" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "base58", + "blake2-rfc", + "byteorder", + "dyn-clonable", + "ed25519-dalek", + "futures", + "hash-db", + "hash256-std-hasher", + "hex", + "impl-serde", + "lazy_static", + "libsecp256k1", + "log", + "merlin", + "num-traits", + "parity-scale-codec", + "parity-util-mem", + "parking_lot", + "primitive-types", + "rand 0.7.3", + "regex", + "scale-info", + "schnorrkel", + "secrecy", + "serde", + "sha2 0.9.9", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", + "sp-std", + "sp-storage", + "ss58-registry", + "substrate-bip39", + "thiserror", + "tiny-bip39", + "tiny-keccak", + "twox-hash", + "wasmi", + "zeroize", +] + +[[package]] +name = "sp-debug-derive" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-externalities" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "environmental", + "parity-scale-codec", + "sp-std", + "sp-storage", +] + +[[package]] +name = "sp-io" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "futures", + "hash-db", + "libsecp256k1", + "log", + "parity-scale-codec", + "parking_lot", + "sp-core", + "sp-externalities", + "sp-keystore", + "sp-runtime-interface", + "sp-state-machine", + "sp-std", + "sp-tracing", + "sp-trie", + "sp-wasm-interface", + "tracing", + "tracing-core", +] + +[[package]] +name = "sp-keyring" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "lazy_static", + "sp-core", + "sp-runtime", + "strum", +] + +[[package]] +name = "sp-keystore" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "async-trait", + "derive_more", + "futures", + "merlin", + "parity-scale-codec", + "parking_lot", + "schnorrkel", + "sp-core", + "sp-externalities", +] + +[[package]] +name = "sp-panic-handler" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "backtrace", +] + +[[package]] +name = "sp-runtime" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "either", + "hash256-std-hasher", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "parity-util-mem", + "paste", + "rand 0.7.3", + "scale-info", + "serde", + "sp-application-crypto", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-std", +] + +[[package]] +name = "sp-runtime-interface" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "primitive-types", + "sp-externalities", + "sp-runtime-interface-proc-macro", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-wasm-interface", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "Inflector", + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-state-machine" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "hash-db", + "log", + "num-traits", + "parity-scale-codec", + "parking_lot", + "rand 0.7.3", + "smallvec", + "sp-core", + "sp-externalities", + "sp-panic-handler", + "sp-std", + "sp-trie", + "thiserror", + "tracing", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-std" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" + +[[package]] +name = "sp-storage" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "impl-serde", + "parity-scale-codec", + "ref-cast", + "serde", + "sp-debug-derive", + "sp-std", +] + +[[package]] +name = "sp-tracing" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "parity-scale-codec", + "sp-std", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sp-trie" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "hash-db", + "memory-db", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-std", + "trie-db", + "trie-root", +] + +[[package]] +name = "sp-version" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "impl-serde", + "parity-scale-codec", + "parity-wasm", + "scale-info", + "serde", + "sp-runtime", + "sp-std", + "sp-version-proc-macro", + "thiserror", +] + +[[package]] +name = "sp-version-proc-macro" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "parity-scale-codec", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sp-wasm-interface" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate/?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" +dependencies = [ + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-std", + "wasmi", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "ss58-registry" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8319f44e20b42e5c11b88b1ad4130c35fe2974665a007b08b02322070177136a" +dependencies = [ + "Inflector", + "proc-macro2", + "quote", + "serde", + "serde_json", + "unicode-xid", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "substrate-bip39" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49eee6965196b32f882dd2ee85a92b1dbead41b04e53907f269de3b0dc04733c" +dependencies = [ + "hmac 0.11.0", + "pbkdf2 0.8.0", + "schnorrkel", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "subxt" +version = "0.15.0" +source = "git+https://github.com/pontem-network/subxt?branch=master#6d736a11779ea55772e3475c394fe5ff69990015" +dependencies = [ + "async-trait", + "bitvec", + "chameleon", + "frame-metadata", + "futures", + "hex", + "jsonrpsee", + "log", + "num-traits", + "parity-scale-codec", + "scale-info", + "serde", + "serde_json", + "sp-core", + "sp-runtime", + "sp-version", + "subxt-macro", + "thiserror", + "url", +] + +[[package]] +name = "subxt-codegen" +version = "0.2.0" +source = "git+https://github.com/pontem-network/subxt?branch=master#6d736a11779ea55772e3475c394fe5ff69990015" +dependencies = [ + "async-trait", + "darling", + "frame-metadata", + "heck", + "parity-scale-codec", + "proc-macro-crate 0.1.5", + "proc-macro-error", + "proc-macro2", + "quote", + "scale-info", + "syn", +] + +[[package]] +name = "subxt-macro" +version = "0.1.0" +source = "git+https://github.com/pontem-network/subxt?branch=master#6d736a11779ea55772e3475c394fe5ff69990015" +dependencies = [ + "async-trait", + "darling", + "frame-metadata", + "heck", + "parity-scale-codec", + "proc-macro-crate 0.1.5", + "proc-macro-error", + "proc-macro2", + "quote", + "scale-info", + "subxt-codegen", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tiny-bip39" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" +dependencies = [ + "anyhow", + "hmac 0.8.1", + "once_cell", + "pbkdf2 0.4.0", + "rand 0.7.3", + "rustc-hash", + "sha2 0.9.9", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a" +dependencies = [ + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "pin-project-lite", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-util" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tower-service" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" + +[[package]] +name = "tracing" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d8d93354fe2a8e50d5953f5ae2e47a3fc2ef03292e7ea46e3cc38f549525fb9" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8276d9a4a3a558d7b7ad5303ad50b53d58264641b82914b7ada36bd762e7a716" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23" +dependencies = [ + "lazy_static", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "ansi_term", + "chrono", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "trie-db" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eac131e334e81b6b3be07399482042838adcd7957aa0010231d0813e39e02fa" +dependencies = [ + "hash-db", + "hashbrown", + "log", + "rustc-hex", + "smallvec", +] + +[[package]] +name = "trie-root" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "652931506d2c1244d7217a70b99f56718a7b4161b37f04e7cd868072a99f68cd" +dependencies = [ + "hash-db", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "twox-hash" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee73e6e4924fe940354b8d4d98cad5231175d615cd855b758adc658c0aac6a0" +dependencies = [ + "cfg-if", + "rand 0.8.4", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "uint" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" + +[[package]] +name = "wasmi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca00c5147c319a8ec91ec1a0edbec31e566ce2c9cc93b3f9bb86a9efd0eb795d" +dependencies = [ + "downcast-rs", + "libc", + "memory_units", + "num-rational", + "num-traits", + "parity-wasm", + "wasmi-validation", +] + +[[package]] +name = "wasmi-validation" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "165343ecd6c018fc09ebcae280752702c9a2ef3e6f8d02f1cfcbdb53ef6d7937" +dependencies = [ + "parity-wasm", +] + +[[package]] +name = "web-sys" +version = "0.3.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552ceb903e957524388c4d3475725ff2c8b7960922063af6ce53c9a43da07449" +dependencies = [ + "webpki", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] +name = "zeroize" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c88870063c39ee00ec285a2f8d6a966e5b6fb2becc4e8dac77ed0d370ed6006" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81e8f13fef10b63c06356d65d416b070798ddabcadc10d3ece0c5be9b3c7eddb" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/pontem/pontemapi/Cargo.toml b/pontem/pontemapi/Cargo.toml new file mode 100644 index 00000000..97515c22 --- /dev/null +++ b/pontem/pontemapi/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "pontemapi" +version = "0.15.0" +edition = "2021" + +[lib] +crate_type = ["cdylib"] + +[workspace] + +[dependencies] +hex = "0.4" +log = "0.4" +anyhow = "1.0" +url = "2" +tokio = "1" +codec = { package = "parity-scale-codec", version = "2.3.1", default-features = false, features = ["derive", "full", "bit-vec"] } +subxt = { git = "https://github.com/pontem-network/subxt", branch = "master" } +sp-keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate/", branch = "polkadot-v0.9.12" } +sp-core = { git = "https://github.com/paritytech/substrate/", branch = "polkadot-v0.9.12" } +# +hash_project = { package="hash_project", path = "../hash_project" } + diff --git a/pontem/pontemapi/metadata/pontem.scale b/pontem/pontemapi/metadata/pontem.scale new file mode 100644 index 0000000000000000000000000000000000000000..f066412aa293b17f5163f17e99dca3b049c04a64 GIT binary patch literal 111486 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 bool { + self.0 == other.0 + } + } + + impl Eq for Id {} + + impl PartialOrd for Id { + fn partial_cmp(&self, other: &Self) -> Option { + self.0.partial_cmp(&other.0) + } + } + + impl Ord for Id { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.cmp(&other.0) + } + } +}; + +use crate::pontem::DefaultConfig; +use crate::pontem::runtime_types::sp_runtime::DispatchError; + +/// Public interface for publishing the module +/// module_path: The path to the module file. PATH/TO/MODULE/FILE.mv +/// url: Node address. ws://127.0.0.1:9944 +/// gas: Gas limit for transaction execution. +/// key_phrase: secret keyphrase +#[export_name = "tx_mvm_publish_module"] +pub fn tx_mvm_publish_module( + module_path: &str, + url_str: &str, + gas: u64, + key_phrase: &str, +) -> Result { + let context = Context::from_keyphrase(module_path, url_str, gas, key_phrase)?; + debug!("fn tx_mvm_publish_module:\n{}", context.debug()); + + let result = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() + .block_on(pb_module(context)); + + result +} + +/// (DEV) Public interface for publishing the module +/// module_path: The path to the module file. PATH/TO/MODULE/FILE.mv +/// url: Node address. ws://127.0.0.1:9944 +/// gas: Gas limit for transaction execution. +/// test_signer: alias or ss58 address of the test account. //Alice, alice, bob... or 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY +#[export_name = "tx_mvm_publish_module_dev"] +pub fn tx_mvm_publish_module_dev( + module_path: &str, + url_str: &str, + gas: u64, + test_signer: &str, +) -> Result { + let context = Context::from_dev(module_path, url_str, gas, test_signer)?; + debug!("fn tx_mvm_publish_module_dev:\n{}", context.debug()); + + let result = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() + .block_on(pb_module(context)); + + result +} + +/// Public interface for transaction execution +/// transaction_path: The path to the transaction file. PATH/TO/TRANSACTION/FILE.mv +/// url: Node address. ws://127.0.0.1:9944 +/// gas: Gas limit for transaction execution. +/// key_phrase: secret keyphrase +#[export_name = "tx_mvm_execute"] +pub fn tx_mvm_execute( + transaction_path: &str, + url_str: &str, + gas: u64, + key_phrase: &str, +) -> Result { + let context = Context::from_keyphrase(transaction_path, url_str, gas, key_phrase)?; + debug!("fn tx_mvm_execute:\n{}", context.debug()); + + let result = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() + .block_on(execute(context)); + + result +} + +/// (DEV) Public interface for transaction execution +/// transaction_path: The path to the transaction file. PATH/TO/TRANSACTION/FILE.mv +/// url: Node address. ws://127.0.0.1:9944 +/// gas: Gas limit for transaction execution. +/// test_signer: alias or ss58 address of the test account. //Alice, alice, bob... or 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY +#[export_name = "tx_mvm_execute_dev"] +pub fn tx_mvm_execute_dev( + transaction_path: &str, + url_str: &str, + gas: u64, + test_signer: &str, +) -> Result { + let context = Context::from_dev(transaction_path, url_str, gas, test_signer)?; + debug!("fn tx_mvm_execute_dev:\n{}", context.debug()); + + let result = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() + .block_on(execute(context)); + + result +} + +/// Public interface for publishing the package +/// package_path: The path to the package file. PATH/TO/PACKAGE/FILE.mv +/// url: Node address. ws://127.0.0.1:9944 +/// gas: Gas limit for transaction execution. +/// key_phrase: secret keyphrase +#[export_name = "tx_mvm_publish_package"] +pub fn tx_mvm_publish_package( + package_path: &str, + url_str: &str, + gas: u64, + key_phrase: &str, +) -> Result { + let context = Context::from_keyphrase(package_path, url_str, gas, key_phrase)?; + debug!("fn tx_mvm_publish_package:\n{}", context.debug()); + + let result = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() + .block_on(pb_package_dev(context)); + + result +} + +/// (DEV) Public interface for publishing the package +/// package_path: The path to the package file. PATH/TO/PACKAGE/FILE.mv +/// url: Node address. ws://127.0.0.1:9944 +/// gas: Gas limit for transaction execution. +/// test_signer: alias or ss58 address of the test account. //Alice, alice, bob... or 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY +#[export_name = "tx_mvm_publish_package_dev"] +pub fn tx_mvm_publish_package_dev( + package_path: &str, + url_str: &str, + gas: u64, + test_signer: &str, +) -> Result { + let context = Context::from_dev(package_path, url_str, gas, test_signer)?; + debug!("fn tx_mvm_publish_package_dev:\n{}", context.debug()); + + let result = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() + .block_on(pb_package_dev(context)); + + result +} + +/// Library Version +#[no_mangle] +pub fn version() -> String { + VERSION.to_string() +} + +/// Publish a module +async fn pb_module(context: Context) -> Result { + debug!("Reading a file: {}", context.path_file.display()); + let module = fs::read(&context.path_file)?; + let pair_signer: PairSigner = + PairSigner::new(context.pair.clone()); + + let api = ClientBuilder::new() + .set_url(context.url.clone()) + .build() + .await? + .to_runtime_api::>(); + + let hash = api + .tx() + .mvm() + .publish_module(module, context.gas) + .sign_and_submit(&pair_signer) + .await? + .to_string(); + + // Only for Websocket you can get the result of publishing + if !context.is_connection_ws() { + return Ok(hash); + } + + // It is necessary to decrypt the message + let metadata = api.client.metadata(); + // Subscribe to events + let sub = api.client.rpc().subscribe_events().await?; + let decoder = api.client.events_decoder(); + let mut sub = EventSubscription::::new(sub, decoder); + + let mut last = 0; + loop { + let raw = sub.next().await.ok_or(anyhow!("No response received"))??; + + match raw.variant.as_str() { + // The event is triggered 3 times. If the event was triggered after "ModulePublished", it is final + "ExtrinsicSuccess" => { + if last == 1 { + return Ok(hash); + } + } + // Called when a module publishing error occurs + "ExtrinsicFailed" => { + let answer = ::decode( + &mut &raw.data[..], + )?; + return Err(anyhow!(dispatcherror_to_string(answer.0, metadata))); + } + // The module is published. Not the last event + "ModulePublished" | "Event" => last = 1, + _ => {} + } + } +} + +/// Transaction execution +async fn execute(context: Context) -> Result { + debug!("Reading a file: {}", context.path_file.display()); + let transaction = fs::read(&context.path_file)?; + let signer_pair: PairSigner = + PairSigner::new(context.pair.clone()); + + let api = ClientBuilder::new() + .set_url(context.url.clone()) + .build() + .await? + .to_runtime_api::>(); + + let hash = api + .tx() + .mvm() + .execute(transaction, context.gas) + .sign_and_submit(&signer_pair) + .await? + .to_string(); + + // Only for Websocket you can get the result of publishing + if !context.is_connection_ws() { + return Ok(hash); + } + + // Subscribe to events + let sub = api.client.rpc().subscribe_events().await?; + let decoder = api.client.events_decoder(); + let mut sub = EventSubscription::::new(sub, decoder); + // It is necessary to decrypt the message + let metadata = api.client.metadata(); + + let mut last = 0; + loop { + let raw = sub.next().await.ok_or(anyhow!("No response received"))??; + + debug!("event {}", raw.variant.as_str()); + match raw.variant.as_str() { + // The event is triggered 4 times + "ExtrinsicSuccess" => { + last += 1; + if last == 4 { + return Ok(hash); + } + } + // Called when a module execute error occurs + "ExtrinsicFailed" => { + let answer = ::decode( + &mut &raw.data[..], + )?; + return Err(anyhow!(dispatcherror_to_string(answer.0, metadata))); + } + _ => {} + } + } +} + +/// Publish a package +async fn pb_package_dev(context: Context) -> Result { + debug!("Reading a file: {}", context.path_file.display()); + let package = fs::read(&context.path_file)?; + let signer_pair: PairSigner = + PairSigner::new(context.pair.clone()); + + let api = ClientBuilder::new() + .set_url(context.url.clone()) + .build() + .await? + .to_runtime_api::>(); + + let hash = api + .tx() + .mvm() + .publish_package(package, context.gas) + .sign_and_submit(&signer_pair) + .await? + .to_string(); + + // Only for Websocket you can get the result of publishing + if !context.is_connection_ws() { + return Ok(hash); + } + + // Subscribe to events + let sub = api.client.rpc().subscribe_events().await?; + let decoder = api.client.events_decoder(); + let mut sub = EventSubscription::::new(sub, decoder); + // It is necessary to decrypt the message + let metadata = api.client.metadata(); + + let mut last = 0; + loop { + let raw = sub.next().await.ok_or(anyhow!("No response received"))??; + + debug!("event {}", raw.variant.as_str()); + match raw.variant.as_str() { + // The event is triggered 4 times + "ExtrinsicSuccess" => { + last += 1; + if last == 4 { + return Ok(hash); + } + } + // Called when a module publishing error occurs + "ExtrinsicFailed" => { + let answer = ::decode( + &mut &raw.data[..], + )?; + return Err(anyhow!(dispatcherror_to_string(answer.0, metadata))); + } + _ => {} + } + } +} + +/// Converting a test account alias or ss58 address into a keyring +fn test_keyring_from_str(signer: &str) -> Result { + let signer_lowercase = signer.strip_prefix("//").unwrap_or(signer).to_lowercase(); + + let keyring = match signer_lowercase.as_str() { + "alice" => AccountKeyring::Alice, + "bob" => AccountKeyring::Bob, + "charlie" => AccountKeyring::Charlie, + "dave" => AccountKeyring::Dave, + "eve" => AccountKeyring::Eve, + "ferdie" => AccountKeyring::Ferdie, + "one" => AccountKeyring::One, + "two" => AccountKeyring::Two, + _ => { + let account_id = + AccountId32::from_string(signer).map_err(|err| anyhow!("{:?}", err))?; + AccountKeyring::from_account_id(&account_id) + .ok_or(anyhow!(r#"Failed to get "keyring""#))? + } + }; + Ok(keyring) +} + +/// Converting an error to a string. Error when calling an external function in the node +fn dispatcherror_to_string(error: DispatchError, meta: &Metadata) -> String { + use crate::pontem::runtime_types::sp_runtime::{ArithmeticError, TokenError}; + match error { + DispatchError::Other => "Other".to_string(), + DispatchError::CannotLookup => "CannotLookup".to_string(), + DispatchError::BadOrigin => "BadOrigin".to_string(), + DispatchError::Module { index, error } => match meta.error(index, error) { + Ok(ok) => format!( + "Pallet: {pallet}\n\ + Error: {error}\n\ + Description: {description}", + pallet = ok.pallet(), + error = ok.error(), + description = ok.description().join(" ") + ), + Err(_) => format!("Error not found: {} {}", index, error), + }, + DispatchError::ConsumerRemaining => "ConsumerRemaining".to_string(), + DispatchError::NoProviders => "NoProviders".to_string(), + DispatchError::Token(value) => match value { + TokenError::NoFunds => "Token.NoFunds", + TokenError::WouldDie => "Token.WouldDie", + TokenError::BelowMinimum => "Token.BelowMinimum", + TokenError::CannotCreate => "Token.CannotCreate", + TokenError::UnknownAsset => "Token.UnknownAsset", + TokenError::Frozen => "Token.Frozen", + TokenError::Unsupported => "Token.Unsupported", + } + .to_string(), + DispatchError::Arithmetic(value) => match value { + ArithmeticError::Underflow => "Arithmetic.Underflow", + ArithmeticError::Overflow => "Arithmetic.Overflow", + ArithmeticError::DivisionByZero => "Arithmetic.DivisionByZero", + } + .to_string(), + } +} + +struct Context { + /// The path to the module|package|transaction file. PATH/TO/FILE.mv + pub path_file: PathBuf, + /// Node address. ws://127.0.0.1:9944 + pub url: Url, + /// Gas limit for transaction execution. + pub gas: u64, + /// ss58 address + pub signer: String, + /// Keypair. An Schnorrkel/Ristretto x25519 ("sr25519") key pair. + pub pair: sr25519Pair, +} + +impl Context { + /// Create Context + /// path_str: The path to the module|package|transaction file. PATH/TO/FILE.mv + /// url_str: Node address. ws://127.0.0.1:9944 + /// gas: Gas limit for transaction execution. + /// test_signer: alias or ss58 address of the test account. //Alice, alice, bob... or 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + pub fn from_dev( + path_str: &str, + url_str: &str, + gas: u64, + test_signer: &str, + ) -> Result { + let pair = test_keyring_from_str(test_signer)?.pair(); + Self::from_pair(path_str, url_str, gas, pair) + } + + /// Create Context + /// path_str: The path to the module file. PATH/TO/FILE.mv + /// url_str: Node address. ws://127.0.0.1:9944 + /// gas: Gas limit for transaction execution. + /// key_phrase: secret keyphrase + pub fn from_keyphrase( + path_str: &str, + url_str: &str, + gas: u64, + key_phrase: &str, + ) -> Result { + let pair = + sr25519Pair::from_string(key_phrase, None).map_err(|err| anyhow!("{:?}", err))?; + Self::from_pair(path_str, url_str, gas, pair) + } + + /// Create Context + /// path_str: The path to the module file. PATH/TO/FILE.mv + /// url_str: Node address. ws://127.0.0.1:9944 + /// gas: Gas limit for transaction execution. + /// pair: An Schnorrkel/Ristretto x25519 ("sr25519") key pair. + pub fn from_pair( + path_str: &str, + url_str: &str, + gas: u64, + pair: sr25519Pair, + ) -> Result { + let url = Url::from_str(url_str)?; + let signer = AccountId32::new(pair.public().0).to_ss58check(); + + let mut path_file = PathBuf::from_str(path_str)?; + ensure!( + path_file.exists(), + "File not found for publication. \n\ + Path: {path}", + path = path_file.display(), + ); + path_file = path_file.canonicalize()?; + + Ok(Context { + path_file, + pair, + url, + gas, + signer, + }) + } + + /// Returns an object as a string + pub fn debug(&self) -> String { + format!( + "path: {path}\n\ + Url: {url}\n\ + Gas: {gas}\n\ + Signer:{signer}", + path = self.path_file.display(), + gas = self.gas, + signer = &self.signer, + url = &self.url + ) + } + + /// is the connection via a web socket + pub fn is_connection_ws(&self) -> bool { + match self.url.origin() { + Origin::Tuple(protocol, _, _) => &protocol.to_lowercase() == "ws", + _ => false, + } + } +} + +#[cfg(test)] +mod tests { + use log::debug; + use crate::{ + test_keyring_from_str, tx_mvm_publish_module_dev, tx_mvm_execute_dev, + tx_mvm_publish_package_dev, version, tx_mvm_publish_module, + }; + + #[test] + #[ignore] + fn test_tx_mvm_publish_module_dev_ws() { + tx_mvm_publish_module_dev("./Alice_Store.mv", "ws://127.0.0.1:9944", 100, "alice") + .unwrap(); + } + + #[test] + #[ignore] + fn test_tx_mvm_execute_dev_ws() { + tx_mvm_execute_dev("./Alice_Main.mvt", "ws://127.0.0.1:9944", 100, "//Alice").unwrap(); + } + + #[test] + #[ignore] + fn test_tx_mvm_publish_package_dev_ws() { + tx_mvm_publish_package_dev( + "./Alice_Store.pac", + "ws://127.0.0.1:9944", + 1000, + "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + ) + .unwrap(); + } + + #[test] + fn test_to_key_pair() { + assert!(test_keyring_from_str("alice").is_ok()); + assert!(test_keyring_from_str("Alice").is_ok()); + assert!(test_keyring_from_str("//Alice").is_ok()); + assert!( + test_keyring_from_str("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY").is_ok() + ); + } + + #[test] + fn test_version() { + debug!("{}", version()); + } + + #[test] + #[ignore] + fn test_key_pair() { + // demo account + // 5DeyRkpWxXkdDHKqsqtYZLG6M3fHdqpAb55W5DPNQSaZPeg4 + // net exotic exchange stadium camp mind walk cart infant hospital will address + // net … … stadium … … walk … … hospital … … + // sr25519 + + let result = tx_mvm_publish_module( + "./Demo_Store.mv", + "ws://127.0.0.1:9944", + 100, + "net exotic exchange stadium camp mind walk cart infant hospital will address", + ) + .unwrap(); + println!("{}", result); + } +}