diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 3197884e73..82aad4ee15 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -1943,6 +1943,68 @@ impl TransportRpcModules { Ok(()) } + /// Returns all unique endpoints installed for the given module. + /// + /// Note: In case of duplicate method names this only record the first occurrance. + pub fn methods_by_module(&self, module: RethRpcModule) -> Methods { + self.methods_by(|name| name.starts_with(module.as_str())) + } + + /// Returns all unique endpoints installed in any of the configured modules. + /// + /// Note: In case of duplicate method names this only record the first occurrance. + pub fn methods_by(&self, mut filter: F) -> Methods + where + F: FnMut(&str) -> bool, + { + let mut methods = Methods::new(); + + // filter that matches the given filter and also removes duplicates we already have + let mut f = + |name: &str, mm: &Methods| filter(name) && !mm.method_names().any(|m| m == name); + + if let Some(m) = self.http_methods(|name| f(name, &methods)) { + let _ = methods.merge(m); + } + if let Some(m) = self.ws_methods(|name| f(name, &methods)) { + let _ = methods.merge(m); + } + if let Some(m) = self.ipc_methods(|name| f(name, &methods)) { + let _ = methods.merge(m); + } + methods + } + + /// Returns all [`Methods`] installed for the http server based in the given closure. + /// + /// Returns `None` if no http support is configured. + pub fn http_methods(&self, filter: F) -> Option + where + F: FnMut(&str) -> bool, + { + self.http.as_ref().map(|module| methods_by(module, filter)) + } + + /// Returns all [`Methods`] installed for the ws server based in the given closure. + /// + /// Returns `None` if no ws support is configured. + pub fn ws_methods(&self, filter: F) -> Option + where + F: FnMut(&str) -> bool, + { + self.ws.as_ref().map(|module| methods_by(module, filter)) + } + + /// Returns all [`Methods`] installed for the ipc server based in the given closure. + /// + /// Returns `None` if no ipc support is configured. + pub fn ipc_methods(&self, filter: F) -> Option + where + F: FnMut(&str) -> bool, + { + self.ipc.as_ref().map(|module| methods_by(module, filter)) + } + /// Removes the method with the given name from the configured http methods. /// /// Returns `true` if the method was found and removed, `false` otherwise. @@ -2086,6 +2148,23 @@ impl TransportRpcModules { } } +/// Returns the methods installed in the given module that match the given filter. +fn methods_by(module: &RpcModule, mut filter: F) -> Methods +where + F: FnMut(&str) -> bool, +{ + let mut methods = Methods::new(); + let method_names = module.method_names().filter(|name| filter(name)); + + for name in method_names { + if let Some(matched_method) = module.method(name).cloned() { + let _ = methods.verify_and_insert(name, matched_method); + } + } + + methods +} + /// A handle to the spawned servers. /// /// When this type is dropped or [`RpcServerHandle::stop`] has been called the server will be