From 07a5bb9a2aa418ee8c32c4dd664b63b1efd0bdf5 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Tue, 19 Aug 2025 14:59:25 -0700 Subject: [PATCH] feat: add a method to return a FID by an authorized verification address Signed-off-by: Ryan Leckey --- src/network/http_server.rs | 56 +++++++++++++++++++ src/network/server.rs | 31 +++++++++- src/proto/request_response.proto | 8 +++ src/proto/rpc.proto | 1 + .../store/account/verification_store.rs | 22 +++++++- 5 files changed, 116 insertions(+), 2 deletions(-) diff --git a/src/network/http_server.rs b/src/network/http_server.rs index 815d2733a..7c71d5c49 100644 --- a/src/network/http_server.rs +++ b/src/network/http_server.rs @@ -427,6 +427,25 @@ impl FidRequest { } } +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct VerificationFidRequest { + #[serde(with = "serdehex")] + pub address: Vec, +} + +impl VerificationFidRequest { + pub fn to_proto(self) -> proto::VerificationFidRequest { + proto::VerificationFidRequest { + address: self.address, + } + } +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct VerificationFidResponse { + pub fid: u64, +} + #[allow(non_snake_case)] #[derive(Debug, Clone, Deserialize, Serialize)] pub struct FidTimestampRequest { @@ -2168,6 +2187,10 @@ pub trait HubHttpService { &self, req: FidRequest, ) -> Result; + async fn get_fid_by_verification( + &self, + req: VerificationFidRequest, + ) -> Result; async fn get_on_chain_signers_by_fid( &self, req: FidRequest, @@ -2816,6 +2839,30 @@ where map_proto_messages_response_to_json_paged_response(proto_resp) } + /// GET /v1/fidByVerification + async fn get_fid_by_verification( + &self, + req: VerificationFidRequest, + ) -> Result { + let service = &self.service; + + let grpc_req = tonic::Request::new(req.to_proto()); + + let response = service + .get_fid_by_verification(grpc_req) + .await + .map_err(|e| ErrorResponse { + error: "Failed to get fid by verification".to_string(), + error_detail: Some(e.to_string()), + })?; + + let proto_resp = response.into_inner(); + + Ok(VerificationFidResponse { + fid: proto_resp.fid, + }) + } + /// GET /v1/onChainSignersByFid async fn get_on_chain_signers_by_fid( &self, @@ -3132,6 +3179,15 @@ where }) .await } + (&Method::GET, "/v1/fidByVerification") => { + self.handle_request::( + req, + |service, req| { + Box::pin(async move { service.get_fid_by_verification(req).await }) + }, + ) + .await + } (&Method::GET, "/v1/onChainSignersByFid") => { self.handle_request::(req, |service, req| { Box::pin(async move { service.get_on_chain_signers_by_fid(req).await }) diff --git a/src/network/server.rs b/src/network/server.rs index e4e396746..70ac13448 100644 --- a/src/network/server.rs +++ b/src/network/server.rs @@ -22,7 +22,8 @@ use crate::proto::{ ShardChunksResponse, SignerEventType, SignerRequest, StorageLimitsResponse, SubscribeRequest, TrieNodeMetadataRequest, TrieNodeMetadataResponse, UserDataRequest, UserNameProof, UserNameType, UsernameProofRequest, UsernameProofsResponse, ValidationResponse, - VerificationAddAddressBody, VerificationRequest, + VerificationAddAddressBody, VerificationFidRequest, VerificationFidResponse, + VerificationRequest, }; use crate::storage::constants::OnChainEventPostfix; use crate::storage::constants::RootPrefix; @@ -1373,6 +1374,34 @@ impl HubService for MyHubService { .as_response() } + async fn get_fid_by_verification( + &self, + request: Request, + ) -> Result, Status> { + let request = request.into_inner(); + + for (_, stores) in &self.shard_stores { + let store = &stores.verification_store; + + match VerificationStore::get_fid_by_verification(store, &request.address) { + Ok(Some(fid)) => { + return Ok(Response::new(VerificationFidResponse { fid })); + } + + Ok(None) => { + // look in the next shard + continue; + } + + Err(err) => { + return Err(Status::internal(err.to_string())); + } + } + } + + Err(Status::not_found("verification not found")) + } + async fn get_all_verification_messages_by_fid( &self, request: Request, diff --git a/src/proto/request_response.proto b/src/proto/request_response.proto index 117263237..449925260 100644 --- a/src/proto/request_response.proto +++ b/src/proto/request_response.proto @@ -214,6 +214,14 @@ message VerificationRequest { bytes address = 2; } +message VerificationFidRequest { + bytes address = 1; +} + +message VerificationFidResponse { + uint64 fid = 1; +} + message SignerRequest { uint64 fid = 1; bytes signer = 2; diff --git a/src/proto/rpc.proto b/src/proto/rpc.proto index 26ef0139f..52df21717 100644 --- a/src/proto/rpc.proto +++ b/src/proto/rpc.proto @@ -52,6 +52,7 @@ service HubService { // Verifications rpc GetVerification(VerificationRequest) returns (Message); rpc GetVerificationsByFid(FidRequest) returns (MessagesResponse); + rpc GetFidByVerification(VerificationFidRequest) returns (VerificationFidResponse); // OnChain Events rpc GetOnChainSigner(SignerRequest) returns (OnChainEvent); diff --git a/src/storage/store/account/verification_store.rs b/src/storage/store/account/verification_store.rs index 44dec0a79..c392777f1 100644 --- a/src/storage/store/account/verification_store.rs +++ b/src/storage/store/account/verification_store.rs @@ -1,5 +1,5 @@ use super::{ - make_fid_key, make_user_key, + make_fid_key, make_user_key, read_fid_key, store::{Store, StoreDef}, MessagesPage, StoreEventHandler, TS_HASH_LENGTH, }; @@ -316,4 +316,24 @@ impl VerificationStore { ) -> Result { store.get_removes_by_fid:: bool>(fid, page_options, None) } + + pub fn get_fid_by_verification( + store: &Store, + address: &[u8], + ) -> Result, HubError> { + if address.is_empty() { + return Err(HubError { + code: "bad_request.invalid_param".to_string(), + message: "address empty".to_string(), + }); + } + + let key = VerificationStoreDef::make_verification_by_address_key(address); + + let Some(value) = store.db().get(&key)? else { + return Ok(None); + }; + + Ok(Some(read_fid_key(&value, 0))) + } }