1use std::borrow::Cow;
4use std::os::unix::net::UnixStream as StdUnixStream;
5use std::sync::Arc;
6
7use hyper_util::rt::TokioIo;
8use nostr::prelude::*;
9use nostr_android_signer_proto::android_signer_client::AndroidSignerClient;
10use nostr_android_signer_proto::{
11 GetPublicKeyReply, GetPublicKeyRequest, IsExternalSignerInstalledReply,
12 IsExternalSignerInstalledRequest, Nip04DecryptReply, Nip04DecryptRequest, Nip04EncryptReply,
13 Nip04EncryptRequest, Nip44DecryptReply, Nip44DecryptRequest, Nip44EncryptReply,
14 Nip44EncryptRequest, SignEventReply, SignEventRequest,
15};
16use tokio::net::UnixStream as TokioUnixStream;
17use tokio::sync::{Mutex, OnceCell};
18use tonic::transport::{Channel, Endpoint, Uri};
19use tonic::{Request, Response};
20use tower::service_fn;
21use uds::{UnixSocketAddr, UnixStreamExt};
22
23use crate::error::Error;
24
25#[derive(Debug, Clone)]
27pub struct AndroidSigner {
28 socket_addr: UnixSocketAddr,
30 client: OnceCell<Arc<Mutex<AndroidSignerClient<Channel>>>>,
32 public_key: OnceCell<PublicKey>,
34}
35
36impl AndroidSigner {
37 #[inline]
39 pub fn new(unique_name: &str) -> Result<Self, Error> {
40 let name: String = format!("nip55_proxy_{unique_name}");
41
42 Ok(Self {
43 socket_addr: UnixSocketAddr::from_abstract(name.as_bytes())?,
44 client: OnceCell::new(),
45 public_key: OnceCell::new(),
46 })
47 }
48
49 async fn client(&self) -> Result<&Arc<Mutex<AndroidSignerClient<Channel>>>, Error> {
50 self.client
51 .get_or_try_init(|| async {
52 let socket_addr: UnixSocketAddr = self.socket_addr;
53
54 let channel: Channel = Endpoint::try_from("unix://fake_uri")?
56 .connect_with_connector(service_fn(move |_: Uri| async move {
57 let stream: TokioUnixStream = connect(&socket_addr)?;
58
59 Ok::<_, Error>(TokioIo::new(stream))
60 }))
61 .await?;
62
63 let client: AndroidSignerClient<Channel> = AndroidSignerClient::new(channel);
65
66 Ok(Arc::new(Mutex::new(client)))
67 })
68 .await
69 }
70
71 pub async fn is_external_signer_installed(&self) -> Result<bool, Error> {
73 let client = self.client().await?;
75
76 let mut client = client.lock().await;
78
79 let req: Request<IsExternalSignerInstalledRequest> =
81 Request::new(IsExternalSignerInstalledRequest {});
82 let res: Response<IsExternalSignerInstalledReply> =
83 client.is_external_signer_installed(req).await?;
84
85 let inner: IsExternalSignerInstalledReply = res.into_inner();
87 Ok(inner.installed)
88 }
89
90 async fn _get_public_key(&self) -> Result<&PublicKey, Error> {
91 self.public_key
92 .get_or_try_init(|| async {
93 let client = self.client().await?;
95
96 let mut client = client.lock().await;
98
99 let req: Request<GetPublicKeyRequest> = Request::new(GetPublicKeyRequest {});
101 let res: Response<GetPublicKeyReply> = client.get_public_key(req).await?;
102
103 let inner: GetPublicKeyReply = res.into_inner();
105 Ok(PublicKey::parse(&inner.public_key)?)
106 })
107 .await
108 }
109
110 async fn _sign_event(&self, unsigned: UnsignedEvent) -> Result<Event, Error> {
111 let client = self.client().await?;
113
114 let mut client = client.lock().await;
116
117 let req: Request<SignEventRequest> = Request::new(SignEventRequest {
119 unsigned_event: unsigned.as_json(),
120 current_user_public_key: unsigned.pubkey.to_hex(),
121 });
122 let res: Response<SignEventReply> = client.sign_event(req).await?;
123
124 let inner: SignEventReply = res.into_inner();
126 let event: Event = Event::from_json(&inner.event)?;
127
128 event.verify()?;
130
131 Ok(event)
132 }
133
134 async fn _nip04_encrypt(
135 &self,
136 current_user_public_key: &PublicKey,
137 public_key: &PublicKey,
138 plaintext: &str,
139 ) -> Result<String, Error> {
140 let client = self.client().await?;
142
143 let mut client = client.lock().await;
145
146 let req: Request<Nip04EncryptRequest> = Request::new(Nip04EncryptRequest {
148 current_user_public_key: current_user_public_key.to_hex(),
149 other_public_key: public_key.to_hex(),
150 plaintext: plaintext.to_string(),
151 });
152 let res: Response<Nip04EncryptReply> = client.nip04_encrypt(req).await?;
153
154 let inner: Nip04EncryptReply = res.into_inner();
156 Ok(inner.ciphertext)
157 }
158
159 async fn _nip04_decrypt(
160 &self,
161 current_user_public_key: &PublicKey,
162 public_key: &PublicKey,
163 ciphertext: &str,
164 ) -> Result<String, Error> {
165 let client = self.client().await?;
167
168 let mut client = client.lock().await;
170
171 let req: Request<Nip04DecryptRequest> = Request::new(Nip04DecryptRequest {
173 current_user_public_key: current_user_public_key.to_hex(),
174 other_public_key: public_key.to_hex(),
175 ciphertext: ciphertext.to_string(),
176 });
177 let res: Response<Nip04DecryptReply> = client.nip04_decrypt(req).await?;
178
179 let inner: Nip04DecryptReply = res.into_inner();
181 Ok(inner.plaintext)
182 }
183
184 async fn _nip44_encrypt(
185 &self,
186 current_user_public_key: &PublicKey,
187 public_key: &PublicKey,
188 plaintext: &str,
189 ) -> Result<String, Error> {
190 let client = self.client().await?;
192
193 let mut client = client.lock().await;
195
196 let req: Request<Nip44EncryptRequest> = Request::new(Nip44EncryptRequest {
198 current_user_public_key: current_user_public_key.to_hex(),
199 other_public_key: public_key.to_hex(),
200 plaintext: plaintext.to_string(),
201 });
202 let res: Response<Nip44EncryptReply> = client.nip44_encrypt(req).await?;
203
204 let inner: Nip44EncryptReply = res.into_inner();
206 Ok(inner.ciphertext)
207 }
208
209 async fn _nip44_decrypt(
210 &self,
211 current_user_public_key: &PublicKey,
212 public_key: &PublicKey,
213 ciphertext: &str,
214 ) -> Result<String, Error> {
215 let client = self.client().await?;
217
218 let mut client = client.lock().await;
220
221 let req: Request<Nip44DecryptRequest> = Request::new(Nip44DecryptRequest {
223 current_user_public_key: current_user_public_key.to_hex(),
224 other_public_key: public_key.to_hex(),
225 ciphertext: ciphertext.to_string(),
226 });
227 let res: Response<Nip44DecryptReply> = client.nip44_decrypt(req).await?;
228
229 let inner: Nip44DecryptReply = res.into_inner();
231 Ok(inner.plaintext)
232 }
233}
234
235impl NostrSigner for AndroidSigner {
236 fn backend(&self) -> SignerBackend {
237 SignerBackend::Custom(Cow::Borrowed("android signer"))
238 }
239
240 fn get_public_key(&self) -> BoxedFuture<Result<PublicKey, SignerError>> {
241 Box::pin(async move {
242 self._get_public_key()
243 .await
244 .copied()
245 .map_err(SignerError::backend)
246 })
247 }
248
249 fn sign_event(&self, unsigned: UnsignedEvent) -> BoxedFuture<Result<Event, SignerError>> {
250 Box::pin(async move {
251 self._sign_event(unsigned)
252 .await
253 .map_err(SignerError::backend)
254 })
255 }
256
257 fn nip04_encrypt<'a>(
258 &'a self,
259 public_key: &'a PublicKey,
260 content: &'a str,
261 ) -> BoxedFuture<'a, Result<String, SignerError>> {
262 Box::pin(async move {
263 let current_user_public_key =
264 self._get_public_key().await.map_err(SignerError::backend)?;
265 self._nip04_encrypt(current_user_public_key, public_key, content)
266 .await
267 .map_err(SignerError::backend)
268 })
269 }
270
271 fn nip04_decrypt<'a>(
272 &'a self,
273 public_key: &'a PublicKey,
274 encrypted_content: &'a str,
275 ) -> BoxedFuture<'a, Result<String, SignerError>> {
276 Box::pin(async move {
277 let current_user_public_key =
278 self._get_public_key().await.map_err(SignerError::backend)?;
279 self._nip04_decrypt(current_user_public_key, public_key, encrypted_content)
280 .await
281 .map_err(SignerError::backend)
282 })
283 }
284
285 fn nip44_encrypt<'a>(
286 &'a self,
287 public_key: &'a PublicKey,
288 content: &'a str,
289 ) -> BoxedFuture<'a, Result<String, SignerError>> {
290 Box::pin(async move {
291 let current_user_public_key =
292 self._get_public_key().await.map_err(SignerError::backend)?;
293 self._nip44_encrypt(current_user_public_key, public_key, content)
294 .await
295 .map_err(SignerError::backend)
296 })
297 }
298
299 fn nip44_decrypt<'a>(
300 &'a self,
301 public_key: &'a PublicKey,
302 payload: &'a str,
303 ) -> BoxedFuture<'a, Result<String, SignerError>> {
304 Box::pin(async move {
305 let current_user_public_key =
306 self._get_public_key().await.map_err(SignerError::backend)?;
307 self._nip44_decrypt(current_user_public_key, public_key, payload)
308 .await
309 .map_err(SignerError::backend)
310 })
311 }
312}
313
314fn connect(socket_addr: &UnixSocketAddr) -> Result<TokioUnixStream, Error> {
315 let std_stream: StdUnixStream = StdUnixStream::connect_to_unix_addr(socket_addr)?;
317
318 std_stream.set_nonblocking(true)?;
320
321 Ok(TokioUnixStream::from_std(std_stream)?)
323}