penumbra_sdk_shielded_pool/component/
rpc.rs

1use std::pin::Pin;
2
3use cnidarium::Storage;
4use penumbra_sdk_asset::asset::{self};
5use penumbra_sdk_proto::core::component::shielded_pool::v1::{
6    query_service_server::QueryService, AssetMetadataByIdRequest, AssetMetadataByIdResponse,
7    AssetMetadataByIdsRequest, AssetMetadataByIdsResponse,
8};
9
10use tonic::Status;
11use tracing::instrument;
12
13use super::AssetRegistryRead;
14
15mod bank_query;
16mod transfer_query;
17
18// TODO: Hide this and only expose a Router?
19pub struct Server {
20    storage: Storage,
21}
22
23impl Server {
24    pub fn new(storage: Storage) -> Self {
25        Self { storage }
26    }
27}
28
29#[tonic::async_trait]
30impl QueryService for Server {
31    type AssetMetadataByIdsStream = Pin<
32        Box<dyn futures::Stream<Item = Result<AssetMetadataByIdsResponse, tonic::Status>> + Send>,
33    >;
34
35    #[instrument(skip(self, request))]
36    async fn asset_metadata_by_id(
37        &self,
38        request: tonic::Request<AssetMetadataByIdRequest>,
39    ) -> Result<tonic::Response<AssetMetadataByIdResponse>, Status> {
40        let state = self.storage.latest_snapshot();
41
42        let request = request.into_inner();
43        let id: asset::Id = request
44            .asset_id
45            .ok_or_else(|| Status::invalid_argument("missing asset_id"))?
46            .try_into()
47            .map_err(|e| Status::invalid_argument(format!("could not parse asset_id: {e}")))?;
48
49        let denom_metadata = state.denom_metadata_by_asset(&id).await;
50
51        let rsp = match denom_metadata {
52            Some(denom_metadata) => {
53                tracing::debug!(?id, ?denom_metadata, "found denom metadata");
54                AssetMetadataByIdResponse {
55                    denom_metadata: Some(denom_metadata.into()),
56                }
57            }
58            None => {
59                tracing::debug!(?id, "unknown asset id");
60                Default::default()
61            }
62        };
63
64        Ok(tonic::Response::new(rsp))
65    }
66
67    async fn asset_metadata_by_ids(
68        &self,
69        _request: tonic::Request<AssetMetadataByIdsRequest>,
70    ) -> Result<tonic::Response<Self::AssetMetadataByIdsStream>, tonic::Status> {
71        unimplemented!("asset_metadata_by_ids not yet implemented")
72    }
73}