mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-25 14:07:58 +00:00
Add subxt_signer crate for native & WASM compatible signing (#1016)
* Add and use subxt-signer crate for WASM compatible signing * cargo fmt * dev keypairs already references * WIP fix various breakages * re-jig features to be simpler and various test fixes etc * doc and web fix * fix various bits and pieces * fix a test I broke * dev-deps can't be linked to in docs, hrmph * cargo fmt * another doc link * document the subxt_signer crate more thoroughly * move feature flag for consistency * more docs, no default subxt feature flag on signer, update release instrs * Add missing license header * unwrap_inner => into_inner * extend a test a little to better check derive junctions * note more clearly that the crypto bits come from sp_core::crypto
This commit is contained in:
@@ -4,26 +4,29 @@
|
||||
|
||||
use crate::{
|
||||
node_runtime::{self, balances, runtime_types, system},
|
||||
pair_signer, test_context,
|
||||
test_context,
|
||||
};
|
||||
use codec::Decode;
|
||||
use sp_core::Pair;
|
||||
use sp_keyring::AccountKeyring;
|
||||
use subxt::{
|
||||
error::{DispatchError, Error, TokenError},
|
||||
utils::{AccountId32, MultiAddress},
|
||||
};
|
||||
use subxt_signer::sr25519::dev;
|
||||
|
||||
#[tokio::test]
|
||||
async fn tx_basic_transfer() -> Result<(), subxt::Error> {
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let bob = pair_signer(AccountKeyring::Bob.pair());
|
||||
let bob_address = bob.account_id().clone().into();
|
||||
let alice = dev::alice();
|
||||
let bob = dev::bob();
|
||||
let bob_address = bob.public_key().to_address();
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let alice_account_addr = node_runtime::storage().system().account(alice.account_id());
|
||||
let bob_account_addr = node_runtime::storage().system().account(bob.account_id());
|
||||
let alice_account_addr = node_runtime::storage()
|
||||
.system()
|
||||
.account(alice.public_key().to_account_id());
|
||||
let bob_account_addr = node_runtime::storage()
|
||||
.system()
|
||||
.account(bob.public_key().to_account_id());
|
||||
|
||||
let alice_pre = api
|
||||
.storage()
|
||||
@@ -56,8 +59,8 @@ async fn tx_basic_transfer() -> Result<(), subxt::Error> {
|
||||
.expect("Failed to find ExtrinisicSuccess");
|
||||
|
||||
let expected_event = balances::events::Transfer {
|
||||
from: alice.account_id().clone(),
|
||||
to: bob.account_id().clone(),
|
||||
from: alice.public_key().to_account_id(),
|
||||
to: bob.public_key().to_account_id(),
|
||||
amount: 10_000,
|
||||
};
|
||||
assert_eq!(event, expected_event);
|
||||
@@ -84,20 +87,20 @@ async fn tx_basic_transfer() -> Result<(), subxt::Error> {
|
||||
async fn tx_dynamic_transfer() -> Result<(), subxt::Error> {
|
||||
use subxt::ext::scale_value::{At, Composite, Value};
|
||||
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let bob = pair_signer(AccountKeyring::Bob.pair());
|
||||
let alice = dev::alice();
|
||||
let bob = dev::bob();
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let alice_account_addr = subxt::dynamic::storage(
|
||||
"System",
|
||||
"Account",
|
||||
vec![Value::from_bytes(alice.account_id())],
|
||||
vec![Value::from_bytes(alice.public_key().to_account_id())],
|
||||
);
|
||||
let bob_account_addr = subxt::dynamic::storage(
|
||||
"System",
|
||||
"Account",
|
||||
vec![Value::from_bytes(bob.account_id())],
|
||||
vec![Value::from_bytes(bob.public_key().to_account_id())],
|
||||
);
|
||||
|
||||
let alice_pre = api
|
||||
@@ -117,7 +120,10 @@ async fn tx_dynamic_transfer() -> Result<(), subxt::Error> {
|
||||
"Balances",
|
||||
"transfer",
|
||||
vec![
|
||||
Value::unnamed_variant("Id", vec![Value::from_bytes(bob.account_id())]),
|
||||
Value::unnamed_variant(
|
||||
"Id",
|
||||
vec![Value::from_bytes(bob.public_key().to_account_id())],
|
||||
),
|
||||
Value::u128(10_000u128),
|
||||
],
|
||||
);
|
||||
@@ -140,11 +146,11 @@ async fn tx_dynamic_transfer() -> Result<(), subxt::Error> {
|
||||
let expected_fields = Composite::Named(vec![
|
||||
(
|
||||
"from".into(),
|
||||
Value::unnamed_composite(vec![Value::from_bytes(alice.account_id())]),
|
||||
Value::unnamed_composite(vec![Value::from_bytes(alice.public_key().to_account_id())]),
|
||||
),
|
||||
(
|
||||
"to".into(),
|
||||
Value::unnamed_composite(vec![Value::from_bytes(bob.account_id())]),
|
||||
Value::unnamed_composite(vec![Value::from_bytes(bob.public_key().to_account_id())]),
|
||||
),
|
||||
("amount".into(), Value::u128(10_000)),
|
||||
]);
|
||||
@@ -201,13 +207,15 @@ async fn tx_dynamic_transfer() -> Result<(), subxt::Error> {
|
||||
|
||||
#[tokio::test]
|
||||
async fn multiple_transfers_work_nonce_incremented() -> Result<(), subxt::Error> {
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let bob = pair_signer(AccountKeyring::Bob.pair());
|
||||
let bob_address: MultiAddress<AccountId32, u32> = bob.account_id().clone().into();
|
||||
let alice = dev::alice();
|
||||
let bob = dev::bob();
|
||||
let bob_address: MultiAddress<AccountId32, u32> = bob.public_key().into();
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let bob_account_addr = node_runtime::storage().system().account(bob.account_id());
|
||||
let bob_account_addr = node_runtime::storage()
|
||||
.system()
|
||||
.account(bob.public_key().to_account_id());
|
||||
|
||||
let bob_pre = api
|
||||
.storage()
|
||||
@@ -259,9 +267,9 @@ async fn storage_total_issuance() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn storage_balance_lock() -> Result<(), subxt::Error> {
|
||||
let bob_signer = pair_signer(AccountKeyring::Bob.pair());
|
||||
let bob: AccountId32 = AccountKeyring::Bob.to_account_id().into();
|
||||
let charlie: AccountId32 = AccountKeyring::Charlie.to_account_id().into();
|
||||
let bob_signer = dev::bob();
|
||||
let bob: AccountId32 = dev::bob().public_key().into();
|
||||
let charlie: AccountId32 = dev::charlie().public_key().into();
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
@@ -302,31 +310,33 @@ async fn storage_balance_lock() -> Result<(), subxt::Error> {
|
||||
|
||||
#[tokio::test]
|
||||
async fn transfer_error() {
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let alice_addr = alice.account_id().clone().into();
|
||||
let hans = pair_signer(Pair::generate().0);
|
||||
let hans_address = hans.account_id().clone().into();
|
||||
let alice = dev::alice();
|
||||
let alice_addr = alice.public_key().into();
|
||||
let bob = dev::one(); // some dev account with no funds.
|
||||
let bob_address = bob.public_key().into();
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let to_hans_tx = node_runtime::tx()
|
||||
let to_bob_tx = node_runtime::tx()
|
||||
.balances()
|
||||
.transfer(hans_address, 100_000_000_000_000_000);
|
||||
.transfer(bob_address, 100_000_000_000_000_000);
|
||||
let to_alice_tx = node_runtime::tx()
|
||||
.balances()
|
||||
.transfer(alice_addr, 100_000_000_000_000_000);
|
||||
|
||||
api.tx()
|
||||
.sign_and_submit_then_watch_default(&to_hans_tx, &alice)
|
||||
.sign_and_submit_then_watch_default(&to_bob_tx, &alice)
|
||||
.await
|
||||
.unwrap()
|
||||
.wait_for_finalized_success()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// When we try giving all of the funds back, Bob doesn't have
|
||||
// anything left to pay transfer fees, so we hit an error.
|
||||
let res = api
|
||||
.tx()
|
||||
.sign_and_submit_then_watch_default(&to_alice_tx, &hans)
|
||||
.sign_and_submit_then_watch_default(&to_alice_tx, &bob)
|
||||
.await
|
||||
.unwrap()
|
||||
.wait_for_finalized_success()
|
||||
@@ -345,8 +355,8 @@ async fn transfer_error() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn transfer_implicit_subscription() {
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let bob: AccountId32 = AccountKeyring::Bob.to_account_id().into();
|
||||
let alice = dev::alice();
|
||||
let bob: AccountId32 = dev::bob().public_key().into();
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
@@ -369,7 +379,7 @@ async fn transfer_implicit_subscription() {
|
||||
assert_eq!(
|
||||
event,
|
||||
balances::events::Transfer {
|
||||
from: alice.account_id().clone(),
|
||||
from: alice.public_key().to_account_id(),
|
||||
to: bob,
|
||||
amount: 10_000
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use sp_keyring::AccountKeyring;
|
||||
|
||||
use crate::{
|
||||
node_runtime::{
|
||||
self,
|
||||
@@ -13,16 +11,12 @@ use crate::{
|
||||
},
|
||||
test_context, TestContext,
|
||||
};
|
||||
use sp_core::sr25519::Pair;
|
||||
use subxt::{
|
||||
tx::{PairSigner, TxProgress},
|
||||
utils::MultiAddress,
|
||||
Config, Error, OnlineClient, SubstrateConfig,
|
||||
};
|
||||
use subxt::{tx::TxProgress, utils::MultiAddress, Config, Error, OnlineClient, SubstrateConfig};
|
||||
use subxt_signer::sr25519::{self, dev};
|
||||
|
||||
struct ContractsTestContext {
|
||||
cxt: TestContext,
|
||||
signer: PairSigner<SubstrateConfig, Pair>,
|
||||
signer: sr25519::Keypair,
|
||||
}
|
||||
|
||||
type Hash = <SubstrateConfig as Config>::Hash;
|
||||
@@ -40,7 +34,7 @@ const PROOF_SIZE: u64 = u64::MAX / 2;
|
||||
impl ContractsTestContext {
|
||||
async fn init() -> Self {
|
||||
let cxt = test_context().await;
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let signer = dev::alice();
|
||||
|
||||
Self { cxt, signer }
|
||||
}
|
||||
|
||||
@@ -11,16 +11,20 @@ use crate::{
|
||||
},
|
||||
staking,
|
||||
},
|
||||
pair_signer, test_context,
|
||||
test_context,
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
use sp_core::{sr25519, Pair};
|
||||
use sp_keyring::AccountKeyring;
|
||||
use subxt::error::{DispatchError, Error};
|
||||
use subxt_signer::{
|
||||
sr25519::{self, dev},
|
||||
SecretUri,
|
||||
};
|
||||
|
||||
/// Helper function to generate a crypto pair from seed
|
||||
fn get_from_seed(seed: &str) -> sr25519::Pair {
|
||||
sr25519::Pair::from_string(&format!("//{seed}"), None).expect("static values are valid; qed")
|
||||
fn get_from_seed(seed: &str) -> sr25519::Keypair {
|
||||
use std::str::FromStr;
|
||||
let uri = SecretUri::from_str(&format!("//{seed}")).expect("expected to be valid");
|
||||
sr25519::Keypair::from_uri(&uri).expect("expected to be valid")
|
||||
}
|
||||
|
||||
fn default_validator_prefs() -> ValidatorPrefs {
|
||||
@@ -35,7 +39,7 @@ async fn validate_with_controller_account() {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let alice = dev::alice();
|
||||
|
||||
let tx = node_runtime::tx()
|
||||
.staking()
|
||||
@@ -55,7 +59,7 @@ async fn validate_not_possible_for_stash_account() -> Result<(), Error> {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let alice_stash = pair_signer(get_from_seed("Alice//stash"));
|
||||
let alice_stash = get_from_seed("Alice//stash");
|
||||
|
||||
let tx = node_runtime::tx()
|
||||
.staking()
|
||||
@@ -80,12 +84,12 @@ async fn nominate_with_controller_account() {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let bob = pair_signer(AccountKeyring::Bob.pair());
|
||||
let alice = dev::alice();
|
||||
let bob = dev::bob();
|
||||
|
||||
let tx = node_runtime::tx()
|
||||
.staking()
|
||||
.nominate(vec![bob.account_id().clone().into()]);
|
||||
.nominate(vec![bob.public_key().to_address()]);
|
||||
|
||||
api.tx()
|
||||
.sign_and_submit_then_watch_default(&tx, &alice)
|
||||
@@ -101,12 +105,12 @@ async fn nominate_not_possible_for_stash_account() -> Result<(), Error> {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let alice_stash = pair_signer(get_from_seed("Alice//stash"));
|
||||
let bob = pair_signer(AccountKeyring::Bob.pair());
|
||||
let alice_stash = get_from_seed("Alice//stash");
|
||||
let bob = dev::bob();
|
||||
|
||||
let tx = node_runtime::tx()
|
||||
.staking()
|
||||
.nominate(vec![bob.account_id().clone().into()]);
|
||||
.nominate(vec![bob.public_key().to_address()]);
|
||||
|
||||
let nomination = api
|
||||
.tx()
|
||||
@@ -129,21 +133,23 @@ async fn chill_works_for_controller_only() -> Result<(), Error> {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let alice_stash = pair_signer(get_from_seed("Alice//stash"));
|
||||
let bob_stash = pair_signer(get_from_seed("Bob//stash"));
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let alice_stash = get_from_seed("Alice//stash");
|
||||
let bob_stash = get_from_seed("Bob//stash");
|
||||
let alice = dev::alice();
|
||||
|
||||
// this will fail the second time, which is why this is one test, not two
|
||||
let nominate_tx = node_runtime::tx()
|
||||
.staking()
|
||||
.nominate(vec![bob_stash.account_id().clone().into()]);
|
||||
.nominate(vec![bob_stash.public_key().to_address()]);
|
||||
api.tx()
|
||||
.sign_and_submit_then_watch_default(&nominate_tx, &alice)
|
||||
.await?
|
||||
.wait_for_finalized_success()
|
||||
.await?;
|
||||
|
||||
let ledger_addr = node_runtime::storage().staking().ledger(alice.account_id());
|
||||
let ledger_addr = node_runtime::storage()
|
||||
.staking()
|
||||
.ledger(alice.public_key().to_account_id());
|
||||
let ledger = api
|
||||
.storage()
|
||||
.at_latest()
|
||||
@@ -151,7 +157,7 @@ async fn chill_works_for_controller_only() -> Result<(), Error> {
|
||||
.fetch(&ledger_addr)
|
||||
.await?
|
||||
.unwrap();
|
||||
assert_eq!(alice_stash.account_id(), &ledger.stash);
|
||||
assert_eq!(alice_stash.public_key().to_account_id(), ledger.stash);
|
||||
|
||||
let chill_tx = node_runtime::tx().staking().chill();
|
||||
|
||||
@@ -185,10 +191,10 @@ async fn tx_bond() -> Result<(), Error> {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let alice = dev::alice();
|
||||
|
||||
let bond_tx = node_runtime::tx().staking().bond(
|
||||
AccountKeyring::Bob.to_account_id().into(),
|
||||
dev::bob().public_key().into(),
|
||||
100_000_000_000_000,
|
||||
RewardDestination::Stash,
|
||||
);
|
||||
|
||||
@@ -8,9 +8,9 @@ use crate::{
|
||||
runtime_types::{self, sp_weights::weight_v2::Weight},
|
||||
sudo,
|
||||
},
|
||||
pair_signer, test_context,
|
||||
test_context,
|
||||
};
|
||||
use sp_keyring::AccountKeyring;
|
||||
use subxt_signer::sr25519::dev;
|
||||
|
||||
type Call = runtime_types::kitchensink_runtime::RuntimeCall;
|
||||
type BalancesCall = runtime_types::pallet_balances::pallet::Call;
|
||||
@@ -20,8 +20,8 @@ async fn test_sudo() -> Result<(), subxt::Error> {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let bob = AccountKeyring::Bob.to_account_id().into();
|
||||
let alice = dev::alice();
|
||||
let bob = dev::bob().public_key().into();
|
||||
|
||||
let call = Call::Balances(BalancesCall::transfer {
|
||||
dest: bob,
|
||||
@@ -46,8 +46,8 @@ async fn test_sudo_unchecked_weight() -> Result<(), subxt::Error> {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let bob = AccountKeyring::Bob.to_account_id().into();
|
||||
let alice = dev::alice();
|
||||
let bob = dev::bob().public_key().into();
|
||||
|
||||
let call = Call::Balances(BalancesCall::transfer {
|
||||
dest: bob,
|
||||
|
||||
@@ -4,19 +4,21 @@
|
||||
|
||||
use crate::{
|
||||
node_runtime::{self, system},
|
||||
pair_signer, test_context,
|
||||
test_context,
|
||||
};
|
||||
use assert_matches::assert_matches;
|
||||
use sp_keyring::AccountKeyring;
|
||||
use subxt_signer::sr25519::dev;
|
||||
|
||||
#[tokio::test]
|
||||
async fn storage_account() -> Result<(), subxt::Error> {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let alice = dev::alice();
|
||||
|
||||
let account_info_addr = node_runtime::storage().system().account(alice.account_id());
|
||||
let account_info_addr = node_runtime::storage()
|
||||
.system()
|
||||
.account(alice.public_key().to_account_id());
|
||||
|
||||
let account_info = api
|
||||
.storage()
|
||||
@@ -34,7 +36,7 @@ async fn tx_remark_with_event() -> Result<(), subxt::Error> {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let alice = pair_signer(AccountKeyring::Alice.pair());
|
||||
let alice = dev::alice();
|
||||
|
||||
let tx = node_runtime::tx()
|
||||
.system()
|
||||
|
||||
Reference in New Issue
Block a user