mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 21:41:12 +00:00
Use async-trait (#264)
* Use async-trait * Use async-trait for store trait too
This commit is contained in:
@@ -24,6 +24,7 @@ tokio02 = ["jsonrpsee-http-client/tokio02"]
|
|||||||
tokio1 = ["jsonrpsee-http-client/tokio1"]
|
tokio1 = ["jsonrpsee-http-client/tokio1"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
async-trait = "0.1.49"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
thiserror = "1.0.24"
|
thiserror = "1.0.24"
|
||||||
futures = "0.3.13"
|
futures = "0.3.13"
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ description = "Derive calls, events, storage and tests for interacting Substrate
|
|||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
async-trait = "0.1.49"
|
||||||
heck = "0.3.2"
|
heck = "0.3.2"
|
||||||
proc-macro2 = "1.0.24"
|
proc-macro2 = "1.0.24"
|
||||||
proc-macro-crate = "0.1.5"
|
proc-macro-crate = "0.1.5"
|
||||||
|
|||||||
+24
-20
@@ -50,42 +50,44 @@ pub fn call(s: Structure) -> TokenStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Call extension trait.
|
/// Call extension trait.
|
||||||
|
#[async_trait::async_trait]
|
||||||
pub trait #call_trait<T: #subxt::Runtime + #module> {
|
pub trait #call_trait<T: #subxt::Runtime + #module> {
|
||||||
/// Create and submit an extrinsic.
|
/// Create and submit an extrinsic.
|
||||||
fn #call<'a>(
|
async fn #call<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
signer: &'a (dyn #subxt::Signer<T> + Send + Sync),
|
signer: &'a (dyn #subxt::Signer<T> + Send + Sync),
|
||||||
#args
|
#args
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<T::Hash, #subxt::Error>> + Send + 'a>>;
|
) -> Result<T::Hash, #subxt::Error>;
|
||||||
|
|
||||||
/// Create, submit and watch an extrinsic.
|
/// Create, submit and watch an extrinsic.
|
||||||
fn #call_and_watch<'a>(
|
async fn #call_and_watch<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
signer: &'a (dyn #subxt::Signer<T> + Send + Sync),
|
signer: &'a (dyn #subxt::Signer<T> + Send + Sync),
|
||||||
#args
|
#args
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<#subxt::ExtrinsicSuccess<T>, #subxt::Error>> + Send + 'a>>;
|
) -> Result<#subxt::ExtrinsicSuccess<T>, #subxt::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
impl<T: #subxt::Runtime + #module> #call_trait<T> for #subxt::Client<T>
|
impl<T: #subxt::Runtime + #module> #call_trait<T> for #subxt::Client<T>
|
||||||
where
|
where
|
||||||
<<T::Extra as #subxt::SignedExtra<T>>::Extra as #subxt::SignedExtension>::AdditionalSigned: Send + Sync,
|
<<T::Extra as #subxt::SignedExtra<T>>::Extra as #subxt::SignedExtension>::AdditionalSigned: Send + Sync,
|
||||||
{
|
{
|
||||||
fn #call<'a>(
|
async fn #call<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
signer: &'a (dyn #subxt::Signer<T> + Send + Sync),
|
signer: &'a (dyn #subxt::Signer<T> + Send + Sync),
|
||||||
#args
|
#args
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<T::Hash, #subxt::Error>> + Send + 'a>> {
|
) -> Result<T::Hash, #subxt::Error> {
|
||||||
let #marker = core::marker::PhantomData::<T>;
|
let #marker = core::marker::PhantomData::<T>;
|
||||||
Box::pin(self.submit(#build_struct, signer))
|
self.submit(#build_struct, signer).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn #call_and_watch<'a>(
|
async fn #call_and_watch<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
signer: &'a (dyn #subxt::Signer<T> + Send + Sync),
|
signer: &'a (dyn #subxt::Signer<T> + Send + Sync),
|
||||||
#args
|
#args
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<#subxt::ExtrinsicSuccess<T>, #subxt::Error>> + Send + 'a>> {
|
) -> Result<#subxt::ExtrinsicSuccess<T>, #subxt::Error> {
|
||||||
let #marker = core::marker::PhantomData::<T>;
|
let #marker = core::marker::PhantomData::<T>;
|
||||||
Box::pin(self.watch(#build_struct, signer))
|
self.watch(#build_struct, signer).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,46 +114,48 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Call extension trait.
|
/// Call extension trait.
|
||||||
|
#[async_trait::async_trait]
|
||||||
pub trait TransferCallExt<T: substrate_subxt::Runtime + Balances> {
|
pub trait TransferCallExt<T: substrate_subxt::Runtime + Balances> {
|
||||||
/// Create and submit an extrinsic.
|
/// Create and submit an extrinsic.
|
||||||
fn transfer<'a>(
|
async fn transfer<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
signer: &'a (dyn substrate_subxt::Signer<T> + Send + Sync),
|
signer: &'a (dyn substrate_subxt::Signer<T> + Send + Sync),
|
||||||
to: &'a <T as System>::Address,
|
to: &'a <T as System>::Address,
|
||||||
amount: T::Balance,
|
amount: T::Balance,
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<T::Hash, substrate_subxt::Error>> + Send + 'a>>;
|
) -> Result<T::Hash, substrate_subxt::Error>;
|
||||||
|
|
||||||
/// Create, submit and watch an extrinsic.
|
/// Create, submit and watch an extrinsic.
|
||||||
fn transfer_and_watch<'a>(
|
async fn transfer_and_watch<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
signer: &'a (dyn substrate_subxt::Signer<T> + Send + Sync),
|
signer: &'a (dyn substrate_subxt::Signer<T> + Send + Sync),
|
||||||
to: &'a <T as System>::Address,
|
to: &'a <T as System>::Address,
|
||||||
amount: T::Balance,
|
amount: T::Balance,
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<substrate_subxt::ExtrinsicSuccess<T>, substrate_subxt::Error>> + Send + 'a>>;
|
) -> Result<substrate_subxt::ExtrinsicSuccess<T>, substrate_subxt::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
impl<T: substrate_subxt::Runtime + Balances> TransferCallExt<T> for substrate_subxt::Client<T>
|
impl<T: substrate_subxt::Runtime + Balances> TransferCallExt<T> for substrate_subxt::Client<T>
|
||||||
where
|
where
|
||||||
<<T::Extra as substrate_subxt::SignedExtra<T>>::Extra as substrate_subxt::SignedExtension>::AdditionalSigned: Send + Sync,
|
<<T::Extra as substrate_subxt::SignedExtra<T>>::Extra as substrate_subxt::SignedExtension>::AdditionalSigned: Send + Sync,
|
||||||
{
|
{
|
||||||
fn transfer<'a>(
|
async fn transfer<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
signer: &'a (dyn substrate_subxt::Signer<T> + Send + Sync),
|
signer: &'a (dyn substrate_subxt::Signer<T> + Send + Sync),
|
||||||
to: &'a <T as System>::Address,
|
to: &'a <T as System>::Address,
|
||||||
amount: T::Balance,
|
amount: T::Balance,
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<T::Hash, substrate_subxt::Error>> + Send + 'a>> {
|
) -> Result<T::Hash, substrate_subxt::Error> {
|
||||||
let _ = core::marker::PhantomData::<T>;
|
let _ = core::marker::PhantomData::<T>;
|
||||||
Box::pin(self.submit(TransferCall { to, amount, }, signer))
|
self.submit(TransferCall { to, amount, }, signer).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transfer_and_watch<'a>(
|
async fn transfer_and_watch<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
signer: &'a (dyn substrate_subxt::Signer<T> + Send + Sync),
|
signer: &'a (dyn substrate_subxt::Signer<T> + Send + Sync),
|
||||||
to: &'a <T as System>::Address,
|
to: &'a <T as System>::Address,
|
||||||
amount: T::Balance,
|
amount: T::Balance,
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<substrate_subxt::ExtrinsicSuccess<T>, substrate_subxt::Error>> + Send + 'a>> {
|
) -> Result<substrate_subxt::ExtrinsicSuccess<T>, substrate_subxt::Error> {
|
||||||
let _ = core::marker::PhantomData::<T>;
|
let _ = core::marker::PhantomData::<T>;
|
||||||
Box::pin(self.watch(TransferCall { to, amount, }, signer))
|
self.watch(TransferCall { to, amount, }, signer).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+24
-20
@@ -141,36 +141,38 @@ pub fn store(s: Structure) -> TokenStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Store extension trait.
|
/// Store extension trait.
|
||||||
|
#[async_trait::async_trait]
|
||||||
pub trait #store_trait<T: #subxt::Runtime + #module> {
|
pub trait #store_trait<T: #subxt::Runtime + #module> {
|
||||||
/// Retrieve the store element.
|
/// Retrieve the store element.
|
||||||
fn #store<'a>(
|
async fn #store<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
#args
|
#args
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<#ret, #subxt::Error>> + Send + 'a>>;
|
) -> Result<#ret, #subxt::Error>;
|
||||||
|
|
||||||
/// Iterate over the store element.
|
/// Iterate over the store element.
|
||||||
fn #store_iter<'a>(
|
async fn #store_iter<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<#key_iter, #subxt::Error>> + Send + 'a>>;
|
) -> Result<#key_iter, #subxt::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
impl<T: #subxt::Runtime + #module> #store_trait<T> for #subxt::Client<T> {
|
impl<T: #subxt::Runtime + #module> #store_trait<T> for #subxt::Client<T> {
|
||||||
fn #store<'a>(
|
async fn #store<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
#args
|
#args
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<#ret, #subxt::Error>> + Send + 'a>> {
|
) -> Result<#ret, #subxt::Error> {
|
||||||
let #marker = core::marker::PhantomData::<T>;
|
let #marker = core::marker::PhantomData::<T>;
|
||||||
Box::pin(async move { self.#fetch(&#build_struct, hash).await })
|
self.#fetch(&#build_struct, hash).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn #store_iter<'a>(
|
async fn #store_iter<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<#key_iter, #subxt::Error>> + Send + 'a>> {
|
) -> Result<#key_iter, #subxt::Error> {
|
||||||
Box::pin(self.iter(hash))
|
self.iter(hash).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,36 +219,38 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Store extension trait.
|
/// Store extension trait.
|
||||||
|
#[async_trait::async_trait]
|
||||||
pub trait AccountStoreExt<T: substrate_subxt::Runtime + Balances> {
|
pub trait AccountStoreExt<T: substrate_subxt::Runtime + Balances> {
|
||||||
/// Retrieve the store element.
|
/// Retrieve the store element.
|
||||||
fn account<'a>(
|
async fn account<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
account_id: &'a <T as System>::AccountId,
|
account_id: &'a <T as System>::AccountId,
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<AccountData<T::Balance>, substrate_subxt::Error>> + Send + 'a>>;
|
) -> Result<AccountData<T::Balance>, substrate_subxt::Error>;
|
||||||
/// Iterate over the store element.
|
/// Iterate over the store element.
|
||||||
fn account_iter<'a>(
|
async fn account_iter<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<substrate_subxt::KeyIter<T, AccountStore<'a, T>>, substrate_subxt::Error>> + Send + 'a>>;
|
) -> Result<substrate_subxt::KeyIter<T, AccountStore<'a, T>>, substrate_subxt::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
impl<T: substrate_subxt::Runtime + Balances> AccountStoreExt<T> for substrate_subxt::Client<T> {
|
impl<T: substrate_subxt::Runtime + Balances> AccountStoreExt<T> for substrate_subxt::Client<T> {
|
||||||
fn account<'a>(
|
async fn account<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
account_id: &'a <T as System>::AccountId,
|
account_id: &'a <T as System>::AccountId,
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<AccountData<T::Balance>, substrate_subxt::Error>> + Send + 'a>>
|
) -> Result<AccountData<T::Balance>, substrate_subxt::Error>
|
||||||
{
|
{
|
||||||
let _ = core::marker::PhantomData::<T>;
|
let _ = core::marker::PhantomData::<T>;
|
||||||
Box::pin(async move { self.fetch_or_default(&AccountStore { account_id, }, hash).await })
|
self.fetch_or_default(&AccountStore { account_id, }, hash).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn account_iter<'a>(
|
async fn account_iter<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
hash: Option<T::Hash>,
|
hash: Option<T::Hash>,
|
||||||
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<substrate_subxt::KeyIter<T, AccountStore<'a, T>>, substrate_subxt::Error>> + Send + 'a>> {
|
) -> Result<substrate_subxt::KeyIter<T, AccountStore<'a, T>>, substrate_subxt::Error> {
|
||||||
Box::pin(self.iter(hash))
|
self.iter(hash).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,12 +30,9 @@ use sp_runtime::traits::{
|
|||||||
SignedExtension,
|
SignedExtension,
|
||||||
Verify,
|
Verify,
|
||||||
};
|
};
|
||||||
use std::{
|
|
||||||
future::Future,
|
|
||||||
pin::Pin,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Extrinsic signer.
|
/// Extrinsic signer.
|
||||||
|
#[async_trait::async_trait]
|
||||||
pub trait Signer<T: Runtime> {
|
pub trait Signer<T: Runtime> {
|
||||||
/// Returns the account id.
|
/// Returns the account id.
|
||||||
fn account_id(&self) -> &T::AccountId;
|
fn account_id(&self) -> &T::AccountId;
|
||||||
@@ -47,10 +44,10 @@ pub trait Signer<T: Runtime> {
|
|||||||
///
|
///
|
||||||
/// Some signers may fail, for instance because the hardware on which the keys are located has
|
/// Some signers may fail, for instance because the hardware on which the keys are located has
|
||||||
/// refused the operation.
|
/// refused the operation.
|
||||||
fn sign(
|
async fn sign(
|
||||||
&self,
|
&self,
|
||||||
extrinsic: SignedPayload<T>,
|
extrinsic: SignedPayload<T>,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<UncheckedExtrinsic<T>, String>> + Send>>;
|
) -> Result<UncheckedExtrinsic<T>, String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extrinsic signer using a private key.
|
/// Extrinsic signer using a private key.
|
||||||
@@ -96,6 +93,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
impl<T, P> Signer<T> for PairSigner<T, P>
|
impl<T, P> Signer<T> for PairSigner<T, P>
|
||||||
where
|
where
|
||||||
T: Runtime,
|
T: Runtime,
|
||||||
@@ -112,10 +110,10 @@ where
|
|||||||
self.nonce
|
self.nonce
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign(
|
async fn sign(
|
||||||
&self,
|
&self,
|
||||||
extrinsic: SignedPayload<T>,
|
extrinsic: SignedPayload<T>,
|
||||||
) -> Pin<Box<dyn Future<Output = Result<UncheckedExtrinsic<T>, String>> + Send>> {
|
) -> Result<UncheckedExtrinsic<T>, String> {
|
||||||
let signature = extrinsic.using_encoded(|payload| self.signer.sign(payload));
|
let signature = extrinsic.using_encoded(|payload| self.signer.sign(payload));
|
||||||
let (call, extra, _) = extrinsic.deconstruct();
|
let (call, extra, _) = extrinsic.deconstruct();
|
||||||
let extrinsic = UncheckedExtrinsic::<T>::new_signed(
|
let extrinsic = UncheckedExtrinsic::<T>::new_signed(
|
||||||
@@ -124,6 +122,6 @@ where
|
|||||||
signature.into(),
|
signature.into(),
|
||||||
extra,
|
extra,
|
||||||
);
|
);
|
||||||
Box::pin(async move { Ok(extrinsic) })
|
Ok(extrinsic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user