Skip to content

Releases: paritytech/subxt

v0.50.0

12 Mar 18:49
4f008f1

Choose a tag to compare

[0.50.0] - 2025-12-17

This release version is a deliberately large bump up from 0.44.0 to signify the extent of the changes in this release.

The headline changes are as follows:

  • Subxt is no longer head-of-chain only, and can work with historic blocks, all the way back to genesis. Note: user-provided type information is required to do this for very old (> ~2year old, ie pre-V14 metadata) blocks.
  • The MVP subxt-historic crate has been removed, its functionality having been merged into Subxt.
  • The subxt-core crate has been removed for now to make way for the above. Subxt itself continues to support WASM use cases.
    • For truly no-std functionality, the frame-decode crate now contains much of the underlying logic used throughout Subxt to encode and decode things, and we would like to expand the functionality here.
    • We would like feedback from any users of the subxt-core crate on how they use it, and will use this feedback to drive future work in this area.
  • No more monitoring for runtime updates is needed; Subxt now works across different runtime versions automatically.
  • Errors are no longer one big Error enum; instead different Subxt APIs return different errors, to limit the number of possible errors in any one place. These all convert into subxt::Error so this can continue to be used as a catch-all.
  • Storage APIs have been redone, fixing some issues and giving much more control over iteration, as well as key and value decoding.

There are also a couple of organizational changes which aren't visible:

  • We now follow the name.rs + name/submodule.rs convention instead of the name/mod.rs + name/submodule.rs convention.
  • CI and testing updates hopefully ensure better organization and coverage with a greater number of different feature flags being tested.

This changes have results in many breaking changes across APIs, which I will try my best to summarize below.

A good place to look for a more holistic understanding of what's changes are the examples, both:

For the smaller examples, start with the basic transaction submission example and then have a look at the blocks example and the storage example to give the best broad overview of the changes. Pick and choose others next depending on what suits.

A breakdown of the significant changes follows, to aid migration efforts:

Configuration

Before

Configuration (PolkadotConfig and SubstrateConfig) was type-only and didn't exist at the value level, and so you'd provide it to the client like so:

use subxt::{OnlineClient, PolkadotConfig};

let api = OnlineClient::<PolkadotConfig>::new().await?;

After

Configuration now exists at the value level too. This is because it has been extended with support for historic types and working with historic metadatas and spec versions. The same code as above will continue to work, but it's now possible to instantiate and tweak the configuration and then use _with_config methods to provide it, like so:

use subxt::{OnlineClient, PolkadotConfig};

let config = PolkadotConfig::builder()
    .use_historic_types(false)
    .build();
let api = OnlineClient::<PolkadotConfig>::new_with_config(config).await?;

The rules for when to use PolkadotConfig and SubstrateConfig remain the same:

  • Use PolkadotConfig for the Polkadot Relay Chain.
  • Use SubstrateConfig by default with other chains.
  • You may need to modify the configuration to work with some chains, as before.

See the docs for PolkadotConfig and SubstrateConfig for more. One example to be aware of is that if you want to work with historic blocks with SubstrateConfig, you'll need to instantiate it yourself and provide historic type information before passing it to OnlineClient or OfflineClient.

Configuration: ExtrinsicParams

Aside from the new historic types support, a notable change to the configuration has been the simplification of transaction extensions, previously called ExtrinsicParams in our Config. Now, the type is called TransactionExtensions and the supporting traits have been simplified and named more appropriately (just TransactionExtensions and TransactionExtension), moving to rely more on frame-decode for the core logic. For any users that implement their own transaction extensions, migrating to the new traits is straightforward and I would encourage you to look at how the built-in transaction extensions are implemented for guidance here.

See (see #2177) for more details around this change.

Working at specific blocks

Before

Previously, you'd be able to select (within a limited range) which block to work at with APIs like so:

let api = OnlineClient::<PolkadotConfig>::new().await?;

let constants = api.constants();

let storage = api.storage().at(block_hash).await?;
let storage = api.storage().at_latest().await?;

let events = api.events().at(block_hash).await?;
let events = api.events().at_latest().await?;

let runtime_apis = api.runtime_api().at(block_hash).await?;
let runtime_apis = api.runtime_api().at_latest().await?;

After

Now, the block is selected first, like so:

let api = OnlineClient::<PolkadotConfig>::new().await?;

let constants = api.at_block(block_hash_or_number).await?.constants();
let constants = api.at_current_block().await?.constants();

let storage = api.at_block(block_hash_or_number).await?.storage();
let storage = api.at_current_block().await?.storage();

let events = api.at_block(block_hash_or_number).await?.events();
let events = api.at_current_block().await?.events();

let runtime_apis = api.at_block(block_hash_or_number).await?.runtime_apis();
let runtime_apis = api.at_current_block().await?.runtime_apis();

Notes:

  • at_latest has been renamed to at_current_block and, like before, it fetches the current finalized block at the time of calling.
  • at_current_block now accepts a block hash or block number, and returns a client that works in the context of that block.
  • Constants were not previously retrieved at a given block; Subxt only knew about a single Metadata and so it was unnecessary. Now, constants are retrieved at a specific block like everything else (different blocks may have different Metadatas).
  • A small thing: runtime_api() was renamed to runtime_apis() to be consistent with other APIs names.
  • .tx() is now callable at a specific block, and uses this block for any account nonce and mortality configuration.

Working with blocks

Before

A .blocks() method accessed block-specific APIs for fetching and subscribing to blocks.

let api = OnlineClient::<PolkadotConfig>::new().await?;

// fetching:
let block = api.blocks().at(block_hash).await?;
let block = api.blocks().at_latest().await?;

// subscribing:
let mut blocks = api.blocks().subscribe_finalized().await?;
while let Some(block) = blocks_sub.next().await {
    let block = block?;

    let extrinsics = block.extrinsics().await?;
    for ext in extrinsics.iter() {
        // See the blocks example for more.
    }
}

After

Now that APIs are largely block-specific up front, we don't need separate APIs for block fetching, and so we move streaming blocks up a level, removing the .blocks() APIs.

let api = OnlineClient::<PolkadotConfig>::new().await?;

// fetching:
let block = api.at_block(block_hash_or_number).await?;
let block = api.at_current_block().await?;

// subscribing:
let mut blocks = api.stream_blocks().await?;
while let Some(block) = blocks_sub.next().await {
    let block = block?;

    // now, we instantiate a client at a given block, which gives back the
    // same thing as api.at_block() and api.at_current_block() does:
    let at_block = block.at().await?;

    let extrinsics = at_block.extrinsics().fetch().await?;
    for ext in extrinsics.iter() {
        // See the blocks example for more.
    }
}

Notes:

  • Working with finalized blocks is always the default now, and API names are shortened to make them the easiest/most obvious to use.
  • Use .at() at a given block to hand back a full client which can do anything at that block.
  • api.blocks().subscribe_finalized() => api.stream_blocks().
  • api.blocks().subscribe_best() => api.stream_best_blocks().
  • api.blocks().subscribe_all() => api.stream_all_blocks().

Transactions

Before

Transactions were implicitly created at the latest block, and the APIs were disconnected from any particular block:

let api = OnlineClient::<PolkadotConfig>::new().await?;

// Submit an extrinsic, waiting for success.
let events = api
    .tx()
    .sign_and_submit_then_watch_default(&balance_transfer_tx, &from)
    .await?
    .wait_for_finalized_success()
    .await?;

After

Transactions are anchored to a given block but we continue to provide a .tx() method on the client as a shorthand for "create transactions at the current block".

let api = OnlineClient::<PolkadotConfig>::new().await?;

// Work at a specific block:
let at_block = api.at_current_block().await?;

// Submit the balance transfer extrinsic anchored at this block:
let events = at_block
    .tx()
    .sign_and_subm...
Read more

v0.44.2

09 Jan 18:12
7308fa1

Choose a tag to compare

[0.44.2] - 2026-01-09

This manually cherry-picks #2142 onto the 0.44 branch to allow using $OUT_DIR in a couple of Subxt macro attributes.

Changed

  • Allow passing $OUT_DIR in the runtime_metadata_path attribute #2142

v0.44.1

08 Jan 16:28
5da1cc7

Choose a tag to compare

[0.44.1] - 2026-01-08

When using .tip_of(some_tip, optional_asset_id) to configure a tip for transactions, the actual tip was being set to 0. This is now fixed.

Fixed

  • Fix tipping for ChargeAssetTxPayment tx extension(#2151)

v0.44.0

22 Oct 11:29
f565bda

Choose a tag to compare

[0.44.0] - 2025-08-28

This small release primarily fixes a few issues, but also adds the code for a prelease of subxt-historic, a new crate (at the moment) for working with historic blocks and state. Future releases will aim to stabilize this crate to the level of other subxt crates or otherwise merge the logic into subxt itself.

This is a minor version bump because, in theory at least, adding the Clone bound to block headers in (#2047) is a breaking change, although I think it is unlikely that this will impact any users.

Added

  • Add prerelease subxt-historic crate for accessing historic (non head-of-chain) blocks (#2040)

Changed

  • Block: Implement clone (#2047)
  • Increase number of dev accounts (#2068)

Fixed

  • Do not panic when encoding call data with invalid fields (#2070)
  • Tweak test to reduce chance of failure, and need jsonrpsee/server for tests (#2057)
  • Fix 1.89 clippy warnings (#2055)
  • Increase reconnecting client request/response size (#2046)

v0.43.0

18 Jul 09:33
841a43b

Choose a tag to compare

[0.43.0] - 2025-07-17

This is a reasonably small release which is mainly bug fixing, but has a couple of changes I'd like to elaborate on:

Remove codec::Encode and codec::Decode derives from generated APIs by default (#2008)

When generating an API using the #[subxt::subxt(...)] macro (or programatically via subxt-codegen), we had always previously added parity_scale_codec::Encode and parity_scale_codec::Decode derives to all of the generated types. Most places in Subxt have not made use of these for a long time (relying instead on scale_encode::EncodeAsType and scale_decode::DecodeAsType, since they allow encoding and encoding which takes the type information into account and can more gracefully handle incompatibilities).

We eventually hit an issue to which the most appropriate fix was just to remove these derives.

If you still need the parity_scale_codec::Encode or parity_scale_codec::Decode derives on certain types, you have two options:

  1. Use the derive_for_type attr to add them back where needed, eg:
    #[subxt::subxt(
      ...
      derive_for_type(
        path = "staging_xcm::v3::multilocation::MultiLocation",
        derive = "parity_scale_codec::Encode, parity_scale_codec::Decode",
        recursive
      )
    )]
  2. Use the derive_for_all_types attr to add them back everywhere, eg:
    #[subxt::subxt(
      ...
      derive_for_all_types = "parity_scale_codec::Encode, parity_scale_codec::Decode"
    )]
    

Prefer (1) where possible to reduce the amount of generated code, and reduce the likelihood of running into issues around those derives in certain edge cases.

This PR changes some things around storage keys to remove one last requirement for Encode and Decode derives, and also as a side effect changes api.storage().call_raw() slightly to no longer also try to decode the resulting type via Decode, leaving this to the user (and also meaning it's much easier now for the user to obtain the raw bytes for some storage entry).

In other words, instead of doing something like:

let (compact_len, metadata) = rt
        .call_raw::<(Compact<u32>, frame_metadata::RuntimeMetadataPrefixed)>(
            "Metadata_metadata",
            None,
        )
        .await?;

You would now do:

let meta_bytes = rt.call_raw("Metadata_metadata", None).await?;
let (compact_len, metadata): (Compact<u32>, frame_metadata::RuntimeMetadataPrefixed) =
    Decode::decode(&mut &*meta_bytes)?;

Address some issues around tx mortality (#2025)

Prior to this change, the intended behavior was that any transaction submitted via an OnlineClient would have a mortality of 32 blocks by default, and any transaction submitted via an OfflineClient would be immortal by default. A couple of issues were present or cropped up however:

  • If you explicitly configure the mortality via setting params like PolkadotExtrinsicParamsBuilder::new().mortal(32).build(), the OfflineClient transaction would still be immortal, because it didn't have enough information to properly configure the mortality as asked for (by virtue of being offline and unable to fetch it).
  • The intended behaviour turned out to have been broken, and transactions were being submitted as immortal even via the OnlineClient by default, unless mortality was explicitly configured.
  • There was no easy way to actually set the mortality for an OfflineClient transaction; you'd have to do something like this:
    let params = DefaultExtrinsicParamsBuilder::new();
    params.5 = CheckMortalityParams::mortal_from_unchecked(for_n_blocks, from_block_n, from_block_hash);

With this PR, transactions are now mortal by default using the OnlineClient, we now return an error if you try to construct a transaction with the OfflineClient and try to use params.mortal(..) when configuring it, and we expose params.mortal_from_unchecked(..) to allow configuration for offline transactions without the ugly code above.

In this PR, we also discovered an issue decoding Eras and fixed this, so that decoding the mortality of a transaction when it is mortal should now work.

Add FFI example (#2037)

I'd like to do a quick shoutout to @wassimans, who submitted an excellent example for how to interact with Subxt via the C FFI in Python and Node.JS. This is something I've wanted to add for a while, so it's lovely to see this new example which highlights one of the strengths of Subxt over Javascript based compatitors in the space.

All of the non-trivial changes in this release are listed below:

Added

  • Add FFI example (#2037)

Changed

  • Remove codec::Encode and codec::Decode derives from generated APIs by default (#2008)
  • Address some issues around tx mortality (#2025)

Fixed

  • Fix 'subxt explore storage': don't turn keys to bytes (#2038)
  • Refactor: improve nonce and block injection in extrinsic params (#2032)
  • Improve docs for at_latest (#2035)
  • Clippy fixes for latest Rustc (#2033)
  • docs: fix minor comment typos (#2027)
  • chore: remove redundant backtick in comment (#2020)
  • Keep codec attrs even when Encode/Decode not used (#2023)
  • Run CI on v0.N.x branches or PRs to them for ease of backporting (#2017)
  • De-dup types early in CLI/macro so that derives/substitutes work for de-duped types (#2015)
  • If only one hasher, always treat any key as a single and not NMap key, even if it's a tuple. (#2010)

v0.42.1

12 May 12:21
v0.42.1
0473cfd

Choose a tag to compare

[0.42.1] - 2025-05-12

This patch release reduces the rust-version to 1.85.0, given that we don't use any features newer than this at the moment.

v0.42.0

12 May 12:21
v0.42.0
77f8355

Choose a tag to compare

[0.42.0] - 2025-05-09

The primary benefit of this release is introducing support for the about-to-be-stabilised-in-polkadot-sdk V16 metadata, and with that, support for calling Pallet View Functions on runtimes which will support this. Pallet View Functions are used much like Runtime APIs, except that they are declared in specific pallets and not declared at the runtime-wide level, allowing pallets to carry their own APIs with them.

Pallet View Functions

Calling a Pallet View Function in this Subxt release will look like:

use runtime::proxy::view_functions::check_permissions::{Call, ProxyType};

// Construct the call, providing the two arguments.
let view_function_call = runtime::view_functions()
    .proxy()
    .check_permissions(
        Call::System(runtime::system::Call::remark { remark: b"hi".to_vec() }),
        ProxyType::Any
    );

// Submit the call and get back a result.
let _is_call_allowed = api
    .view_functions()
    .at_latest()
    .await?
    .call(view_function_call)
    .await?;

Like Runtime APIs and others, the dynamic API can also be used to call into Pallet View Functions, which has the advantage of not needing the statically generated interface, but the downside of not being strongly typed. This looks like the following:

use scale_value::value;

let metadata = api.metadata();

// Look up the query ID for the View Function in the node metadata:
let query_id = metadata
    .pallet_by_name("Proxy")
    .unwrap()
    .view_function_by_name("check_permissions")
    .unwrap()
    .query_id();

// Construct the call, providing the two arguments.
let view_function_call = subxt::dynamic::view_function_call(
    *query_id,
    vec![
        value!(System(remark(b"hi".to_vec()))), 
        value!(Any())
    ],
);

// Submit the call and get back a result.
let _is_call_allowed = api
    .view_functions()
    .at_latest()
    .await?
    .call(view_function_call)
    .await?;

Updated Config trait

Another change to be aware of is that our Config trait has been tweaked. The Hash associated type is no longer needed, as it can be obtained via the Hasher associated type already, and PolkadotConfig/SubstrateConfig now set the hasher by default to be DynamicHasher256, which will (when V16 metadata is available for a runtime) automatically select between Keccak256 and BlakeTwo256 hashers depending on what the chain requires.

Other changes

We also solidify our support for V1 archive RPCs, upgrade the codebase to Rust 2024 edition, and a bunch of other changes, the full list of which is here:

Added

  • Support v16 metadata and use it by default if it's available (#1999)
  • Metadata V16: Implement support for Pallet View Functions (#1981)
  • Metadata V16: Be more dynamic over which hasher is used. (#1974)

Changed

  • Update to 2024 edition (#2001)
  • Update Smoldot to latest version (#1991)
  • Update native test timeout to 45 mins (#2002)
  • chore(deps): tokio ^1.44.2 (#1989)
  • Add DefaultParams to allow more transaction extensions to be used when calling _default() methods (#1979)
  • Use wat instead of wabt to avoid CI cmake error (and use supported dep) (#1980)
  • Support v1 archive RPCs (#1977)
  • Support V16 metadata and refactor metadata code (#1967)
  • Allow submitting transactions ignoring follow events (#1962)
  • Improve error message regarding failure to extract metadata from WASM runtime (#1961)
  • Add docs for subxt-rpcs and fix example (#1954)

Fixed

  • Fix CLI storage diff (#1958)
  • chore: fix some typos (#1997)

v0.41.0

11 Mar 15:49
v0.41.0
4c32ee1

Choose a tag to compare

[0.41.0] - 2025-03-10

This release makes two main changes:

Add subxt-rpcs crate.

Previously, if you wanted to make raw RPC calls but weren't otherwise interested in using the higher level Subxt interface, you still needed to include the entire Subxt crate.

Now, one can depend on subxt-rpcs directly. This crate implements the new RPC-V2 chainHead/transaction endpoints as well as the currently unstable archive endpoints. it also implements various legacy endpoints that Subxt uses as a fallback to the modern ones. It also provides several feature gated clients for interacting with them:

  • jsonrpsee: A jsonrpsee based RPC client for connecting to individual RPC nodes.
  • unstable-light-client: A Smoldot based light client which connects to multiple nodes in chains via p2p and verifies everything handed back, removing the need to trust any individual nodes.
  • reconnecting-rpc-client: Another jsonrpsee based client which handles reconnecting automatically in the event of network issues.
  • mock-rpc-client: A mock RPC client that can be used in tests.

Custom clients can be implemented if preferred.

Example usage via jsonrpsee feature:

use subxt_rpcs::{RpcClient, ChainHeadRpcMethods};

// Connect to a local node:
let client = RpcClient::("ws://127.0.0.1:9944").await?;
// Use chainHead/archive V2 methods:
let methods = ChainHeadRpcMethods::new(client);

// Call some RPC methods (in this case a subscription):
let mut follow_subscription = methods.chainhead_v1_follow(false).await.unwrap();
while let Some(follow_event) = follow_subscription.next().await {
    // do something with events..
}

Support creating V5 transactions.

Subxt has supported decoding V5 transactions from blocks since 0.38.0, but now it also supports constructing V5 transactions where allowed. Some naming changes have also taken place to align with the Substrate terminology now around transactions (see #1931 for more!).

The main changes here are:

  • subxt_core now contains versioned methods for creating each of the possible types of transaction (V4 unsigned, V4 signed, V5 "bare" or V5 "general"), enabling the APIs to be tailored for each case.
  • subxt exposes higher level wrappers these (ie api.tx().create_v4_unsigned(..), api.tx().create_v5_bare(..)), but also continues to expose the same standard APIs for creating transactions which will, under the hood, decide what to create based on the chain we're connected to.
  • APIs like sign_and_submit now take a T::AccountId rather than a T::Address since it was found to not be useful to provide the latter, and V5 transactions only expect an T::AccountId.
  • Signed Extensions are now referred to as Transaction Extensions, and we've tweaked the interface around how these work slightly to accomodate the fact that in V5 transactions, the signature is passed into a transaction extension where applicable (VerifySignature).
  • As a side effect, it's simpler to set mortality on transactions; no more block hash needs to be provided; only the number of blocks you would like a transaction to live for.

A full list of the relevant changes is as follows:

Added

  • Support constructing and submitting V5 transactions (#1931)
  • Add archive RPCs to subxt-rpcs (#1940)
  • Document generating interface from Runtime WASM and change feature to runtime-wasm-path (#1936)
  • Split RPCs into a separate crate (#1910)

Changed

  • Wrap the subxt::events::Events type to avoid exposing subxt_core errors and types unnecessarily (#1948)
  • Allow transaction timeout in ChainheadBackend to be configured (#1943)
  • refactor: make ExtrinsicEvents::new public for external access (#1933)

v0.40.0

06 Mar 12:49
v0.40.0
9573b55

Choose a tag to compare

[0.40.0] - 2025-03-06

This release reverts the usage of the polkadot-sdk umbrella crate, which was causing issues such as an increased number of dependencies in Cargo.lock. For more details, see #1925.

Additionally, this update bumps the Polkadot SDK-related dependencies to their latest versions, ensuring compatibility and stability.

Fixed

  • Remove usage of polkadot-sdk umbrella crate (#1926)

Full Changelog: v0.39.0...v0.40.0

v0.39.0

05 Feb 11:06
c96387c

Choose a tag to compare

[0.39.0] - 2025-02-04

This release is mostly bug fixes and changes. The only change that should be a breaking change is removing the substrate-compat feature flag (see #1850), which we'll go into more detail about.

The substrate-compat feature flag has been removed.

The substrate-compat feature flag essentially provided:

  1. An implementation of the subxt::config::Header trait for anything implementing sp_runtime::traits::Header (here).
  2. Same for subxt::config::Hasher and anything implementing sp_runtime::traits::Hasher (here).
  3. A subxt_core::tx::PairSigner type which could be given something implementing sp_core::Pair and then be used to sign transactions (here).
  4. From impls for sp_runtime::AccountId32 and related for subxt::utils::AccountId32 (here).
  5. Likewise for sp_runtime::MultiAddress and subxt::utils::MultiAddress (here).
  6. Likewise for sp_runtime::MultiSignature and subxt::utils::MultiSignature (here).

While useful, providing these features in Subxt is almost impossible to maintain: we can only support a single version of sp_runtime/sp_core at a time, but many versions are in use in the wild. This led to various issues regarding the mismatch between sp_* crates in use and a given version of Subxt. More generally, the goal of Subxt is to be independent from any specific version of Substrate, and communicate via the exposed RPC APIs in order to work across any compatible Substrate version (or indeed, alternative implementations that follow things like the RPC spec).

As a result, we've taken the decision to remove this compatibility layer from Subxt itself. To migrate away from this feature, we suggest:

  1. Using the example here to see how to use a Substrate signer to sign Subxt transactions.
  2. Looking at subxt_signer instead, if it's a viable alternative in your case.
  3. Following the "here" links above to see what impls were removed. Impls can generally be recreated as needed using wrapper types which allow converting between Substrate and Subxt types/traits, for instance:
// Wrap a substrate header type in this to impl the subxt Header trait:
struct SubxtHeader<T>(pub T);

// This basically copies the code removed from Subxt, but on a wrapper type:
impl <T> subxt::config::Header for SubxtHeader<T>
where
    T: sp_runtime::traits::Header,
    <T as sp_runtime::traits::Header>::Number: Into<u64>,
{
    type Number = T::Number;
    type Hasher = T::Hashing;

    fn number(&self) -> Self::Number {
        *self.0.number()
    }
}

The hope is that this pattern is applicable to any such types that you find useful to share between Substrate and Subxt code. Please raise an issue if you can't find a solution in your case, and we'll endeavour to help!

The result of this is that your code will work against whichever Substrate crate versions you are using, at the cost of this code no longer being included behind the substrate-compat feature flag.

A full list of relevant changes and fixes (nothing was added in this release) is as follows:

Changed

  • remove substrate compat (#1850)
  • migrate custom error trait impls to thiserror (#1856)
  • re-export jsonrpsee in subxt::ext (#1843)

Fixed

  • don't double hash: use the same hash in ExtrinsicDetails and ExtrinsicDetails (#1917)
  • fix and test sr25519 signing in nostd (#1872)
  • preserve custom metadata when converting between Subxt metadata and frame_metadata (#1914)
  • fix: don't wrap rpc error in DisconnectedWillReconnect in reconnecting rpc client (#1904)
  • fix: substrate runner, support new libp2p addr log (#1892)
  • update Artifacts (auto-generated) (#1874)
  • bump frame-decode and frame-metadata to latest (#1870)
  • fix unstable-light-client + ChainHeadBackend tx events (#1865)
  • when native feature is enabled, we need polkadot-sdk/std for eg examples to work (#1864)
  • load latest metadata version from Wasm blobs. (#1859)
  • minor fix - Yew example (#1852)
  • update the release notes to work for current releases (#1842)