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:
James Wilson
2023-06-20 11:32:12 +01:00
committed by GitHub
parent d091c091ae
commit b4eb406ee5
52 changed files with 1388 additions and 302 deletions
+5 -5
View File
@@ -2,12 +2,12 @@
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
// see LICENSE for license details.
use crate::{pair_signer, test_context, utils::node_runtime};
use crate::{test_context, utils::node_runtime};
use codec::{Compact, Encode};
use futures::StreamExt;
use sp_keyring::AccountKeyring;
use subxt::blocks::BlocksClient;
use subxt_metadata::Metadata;
use subxt_signer::sr25519::dev;
// Check that we can subscribe to non-finalized blocks.
#[tokio::test]
@@ -122,13 +122,13 @@ async fn decode_extrinsics() {
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();
// Generate a block that has unsigned and signed transactions.
let tx = node_runtime::tx()
.balances()
.transfer(bob.account_id().clone().into(), 10_000);
.transfer(bob.public_key().into(), 10_000);
let signed_extrinsic = api
.tx()
+25 -31
View File
@@ -3,31 +3,29 @@
// see LICENSE for license details.
use crate::{
pair_signer, test_context, test_context_with,
test_context, test_context_with,
utils::{node_runtime, wait_for_blocks},
};
use assert_matches::assert_matches;
use codec::{Compact, Decode, Encode};
use sp_core::storage::well_known_keys;
use sp_core::{sr25519::Pair as Sr25519Pair, Pair};
use sp_keyring::AccountKeyring;
use subxt::{
error::{DispatchError, Error, TokenError},
rpc::types::{
ChainHeadEvent, DryRunResult, DryRunResultBytes, FollowEvent, Initialized, RuntimeEvent,
RuntimeVersionEvent,
},
tx::Signer,
utils::AccountId32,
};
use subxt_metadata::Metadata;
use subxt_signer::sr25519::dev;
#[tokio::test]
async fn insert_key() {
let ctx = test_context_with(AccountKeyring::Bob).await;
let ctx = test_context_with("bob".to_string()).await;
let api = ctx.client();
let public = AccountKeyring::Alice.public().as_array_ref().to_vec();
let public = dev::alice().public_key().as_ref().to_vec();
api.rpc()
.insert_key(
"aura".to_string(),
@@ -156,14 +154,14 @@ async fn dry_run_passes() {
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();
wait_for_blocks(&api).await;
let tx = node_runtime::tx()
.balances()
.transfer(bob.account_id().clone().into(), 10_000);
.transfer(bob.public_key().into(), 10_000);
let signed_extrinsic = api
.tx()
@@ -192,11 +190,11 @@ async fn dry_run_fails() {
wait_for_blocks(&api).await;
let alice = pair_signer(AccountKeyring::Alice.pair());
let hans = pair_signer(Sr25519Pair::generate().0);
let alice = dev::alice();
let bob = dev::bob();
let tx = node_runtime::tx().balances().transfer(
hans.account_id().clone().into(),
bob.public_key().into(),
// 7 more than the default amount Alice has, so this should fail; insufficient funds:
1_000_000_000_000_000_000_007,
);
@@ -295,14 +293,14 @@ async fn dry_run_result_is_substrate_compatible() {
async fn external_signing() {
let ctx = test_context().await;
let api = ctx.client();
let alice = pair_signer(AccountKeyring::Alice.pair());
let alice = dev::alice();
// Create a partial extrinsic. We can get the signer payload at this point, to be
// signed externally.
let tx = node_runtime::tx().preimage().note_preimage(vec![0u8]);
let partial_extrinsic = api
.tx()
.create_partial_signed(&tx, alice.account_id(), Default::default())
.create_partial_signed(&tx, &alice.public_key().into(), Default::default())
.await
.unwrap();
@@ -311,7 +309,8 @@ async fn external_signing() {
// Sign it (possibly externally).
let signature = alice.sign(&signer_payload);
// Use this to build a signed extrinsic.
let extrinsic = partial_extrinsic.sign_with_address_and_signature(&alice.address(), &signature);
let extrinsic = partial_extrinsic
.sign_with_address_and_signature(&alice.public_key().into(), &signature.into());
// And now submit it.
extrinsic
@@ -328,7 +327,7 @@ async fn submit_large_extrinsic() {
let ctx = test_context().await;
let api = ctx.client();
let alice = pair_signer(AccountKeyring::Alice.pair());
let alice = dev::alice();
// 2 MiB blob of data.
let bytes = vec![0_u8; 2 * 1024 * 1024];
@@ -357,8 +356,8 @@ async fn decode_a_module_error() {
let ctx = test_context().await;
let api = ctx.client();
let alice = pair_signer(AccountKeyring::Alice.pair());
let alice_addr = alice.account_id().clone().into();
let alice = dev::alice();
let alice_addr = alice.public_key().into();
// Trying to work with an asset ID 1 which doesn't exist should return an
// "unknown" module error from the assets pallet.
@@ -392,13 +391,9 @@ async fn unsigned_extrinsic_is_same_shape_as_polkadotjs() {
let ctx = test_context().await;
let api = ctx.client();
let tx = node_runtime::tx().balances().transfer(
pair_signer(AccountKeyring::Alice.pair())
.account_id()
.clone()
.into(),
12345000000000000,
);
let tx = node_runtime::tx()
.balances()
.transfer(dev::alice().public_key().into(), 12345000000000000);
let actual_tx = api.tx().create_unsigned(&tx).unwrap();
@@ -545,7 +540,7 @@ async fn chainhead_unstable_storage() {
};
let sub_id = blocks.subscription_id().unwrap().clone();
let alice: AccountId32 = AccountKeyring::Alice.to_account_id().into();
let alice: AccountId32 = dev::alice().public_key().into();
let addr = node_runtime::storage().system().account(alice);
let addr_bytes = api.storage().address_bytes(&addr).unwrap();
@@ -572,7 +567,7 @@ async fn chainhead_unstable_call() {
};
let sub_id = blocks.subscription_id().unwrap().clone();
let alice_id = AccountKeyring::Alice.to_account_id();
let alice_id = dev::alice().public_key().to_account_id();
let mut sub = api
.rpc()
.chainhead_unstable_call(
@@ -646,12 +641,11 @@ async fn partial_fee_estimate_correct() {
let ctx = test_context().await;
let api = ctx.client();
let alice = pair_signer(AccountKeyring::Alice.pair());
let hans = pair_signer(Sr25519Pair::generate().0);
let alice = dev::alice();
let bob = dev::bob();
let tx = node_runtime::tx()
.balances()
.transfer(hans.account_id().clone().into(), 1_000_000_000_000);
.transfer(bob.public_key().into(), 1_000_000_000_000);
let signed_extrinsic = api
.tx()
+45 -35
View File
@@ -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 }
}
+27 -21
View File
@@ -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,
);
+6 -6
View File
@@ -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()
@@ -2,22 +2,22 @@
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
// see LICENSE for license details.
use crate::{node_runtime, pair_signer, test_context};
use sp_keyring::AccountKeyring;
use crate::{node_runtime, test_context};
use subxt::utils::AccountId32;
use subxt_signer::sr25519::dev;
#[tokio::test]
async fn account_nonce() -> Result<(), subxt::Error> {
let ctx = test_context().await;
let api = ctx.client();
let signer = pair_signer(AccountKeyring::Alice.pair());
let alice: AccountId32 = AccountKeyring::Alice.to_account_id().into();
let alice = dev::alice();
let alice_account_id: AccountId32 = alice.public_key().into();
// Check Alice nonce is starting from 0.
let runtime_api_call = node_runtime::apis()
.account_nonce_api()
.account_nonce(alice.clone());
.account_nonce(alice_account_id.clone());
let nonce = api
.runtime_api()
.at_latest()
@@ -29,14 +29,14 @@ async fn account_nonce() -> Result<(), subxt::Error> {
// Do some transaction to bump the Alice nonce to 1:
let remark_tx = node_runtime::tx().system().remark(vec![1, 2, 3, 4, 5]);
api.tx()
.sign_and_submit_then_watch_default(&remark_tx, &signer)
.sign_and_submit_then_watch_default(&remark_tx, &alice)
.await?
.wait_for_finalized_success()
.await?;
let runtime_api_call = node_runtime::apis()
.account_nonce_api()
.account_nonce(alice);
.account_nonce(alice_account_id);
let nonce = api
.runtime_api()
.at_latest()
+7 -7
View File
@@ -2,9 +2,9 @@
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
// see LICENSE for license details.
use crate::{node_runtime, pair_signer, test_context, utils::wait_for_blocks};
use sp_keyring::AccountKeyring;
use crate::{node_runtime, test_context, utils::wait_for_blocks};
use subxt::utils::AccountId32;
use subxt_signer::sr25519::dev;
#[tokio::test]
async fn storage_plain_lookup() -> Result<(), subxt::Error> {
@@ -32,8 +32,8 @@ async fn storage_map_lookup() -> Result<(), subxt::Error> {
let ctx = test_context().await;
let api = ctx.client();
let signer = pair_signer(AccountKeyring::Alice.pair());
let alice: AccountId32 = AccountKeyring::Alice.to_account_id().into();
let signer = dev::alice();
let alice: AccountId32 = dev::alice().public_key().into();
// Do some transaction to bump the Alice nonce to 1:
let remark_tx = node_runtime::tx().system().remark(vec![1, 2, 3, 4, 5]);
@@ -98,9 +98,9 @@ async fn storage_n_map_storage_lookup() -> Result<(), subxt::Error> {
// Boilerplate; we create a new asset class with ID 99, and then
// we "approveTransfer" of some of this asset class. This gives us an
// entry in the `Approvals` StorageNMap that we can try to look up.
let signer = pair_signer(AccountKeyring::Alice.pair());
let alice: AccountId32 = AccountKeyring::Alice.to_account_id().into();
let bob: AccountId32 = AccountKeyring::Bob.to_account_id().into();
let signer = dev::alice();
let alice: AccountId32 = dev::alice().public_key().into();
let bob: AccountId32 = dev::bob().public_key().into();
let tx1 = node_runtime::tx()
.assets()
+4 -10
View File
@@ -4,14 +4,12 @@
pub(crate) use crate::{node_runtime, TestNodeProcess};
use sp_core::sr25519::Pair;
use sp_keyring::AccountKeyring;
use subxt::{tx::PairSigner, SubstrateConfig};
use subxt::SubstrateConfig;
/// substrate node should be installed on the $PATH
const SUBSTRATE_NODE_PATH: &str = "substrate";
pub async fn test_context_with(key: AccountKeyring) -> TestContext {
pub async fn test_context_with(authority: String) -> TestContext {
let path = std::env::var("SUBSTRATE_NODE_PATH").unwrap_or_else(|_| {
if which::which(SUBSTRATE_NODE_PATH).is_err() {
panic!(
@@ -23,16 +21,12 @@ pub async fn test_context_with(key: AccountKeyring) -> TestContext {
});
let mut proc = TestContext::build(path.as_str());
proc.with_authority(key);
proc.with_authority(authority);
proc.spawn::<SubstrateConfig>().await.unwrap()
}
pub type TestContext = TestNodeProcess<SubstrateConfig>;
pub async fn test_context() -> TestContext {
test_context_with(AccountKeyring::Alice).await
}
pub fn pair_signer(pair: Pair) -> PairSigner<SubstrateConfig, Pair> {
PairSigner::new(pair)
test_context_with("alice".to_string()).await
}
@@ -2,7 +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 std::ffi::{OsStr, OsString};
use substrate_runner::SubstrateNode;
use subxt::{Config, OnlineClient};
@@ -35,7 +34,7 @@ where
/// Construct a test node process.
pub struct TestNodeProcessBuilder {
node_path: OsString,
authority: Option<AccountKeyring>,
authority: Option<String>,
}
impl TestNodeProcessBuilder {
@@ -50,7 +49,7 @@ impl TestNodeProcessBuilder {
}
/// Set the authority dev account for a node in validator mode e.g. --alice.
pub fn with_authority(&mut self, account: AccountKeyring) -> &mut Self {
pub fn with_authority(&mut self, account: String) -> &mut Self {
self.authority = Some(account);
self
}
@@ -64,9 +63,8 @@ impl TestNodeProcessBuilder {
node_builder.binary_path(self.node_path);
if let Some(authority) = self.authority {
let authority = format!("{authority:?}");
node_builder.arg(authority.as_str().to_lowercase());
if let Some(authority) = &self.authority {
node_builder.arg(authority.to_lowercase());
}
// Spawn the node and retrieve a URL to it: