polymesh_api_tester/
account.rs

1use std::sync::Arc;
2
3use sp_keyring::{ed25519, sr25519};
4use sp_runtime::MultiSignature;
5
6use polymesh_api::client::{AccountId, KeypairSigner, LockableSigner, PairSigner, Signer};
7
8use crate::error::Result;
9use crate::Db;
10
11/// DbAccountSigner is wrapper for signing keys (sr25519, ed25519, etc...) and using
12/// a local Database for managing account nonces.
13#[derive(Clone)]
14pub struct DbAccountSigner {
15  signer: Arc<dyn Signer + Send + Sync>,
16  db: Db,
17  account: AccountId,
18}
19
20impl DbAccountSigner {
21  pub fn new<P: KeypairSigner + 'static>(db: Db, pair: P) -> Self {
22    let signer = PairSigner::new(pair);
23    let account = signer.account();
24    Self {
25      signer: Arc::new(signer),
26      db: db.clone(),
27      account,
28    }
29  }
30
31  pub fn alice(db: Db) -> Self {
32    Self::new(db, sr25519::Keyring::Alice.pair())
33  }
34
35  pub fn bob(db: Db) -> Self {
36    Self::new(db, sr25519::Keyring::Bob.pair())
37  }
38
39  /// Generate signing key pair from string `s`.
40  pub fn from_string(db: Db, s: &str) -> Result<Self> {
41    Ok(Self::new(
42      db,
43      <sr25519::sr25519::Pair as KeypairSigner>::from_string(s, None)?,
44    ))
45  }
46}
47
48#[async_trait::async_trait]
49impl Signer for DbAccountSigner {
50  fn account(&self) -> AccountId {
51    self.account
52  }
53
54  async fn nonce(&self) -> Option<u32> {
55    self.db.get_next_nonce(self.account).await.ok()
56  }
57
58  async fn sign(&self, msg: &[u8]) -> polymesh_api::client::Result<MultiSignature> {
59    Ok(self.signer.sign(msg).await?)
60  }
61}
62
63/// AccountSigner is wrapper for signing keys (sr25519, ed25519, etc...).
64#[derive(Clone)]
65pub struct AccountSigner {
66  signer: Arc<LockableSigner<Box<dyn Signer>>>,
67  account: AccountId,
68}
69
70impl AccountSigner {
71  pub fn new<P: KeypairSigner + 'static>(pair: P) -> Self {
72    let signer = PairSigner::new(pair);
73    let account = signer.account();
74    Self {
75      signer: Arc::new(LockableSigner::new(Box::new(signer))),
76      account,
77    }
78  }
79
80  /// Generate signing key pair from string `s`.
81  pub fn from_string(s: &str) -> Result<Self> {
82    Ok(Self::new(
83      <sr25519::sr25519::Pair as KeypairSigner>::from_string(s, None)?,
84    ))
85  }
86}
87
88impl From<sr25519::Keyring> for AccountSigner {
89  fn from(key: sr25519::Keyring) -> Self {
90    Self::new(key.pair())
91  }
92}
93
94impl From<ed25519::Keyring> for AccountSigner {
95  fn from(key: ed25519::Keyring) -> Self {
96    Self::new(key.pair())
97  }
98}
99
100#[async_trait::async_trait]
101impl Signer for AccountSigner {
102  fn account(&self) -> AccountId {
103    self.account.clone()
104  }
105
106  async fn sign(&self, msg: &[u8]) -> polymesh_api::client::Result<MultiSignature> {
107    let locked = self.signer.lock().await;
108    locked.sign(msg).await
109  }
110
111  async fn lock(&self) -> Option<Box<dyn Signer>> {
112    let locked = self.signer.lock().await;
113    Some(Box::new(locked))
114  }
115}