1use std::{collections::HashMap, ops::Deref};
21use lazy_static::lazy_static;
22use tet_core::{ed25519::{Pair, Public, Signature}, Pair as PairT, Public as PublicT, H256};
23pub use tet_core::ed25519;
24use tp_runtime::AccountId32;
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::Display, strum::EnumIter)]
28pub enum Keyring {
29 Alice,
30 Bob,
31 Charlie,
32 Dave,
33 Eve,
34 Ferdie,
35 One,
36 Two,
37}
38
39impl Keyring {
40 pub fn from_public(who: &Public) -> Option<Keyring> {
41 Self::iter().find(|&k| &Public::from(k) == who)
42 }
43
44 pub fn from_account_id(who: &AccountId32) -> Option<Keyring> {
45 Self::iter().find(|&k| &k.to_account_id() == who)
46 }
47
48 pub fn from_raw_public(who: [u8; 32]) -> Option<Keyring> {
49 Self::from_public(&Public::from_raw(who))
50 }
51
52 pub fn to_raw_public(self) -> [u8; 32] {
53 *Public::from(self).as_array_ref()
54 }
55
56 pub fn from_h256_public(who: H256) -> Option<Keyring> {
57 Self::from_public(&Public::from_raw(who.into()))
58 }
59
60 pub fn to_h256_public(self) -> H256 {
61 Public::from(self).as_array_ref().into()
62 }
63
64 pub fn to_raw_public_vec(self) -> Vec<u8> {
65 Public::from(self).to_raw_vec()
66 }
67
68 pub fn to_account_id(self) -> AccountId32 {
69 self.to_raw_public().into()
70 }
71
72 pub fn sign(self, msg: &[u8]) -> Signature {
73 Pair::from(self).sign(msg)
74 }
75
76 pub fn pair(self) -> Pair {
77 Pair::from_string(&format!("//{}", <&'static str>::from(self)), None)
78 .expect("static values are known good; qed")
79 }
80
81 pub fn iter() -> impl Iterator<Item=Keyring> {
83 <Self as strum::IntoEnumIterator>::iter()
84 }
85
86 pub fn public(self) -> Public {
87 self.pair().public()
88 }
89
90 pub fn to_seed(self) -> String {
91 format!("//{}", self)
92 }
93}
94
95impl From<Keyring> for &'static str {
96 fn from(k: Keyring) -> Self {
97 match k {
98 Keyring::Alice => "Alice",
99 Keyring::Bob => "Bob",
100 Keyring::Charlie => "Charlie",
101 Keyring::Dave => "Dave",
102 Keyring::Eve => "Eve",
103 Keyring::Ferdie => "Ferdie",
104 Keyring::One => "One",
105 Keyring::Two => "Two",
106 }
107 }
108}
109
110impl From<Keyring> for tp_runtime::MultiSigner {
111 fn from(x: Keyring) -> Self {
112 tp_runtime::MultiSigner::Ed25519(x.into())
113 }
114}
115
116lazy_static! {
117 static ref PRIVATE_KEYS: HashMap<Keyring, Pair> = {
118 Keyring::iter().map(|i| (i, i.pair())).collect()
119 };
120
121 static ref PUBLIC_KEYS: HashMap<Keyring, Public> = {
122 PRIVATE_KEYS.iter().map(|(&name, pair)| (name, pair.public())).collect()
123 };
124}
125
126impl From<Keyring> for Public {
127 fn from(k: Keyring) -> Self {
128 (*PUBLIC_KEYS).get(&k).unwrap().clone()
129 }
130}
131
132impl From<Keyring> for AccountId32 {
133 fn from(k: Keyring) -> Self {
134 k.to_account_id()
135 }
136}
137
138impl From<Keyring> for Pair {
139 fn from(k: Keyring) -> Self {
140 k.pair()
141 }
142}
143
144impl From<Keyring> for [u8; 32] {
145 fn from(k: Keyring) -> Self {
146 *(*PUBLIC_KEYS).get(&k).unwrap().as_array_ref()
147 }
148}
149
150impl From<Keyring> for H256 {
151 fn from(k: Keyring) -> Self {
152 (*PUBLIC_KEYS).get(&k).unwrap().as_array_ref().into()
153 }
154}
155
156impl From<Keyring> for &'static [u8; 32] {
157 fn from(k: Keyring) -> Self {
158 (*PUBLIC_KEYS).get(&k).unwrap().as_array_ref()
159 }
160}
161
162impl AsRef<[u8; 32]> for Keyring {
163 fn as_ref(&self) -> &[u8; 32] {
164 (*PUBLIC_KEYS).get(self).unwrap().as_array_ref()
165 }
166}
167
168impl AsRef<Public> for Keyring {
169 fn as_ref(&self) -> &Public {
170 (*PUBLIC_KEYS).get(self).unwrap()
171 }
172}
173
174impl Deref for Keyring {
175 type Target = [u8; 32];
176 fn deref(&self) -> &[u8; 32] {
177 (*PUBLIC_KEYS).get(self).unwrap().as_array_ref()
178 }
179}
180
181#[cfg(test)]
182mod tests {
183 use super::*;
184 use tet_core::{ed25519::Pair, Pair as PairT};
185
186 #[test]
187 fn should_work() {
188 assert!(
189 Pair::verify(
190 &Keyring::Alice.sign(b"I am Alice!"),
191 b"I am Alice!",
192 &Keyring::Alice.public(),
193 )
194 );
195 assert!(
196 !Pair::verify(
197 &Keyring::Alice.sign(b"I am Alice!"),
198 b"I am Bob!",
199 &Keyring::Alice.public(),
200 )
201 );
202 assert!(
203 !Pair::verify(
204 &Keyring::Alice.sign(b"I am Alice!"),
205 b"I am Alice!",
206 &Keyring::Bob.public(),
207 )
208 );
209 }
210}