polymesh_api_client/
signer.rs1#[cfg(feature = "std")]
2use sp_core::Pair;
3
4use sp_runtime::MultiSignature;
5use sp_std::prelude::*;
6
7use async_trait::async_trait;
8
9#[cfg(not(feature = "std"))]
10use alloc::string::ToString;
11
12use crate::*;
13
14#[cfg(feature = "std")]
15pub type DefaultSigner = PairSigner<sp_core::sr25519::Pair>;
16#[cfg(not(feature = "std"))]
17pub type DefaultSigner = PairSigner<subxt_signer::sr25519::Keypair>;
18
19pub mod dev {
20 use super::DefaultSigner;
21
22 pub fn alice() -> DefaultSigner {
23 DefaultSigner::from_string("//Alice", None).expect("Const seed")
24 }
25
26 pub fn bob() -> DefaultSigner {
27 DefaultSigner::from_string("//Bob", None).expect("Const seed")
28 }
29
30 pub fn charlie() -> DefaultSigner {
31 DefaultSigner::from_string("//Charlie", None).expect("Const seed")
32 }
33
34 pub fn dave() -> DefaultSigner {
35 DefaultSigner::from_string("//Dave", None).expect("Const seed")
36 }
37
38 pub fn eve() -> DefaultSigner {
39 DefaultSigner::from_string("//Eve", None).expect("Const seed")
40 }
41
42 pub fn ferdie() -> DefaultSigner {
43 DefaultSigner::from_string("//Ferdie", None).expect("Const seed")
44 }
45
46 pub fn one() -> DefaultSigner {
47 DefaultSigner::from_string("//One", None).expect("Const seed")
48 }
49
50 pub fn two() -> DefaultSigner {
51 DefaultSigner::from_string("//Two", None).expect("Const seed")
52 }
53
54 pub fn alice_stash() -> DefaultSigner {
55 DefaultSigner::from_string("//Alice//stash", None).expect("Const seed")
56 }
57
58 pub fn bob_stash() -> DefaultSigner {
59 DefaultSigner::from_string("//Bob//stash", None).expect("Const seed")
60 }
61
62 pub fn charlie_stash() -> DefaultSigner {
63 DefaultSigner::from_string("//Charlie//stash", None).expect("Const seed")
64 }
65
66 pub fn dave_stash() -> DefaultSigner {
67 DefaultSigner::from_string("//Dave//stash", None).expect("Const seed")
68 }
69
70 pub fn eve_stash() -> DefaultSigner {
71 DefaultSigner::from_string("//Eve//stash", None).expect("Const seed")
72 }
73
74 pub fn ferdie_stash() -> DefaultSigner {
75 DefaultSigner::from_string("//Ferdie//stash", None).expect("Const seed")
76 }
77}
78
79#[async_trait]
80pub trait Signer: Send + Sync {
81 fn account(&self) -> AccountId;
82
83 async fn nonce(&self) -> Option<u32> {
86 None
87 }
88
89 async fn set_nonce(&mut self, _nonce: u32) {}
93
94 async fn sign(&self, msg: &[u8]) -> Result<MultiSignature>;
95
96 async fn lock(&self) -> Option<Box<dyn Signer>> {
98 None
99 }
100}
101
102pub trait KeypairSigner: Send + Sync + Sized + Clone {
103 fn account(&self) -> AccountId;
104 fn sign(&self, message: &[u8]) -> MultiSignature;
105 fn from_string(s: &str, password_override: Option<&str>) -> Result<Self>;
106
107 fn verify<M: AsRef<[u8]>>(&self, _sig: &MultiSignature, _message: M) -> Result<bool> {
108 unimplemented!()
109 }
110}
111
112#[cfg(feature = "std")]
113impl KeypairSigner for sp_core::ed25519::Pair {
114 fn account(&self) -> AccountId {
115 self.public().into()
116 }
117
118 fn sign(&self, message: &[u8]) -> MultiSignature {
119 <sp_core::ed25519::Pair as sp_core::Pair>::sign(self, message).into()
120 }
121
122 fn from_string(s: &str, password_override: Option<&str>) -> Result<Self> {
123 Ok(<sp_core::ed25519::Pair as sp_core::Pair>::from_string(
124 s,
125 password_override,
126 )?)
127 }
128
129 fn verify<M: AsRef<[u8]>>(&self, sig: &MultiSignature, message: M) -> Result<bool> {
130 let sig = match sig {
131 MultiSignature::Ed25519(sig) => sig,
132 _ => {
133 return Err(Error::CoreCryptoError(format!(
134 "Invalid signature type: {sig:?}"
135 )))
136 }
137 };
138 Ok(<sp_core::ed25519::Pair as sp_core::Pair>::verify(
139 sig,
140 message.as_ref(),
141 &self.public(),
142 ))
143 }
144}
145
146#[cfg(feature = "std")]
147impl KeypairSigner for sp_core::sr25519::Pair {
148 fn account(&self) -> AccountId {
149 self.public().into()
150 }
151
152 fn sign(&self, message: &[u8]) -> MultiSignature {
153 <sp_core::sr25519::Pair as sp_core::Pair>::sign(self, message).into()
154 }
155
156 fn from_string(s: &str, password_override: Option<&str>) -> Result<Self> {
157 Ok(<sp_core::sr25519::Pair as sp_core::Pair>::from_string(
158 s,
159 password_override,
160 )?)
161 }
162
163 fn verify<M: AsRef<[u8]>>(&self, sig: &MultiSignature, message: M) -> Result<bool> {
164 let sig = match sig {
165 MultiSignature::Sr25519(sig) => sig,
166 _ => {
167 return Err(Error::CoreCryptoError(format!(
168 "Invalid signature type: {sig:?}"
169 )))
170 }
171 };
172 Ok(<sp_core::sr25519::Pair as sp_core::Pair>::verify(
173 sig,
174 message.as_ref(),
175 &self.public(),
176 ))
177 }
178}
179
180impl KeypairSigner for subxt_signer::sr25519::Keypair {
181 fn account(&self) -> AccountId {
182 AccountId(self.public_key().0)
183 }
184
185 fn sign(&self, message: &[u8]) -> MultiSignature {
186 let sig = subxt_signer::sr25519::Keypair::sign(self, message).0;
187 MultiSignature::Sr25519(sig.into())
188 }
189
190 fn from_string(s: &str, password_override: Option<&str>) -> Result<Self> {
191 use alloc::str::FromStr;
192 let mut uri = subxt_signer::SecretUri::from_str(s)?;
193 if let Some(password_override) = password_override {
194 uri.password = Some(password_override.to_string().into());
195 }
196 Ok(subxt_signer::sr25519::Keypair::from_uri(&uri)?)
197 }
198}
199
200impl KeypairSigner for subxt_signer::ecdsa::Keypair {
201 fn account(&self) -> AccountId {
202 let pub_key = self.public_key();
203 let hash = sp_core::hashing::blake2_256(&pub_key.0[..]);
204 AccountId(hash)
205 }
206
207 fn sign(&self, message: &[u8]) -> MultiSignature {
208 let sig = subxt_signer::ecdsa::Keypair::sign(self, message).0;
209 MultiSignature::Ecdsa(sig.into())
210 }
211
212 fn from_string(s: &str, password_override: Option<&str>) -> Result<Self> {
213 use alloc::str::FromStr;
214 let mut uri = subxt_signer::SecretUri::from_str(s)?;
215 if let Some(password_override) = password_override {
216 uri.password = Some(password_override.to_string().into());
217 }
218 Ok(subxt_signer::ecdsa::Keypair::from_uri(&uri)?)
219 }
220}
221
222#[derive(Clone)]
223pub struct PairSigner<P: KeypairSigner + Clone> {
224 pub pair: P,
225 pub nonce: u32,
226 pub account: AccountId,
227}
228
229impl<P> PairSigner<P>
230where
231 P: KeypairSigner,
232{
233 pub fn new(pair: P) -> Self {
234 let account = pair.account();
235 Self {
236 pair,
237 nonce: 0,
238 account,
239 }
240 }
241
242 pub fn from_string(s: &str, password_override: Option<&str>) -> Result<Self> {
244 Ok(Self::new(P::from_string(s, password_override)?))
245 }
246}
247
248#[async_trait]
249impl Signer for Box<dyn Signer> {
250 fn account(&self) -> AccountId {
251 self.as_ref().account()
252 }
253
254 async fn nonce(&self) -> Option<u32> {
255 self.as_ref().nonce().await
256 }
257
258 async fn set_nonce(&mut self, nonce: u32) {
259 self.as_mut().set_nonce(nonce).await
260 }
261
262 async fn sign(&self, msg: &[u8]) -> Result<MultiSignature> {
263 self.as_ref().sign(msg).await
264 }
265
266 async fn lock(&self) -> Option<Box<dyn Signer>> {
267 self.as_ref().lock().await
268 }
269}
270
271#[async_trait]
272impl<P: KeypairSigner> Signer for PairSigner<P> {
273 fn account(&self) -> AccountId {
274 self.account.clone()
275 }
276
277 async fn nonce(&self) -> Option<u32> {
278 if self.nonce > 0 {
279 Some(self.nonce)
280 } else {
281 None
282 }
283 }
284
285 async fn set_nonce(&mut self, nonce: u32) {
286 self.nonce = nonce;
287 }
288
289 async fn sign(&self, msg: &[u8]) -> Result<MultiSignature> {
290 Ok(self.pair.sign(msg))
291 }
292}