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

Refactors the api #113

Merged
merged 4 commits into from
May 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 1 addition & 2 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ jobs:

- name: setup
run: |
rustup install nightly
rustup component add rustfmt --toolchain nightly
rustup install nightly --profile default

- name: fmt
run: cargo +nightly fmt --all -- --check
Expand Down
10 changes: 3 additions & 7 deletions examples/kusama_balance_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,18 @@ use substrate_subxt::{
balances::*,
ClientBuilder,
KusamaRuntime,
PairSigner,
};

#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();

let signer = AccountKeyring::Alice.pair();
let signer = PairSigner::new(AccountKeyring::Alice.pair());
let dest = AccountKeyring::Bob.to_account_id().into();

let client = ClientBuilder::<KusamaRuntime>::new().build().await?;

let hash = client
.xt(signer, None)
.await?
.transfer(&dest, 10_000)
.await?;
let hash = client.transfer(&signer, &dest, 10_000).await?;

println!("Balance transfer extrinsic submitted: {}", hash);

Expand Down
10 changes: 3 additions & 7 deletions examples/submit_and_watch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,18 @@ use substrate_subxt::{
balances::*,
ClientBuilder,
DefaultNodeRuntime,
PairSigner,
};

#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();

let signer = AccountKeyring::Alice.pair();
let signer = PairSigner::new(AccountKeyring::Alice.pair());
let dest = AccountKeyring::Bob.to_account_id().into();

let client = ClientBuilder::<DefaultNodeRuntime>::new().build().await?;
let result = client
.xt(signer, None)
.await?
.watch()
.transfer(&dest, 10_000)
.await?;
let result = client.transfer_and_watch(&signer, &dest, 10_000).await?;

if let Some(event) = result.transfer()? {
println!("Balance transfer success: value: {:?}", event.amount);
Expand Down
141 changes: 52 additions & 89 deletions proc-macro/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use synstructure::Structure;

pub fn call(s: Structure) -> TokenStream {
let subxt = utils::use_crate("substrate-subxt");
let codec = utils::use_crate("parity-scale-codec");
let ident = &s.ast().ident;
let generics = &s.ast().generics;
let params = utils::type_params(generics);
Expand All @@ -43,26 +44,9 @@ pub fn call(s: Structure) -> TokenStream {
let filtered_fields = utils::filter_fields(&fields, &marker);
let args = utils::fields_to_args(&filtered_fields);
let build_struct = utils::build_struct(ident, &fields);
let xt_builder = generate_trait(
&module,
&call_name,
"XtBuilder",
quote!(&'a self),
quote!(T::Hash),
&args,
&build_struct,
&marker,
);
let events_subscriber = generate_trait(
&module,
&call_name,
"EventsSubscriber",
quote!(self),
quote!(#subxt::ExtrinsicSuccess<T>),
&args,
&build_struct,
&marker,
);
let call_trait = format_ident!("{}CallExt", call_name.to_camel_case());
let call = format_ident!("{}", call_name);
let call_and_watch = format_ident!("{}_and_watch", call_name);

quote! {
impl#generics #subxt::Call<T> for #ident<#(#params),*> {
Expand All @@ -76,52 +60,45 @@ pub fn call(s: Structure) -> TokenStream {
}
}

#xt_builder

#events_subscriber
}
}

pub fn generate_trait(
module: &syn::Path,
call: &str,
ty: &str,
me: TokenStream,
ret: TokenStream,
args: &TokenStream,
build_struct: &TokenStream,
marker: &syn::Ident,
) -> TokenStream {
let subxt = utils::use_crate("substrate-subxt");
let codec = utils::use_crate("parity-scale-codec");
let call_trait = format_ident!("{}Call{}", call.to_camel_case(), ty);
let call = format_ident!("{}", call);
let ty = format_ident!("{}", ty);
quote! {
/// Call extension trait.
pub trait #call_trait<T: #module> {
/// Create and submit the extrinsic.
pub trait #call_trait<T: #module, S: #codec::Encode, E: #subxt::SignedExtra<T>> {
/// Create and submit an extrinsic.
fn #call<'a>(
#me,
&'a self,
signer: &'a (dyn #subxt::Signer<T, S, E> + Send + Sync),
#args
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<T::Hash, #subxt::Error>> + Send + 'a>>;

/// Create, submit and watch an extrinsic.
fn #call_and_watch<'a>(
&'a self,
signer: &'a (dyn #subxt::Signer<T, S, E> + Send + Sync),
#args
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<#ret, #subxt::Error>> + Send + 'a>>;
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<#subxt::ExtrinsicSuccess<T>, #subxt::Error>> + Send + 'a>>;
}

impl<T, P, S, E> #call_trait<T> for #subxt::#ty<T, P, S, E>
impl<T, S, E> #call_trait<T, S, E> for #subxt::Client<T, S, E>
where
T: #module + #subxt::system::System + Send + Sync + 'static,
P: #subxt::sp_core::Pair,
S: #subxt::sp_runtime::traits::Verify + #codec::Codec + From<P::Signature> + Send + 'static,
S::Signer: From<P::Public> + #subxt::sp_runtime::traits::IdentifyAccount<AccountId = T::AccountId>,
T::Address: From<T::AccountId>,
E: #subxt::SignedExtra<T> + #subxt::sp_runtime::traits::SignedExtension + 'static,
S: #codec::Encode + Send + Sync + 'static,
E: #subxt::SignedExtra<T> + #subxt::sp_runtime::traits::SignedExtension + Send + Sync + 'static,
{
fn #call<'a>(
#me,
&'a self,
signer: &'a (dyn #subxt::Signer<T, S, E> + Send + Sync),
#args
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<T::Hash, #subxt::Error>> + Send + 'a>> {
let #marker = core::marker::PhantomData::<T>;
Box::pin(self.submit(#build_struct, signer))
}

fn #call_and_watch<'a>(
&'a self,
signer: &'a (dyn #subxt::Signer<T, S, E> + Send + Sync),
#args
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<#ret, #subxt::Error>> + Send + 'a>> {
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<#subxt::ExtrinsicSuccess<T>, #subxt::Error>> + Send + 'a>> {
let #marker = core::marker::PhantomData::<T>;
Box::pin(self.submit(#build_struct))
Box::pin(self.watch(#build_struct, signer))
}
}
}
Expand Down Expand Up @@ -154,62 +131,48 @@ mod tests {
}

/// Call extension trait.
pub trait TransferCallXtBuilder<T: Balances> {
/// Create and submit the extrinsic.
pub trait TransferCallExt<T: Balances, S: codec::Encode, E: substrate_subxt::SignedExtra<T>> {
/// Create and submit an extrinsic.
fn transfer<'a>(
&'a self,
signer: &'a (dyn substrate_subxt::Signer<T, S, E> + Send + Sync),
to: &'a <T as System>::Address,
amount: T::Balance,
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<T::Hash, substrate_subxt::Error>> + Send + 'a>>;

/// Create, submit and watch an extrinsic.
fn transfer_and_watch<'a>(
&'a self,
signer: &'a (dyn substrate_subxt::Signer<T, S, E> + Send + Sync),
to: &'a <T as System>::Address,
amount: T::Balance,
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<substrate_subxt::ExtrinsicSuccess<T>, substrate_subxt::Error>> + Send + 'a>>;
}

impl<T, P, S, E> TransferCallXtBuilder<T> for substrate_subxt::XtBuilder<T, P, S, E>
impl<T, S, E> TransferCallExt<T, S, E> for substrate_subxt::Client<T, S, E>
where
T: Balances + substrate_subxt::system::System + Send + Sync + 'static,
P: substrate_subxt::sp_core::Pair,
S: substrate_subxt::sp_runtime::traits::Verify + codec::Codec + From<P::Signature> + Send + 'static,
S::Signer: From<P::Public> + substrate_subxt::sp_runtime::traits::IdentifyAccount<
AccountId = T::AccountId>,
T::Address: From<T::AccountId>,
E: substrate_subxt::SignedExtra<T> + substrate_subxt::sp_runtime::traits::SignedExtension + 'static,
S: codec::Encode + Send + Sync + 'static,
E: substrate_subxt::SignedExtra<T> + substrate_subxt::sp_runtime::traits::SignedExtension + Send + Sync + 'static,
{
fn transfer<'a>(
&'a self,
signer: &'a (dyn substrate_subxt::Signer<T, S, E> + Send + Sync),
to: &'a <T as System>::Address,
amount: T::Balance,
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<T::Hash, substrate_subxt::Error>> + Send + 'a>> {
let _ = core::marker::PhantomData::<T>;
Box::pin(self.submit(TransferCall { to, amount, }))
Box::pin(self.submit(TransferCall { to, amount, }, signer))
}
}

/// Call extension trait.
pub trait TransferCallEventsSubscriber<T: Balances> {
/// Create and submit the extrinsic.
fn transfer<'a>(
self,
to: &'a <T as System>::Address,
amount: T::Balance,
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<substrate_subxt::ExtrinsicSuccess<T>, substrate_subxt::Error>> + Send + 'a>>;
}

impl<T, P, S, E> TransferCallEventsSubscriber<T> for substrate_subxt::EventsSubscriber<T, P, S, E>
where
T: Balances + substrate_subxt::system::System + Send + Sync + 'static,
P: substrate_subxt::sp_core::Pair,
S: substrate_subxt::sp_runtime::traits::Verify + codec::Codec + From<P::Signature> + Send + 'static,
S::Signer: From<P::Public> + substrate_subxt::sp_runtime::traits::IdentifyAccount<
AccountId = T::AccountId>,
T::Address: From<T::AccountId>,
E: substrate_subxt::SignedExtra<T> + substrate_subxt::sp_runtime::traits::SignedExtension + 'static,
{
fn transfer<'a>(
self,
fn transfer_and_watch<'a>(
&'a self,
signer: &'a (dyn substrate_subxt::Signer<T, S, E> + Send + Sync),
to: &'a <T as System>::Address,
amount: T::Balance,
) -> core::pin::Pin<Box<dyn core::future::Future<Output = Result<substrate_subxt::ExtrinsicSuccess<T>, substrate_subxt::Error>> + Send + 'a>> {
let _ = core::marker::PhantomData::<T>;
Box::pin(self.submit(TransferCall { to, amount, }))
Box::pin(self.watch(TransferCall { to, amount, }, signer))
}
}
};
Expand Down
28 changes: 10 additions & 18 deletions proc-macro/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,16 @@ impl Test {
let prelude = prelude.map(|block| block.stmts).unwrap_or_default();
let step = steps
.into_iter()
.map(|step| step.into_tokens(&account, state.as_ref()));
.map(|step| step.into_tokens(state.as_ref()));
quote! {
#[async_std::test]
#[ignore]
async fn #name() {
#env_logger
let client = #subxt::ClientBuilder::<#runtime, #signature, #extra>::new()
.build().await.unwrap();
let signer = #subxt::PairSigner::new(#sp_keyring::AccountKeyring::#account.pair());

#[allow(unused)]
let alice = #sp_keyring::AccountKeyring::Alice.to_account_id();
#[allow(unused)]
Expand Down Expand Up @@ -304,12 +306,7 @@ impl From<ItemStep> for Step {
}

impl Step {
fn into_tokens(
self,
account: &syn::Ident,
test_state: Option<&State>,
) -> TokenStream {
let sp_keyring = utils::use_crate("sp-keyring");
fn into_tokens(self, test_state: Option<&State>) -> TokenStream {
let Step {
state,
call,
Expand Down Expand Up @@ -359,14 +356,11 @@ impl Step {
});
let assert = assert.map(|block| block.stmts).unwrap_or_default();
quote! {
let xt = client.xt(#sp_keyring::AccountKeyring::#account.pair(), None).await.unwrap();

#pre

#[allow(unused)]
let result = xt
.watch()
.submit(#call)
let result = client
.watch(#call, &signer)
.await
.unwrap();

Expand Down Expand Up @@ -461,6 +455,7 @@ mod tests {
substrate_subxt::sp_runtime::MultiSignature,
substrate_subxt::DefaultExtra<KusamaRuntime>
>::new().build().await.unwrap();
let signer = substrate_subxt::PairSigner::new(sp_keyring::AccountKeyring::Alice.pair());
#[allow(unused)]
let alice = sp_keyring::AccountKeyring::Alice.to_account_id();
#[allow(unused)]
Expand All @@ -475,8 +470,6 @@ mod tests {
let ferdie = sp_keyring::AccountKeyring::Ferdie.to_account_id();

{
let xt = client.xt(sp_keyring::AccountKeyring::Alice.pair(), None).await.unwrap();

struct State<A, B> {
alice: A,
bob: B,
Expand All @@ -495,12 +488,11 @@ mod tests {
};

#[allow(unused)]
let result = xt
.watch()
.submit(TransferCall {
let result = client
.watch(TransferCall {
to: &bob,
amount: 10_000,
})
}, &signer)
.await
.unwrap();

Expand Down
13 changes: 7 additions & 6 deletions proc-macro/tests/balances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use substrate_subxt::{
},
ClientBuilder,
KusamaRuntime,
PairSigner,
};

#[module]
Expand Down Expand Up @@ -112,20 +113,20 @@ subxt_test!({
async fn transfer_balance_example() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
let client = ClientBuilder::<KusamaRuntime>::new().build().await?;
let signer = PairSigner::new(AccountKeyring::Alice.pair());
let alice = AccountKeyring::Alice.to_account_id();
let bob = AccountKeyring::Bob.to_account_id();

let alice_account = client.account(&alice).await?;
let bob_account = client.account(&bob).await?;
let pre = (alice_account, bob_account);

let builder = client.xt(AccountKeyring::Alice.pair(), None).await?;

let _hash = builder.transfer(&bob.clone().into(), 10_000).await?;
let _hash = client
.transfer(&signer, &bob.clone().into(), 10_000)
.await?;

let result = builder
.watch()
.transfer(&bob.clone().into(), 10_000)
let result = client
.transfer_and_watch(&signer, &bob.clone().into(), 10_000)
.await?;

assert_eq!(
Expand Down
Loading