1pub mod error;
22mod sdk_adapter;
23#[cfg(test)]
24pub mod test_util;
25#[cfg(feature = "integration-tests")]
26pub mod tests;
27pub mod traits;
28pub mod transaction_util;
29
30#[cfg(feature = "memory")]
31pub mod memory;
32
33#[cfg(feature = "vault")]
34pub mod vault;
35
36#[cfg(feature = "privy")]
37pub mod privy;
38
39#[cfg(feature = "turnkey")]
40pub mod turnkey;
41
42pub use error::SignerError;
44pub use traits::SolanaSigner;
45
46#[cfg(feature = "memory")]
48pub use memory::MemorySigner;
49
50#[cfg(feature = "vault")]
51pub use vault::VaultSigner;
52
53#[cfg(feature = "privy")]
54pub use privy::PrivySigner;
55
56#[cfg(feature = "turnkey")]
57pub use turnkey::TurnkeySigner;
58
59use crate::traits::SignedTransaction;
60
61#[cfg(not(any(
63 feature = "memory",
64 feature = "vault",
65 feature = "privy",
66 feature = "turnkey"
67)))]
68compile_error!(
69 "At least one signer backend feature must be enabled: memory, vault, privy, or turnkey"
70);
71
72pub enum Signer {
74 #[cfg(feature = "memory")]
75 Memory(MemorySigner),
76
77 #[cfg(feature = "vault")]
78 Vault(VaultSigner),
79
80 #[cfg(feature = "privy")]
81 Privy(PrivySigner),
82
83 #[cfg(feature = "turnkey")]
84 Turnkey(TurnkeySigner),
85}
86
87impl Signer {
88 #[cfg(feature = "memory")]
90 pub fn from_memory(private_key: &str) -> Result<Self, SignerError> {
91 Ok(Self::Memory(MemorySigner::from_private_key_string(
92 private_key,
93 )?))
94 }
95
96 #[cfg(feature = "vault")]
98 pub fn from_vault(
99 vault_addr: String,
100 vault_token: String,
101 key_name: String,
102 pubkey: String,
103 ) -> Result<Self, SignerError> {
104 Ok(Self::Vault(VaultSigner::new(
105 vault_addr,
106 vault_token,
107 key_name,
108 pubkey,
109 )?))
110 }
111
112 #[cfg(feature = "privy")]
114 pub async fn from_privy(
115 app_id: String,
116 app_secret: String,
117 wallet_id: String,
118 ) -> Result<Self, SignerError> {
119 let mut signer = PrivySigner::new(app_id, app_secret, wallet_id);
120 signer.init().await?;
121 Ok(Self::Privy(signer))
122 }
123
124 #[cfg(feature = "turnkey")]
126 pub fn from_turnkey(
127 api_public_key: String,
128 api_private_key: String,
129 organization_id: String,
130 private_key_id: String,
131 public_key: String,
132 ) -> Result<Self, SignerError> {
133 Ok(Self::Turnkey(TurnkeySigner::new(
134 api_public_key,
135 api_private_key,
136 organization_id,
137 private_key_id,
138 public_key,
139 )?))
140 }
141}
142
143#[async_trait::async_trait]
144impl SolanaSigner for Signer {
145 fn pubkey(&self) -> sdk_adapter::Pubkey {
146 match self {
147 #[cfg(feature = "memory")]
148 Signer::Memory(s) => s.pubkey(),
149
150 #[cfg(feature = "vault")]
151 Signer::Vault(s) => s.pubkey(),
152
153 #[cfg(feature = "privy")]
154 Signer::Privy(s) => s.pubkey(),
155
156 #[cfg(feature = "turnkey")]
157 Signer::Turnkey(s) => s.pubkey(),
158 }
159 }
160
161 async fn sign_transaction(
162 &self,
163 tx: &mut sdk_adapter::Transaction,
164 ) -> Result<SignedTransaction, SignerError> {
165 match self {
166 #[cfg(feature = "memory")]
167 Signer::Memory(s) => s.sign_transaction(tx).await,
168
169 #[cfg(feature = "vault")]
170 Signer::Vault(s) => s.sign_transaction(tx).await,
171
172 #[cfg(feature = "privy")]
173 Signer::Privy(s) => s.sign_transaction(tx).await,
174
175 #[cfg(feature = "turnkey")]
176 Signer::Turnkey(s) => s.sign_transaction(tx).await,
177 }
178 }
179
180 async fn sign_message(&self, message: &[u8]) -> Result<sdk_adapter::Signature, SignerError> {
181 match self {
182 #[cfg(feature = "memory")]
183 Signer::Memory(s) => s.sign_message(message).await,
184
185 #[cfg(feature = "vault")]
186 Signer::Vault(s) => s.sign_message(message).await,
187
188 #[cfg(feature = "privy")]
189 Signer::Privy(s) => s.sign_message(message).await,
190
191 #[cfg(feature = "turnkey")]
192 Signer::Turnkey(s) => s.sign_message(message).await,
193 }
194 }
195
196 async fn sign_partial_transaction(
197 &self,
198 tx: &mut sdk_adapter::Transaction,
199 ) -> Result<SignedTransaction, SignerError> {
200 match self {
201 #[cfg(feature = "memory")]
202 Signer::Memory(s) => s.sign_partial_transaction(tx).await,
203
204 #[cfg(feature = "vault")]
205 Signer::Vault(s) => s.sign_partial_transaction(tx).await,
206
207 #[cfg(feature = "privy")]
208 Signer::Privy(s) => s.sign_partial_transaction(tx).await,
209
210 #[cfg(feature = "turnkey")]
211 Signer::Turnkey(s) => s.sign_partial_transaction(tx).await,
212 }
213 }
214
215 async fn is_available(&self) -> bool {
216 match self {
217 #[cfg(feature = "memory")]
218 Signer::Memory(s) => s.is_available().await,
219
220 #[cfg(feature = "vault")]
221 Signer::Vault(s) => s.is_available().await,
222
223 #[cfg(feature = "privy")]
224 Signer::Privy(s) => s.is_available().await,
225
226 #[cfg(feature = "turnkey")]
227 Signer::Turnkey(s) => s.is_available().await,
228 }
229 }
230}