Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter one or multiple events by type from an EventSubscription #461

Merged
merged 18 commits into from
Mar 1, 2022
Merged
10 changes: 5 additions & 5 deletions examples/examples/submit_and_watch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ async fn simple_transfer() -> Result<(), Box<dyn std::error::Error>> {
.await?;

let transfer_event =
balance_transfer.find_first_event::<polkadot::balances::events::Transfer>()?;
balance_transfer.find_first::<polkadot::balances::events::Transfer>()?;

if let Some(event) = transfer_event {
println!("Balance transfer success: {event:?}");
Expand Down Expand Up @@ -108,7 +108,7 @@ async fn simple_transfer_separate_events() -> Result<(), Box<dyn std::error::Err
let events = balance_transfer.fetch_events().await?;

let failed_event =
events.find_first_event::<polkadot::system::events::ExtrinsicFailed>()?;
events.find_first::<polkadot::system::events::ExtrinsicFailed>()?;

if let Some(_ev) = failed_event {
// We found a failed event; the transfer didn't succeed.
Expand All @@ -117,7 +117,7 @@ async fn simple_transfer_separate_events() -> Result<(), Box<dyn std::error::Err
// We didn't find a failed event; the transfer succeeded. Find
// more details about it to report..
let transfer_event =
events.find_first_event::<polkadot::balances::events::Transfer>()?;
events.find_first::<polkadot::balances::events::Transfer>()?;
if let Some(event) = transfer_event {
println!("Balance transfer success: {event:?}");
} else {
Expand Down Expand Up @@ -161,7 +161,7 @@ async fn handle_transfer_events() -> Result<(), Box<dyn std::error::Error>> {

let events = details.wait_for_success().await?;
let transfer_event =
events.find_first_event::<polkadot::balances::events::Transfer>()?;
events.find_first::<polkadot::balances::events::Transfer>()?;

if let Some(event) = transfer_event {
println!(
Expand All @@ -181,7 +181,7 @@ async fn handle_transfer_events() -> Result<(), Box<dyn std::error::Error>> {

let events = details.wait_for_success().await?;
let transfer_event =
events.find_first_event::<polkadot::balances::events::Transfer>()?;
events.find_first::<polkadot::balances::events::Transfer>()?;

if let Some(event) = transfer_event {
println!("Balance transfer success: {event:?}");
Expand Down
2 changes: 1 addition & 1 deletion examples/examples/subscribe_all_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

// Or we can dynamically find the first transfer event, ignoring any others:
let transfer_event =
events.find_first_event::<polkadot::balances::events::Transfer>()?;
events.find_first::<polkadot::balances::events::Transfer>()?;

if let Some(ev) = transfer_event {
println!(" - Balance transfer success: value: {:?}", ev.amount);
Expand Down
20 changes: 4 additions & 16 deletions examples/examples/subscribe_one_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@
//! polkadot --dev --tmp
//! ```
use futures::{
future,
stream,
StreamExt,
};
use futures::StreamExt;
use sp_keyring::AccountKeyring;
use std::time::Duration;
use subxt::{
Expand All @@ -51,21 +47,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.await?
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, DefaultExtra<DefaultConfig>>>();

// Subscribe to just balance transfer events, making use of `flat_map` and
// `filter_map` from the StreamExt trait to filter everything else out.
// Subscribe to just balance transfer events, making use of `filter_events`
// to select a single event type (note the 1-tuple) to filter out and return.
let mut transfer_events = api
.events()
.subscribe()
.await?
// Ignore errors returning events:
.filter_map(|events| future::ready(events.ok()))
// Map events to just the one we care about:
.flat_map(|events| {
let transfer_events = events
.find::<polkadot::balances::events::Transfer>()
.collect::<Vec<_>>();
stream::iter(transfer_events)
});
.filter_events::<(polkadot::balances::events::Transfer,)>();

// While this subscription is active, we imagine some balance transfers are made somewhere else:
async_std::task::spawn(async {
Expand Down
100 changes: 100 additions & 0 deletions examples/examples/subscribe_some_events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
// This file is part of subxt.
//
// subxt is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// subxt is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with subxt. If not, see <http://www.gnu.org/licenses/>.

//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.13-82616422d0-aarch64-macos.
//!
//! E.g.
//! ```bash
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.13/polkadot" --output /usr/local/bin/polkadot --location
//! polkadot --dev --tmp
//! ```

use futures::StreamExt;
use sp_keyring::AccountKeyring;
use std::time::Duration;
use subxt::{
ClientBuilder,
DefaultConfig,
DefaultExtra,
PairSigner,
};

#[subxt::subxt(runtime_metadata_path = "examples/polkadot_metadata.scale")]
pub mod polkadot {}

/// Subscribe to all events, and then manually look through them and
/// pluck out the events that we care about.
#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();

// Subscribe to any events that occur:
let api = ClientBuilder::new()
.build()
.await?
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, DefaultExtra<DefaultConfig>>>();

// Subscribe to several balance related events. If we ask for more than one event,
// we'll be given a correpsonding tuple of `Option`'s, with exactly one
// variant populated each time.
let mut balance_events = api.events().subscribe().await?.filter_events::<(
polkadot::balances::events::Withdraw,
polkadot::balances::events::Transfer,
polkadot::balances::events::Deposit,
)>();
Comment on lines +53 to +57
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this new example to show off the "filter multiple events" case.


// While this subscription is active, we imagine some balance transfers are made somewhere else:
async_std::task::spawn(async {
let signer = PairSigner::new(AccountKeyring::Alice.pair());
let api = ClientBuilder::new()
.build()
.await
.unwrap()
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, DefaultExtra<DefaultConfig>>>();

// Make small balance transfers from Alice to Bob in a loop:
loop {
api.tx()
.balances()
.transfer(AccountKeyring::Bob.to_account_id().into(), 1_000_000_000)
.sign_and_submit(&signer)
.await
.unwrap();
async_std::task::sleep(Duration::from_secs(10)).await;
}
});

// Our subscription will see all of the balance events we're filtering on:
while let Some(ev) = balance_events.next().await {
let event_details = ev?;

let block_hash = event_details.block_hash;
let event = event_details.event;
println!("Event at {:?}:", block_hash);

if let (Some(withdraw), _, _) = &event {
println!(" Withdraw event: {withdraw:?}");
}
if let (_, Some(transfer), _) = &event {
println!(" Transfer event: {transfer:?}");
}
if let (_, _, Some(deposit)) = &event {
println!(" Deposit event: {deposit:?}");
}
}

Ok(())
}
Loading