commit a1279869f1ca0075e0ac710538d6b85d7d1afc27
parent 041f741267f91659af9715e0e45263fbe1351dca
Author: triesap <tyson@radroots.org>
Date: Sat, 25 Apr 2026 09:06:29 +0000
sdk: add signer session public key hydration
Diffstat:
4 files changed, 128 insertions(+), 2 deletions(-)
diff --git a/crates/sdk/src/adapters/radrootsd.rs b/crates/sdk/src/adapters/radrootsd.rs
@@ -813,6 +813,11 @@ pub(crate) struct SdkRadrootsdSignerSessionAuthorizeResponse {
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
+pub(crate) struct SdkRadrootsdSignerSessionPublicKeyResponse {
+ pub pubkey: String,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
pub(crate) struct SdkRadrootsdSignerSessionRequireAuthResponse {
pub required: bool,
}
@@ -1361,6 +1366,23 @@ pub(crate) async fn authorize_signer_session(
.await
}
+pub(crate) async fn get_signer_session_public_key(
+ endpoint: &str,
+ auth: &RadrootsdAuth,
+ session_id: &str,
+ timeout: Duration,
+) -> Result<SdkRadrootsdSignerSessionPublicKeyResponse, RadrootsdError> {
+ jsonrpc_call(
+ endpoint,
+ auth,
+ "radroots-sdk-nip46-get-public-key",
+ "nip46.get_public_key",
+ &SdkRadrootsdSignerSessionParams { session_id },
+ timeout,
+ )
+ .await
+}
+
pub(crate) async fn require_signer_session_auth(
endpoint: &str,
auth: &RadrootsdAuth,
diff --git a/crates/sdk/src/client.rs b/crates/sdk/src/client.rs
@@ -498,6 +498,12 @@ pub struct SdkRadrootsdSignerSessionAuthorizeResult {
#[cfg(feature = "radrootsd-client")]
#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct SdkRadrootsdSignerSessionPublicKeyResult {
+ pub pubkey: String,
+}
+
+#[cfg(feature = "radrootsd-client")]
+#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SdkRadrootsdSignerSessionRequireAuthResult {
pub required: bool,
}
@@ -546,6 +552,17 @@ impl From<radrootsd::SdkRadrootsdSignerSessionAuthorizeResponse>
}
#[cfg(feature = "radrootsd-client")]
+impl From<radrootsd::SdkRadrootsdSignerSessionPublicKeyResponse>
+ for SdkRadrootsdSignerSessionPublicKeyResult
+{
+ fn from(value: radrootsd::SdkRadrootsdSignerSessionPublicKeyResponse) -> Self {
+ Self {
+ pubkey: value.pubkey,
+ }
+ }
+}
+
+#[cfg(feature = "radrootsd-client")]
impl From<radrootsd::SdkRadrootsdSignerSessionRequireAuthResponse>
for SdkRadrootsdSignerSessionRequireAuthResult
{
@@ -1332,6 +1349,29 @@ impl RadrootsSdkClient {
}
#[cfg(feature = "radrootsd-client")]
+ async fn get_radrootsd_signer_session_public_key(
+ &self,
+ session: &SdkRadrootsdSignerSessionRef,
+ ) -> Result<SdkRadrootsdSignerSessionPublicKeyResult, SdkRadrootsdSessionError> {
+ if self.transport() != SdkTransportMode::Radrootsd {
+ return Err(SdkRadrootsdSessionError::UnsupportedTransport {
+ transport: self.transport(),
+ operation: "radrootsd.signer_sessions.get_public_key",
+ });
+ }
+
+ let response = radrootsd::get_signer_session_public_key(
+ self.require_radrootsd_endpoint("radrootsd.signer_sessions.get_public_key")?,
+ &self.config.radrootsd.auth,
+ session.session_id(),
+ Duration::from_millis(self.config.network.timeout_ms),
+ )
+ .await
+ .map_err(|err| SdkRadrootsdSessionError::Radrootsd(err.to_string()))?;
+ Ok(response.into())
+ }
+
+ #[cfg(feature = "radrootsd-client")]
async fn require_radrootsd_signer_session_auth(
&self,
session: &SdkRadrootsdSignerSessionRef,
@@ -1753,6 +1793,15 @@ impl<'a> RadrootsdSignerSessionClient<'a> {
.await
}
+ pub async fn get_public_key(
+ &self,
+ session: &SdkRadrootsdSignerSessionRef,
+ ) -> Result<SdkRadrootsdSignerSessionPublicKeyResult, SdkRadrootsdSessionError> {
+ self.client
+ .get_radrootsd_signer_session_public_key(session)
+ .await
+ }
+
pub async fn require_auth(
&self,
session: &SdkRadrootsdSignerSessionRef,
diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs
@@ -47,8 +47,8 @@ pub use crate::client::{
SdkRadrootsdPublicTradeMessage, SdkRadrootsdPublicTradePublishOptions,
SdkRadrootsdSessionError, SdkRadrootsdSignerSessionAuthorizeResult,
SdkRadrootsdSignerSessionCloseResult, SdkRadrootsdSignerSessionHandle,
- SdkRadrootsdSignerSessionRef, SdkRadrootsdSignerSessionRequireAuthResult,
- SdkRadrootsdSignerSessionView,
+ SdkRadrootsdSignerSessionPublicKeyResult, SdkRadrootsdSignerSessionRef,
+ SdkRadrootsdSignerSessionRequireAuthResult, SdkRadrootsdSignerSessionView,
};
pub use crate::config::{
NetworkConfig, RADROOTS_SDK_LOCAL_RADROOTSD_ENDPOINT, RADROOTS_SDK_LOCAL_RELAY_URL,
diff --git a/crates/sdk/tests/radrootsd.rs b/crates/sdk/tests/radrootsd.rs
@@ -971,6 +971,61 @@ async fn radrootsd_signer_session_authorize_returns_typed_result() -> TestResult
}
#[tokio::test]
+async fn radrootsd_signer_session_get_public_key_returns_typed_result() -> TestResult<()> {
+ let (connect_server, _) = JsonRpcServer::spawn(
+ Some("Bearer sdk-secret"),
+ json!({
+ "jsonrpc": "2.0",
+ "id": "radroots-sdk-nip46-connect",
+ "result": {
+ "session_id": "session-123",
+ "mode": "Bunker",
+ "remote_signer_pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "client_pubkey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+ "relays": ["wss://radroots.org"]
+ }
+ }),
+ )
+ .await?;
+ let connect_client = radrootsd_test_client(connect_server.endpoint())?;
+ let handle: SdkRadrootsdSignerSessionHandle = connect_client
+ .radrootsd()
+ .signer_sessions()
+ .connect_bunker(
+ "bunker://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?relay=wss%3A%2F%2Fradroots.org&secret=shared-secret",
+ )
+ .await?;
+
+ let (server, request_rx) = JsonRpcServer::spawn(
+ Some("Bearer sdk-secret"),
+ json!({
+ "jsonrpc": "2.0",
+ "id": "radroots-sdk-nip46-get-public-key",
+ "result": {
+ "pubkey": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
+ }
+ }),
+ )
+ .await?;
+ let client = radrootsd_test_client(server.endpoint())?;
+ let result = client
+ .radrootsd()
+ .signer_sessions()
+ .get_public_key(handle.session())
+ .await?;
+ let request_json = request_rx.await?;
+
+ assert_eq!(request_json["method"], "nip46.get_public_key");
+ assert_eq!(request_json["params"]["session_id"], "session-123");
+ assert_eq!(
+ result.pubkey,
+ "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
+ );
+
+ Ok(())
+}
+
+#[tokio::test]
async fn radrootsd_signer_session_require_auth_returns_typed_result() -> TestResult<()> {
let (connect_server, _) = JsonRpcServer::spawn(
Some("Bearer sdk-secret"),