Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"]
[dependencies]
log = "0.4"
thiserror = "1.0"
futures = "0.3"
futures = "0.3.5"
jsonrpsee = { version = "0.1", features = ["ws"] }
num-traits = { version = "0.2", default-features = false }
serde = { version = "1.0", features = ["derive"] }
Expand Down
2 changes: 2 additions & 0 deletions proc-macro/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pub fn call(s: Structure) -> TokenStream {
T: #module + #subxt::system::System + Send + Sync + 'static,
S: #codec::Encode + Send + Sync + 'static,
E: #subxt::SignedExtra<T> + #subxt::sp_runtime::traits::SignedExtension + Send + Sync + 'static,
<<E as #subxt::SignedExtra<T>>::Extra as #subxt::sp_runtime::traits::SignedExtension>::AdditionalSigned: Send + Sync,
{
fn #call<'a>(
&'a self,
Expand Down Expand Up @@ -154,6 +155,7 @@ mod tests {
T: Balances + substrate_subxt::system::System + Send + Sync + 'static,
S: codec::Encode + Send + Sync + 'static,
E: substrate_subxt::SignedExtra<T> + substrate_subxt::sp_runtime::traits::SignedExtension + Send + Sync + 'static,
<<E as substrate_subxt::SignedExtra<T>>::Extra as substrate_subxt::sp_runtime::traits::SignedExtension>::AdditionalSigned: Send + Sync,
{
fn transfer<'a>(
&'a self,
Expand Down
21 changes: 4 additions & 17 deletions src/frame/balances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,11 @@

//! Implements support for the pallet_balances module.

use crate::frame::system::{
System,
SystemEventsDecoder,
};
use codec::{
Decode,
Encode,
};
use crate::frame::system::{System, SystemEventsDecoder};
use codec::{Decode, Encode};
use core::marker::PhantomData;
use frame_support::Parameter;
use sp_runtime::traits::{
AtLeast32Bit,
MaybeSerialize,
Member,
};
use sp_runtime::traits::{AtLeast32Bit, MaybeSerialize, Member};
use std::fmt::Debug;

/// The subset of the `pallet_balances::Trait` that a client must implement.
Expand Down Expand Up @@ -110,10 +100,7 @@ pub struct TransferEvent<T: Balances> {
mod tests {
use super::*;
use crate::{
system::{
AccountStore,
AccountStoreExt,
},
system::{AccountStore, AccountStoreExt},
tests::test_client,
};
use sp_keyring::AccountKeyring;
Expand Down
30 changes: 21 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ pub use sp_core;
pub use sp_runtime;

use codec::Encode;
use futures::future;
use futures::{
future,
future::TryFutureExt as _,
};
use jsonrpsee::client::Subscription;
use sc_rpc_api::state::ReadProof;
use sp_core::storage::{
Expand Down Expand Up @@ -118,7 +121,7 @@ pub struct ClientBuilder<T: System, S = MultiSignature, E = DefaultExtra<T>> {
client: Option<jsonrpsee::Client>,
}

impl<T: System, S, E> ClientBuilder<T, S, E> {
impl<T: System + Send + Sync, S, E> ClientBuilder<T, S, E> {
/// Creates a new ClientBuilder.
pub fn new() -> Self {
Self {
Expand Down Expand Up @@ -327,18 +330,21 @@ where
}

/// Creates a signed extrinsic.
pub async fn create_signed<C: Call<T>>(
pub async fn create_signed<C: Call<T> + Send + Sync>(
&self,
call: C,
signer: &(dyn Signer<T, S, E> + Send + Sync),
) -> Result<
UncheckedExtrinsic<T::Address, Encoded, S, <E as SignedExtra<T>>::Extra>,
Error,
> {
>
where
<<E as SignedExtra<T>>::Extra as SignedExtension>::AdditionalSigned: Send + Sync,
{
let unsigned = self
.create_unsigned(call, signer.account_id(), signer.nonce())
.await?;
Ok(signer.sign(unsigned))
signer.sign(unsigned).map_err(From::from).await
}

/// Returns an events decoder for a call.
Expand Down Expand Up @@ -379,21 +385,27 @@ where
}

/// Submits a transaction to the chain.
pub async fn submit<C: Call<T>>(
pub async fn submit<C: Call<T> + Send + Sync>(
&self,
call: C,
signer: &(dyn Signer<T, S, E> + Send + Sync),
) -> Result<T::Hash, Error> {
) -> Result<T::Hash, Error>
where
<<E as SignedExtra<T>>::Extra as SignedExtension>::AdditionalSigned: Send + Sync,
{
let extrinsic = self.create_signed(call, signer).await?;
self.submit_extrinsic(extrinsic).await
}

/// Submits transaction to the chain and watch for events.
pub async fn watch<C: Call<T>>(
pub async fn watch<C: Call<T> + Send + Sync>(
&self,
call: C,
signer: &(dyn Signer<T, S, E> + Send + Sync),
) -> Result<ExtrinsicSuccess<T>, Error> {
) -> Result<ExtrinsicSuccess<T>, Error>
where
<<E as SignedExtra<T>>::Extra as SignedExtension>::AdditionalSigned: Send + Sync,
{
let extrinsic = self.create_signed(call, signer).await?;
let decoder = self.events_decoder::<C>()?;
self.submit_and_watch_extrinsic(extrinsic, decoder).await
Expand Down
66 changes: 41 additions & 25 deletions src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,43 @@
//! A library to **sub**mit e**xt**rinsics to a
//! [substrate](https://github.com/paritytech/substrate) node via RPC.

use crate::{
extra::SignedExtra,
frame::system::System,
Encoded,
};
use crate::{extra::SignedExtra, frame::system::System, Encoded};
use codec::Encode;
use sp_core::Pair;
use sp_runtime::{
generic::{
SignedPayload,
UncheckedExtrinsic,
},
traits::{
IdentifyAccount,
Verify,
},
generic::{SignedPayload, UncheckedExtrinsic},
traits::{IdentifyAccount, Verify, SignedExtension},
};
use std::marker::PhantomData;
use std::{future::Future, marker::PhantomData, pin::Pin};

/// Extrinsic signer.
pub trait Signer<T: System, S: Encode, E: SignedExtra<T>> {
pub trait Signer<T: System, S: Encode, E: SignedExtra<T>>
where <<E as SignedExtra<T>>::Extra as SignedExtension>::AdditionalSigned: Send + Sync
{
/// Returns the account id.
fn account_id(&self) -> &T::AccountId;

/// Optionally returns a nonce.
fn nonce(&self) -> Option<T::Index>;

/// Takes an unsigned extrinsic and returns a signed extrinsic.
///
/// Some signers may fail, for instance because the hardware on which the keys are located has
/// refused the operation.
fn sign(
&self,
extrinsic: SignedPayload<Encoded, E::Extra>,
) -> UncheckedExtrinsic<T::Address, Encoded, S, E::Extra>;
) -> Pin<
Box<
dyn Future<
Output = Result<
UncheckedExtrinsic<T::Address, Encoded, S, E::Extra>,
String,
>,
> + Send
+ Sync,
>,
>;
}

/// Extrinsic signer using a private key.
Expand Down Expand Up @@ -91,12 +96,13 @@ where

impl<T, S, E, P> Signer<T, S, E> for PairSigner<T, S, E, P>
where
T: System,
T::AccountId: Into<T::Address>,
S: Encode,
E: SignedExtra<T>,
P: Pair,
P::Signature: Into<S>,
T: System + 'static,
T::AccountId: Into<T::Address> + 'static,
S: Encode + 'static + Send + Sync,
E: SignedExtra<T> + 'static,
P: Pair + 'static,
P::Signature: Into<S> + 'static,
<<E as SignedExtra<T>>::Extra as SignedExtension>::AdditionalSigned: Send + Sync,
{
fn account_id(&self) -> &T::AccountId {
&self.account_id
Expand All @@ -109,14 +115,24 @@ where
fn sign(
&self,
extrinsic: SignedPayload<Encoded, E::Extra>,
) -> UncheckedExtrinsic<T::Address, Encoded, S, E::Extra> {
) -> Pin<
Box<
dyn Future<
Output = Result<
UncheckedExtrinsic<T::Address, Encoded, S, E::Extra>,
String,
>,
> + Send
+ Sync,
>,
> {
let signature = extrinsic.using_encoded(|payload| self.signer.sign(payload));
let (call, extra, _) = extrinsic.deconstruct();
UncheckedExtrinsic::new_signed(
Box::pin(futures::future::ready(Ok(UncheckedExtrinsic::new_signed(
call,
self.account_id.clone().into(),
signature.into(),
extra,
)
))))
}
}