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