sp_keystore/
lib.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Keystore traits
19
20#![cfg_attr(not(feature = "std"), no_std)]
21
22extern crate alloc;
23
24#[cfg(feature = "std")]
25pub mod testing;
26
27#[cfg(feature = "bandersnatch-experimental")]
28use sp_core::bandersnatch;
29#[cfg(feature = "bls-experimental")]
30use sp_core::{bls381, ecdsa_bls381};
31use sp_core::{
32	crypto::{ByteArray, CryptoTypeId, KeyTypeId},
33	ecdsa, ed25519, sr25519,
34};
35
36use alloc::{string::String, sync::Arc, vec::Vec};
37
38/// Keystore error
39#[derive(Debug)]
40pub enum Error {
41	/// Public key type is not supported
42	KeyNotSupported(KeyTypeId),
43	/// Validation error
44	ValidationError(String),
45	/// Keystore unavailable
46	Unavailable,
47	/// Programming errors
48	Other(String),
49}
50
51impl core::fmt::Display for Error {
52	fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
53		match self {
54			Error::KeyNotSupported(key_type) => write!(fmt, "Key not supported: {key_type:?}"),
55			Error::ValidationError(error) => write!(fmt, "Validation error: {error}"),
56			Error::Unavailable => fmt.write_str("Keystore unavailable"),
57			Error::Other(error) => write!(fmt, "An unknown keystore error occurred: {error}"),
58		}
59	}
60}
61
62#[cfg(feature = "std")]
63impl std::error::Error for Error {}
64
65/// Something that generates, stores and provides access to secret keys.
66pub trait Keystore: Send + Sync {
67	/// Returns all the sr25519 public keys for the given key type.
68	fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec<sr25519::Public>;
69
70	/// Generate a new sr25519 key pair for the given key type and an optional seed.
71	///
72	/// Returns an `sr25519::Public` key of the generated key pair or an `Err` if
73	/// something failed during key generation.
74	fn sr25519_generate_new(
75		&self,
76		key_type: KeyTypeId,
77		seed: Option<&str>,
78	) -> Result<sr25519::Public, Error>;
79
80	/// Generate an sr25519 signature for a given message.
81	///
82	/// Receives [`KeyTypeId`] and an [`sr25519::Public`] key to be able to map
83	/// them to a private key that exists in the keystore.
84	///
85	/// Returns an [`sr25519::Signature`] or `None` in case the given `key_type`
86	/// and `public` combination doesn't exist in the keystore.
87	/// An `Err` will be returned if generating the signature itself failed.
88	fn sr25519_sign(
89		&self,
90		key_type: KeyTypeId,
91		public: &sr25519::Public,
92		msg: &[u8],
93	) -> Result<Option<sr25519::Signature>, Error>;
94
95	/// Generate an sr25519 VRF signature for the given data.
96	///
97	/// Receives [`KeyTypeId`] and an [`sr25519::Public`] key to be able to map
98	/// them to a private key that exists in the keystore.
99	///
100	/// Returns `None` if the given `key_type` and `public` combination doesn't
101	/// exist in the keystore or an `Err` when something failed.
102	fn sr25519_vrf_sign(
103		&self,
104		key_type: KeyTypeId,
105		public: &sr25519::Public,
106		data: &sr25519::vrf::VrfSignData,
107	) -> Result<Option<sr25519::vrf::VrfSignature>, Error>;
108
109	/// Generate an sr25519 VRF pre-output for a given input data.
110	///
111	/// Receives [`KeyTypeId`] and an [`sr25519::Public`] key to be able to map
112	/// them to a private key that exists in the keystore.
113	///
114	/// Returns `None` if the given `key_type` and `public` combination doesn't
115	/// exist in the keystore or an `Err` when something failed.
116	fn sr25519_vrf_pre_output(
117		&self,
118		key_type: KeyTypeId,
119		public: &sr25519::Public,
120		input: &sr25519::vrf::VrfInput,
121	) -> Result<Option<sr25519::vrf::VrfPreOutput>, Error>;
122
123	/// Returns all ed25519 public keys for the given key type.
124	fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public>;
125
126	/// Generate a new ed25519 key pair for the given key type and an optional seed.
127	///
128	/// Returns an `ed25519::Public` key of the generated key pair or an `Err` if
129	/// something failed during key generation.
130	fn ed25519_generate_new(
131		&self,
132		key_type: KeyTypeId,
133		seed: Option<&str>,
134	) -> Result<ed25519::Public, Error>;
135
136	/// Generate an ed25519 signature for a given message.
137	///
138	/// Receives [`KeyTypeId`] and an [`ed25519::Public`] key to be able to map
139	/// them to a private key that exists in the keystore.
140	///
141	/// Returns an [`ed25519::Signature`] or `None` in case the given `key_type`
142	/// and `public` combination doesn't exist in the keystore.
143	/// An `Err` will be returned if generating the signature itself failed.
144	fn ed25519_sign(
145		&self,
146		key_type: KeyTypeId,
147		public: &ed25519::Public,
148		msg: &[u8],
149	) -> Result<Option<ed25519::Signature>, Error>;
150
151	/// Returns all ecdsa public keys for the given key type.
152	fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec<ecdsa::Public>;
153
154	/// Generate a new ecdsa key pair for the given key type and an optional seed.
155	///
156	/// Returns an `ecdsa::Public` key of the generated key pair or an `Err` if
157	/// something failed during key generation.
158	fn ecdsa_generate_new(
159		&self,
160		key_type: KeyTypeId,
161		seed: Option<&str>,
162	) -> Result<ecdsa::Public, Error>;
163
164	/// Generate an ecdsa signature for a given message.
165	///
166	/// Receives [`KeyTypeId`] and an [`ecdsa::Public`] key to be able to map
167	/// them to a private key that exists in the keystore.
168	///
169	/// Returns an [`ecdsa::Signature`] or `None` in case the given `key_type`
170	/// and `public` combination doesn't exist in the keystore.
171	/// An `Err` will be returned if generating the signature itself failed.
172	fn ecdsa_sign(
173		&self,
174		key_type: KeyTypeId,
175		public: &ecdsa::Public,
176		msg: &[u8],
177	) -> Result<Option<ecdsa::Signature>, Error>;
178
179	/// Generate an ecdsa signature for a given pre-hashed message.
180	///
181	/// Receives [`KeyTypeId`] and an [`ecdsa::Public`] key to be able to map
182	/// them to a private key that exists in the keystore.
183	///
184	/// Returns an [`ecdsa::Signature`] or `None` in case the given `key_type`
185	/// and `public` combination doesn't exist in the keystore.
186	/// An `Err` will be returned if generating the signature itself failed.
187	fn ecdsa_sign_prehashed(
188		&self,
189		key_type: KeyTypeId,
190		public: &ecdsa::Public,
191		msg: &[u8; 32],
192	) -> Result<Option<ecdsa::Signature>, Error>;
193
194	/// Returns all the bandersnatch public keys for the given key type.
195	#[cfg(feature = "bandersnatch-experimental")]
196	fn bandersnatch_public_keys(&self, key_type: KeyTypeId) -> Vec<bandersnatch::Public>;
197
198	/// Generate a new bandersnatch key pair for the given key type and an optional seed.
199	///
200	/// Returns an `bandersnatch::Public` key of the generated key pair or an `Err` if
201	/// something failed during key generation.
202	#[cfg(feature = "bandersnatch-experimental")]
203	fn bandersnatch_generate_new(
204		&self,
205		key_type: KeyTypeId,
206		seed: Option<&str>,
207	) -> Result<bandersnatch::Public, Error>;
208
209	/// Generate an bandersnatch signature for a given message.
210	///
211	/// Receives [`KeyTypeId`] and an [`bandersnatch::Public`] key to be able to map
212	/// them to a private key that exists in the keystore.
213	///
214	/// Returns an [`bandersnatch::Signature`] or `None` in case the given `key_type`
215	/// and `public` combination doesn't exist in the keystore.
216	/// An `Err` will be returned if generating the signature itself failed.
217	#[cfg(feature = "bandersnatch-experimental")]
218	fn bandersnatch_sign(
219		&self,
220		key_type: KeyTypeId,
221		public: &bandersnatch::Public,
222		msg: &[u8],
223	) -> Result<Option<bandersnatch::Signature>, Error>;
224
225	/// Generate a bandersnatch VRF signature for the given data.
226	///
227	/// Receives [`KeyTypeId`] and an [`bandersnatch::Public`] key to be able to map
228	/// them to a private key that exists in the keystore.
229	///
230	/// Returns `None` if the given `key_type` and `public` combination doesn't
231	/// exist in the keystore or an `Err` when something failed.
232	#[cfg(feature = "bandersnatch-experimental")]
233	fn bandersnatch_vrf_sign(
234		&self,
235		key_type: KeyTypeId,
236		public: &bandersnatch::Public,
237		input: &bandersnatch::vrf::VrfSignData,
238	) -> Result<Option<bandersnatch::vrf::VrfSignature>, Error>;
239
240	/// Generate a bandersnatch VRF pre-output for a given input data.
241	///
242	/// Receives [`KeyTypeId`] and an [`bandersnatch::Public`] key to be able to map
243	/// them to a private key that exists in the keystore.
244	///
245	/// Returns `None` if the given `key_type` and `public` combination doesn't
246	/// exist in the keystore or an `Err` when something failed.
247	#[cfg(feature = "bandersnatch-experimental")]
248	fn bandersnatch_vrf_pre_output(
249		&self,
250		key_type: KeyTypeId,
251		public: &bandersnatch::Public,
252		input: &bandersnatch::vrf::VrfInput,
253	) -> Result<Option<bandersnatch::vrf::VrfPreOutput>, Error>;
254
255	/// Generate a bandersnatch ring-VRF signature for the given data.
256	///
257	/// Receives [`KeyTypeId`] and an [`bandersnatch::Public`] key to be able to map
258	/// them to a private key that exists in the keystore.
259	///
260	/// Also takes a [`bandersnatch::ring_vrf::RingProver`] instance obtained from
261	/// a valid [`bandersnatch::ring_vrf::RingContext`].
262	///
263	/// The ring signature is verifiable if the public key corresponding to the
264	/// signing [`bandersnatch::Pair`] is part of the ring from which the
265	/// [`bandersnatch::ring_vrf::RingProver`] has been constructed.
266	/// If not, the produced signature is just useless.
267	///
268	/// Returns `None` if the given `key_type` and `public` combination doesn't
269	/// exist in the keystore or an `Err` when something failed.
270	#[cfg(feature = "bandersnatch-experimental")]
271	fn bandersnatch_ring_vrf_sign(
272		&self,
273		key_type: KeyTypeId,
274		public: &bandersnatch::Public,
275		input: &bandersnatch::vrf::VrfSignData,
276		prover: &bandersnatch::ring_vrf::RingProver,
277	) -> Result<Option<bandersnatch::ring_vrf::RingVrfSignature>, Error>;
278
279	/// Returns all bls12-381 public keys for the given key type.
280	#[cfg(feature = "bls-experimental")]
281	fn bls381_public_keys(&self, id: KeyTypeId) -> Vec<bls381::Public>;
282
283	/// Returns all (ecdsa,bls12-381) paired public keys for the given key type.
284	#[cfg(feature = "bls-experimental")]
285	fn ecdsa_bls381_public_keys(&self, id: KeyTypeId) -> Vec<ecdsa_bls381::Public>;
286
287	/// Generate a new bls381 key pair for the given key type and an optional seed.
288	///
289	/// Returns an `bls381::Public` key of the generated key pair or an `Err` if
290	/// something failed during key generation.
291	#[cfg(feature = "bls-experimental")]
292	fn bls381_generate_new(
293		&self,
294		key_type: KeyTypeId,
295		seed: Option<&str>,
296	) -> Result<bls381::Public, Error>;
297
298	/// Generate a new (ecdsa,bls381) key pair for the given key type and an optional seed.
299	///
300	/// Returns an `ecdsa_bls381::Public` key of the generated key pair or an `Err` if
301	/// something failed during key generation.
302	#[cfg(feature = "bls-experimental")]
303	fn ecdsa_bls381_generate_new(
304		&self,
305		key_type: KeyTypeId,
306		seed: Option<&str>,
307	) -> Result<ecdsa_bls381::Public, Error>;
308
309	/// Generate a bls381 signature for a given message.
310	///
311	/// Receives [`KeyTypeId`] and a [`bls381::Public`] key to be able to map
312	/// them to a private key that exists in the keystore.
313	///
314	/// Returns an [`bls381::Signature`] or `None` in case the given `key_type`
315	/// and `public` combination doesn't exist in the keystore.
316	/// An `Err` will be returned if generating the signature itself failed.
317	#[cfg(feature = "bls-experimental")]
318	fn bls381_sign(
319		&self,
320		key_type: KeyTypeId,
321		public: &bls381::Public,
322		msg: &[u8],
323	) -> Result<Option<bls381::Signature>, Error>;
324
325	/// Generate a (ecdsa,bls381) signature pair for a given message.
326	///
327	/// Receives [`KeyTypeId`] and a [`ecdsa_bls381::Public`] key to be able to map
328	/// them to a private key that exists in the keystore.
329	///
330	/// Returns an [`ecdsa_bls381::Signature`] or `None` in case the given `key_type`
331	/// and `public` combination doesn't exist in the keystore.
332	/// An `Err` will be returned if generating the signature itself failed.
333	#[cfg(feature = "bls-experimental")]
334	fn ecdsa_bls381_sign(
335		&self,
336		key_type: KeyTypeId,
337		public: &ecdsa_bls381::Public,
338		msg: &[u8],
339	) -> Result<Option<ecdsa_bls381::Signature>, Error>;
340
341	/// Hashes the `message` using keccak256 and then signs it using ECDSA
342	/// algorithm. It does not affect the behavior of BLS12-381 component. It generates
343	/// BLS12-381 Signature according to IETF standard.
344	///
345	/// Receives [`KeyTypeId`] and a [`ecdsa_bls381::Public`] key to be able to map
346	/// them to a private key that exists in the keystore.
347	///
348	/// Returns an [`ecdsa_bls381::Signature`] or `None` in case the given `key_type`
349	/// and `public` combination doesn't exist in the keystore.
350	/// An `Err` will be returned if generating the signature itself failed.
351	#[cfg(feature = "bls-experimental")]
352	fn ecdsa_bls381_sign_with_keccak256(
353		&self,
354		key_type: KeyTypeId,
355		public: &ecdsa_bls381::Public,
356		msg: &[u8],
357	) -> Result<Option<ecdsa_bls381::Signature>, Error>;
358
359	/// Insert a new secret key.
360	fn insert(&self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()>;
361
362	/// List all supported keys of a given type.
363	///
364	/// Returns a set of public keys the signer supports in raw format.
365	fn keys(&self, key_type: KeyTypeId) -> Result<Vec<Vec<u8>>, Error>;
366
367	/// Checks if the private keys for the given public key and key type combinations exist.
368	///
369	/// Returns `true` iff all private keys could be found.
370	fn has_keys(&self, public_keys: &[(Vec<u8>, KeyTypeId)]) -> bool;
371
372	/// Convenience method to sign a message using the given key type and a raw public key
373	/// for secret lookup.
374	///
375	/// The message is signed using the cryptographic primitive specified by `crypto_id`.
376	///
377	/// Schemes supported by the default trait implementation:
378	/// - sr25519
379	/// - ed25519
380	/// - ecdsa
381	/// - bandersnatch
382	/// - bls381
383	/// - (ecdsa,bls381) paired keys
384	///
385	/// To support more schemes you can overwrite this method.
386	///
387	/// Returns the SCALE encoded signature if key is found and supported, `None` if the key doesn't
388	/// exist or an error when something failed.
389	fn sign_with(
390		&self,
391		id: KeyTypeId,
392		crypto_id: CryptoTypeId,
393		public: &[u8],
394		msg: &[u8],
395	) -> Result<Option<Vec<u8>>, Error> {
396		use codec::Encode;
397
398		let signature = match crypto_id {
399			sr25519::CRYPTO_ID => {
400				let public = sr25519::Public::from_slice(public)
401					.map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
402				self.sr25519_sign(id, &public, msg)?.map(|s| s.encode())
403			},
404			ed25519::CRYPTO_ID => {
405				let public = ed25519::Public::from_slice(public)
406					.map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
407				self.ed25519_sign(id, &public, msg)?.map(|s| s.encode())
408			},
409			ecdsa::CRYPTO_ID => {
410				let public = ecdsa::Public::from_slice(public)
411					.map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
412
413				self.ecdsa_sign(id, &public, msg)?.map(|s| s.encode())
414			},
415			#[cfg(feature = "bandersnatch-experimental")]
416			bandersnatch::CRYPTO_ID => {
417				let public = bandersnatch::Public::from_slice(public)
418					.map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
419				self.bandersnatch_sign(id, &public, msg)?.map(|s| s.encode())
420			},
421			#[cfg(feature = "bls-experimental")]
422			bls381::CRYPTO_ID => {
423				let public = bls381::Public::from_slice(public)
424					.map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
425				self.bls381_sign(id, &public, msg)?.map(|s| s.encode())
426			},
427			#[cfg(feature = "bls-experimental")]
428			ecdsa_bls381::CRYPTO_ID => {
429				let public = ecdsa_bls381::Public::from_slice(public)
430					.map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
431				self.ecdsa_bls381_sign(id, &public, msg)?.map(|s| s.encode())
432			},
433			_ => return Err(Error::KeyNotSupported(id)),
434		};
435		Ok(signature)
436	}
437}
438
439impl<T: Keystore + ?Sized> Keystore for Arc<T> {
440	fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec<sr25519::Public> {
441		(**self).sr25519_public_keys(key_type)
442	}
443
444	fn sr25519_generate_new(
445		&self,
446		key_type: KeyTypeId,
447		seed: Option<&str>,
448	) -> Result<sr25519::Public, Error> {
449		(**self).sr25519_generate_new(key_type, seed)
450	}
451
452	fn sr25519_sign(
453		&self,
454		key_type: KeyTypeId,
455		public: &sr25519::Public,
456		msg: &[u8],
457	) -> Result<Option<sr25519::Signature>, Error> {
458		(**self).sr25519_sign(key_type, public, msg)
459	}
460
461	fn sr25519_vrf_sign(
462		&self,
463		key_type: KeyTypeId,
464		public: &sr25519::Public,
465		data: &sr25519::vrf::VrfSignData,
466	) -> Result<Option<sr25519::vrf::VrfSignature>, Error> {
467		(**self).sr25519_vrf_sign(key_type, public, data)
468	}
469
470	fn sr25519_vrf_pre_output(
471		&self,
472		key_type: KeyTypeId,
473		public: &sr25519::Public,
474		input: &sr25519::vrf::VrfInput,
475	) -> Result<Option<sr25519::vrf::VrfPreOutput>, Error> {
476		(**self).sr25519_vrf_pre_output(key_type, public, input)
477	}
478
479	fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public> {
480		(**self).ed25519_public_keys(key_type)
481	}
482
483	fn ed25519_generate_new(
484		&self,
485		key_type: KeyTypeId,
486		seed: Option<&str>,
487	) -> Result<ed25519::Public, Error> {
488		(**self).ed25519_generate_new(key_type, seed)
489	}
490
491	fn ed25519_sign(
492		&self,
493		key_type: KeyTypeId,
494		public: &ed25519::Public,
495		msg: &[u8],
496	) -> Result<Option<ed25519::Signature>, Error> {
497		(**self).ed25519_sign(key_type, public, msg)
498	}
499
500	fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec<ecdsa::Public> {
501		(**self).ecdsa_public_keys(key_type)
502	}
503
504	fn ecdsa_generate_new(
505		&self,
506		key_type: KeyTypeId,
507		seed: Option<&str>,
508	) -> Result<ecdsa::Public, Error> {
509		(**self).ecdsa_generate_new(key_type, seed)
510	}
511
512	fn ecdsa_sign(
513		&self,
514		key_type: KeyTypeId,
515		public: &ecdsa::Public,
516		msg: &[u8],
517	) -> Result<Option<ecdsa::Signature>, Error> {
518		(**self).ecdsa_sign(key_type, public, msg)
519	}
520
521	fn ecdsa_sign_prehashed(
522		&self,
523		key_type: KeyTypeId,
524		public: &ecdsa::Public,
525		msg: &[u8; 32],
526	) -> Result<Option<ecdsa::Signature>, Error> {
527		(**self).ecdsa_sign_prehashed(key_type, public, msg)
528	}
529
530	#[cfg(feature = "bandersnatch-experimental")]
531	fn bandersnatch_public_keys(&self, key_type: KeyTypeId) -> Vec<bandersnatch::Public> {
532		(**self).bandersnatch_public_keys(key_type)
533	}
534
535	#[cfg(feature = "bandersnatch-experimental")]
536	fn bandersnatch_generate_new(
537		&self,
538		key_type: KeyTypeId,
539		seed: Option<&str>,
540	) -> Result<bandersnatch::Public, Error> {
541		(**self).bandersnatch_generate_new(key_type, seed)
542	}
543
544	#[cfg(feature = "bandersnatch-experimental")]
545	fn bandersnatch_sign(
546		&self,
547		key_type: KeyTypeId,
548		public: &bandersnatch::Public,
549		msg: &[u8],
550	) -> Result<Option<bandersnatch::Signature>, Error> {
551		(**self).bandersnatch_sign(key_type, public, msg)
552	}
553
554	#[cfg(feature = "bandersnatch-experimental")]
555	fn bandersnatch_vrf_sign(
556		&self,
557		key_type: KeyTypeId,
558		public: &bandersnatch::Public,
559		input: &bandersnatch::vrf::VrfSignData,
560	) -> Result<Option<bandersnatch::vrf::VrfSignature>, Error> {
561		(**self).bandersnatch_vrf_sign(key_type, public, input)
562	}
563
564	#[cfg(feature = "bandersnatch-experimental")]
565	fn bandersnatch_vrf_pre_output(
566		&self,
567		key_type: KeyTypeId,
568		public: &bandersnatch::Public,
569		input: &bandersnatch::vrf::VrfInput,
570	) -> Result<Option<bandersnatch::vrf::VrfPreOutput>, Error> {
571		(**self).bandersnatch_vrf_pre_output(key_type, public, input)
572	}
573
574	#[cfg(feature = "bandersnatch-experimental")]
575	fn bandersnatch_ring_vrf_sign(
576		&self,
577		key_type: KeyTypeId,
578		public: &bandersnatch::Public,
579		input: &bandersnatch::vrf::VrfSignData,
580		prover: &bandersnatch::ring_vrf::RingProver,
581	) -> Result<Option<bandersnatch::ring_vrf::RingVrfSignature>, Error> {
582		(**self).bandersnatch_ring_vrf_sign(key_type, public, input, prover)
583	}
584
585	#[cfg(feature = "bls-experimental")]
586	fn bls381_public_keys(&self, id: KeyTypeId) -> Vec<bls381::Public> {
587		(**self).bls381_public_keys(id)
588	}
589
590	#[cfg(feature = "bls-experimental")]
591	fn ecdsa_bls381_public_keys(&self, id: KeyTypeId) -> Vec<ecdsa_bls381::Public> {
592		(**self).ecdsa_bls381_public_keys(id)
593	}
594
595	#[cfg(feature = "bls-experimental")]
596	fn bls381_generate_new(
597		&self,
598		key_type: KeyTypeId,
599		seed: Option<&str>,
600	) -> Result<bls381::Public, Error> {
601		(**self).bls381_generate_new(key_type, seed)
602	}
603
604	#[cfg(feature = "bls-experimental")]
605	fn ecdsa_bls381_generate_new(
606		&self,
607		key_type: KeyTypeId,
608		seed: Option<&str>,
609	) -> Result<ecdsa_bls381::Public, Error> {
610		(**self).ecdsa_bls381_generate_new(key_type, seed)
611	}
612
613	#[cfg(feature = "bls-experimental")]
614	fn bls381_sign(
615		&self,
616		key_type: KeyTypeId,
617		public: &bls381::Public,
618		msg: &[u8],
619	) -> Result<Option<bls381::Signature>, Error> {
620		(**self).bls381_sign(key_type, public, msg)
621	}
622
623	#[cfg(feature = "bls-experimental")]
624	fn ecdsa_bls381_sign(
625		&self,
626		key_type: KeyTypeId,
627		public: &ecdsa_bls381::Public,
628		msg: &[u8],
629	) -> Result<Option<ecdsa_bls381::Signature>, Error> {
630		(**self).ecdsa_bls381_sign(key_type, public, msg)
631	}
632
633	#[cfg(feature = "bls-experimental")]
634	fn ecdsa_bls381_sign_with_keccak256(
635		&self,
636		key_type: KeyTypeId,
637		public: &ecdsa_bls381::Public,
638		msg: &[u8],
639	) -> Result<Option<ecdsa_bls381::Signature>, Error> {
640		(**self).ecdsa_bls381_sign_with_keccak256(key_type, public, msg)
641	}
642
643	fn insert(&self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> {
644		(**self).insert(key_type, suri, public)
645	}
646
647	fn keys(&self, key_type: KeyTypeId) -> Result<Vec<Vec<u8>>, Error> {
648		(**self).keys(key_type)
649	}
650
651	fn has_keys(&self, public_keys: &[(Vec<u8>, KeyTypeId)]) -> bool {
652		(**self).has_keys(public_keys)
653	}
654}
655
656/// A shared pointer to a keystore implementation.
657pub type KeystorePtr = Arc<dyn Keystore>;
658
659sp_externalities::decl_extension! {
660	/// The keystore extension to register/retrieve from the externalities.
661	pub struct KeystoreExt(KeystorePtr);
662}
663
664impl KeystoreExt {
665	/// Create a new instance of `KeystoreExt`
666	///
667	/// This is more performant as we don't need to wrap keystore in another [`Arc`].
668	pub fn from(keystore: KeystorePtr) -> Self {
669		Self(keystore)
670	}
671
672	/// Create a new instance of `KeystoreExt` using the given `keystore`.
673	pub fn new<T: Keystore + 'static>(keystore: T) -> Self {
674		Self(Arc::new(keystore))
675	}
676}
677
678sp_core::generate_feature_enabled_macro!(
679	bandersnatch_experimental_enabled,
680	feature = "bandersnatch-experimental",
681	$
682);
683
684sp_core::generate_feature_enabled_macro!(
685	bls_experimental_enabled,
686	feature = "bls-experimental",
687	$
688);