solana_sdk/signer/
signers.rs1#![cfg(feature = "full")]
2
3use {
4 crate::{
5 pubkey::Pubkey,
6 signature::{Signature, Signer, SignerError},
7 },
8 std::sync::Arc,
9};
10
11pub trait Signers {
13 fn pubkeys(&self) -> Vec<Pubkey>;
14 fn try_pubkeys(&self) -> Result<Vec<Pubkey>, SignerError>;
15 fn sign_message(&self, message: &[u8]) -> Vec<Signature>;
16 fn try_sign_message(&self, message: &[u8]) -> Result<Vec<Signature>, SignerError>;
17 fn is_interactive(&self) -> bool;
18}
19
20macro_rules! default_keypairs_impl {
21 () => {
22 fn pubkeys(&self) -> Vec<Pubkey> {
23 self.iter().map(|keypair| keypair.pubkey()).collect()
24 }
25
26 fn try_pubkeys(&self) -> Result<Vec<Pubkey>, SignerError> {
27 let mut pubkeys = Vec::new();
28 for keypair in self.iter() {
29 pubkeys.push(keypair.try_pubkey()?);
30 }
31 Ok(pubkeys)
32 }
33
34 fn sign_message(&self, message: &[u8]) -> Vec<Signature> {
35 self.iter()
36 .map(|keypair| keypair.sign_message(message))
37 .collect()
38 }
39
40 fn try_sign_message(&self, message: &[u8]) -> Result<Vec<Signature>, SignerError> {
41 let mut signatures = Vec::new();
42 for keypair in self.iter() {
43 signatures.push(keypair.try_sign_message(message)?);
44 }
45 Ok(signatures)
46 }
47
48 fn is_interactive(&self) -> bool {
49 self.iter().any(|s| s.is_interactive())
50 }
51 };
52}
53
54impl<T: Signer> Signers for [&T] {
55 default_keypairs_impl!();
56}
57
58impl Signers for [Box<dyn Signer>] {
59 default_keypairs_impl!();
60}
61
62impl Signers for Vec<Box<dyn Signer>> {
63 default_keypairs_impl!();
64}
65
66impl Signers for [Arc<dyn Signer>] {
67 default_keypairs_impl!();
68}
69
70impl Signers for Vec<Arc<dyn Signer>> {
71 default_keypairs_impl!();
72}
73
74impl Signers for Vec<&dyn Signer> {
75 default_keypairs_impl!();
76}
77
78impl Signers for [&dyn Signer] {
79 default_keypairs_impl!();
80}
81
82impl Signers for [&dyn Signer; 0] {
83 default_keypairs_impl!();
84}
85
86impl Signers for [&dyn Signer; 1] {
87 default_keypairs_impl!();
88}
89
90impl Signers for [&dyn Signer; 2] {
91 default_keypairs_impl!();
92}
93
94impl Signers for [&dyn Signer; 3] {
95 default_keypairs_impl!();
96}
97
98impl Signers for [&dyn Signer; 4] {
99 default_keypairs_impl!();
100}
101
102impl<T: Signer> Signers for [&T; 0] {
103 default_keypairs_impl!();
104}
105
106impl<T: Signer> Signers for [&T; 1] {
107 default_keypairs_impl!();
108}
109
110impl<T: Signer> Signers for [&T; 2] {
111 default_keypairs_impl!();
112}
113
114impl<T: Signer> Signers for [&T; 3] {
115 default_keypairs_impl!();
116}
117
118impl<T: Signer> Signers for [&T; 4] {
119 default_keypairs_impl!();
120}
121
122impl<T: Signer> Signers for Vec<&T> {
123 default_keypairs_impl!();
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 struct Foo;
131 impl Signer for Foo {
132 fn try_pubkey(&self) -> Result<Pubkey, SignerError> {
133 Ok(Pubkey::default())
134 }
135 fn try_sign_message(&self, _message: &[u8]) -> Result<Signature, SignerError> {
136 Ok(Signature::default())
137 }
138 fn is_interactive(&self) -> bool {
139 false
140 }
141 }
142
143 struct Bar;
144 impl Signer for Bar {
145 fn try_pubkey(&self) -> Result<Pubkey, SignerError> {
146 Ok(Pubkey::default())
147 }
148 fn try_sign_message(&self, _message: &[u8]) -> Result<Signature, SignerError> {
149 Ok(Signature::default())
150 }
151 fn is_interactive(&self) -> bool {
152 false
153 }
154 }
155
156 #[test]
157 fn test_dyn_keypairs_compile() {
158 let xs: Vec<Box<dyn Signer>> = vec![Box::new(Foo {}), Box::new(Bar {})];
159 assert_eq!(
160 xs.sign_message(b""),
161 vec![Signature::default(), Signature::default()],
162 );
163
164 let xs_ref: &[Box<dyn Signer>] = &xs;
166 assert_eq!(
167 Signers::sign_message(xs_ref, b""),
168 vec![Signature::default(), Signature::default()],
169 );
170 }
171
172 #[test]
173 fn test_dyn_keypairs_by_ref_compile() {
174 let foo = Foo {};
175 let bar = Bar {};
176 let xs: Vec<&dyn Signer> = vec![&foo, &bar];
177 assert_eq!(
178 xs.sign_message(b""),
179 vec![Signature::default(), Signature::default()],
180 );
181
182 let xs_ref: &[&dyn Signer] = &xs;
184 assert_eq!(
185 Signers::sign_message(xs_ref, b""),
186 vec![Signature::default(), Signature::default()],
187 );
188 }
189}