diff --git a/.gitignore b/.gitignore index b92643636e..0dde365146 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ cargo-timing* /examples/wasm-example/target /examples/parachain-example/target /examples/parachain-example/metadata/target +.vscode diff --git a/subxt/examples/unstable_light_client_tx_basic.rs b/subxt/examples/unstable_light_client_tx_basic.rs index e6384c5644..750a7c2c7a 100644 --- a/subxt/examples/unstable_light_client_tx_basic.rs +++ b/subxt/examples/unstable_light_client_tx_basic.rs @@ -1,9 +1,5 @@ -use sp_keyring::AccountKeyring; -use subxt::{ - client::{LightClient, LightClientBuilder, OfflineClientT}, - tx::PairSigner, - PolkadotConfig, -}; +use subxt::{client::LightClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; // Generate an interface that we can use from the node's metadata. #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] @@ -11,6 +7,7 @@ pub mod polkadot {} #[tokio::main] async fn main() -> Result<(), Box> { + // The smoldot logs are informative: tracing_subscriber::fmt::init(); // Create a light client by fetching the chain spec of a local running node. @@ -20,7 +17,7 @@ async fn main() -> Result<(), Box> { // The `12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp` is the P2P address // from a local polkadot node starting with // `--node-key 0000000000000000000000000000000000000000000000000000000000000001` - let api: LightClient = LightClientBuilder::new() + let api = LightClient::::builder() .bootnodes([ "/ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp", ]) @@ -28,12 +25,12 @@ async fn main() -> Result<(), Box> { .await?; // Build a balance transfer extrinsic. - let dest = AccountKeyring::Bob.to_account_id().into(); + let dest = dev::bob().public_key().into(); let balance_transfer_tx = polkadot::tx().balances().transfer(dest, 10_000); // Submit the balance transfer extrinsic from Alice, and wait for it to be successful // and in a finalized block. We get back the extrinsic events if all is well. - let from = PairSigner::new(AccountKeyring::Alice.pair()); + let from = dev::alice(); let events = api .tx() .sign_and_submit_then_watch_default(&balance_transfer_tx, &from) diff --git a/subxt/src/client/lightclient/builder.rs b/subxt/src/client/lightclient/builder.rs index 56e3696ffa..51e72c4b60 100644 --- a/subxt/src/client/lightclient/builder.rs +++ b/subxt/src/client/lightclient/builder.rs @@ -12,14 +12,15 @@ use std::sync::Arc; /// Builder for [`LightClient`]. #[derive(Clone, Debug)] -pub struct LightClientBuilder { +pub struct LightClientBuilder { max_pending_requests: NonZeroU32, max_subscriptions: u32, bootnodes: Option>, potential_relay_chains: Option>, + _marker: std::marker::PhantomData, } -impl Default for LightClientBuilder { +impl Default for LightClientBuilder { fn default() -> Self { Self { max_pending_requests: NonZeroU32::new(128) @@ -27,13 +28,14 @@ impl Default for LightClientBuilder { max_subscriptions: 1024, bootnodes: None, potential_relay_chains: None, + _marker: std::marker::PhantomData, } } } -impl LightClientBuilder { +impl LightClientBuilder { /// Create a new [`LightClientBuilder`]. - pub fn new() -> LightClientBuilder { + pub fn new() -> LightClientBuilder { LightClientBuilder::default() } @@ -90,10 +92,7 @@ impl LightClientBuilder { /// /// Panics if being called outside of `tokio` runtime context. #[cfg(feature = "jsonrpsee")] - pub async fn build_from_url>( - self, - url: Url, - ) -> Result, Error> { + pub async fn build_from_url>(self, url: Url) -> Result, Error> { let chain_spec = fetch_url(url.as_ref()).await?; self.build_client(chain_spec).await @@ -120,7 +119,7 @@ impl LightClientBuilder { /// ## Panics /// /// Panics if being called outside of `tokio` runtime context. - pub async fn build(self, chain_spec: &str) -> Result, Error> { + pub async fn build(self, chain_spec: &str) -> Result, Error> { let chain_spec = serde_json::from_str(chain_spec) .map_err(|_| Error::LightClient(LightClientError::InvalidChainSpec))?; @@ -128,7 +127,7 @@ impl LightClientBuilder { } /// Build the light client. - async fn build_client( + async fn build_client( self, mut chain_spec: serde_json::Value, ) -> Result, Error> { diff --git a/subxt/src/client/lightclient/mod.rs b/subxt/src/client/lightclient/mod.rs index c77ffa4fc2..63bb48a0b6 100644 --- a/subxt/src/client/lightclient/mod.rs +++ b/subxt/src/client/lightclient/mod.rs @@ -8,8 +8,14 @@ mod builder; mod rpc; use crate::{ + blocks::BlocksClient, client::{OfflineClientT, OnlineClientT}, config::Config, + constants::ConstantsClient, + events::EventsClient, + runtime_api::RuntimeApiClient, + storage::StorageClient, + tx::TxClient, OnlineClient, }; pub use builder::LightClientBuilder; @@ -49,6 +55,62 @@ pub enum LightClientError { #[derivative(Clone(bound = ""))] pub struct LightClient(OnlineClient); +impl LightClient { + /// Construct a [`LightClient`] using its builder interface. + pub fn builder() -> LightClientBuilder { + LightClientBuilder::new() + } + + // We add the below impls so that we don't need to + // think about importing the OnlineClientT/OfflineClientT + // traits to use these things: + + /// Return the [`crate::Metadata`] used in this client. + fn metadata(&self) -> crate::Metadata { + self.0.metadata() + } + + /// Return the genesis hash. + fn genesis_hash(&self) -> ::Hash { + self.0.genesis_hash() + } + + /// Return the runtime version. + fn runtime_version(&self) -> crate::rpc::types::RuntimeVersion { + self.0.runtime_version() + } + + /// Work with transactions. + pub fn tx(&self) -> TxClient { + >::tx(self) + } + + /// Work with events. + pub fn events(&self) -> EventsClient { + >::events(self) + } + + /// Work with storage. + pub fn storage(&self) -> StorageClient { + >::storage(self) + } + + /// Access constants. + pub fn constants(&self) -> ConstantsClient { + >::constants(self) + } + + /// Work with blocks. + pub fn blocks(&self) -> BlocksClient { + >::blocks(self) + } + + /// Work with runtime API. + pub fn runtime_api(&self) -> RuntimeApiClient { + >::runtime_api(self) + } +} + impl OnlineClientT for LightClient { fn rpc(&self) -> &crate::rpc::Rpc { self.0.rpc() @@ -57,14 +119,14 @@ impl OnlineClientT for LightClient { impl OfflineClientT for LightClient { fn metadata(&self) -> crate::Metadata { - self.0.metadata() + self.metadata() } fn genesis_hash(&self) -> ::Hash { - self.0.genesis_hash() + self.genesis_hash() } fn runtime_version(&self) -> crate::rpc::types::RuntimeVersion { - self.0.runtime_version() + self.runtime_version() } }