1pub mod error;
28mod sdk_adapter;
29pub mod signature_util;
30#[cfg(test)]
31pub mod test_util;
32#[cfg(feature = "integration-tests")]
33pub mod tests;
34pub mod traits;
35pub mod transaction_util;
36
37#[cfg(feature = "memory")]
38pub mod memory;
39
40#[cfg(feature = "vault")]
41pub mod vault;
42
43#[cfg(feature = "privy")]
44pub mod privy;
45
46#[cfg(feature = "turnkey")]
47pub mod turnkey;
48
49#[cfg(feature = "aws_kms")]
50pub mod aws_kms;
51
52#[cfg(feature = "fireblocks")]
53pub mod fireblocks;
54
55#[cfg(feature = "gcp_kms")]
56pub mod gcp_kms;
57
58#[cfg(feature = "cdp")]
59pub mod cdp;
60#[cfg(feature = "dfns")]
61pub mod dfns;
62#[cfg(feature = "para")]
63pub mod para;
64
65pub use error::SignerError;
67pub use traits::SolanaSigner;
68
69#[cfg(feature = "memory")]
71pub use memory::MemorySigner;
72
73#[cfg(feature = "vault")]
74pub use vault::VaultSigner;
75
76#[cfg(feature = "privy")]
77pub use privy::PrivySigner;
78
79#[cfg(feature = "turnkey")]
80pub use turnkey::TurnkeySigner;
81
82#[cfg(feature = "aws_kms")]
83pub use aws_kms::AwsKmsSigner;
84
85#[cfg(feature = "fireblocks")]
86pub use fireblocks::{FireblocksSigner, FireblocksSignerConfig};
87
88#[cfg(feature = "gcp_kms")]
89pub use gcp_kms::GcpKmsSigner;
90
91#[cfg(feature = "cdp")]
92pub use cdp::CdpSigner;
93#[cfg(feature = "dfns")]
94pub use dfns::{DfnsSigner, DfnsSignerConfig};
95#[cfg(feature = "para")]
96pub use para::ParaSigner;
97
98use crate::traits::SignedTransaction;
99
100#[cfg(not(any(
102 feature = "memory",
103 feature = "vault",
104 feature = "privy",
105 feature = "turnkey",
106 feature = "aws_kms",
107 feature = "fireblocks",
108 feature = "gcp_kms",
109 feature = "cdp",
110 feature = "dfns",
111 feature = "para"
112)))]
113compile_error!(
114 "At least one signer backend feature must be enabled: memory, vault, privy, turnkey, aws_kms, fireblocks, gcp_kms, cdp, para, or dfns"
115);
116
117pub enum Signer {
119 #[cfg(feature = "memory")]
120 Memory(MemorySigner),
121
122 #[cfg(feature = "vault")]
123 Vault(VaultSigner),
124
125 #[cfg(feature = "privy")]
126 Privy(PrivySigner),
127
128 #[cfg(feature = "turnkey")]
129 Turnkey(TurnkeySigner),
130
131 #[cfg(feature = "aws_kms")]
132 AwsKms(AwsKmsSigner),
133
134 #[cfg(feature = "fireblocks")]
135 Fireblocks(FireblocksSigner),
136
137 #[cfg(feature = "gcp_kms")]
138 GcpKms(GcpKmsSigner),
139
140 #[cfg(feature = "cdp")]
141 Cdp(CdpSigner),
142 #[cfg(feature = "dfns")]
143 Dfns(DfnsSigner),
144 #[cfg(feature = "para")]
145 Para(ParaSigner),
146}
147
148impl Signer {
149 #[cfg(feature = "memory")]
151 pub fn from_memory(private_key: &str) -> Result<Self, SignerError> {
152 Ok(Self::Memory(MemorySigner::from_private_key_string(
153 private_key,
154 )?))
155 }
156
157 #[cfg(feature = "vault")]
159 pub fn from_vault(
160 vault_addr: String,
161 vault_token: String,
162 key_name: String,
163 pubkey: String,
164 ) -> Result<Self, SignerError> {
165 Ok(Self::Vault(VaultSigner::new(
166 vault_addr,
167 vault_token,
168 key_name,
169 pubkey,
170 )?))
171 }
172
173 #[cfg(feature = "privy")]
175 pub async fn from_privy(
176 app_id: String,
177 app_secret: String,
178 wallet_id: String,
179 ) -> Result<Self, SignerError> {
180 let mut signer = PrivySigner::new(app_id, app_secret, wallet_id);
181 signer.init().await?;
182 Ok(Self::Privy(signer))
183 }
184
185 #[cfg(feature = "turnkey")]
187 pub fn from_turnkey(
188 api_public_key: String,
189 api_private_key: String,
190 organization_id: String,
191 private_key_id: String,
192 public_key: String,
193 ) -> Result<Self, SignerError> {
194 Ok(Self::Turnkey(TurnkeySigner::new(
195 api_public_key,
196 api_private_key,
197 organization_id,
198 private_key_id,
199 public_key,
200 )?))
201 }
202
203 #[cfg(feature = "aws_kms")]
205 pub async fn from_aws_kms(
206 key_id: String,
207 public_key: String,
208 region: Option<String>,
209 ) -> Result<Self, SignerError> {
210 Ok(Self::AwsKms(
211 AwsKmsSigner::new(key_id, public_key, region).await?,
212 ))
213 }
214
215 #[cfg(feature = "fireblocks")]
217 pub async fn from_fireblocks(config: FireblocksSignerConfig) -> Result<Self, SignerError> {
218 let mut signer = FireblocksSigner::new(config);
219 signer.init().await?;
220 Ok(Self::Fireblocks(signer))
221 }
222
223 #[cfg(feature = "gcp_kms")]
225 pub async fn from_gcp_kms(key_name: String, public_key: String) -> Result<Self, SignerError> {
226 Ok(Self::GcpKms(GcpKmsSigner::new(key_name, public_key).await?))
227 }
228
229 #[cfg(feature = "para")]
231 pub async fn from_para(
232 api_key: String,
233 wallet_id: String,
234 api_base_url: Option<String>,
235 ) -> Result<Self, SignerError> {
236 let mut signer = ParaSigner::new(api_key, wallet_id, api_base_url)?;
237 signer.init().await?;
238 Ok(Self::Para(signer))
239 }
240
241 #[cfg(feature = "cdp")]
243 pub fn from_cdp(
244 api_key_id: String,
245 api_key_secret: String,
246 wallet_secret: String,
247 address: String,
248 ) -> Result<Self, SignerError> {
249 Ok(Self::Cdp(CdpSigner::new(
250 api_key_id,
251 api_key_secret,
252 wallet_secret,
253 address,
254 )?))
255 }
256
257 #[cfg(feature = "dfns")]
259 pub async fn from_dfns(config: DfnsSignerConfig) -> Result<Self, SignerError> {
260 let mut signer = DfnsSigner::new(config);
261 signer.init().await?;
262 Ok(Self::Dfns(signer))
263 }
264}
265
266#[async_trait::async_trait]
267impl SolanaSigner for Signer {
268 fn pubkey(&self) -> sdk_adapter::Pubkey {
269 match self {
270 #[cfg(feature = "memory")]
271 Signer::Memory(s) => s.pubkey(),
272
273 #[cfg(feature = "vault")]
274 Signer::Vault(s) => s.pubkey(),
275
276 #[cfg(feature = "privy")]
277 Signer::Privy(s) => s.pubkey(),
278
279 #[cfg(feature = "turnkey")]
280 Signer::Turnkey(s) => s.pubkey(),
281
282 #[cfg(feature = "aws_kms")]
283 Signer::AwsKms(s) => s.pubkey(),
284
285 #[cfg(feature = "fireblocks")]
286 Signer::Fireblocks(s) => s.pubkey(),
287
288 #[cfg(feature = "gcp_kms")]
289 Signer::GcpKms(s) => s.pubkey(),
290
291 #[cfg(feature = "cdp")]
292 Signer::Cdp(s) => s.pubkey(),
293 #[cfg(feature = "dfns")]
294 Signer::Dfns(s) => s.pubkey(),
295 #[cfg(feature = "para")]
296 Signer::Para(s) => s.pubkey(),
297 }
298 }
299
300 async fn sign_transaction(
301 &self,
302 tx: &mut sdk_adapter::Transaction,
303 ) -> Result<SignedTransaction, SignerError> {
304 match self {
305 #[cfg(feature = "memory")]
306 Signer::Memory(s) => s.sign_transaction(tx).await,
307
308 #[cfg(feature = "vault")]
309 Signer::Vault(s) => s.sign_transaction(tx).await,
310
311 #[cfg(feature = "privy")]
312 Signer::Privy(s) => s.sign_transaction(tx).await,
313
314 #[cfg(feature = "turnkey")]
315 Signer::Turnkey(s) => s.sign_transaction(tx).await,
316
317 #[cfg(feature = "aws_kms")]
318 Signer::AwsKms(s) => s.sign_transaction(tx).await,
319
320 #[cfg(feature = "fireblocks")]
321 Signer::Fireblocks(s) => s.sign_transaction(tx).await,
322
323 #[cfg(feature = "gcp_kms")]
324 Signer::GcpKms(s) => s.sign_transaction(tx).await,
325
326 #[cfg(feature = "cdp")]
327 Signer::Cdp(s) => s.sign_transaction(tx).await,
328 #[cfg(feature = "dfns")]
329 Signer::Dfns(s) => s.sign_transaction(tx).await,
330 #[cfg(feature = "para")]
331 Signer::Para(s) => s.sign_transaction(tx).await,
332 }
333 }
334
335 async fn sign_message(&self, message: &[u8]) -> Result<sdk_adapter::Signature, SignerError> {
336 match self {
337 #[cfg(feature = "memory")]
338 Signer::Memory(s) => s.sign_message(message).await,
339
340 #[cfg(feature = "vault")]
341 Signer::Vault(s) => s.sign_message(message).await,
342
343 #[cfg(feature = "privy")]
344 Signer::Privy(s) => s.sign_message(message).await,
345
346 #[cfg(feature = "turnkey")]
347 Signer::Turnkey(s) => s.sign_message(message).await,
348
349 #[cfg(feature = "aws_kms")]
350 Signer::AwsKms(s) => s.sign_message(message).await,
351
352 #[cfg(feature = "fireblocks")]
353 Signer::Fireblocks(s) => s.sign_message(message).await,
354
355 #[cfg(feature = "gcp_kms")]
356 Signer::GcpKms(s) => s.sign_message(message).await,
357
358 #[cfg(feature = "cdp")]
359 Signer::Cdp(s) => s.sign_message(message).await,
360 #[cfg(feature = "dfns")]
361 Signer::Dfns(s) => s.sign_message(message).await,
362 #[cfg(feature = "para")]
363 Signer::Para(s) => s.sign_message(message).await,
364 }
365 }
366
367 async fn sign_partial_transaction(
368 &self,
369 tx: &mut sdk_adapter::Transaction,
370 ) -> Result<SignedTransaction, SignerError> {
371 match self {
372 #[cfg(feature = "memory")]
373 Signer::Memory(s) => s.sign_partial_transaction(tx).await,
374
375 #[cfg(feature = "vault")]
376 Signer::Vault(s) => s.sign_partial_transaction(tx).await,
377
378 #[cfg(feature = "privy")]
379 Signer::Privy(s) => s.sign_partial_transaction(tx).await,
380
381 #[cfg(feature = "turnkey")]
382 Signer::Turnkey(s) => s.sign_partial_transaction(tx).await,
383
384 #[cfg(feature = "aws_kms")]
385 Signer::AwsKms(s) => s.sign_partial_transaction(tx).await,
386
387 #[cfg(feature = "fireblocks")]
388 Signer::Fireblocks(s) => s.sign_partial_transaction(tx).await,
389
390 #[cfg(feature = "gcp_kms")]
391 Signer::GcpKms(s) => s.sign_partial_transaction(tx).await,
392
393 #[cfg(feature = "cdp")]
394 Signer::Cdp(s) => s.sign_partial_transaction(tx).await,
395 #[cfg(feature = "dfns")]
396 Signer::Dfns(s) => s.sign_partial_transaction(tx).await,
397 #[cfg(feature = "para")]
398 Signer::Para(s) => s.sign_partial_transaction(tx).await,
399 }
400 }
401
402 async fn is_available(&self) -> bool {
403 match self {
404 #[cfg(feature = "memory")]
405 Signer::Memory(s) => s.is_available().await,
406
407 #[cfg(feature = "vault")]
408 Signer::Vault(s) => s.is_available().await,
409
410 #[cfg(feature = "privy")]
411 Signer::Privy(s) => s.is_available().await,
412
413 #[cfg(feature = "turnkey")]
414 Signer::Turnkey(s) => s.is_available().await,
415
416 #[cfg(feature = "aws_kms")]
417 Signer::AwsKms(s) => s.is_available().await,
418
419 #[cfg(feature = "fireblocks")]
420 Signer::Fireblocks(s) => s.is_available().await,
421
422 #[cfg(feature = "gcp_kms")]
423 Signer::GcpKms(s) => s.is_available().await,
424
425 #[cfg(feature = "cdp")]
426 Signer::Cdp(s) => s.is_available().await,
427 #[cfg(feature = "dfns")]
428 Signer::Dfns(s) => s.is_available().await,
429 #[cfg(feature = "para")]
430 Signer::Para(s) => s.is_available().await,
431 }
432 }
433}