openzeppelin_relayer/services/signer/stellar/
mod.rs1mod google_cloud_kms_signer;
5mod local_signer;
6mod turnkey_signer;
7mod vault_signer;
8
9use async_trait::async_trait;
10use google_cloud_kms_signer::*;
11use local_signer::*;
12use turnkey_signer::*;
13use vault_signer::*;
14
15use crate::{
16 domain::{SignDataRequest, SignDataResponse, SignTransactionResponse, SignTypedDataRequest},
17 models::{
18 Address, NetworkTransactionData, Signer as SignerDomainModel, SignerConfig,
19 SignerRepoModel, SignerType, TransactionRepoModel, VaultSignerConfig,
20 },
21 services::{
22 signer::{SignXdrTransactionResponseStellar, Signer, SignerError, SignerFactoryError},
23 GoogleCloudKmsService, TurnkeyService, VaultConfig, VaultService,
24 },
25};
26
27use super::DataSignerTrait;
28
29#[cfg(test)]
30use mockall::automock;
31
32#[cfg_attr(test, automock)]
33#[async_trait]
38pub trait StellarSignTrait: Sync + Send {
39 async fn sign_xdr_transaction(
50 &self,
51 unsigned_xdr: &str,
52 network_passphrase: &str,
53 ) -> Result<SignXdrTransactionResponseStellar, SignerError>;
54}
55
56pub enum StellarSigner {
57 Local(Box<LocalSigner>),
58 Vault(VaultSigner<VaultService>),
59 GoogleCloudKms(GoogleCloudKmsSigner),
60 Turnkey(TurnkeySigner),
61}
62
63#[async_trait]
64impl Signer for StellarSigner {
65 async fn address(&self) -> Result<Address, SignerError> {
66 match self {
67 Self::Local(s) => s.address().await,
68 Self::Vault(s) => s.address().await,
69 Self::GoogleCloudKms(s) => s.address().await,
70 Self::Turnkey(s) => s.address().await,
71 }
72 }
73
74 async fn sign_transaction(
75 &self,
76 tx: NetworkTransactionData,
77 ) -> Result<SignTransactionResponse, SignerError> {
78 match self {
79 Self::Local(s) => s.sign_transaction(tx).await,
80 Self::Vault(s) => s.sign_transaction(tx).await,
81 Self::GoogleCloudKms(s) => s.sign_transaction(tx).await,
82 Self::Turnkey(s) => s.sign_transaction(tx).await,
83 }
84 }
85}
86
87#[async_trait]
88impl StellarSignTrait for StellarSigner {
89 async fn sign_xdr_transaction(
90 &self,
91 unsigned_xdr: &str,
92 network_passphrase: &str,
93 ) -> Result<SignXdrTransactionResponseStellar, SignerError> {
94 match self {
95 Self::Local(s) => {
96 s.sign_xdr_transaction(unsigned_xdr, network_passphrase)
97 .await
98 }
99 Self::Vault(s) => {
100 s.sign_xdr_transaction(unsigned_xdr, network_passphrase)
101 .await
102 }
103 Self::GoogleCloudKms(s) => {
104 s.sign_xdr_transaction(unsigned_xdr, network_passphrase)
105 .await
106 }
107 Self::Turnkey(s) => {
108 s.sign_xdr_transaction(unsigned_xdr, network_passphrase)
109 .await
110 }
111 }
112 }
113}
114
115pub struct StellarSignerFactory;
116
117impl StellarSignerFactory {
118 pub fn create_stellar_signer(
119 m: &SignerDomainModel,
120 ) -> Result<StellarSigner, SignerFactoryError> {
121 let signer = match &m.config {
122 SignerConfig::Local(_) => {
123 let local_signer = LocalSigner::new(m)?;
124 StellarSigner::Local(Box::new(local_signer))
125 }
126 SignerConfig::Vault(config) => {
127 let vault_config = VaultConfig::new(
128 config.address.clone(),
129 config.role_id.clone(),
130 config.secret_id.clone(),
131 config.namespace.clone(),
132 config
133 .mount_point
134 .clone()
135 .unwrap_or_else(|| "secret".to_string()),
136 None,
137 );
138 let vault_service = VaultService::new(vault_config);
139
140 StellarSigner::Vault(VaultSigner::new(
141 m.id.clone(),
142 config.clone(),
143 vault_service,
144 ))
145 }
146 SignerConfig::GoogleCloudKms(config) => {
147 let service = GoogleCloudKmsService::new(config)
148 .map_err(|e| SignerFactoryError::CreationFailed(e.to_string()))?;
149 StellarSigner::GoogleCloudKms(GoogleCloudKmsSigner::new(service))
150 }
151 SignerConfig::Turnkey(config) => {
152 let service = TurnkeyService::new(config.clone())
153 .map_err(|e| SignerFactoryError::CreationFailed(e.to_string()))?;
154 StellarSigner::Turnkey(TurnkeySigner::new(service))
155 }
156 SignerConfig::AwsKms(_) => {
157 return Err(SignerFactoryError::UnsupportedType("AWS KMS".into()))
158 }
159 SignerConfig::VaultTransit(_) => {
160 return Err(SignerFactoryError::UnsupportedType("Vault Transit".into()))
161 }
162 SignerConfig::Cdp(_) => return Err(SignerFactoryError::UnsupportedType("CDP".into())),
163 };
164 Ok(signer)
165 }
166}