commit 284c74df8dd1e6a4dd5b0b8a17a8f65c0d4ece9b
parent 4e6b4cb2328e14e63e0feb223ef96543e89a22db
Author: triesap <tyson@radroots.org>
Date: Wed, 8 Apr 2026 19:21:49 +0000
surface signer session in cli write and job output
Diffstat:
9 files changed, 159 insertions(+), 11 deletions(-)
diff --git a/src/domain/runtime.rs b/src/domain/runtime.rs
@@ -453,6 +453,8 @@ pub struct JobSummaryView {
pub state: String,
pub terminal: bool,
pub signer: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub signer_session_id: Option<String>,
pub requested_at_unix: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub completed_at_unix: Option<u64>,
@@ -466,6 +468,8 @@ pub struct JobDetailView {
pub state: String,
pub terminal: bool,
pub signer: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub signer_session_id: Option<String>,
pub requested_at_unix: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub completed_at_unix: Option<u64>,
@@ -492,6 +496,9 @@ pub struct JobWatchFrameView {
pub observed_at_unix: u64,
pub state: String,
pub terminal: bool,
+ pub signer: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub signer_session_id: Option<String>,
pub summary: String,
}
@@ -615,6 +622,10 @@ pub struct OrderSubmitView {
#[serde(skip_serializing_if = "Option::is_none")]
pub idempotency_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
+ pub signer_mode: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub signer_session_id: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
pub requested_signer_session_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
@@ -670,6 +681,9 @@ pub struct OrderWatchFrameView {
pub observed_at_unix: u64,
pub state: String,
pub terminal: bool,
+ pub signer_mode: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub signer_session_id: Option<String>,
pub summary: String,
}
@@ -779,6 +793,10 @@ pub struct OrderJobView {
#[serde(skip_serializing_if = "Option::is_none")]
pub command: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
+ pub signer_mode: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub signer_session_id: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
pub requested_signer_session_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub event_id: Option<String>,
@@ -894,6 +912,8 @@ pub struct ListingMutationView {
#[serde(skip_serializing_if = "Option::is_none")]
pub idempotency_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
+ pub signer_session_id: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
pub requested_signer_session_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
@@ -928,6 +948,8 @@ pub struct ListingMutationJobView {
pub requested_signer_session_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signer_mode: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub signer_session_id: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
diff --git a/src/render/mod.rs b/src/render/mod.rs
@@ -739,7 +739,7 @@ fn render_job_list(stdout: &mut dyn Write, view: &JobListView) -> Result<(), Run
}
} else {
let table = Table {
- headers: &["job", "type", "state", "signer", "updated"],
+ headers: &["job", "type", "state", "signer", "session", "updated"],
rows: view
.jobs
.iter()
@@ -750,6 +750,7 @@ fn render_job_list(stdout: &mut dyn Write, view: &JobListView) -> Result<(), Run
job.command.clone(),
job.state.clone(),
job.signer.clone(),
+ job.signer_session_id.clone().unwrap_or_default(),
crate::runtime::job::format_timestamp(updated_at),
]
})
@@ -774,7 +775,11 @@ fn render_job_get(stdout: &mut dyn Write, view: &JobGetView) -> Result<(), Runti
("id", job.id.clone()),
("type", job.command.clone()),
("state", job.state.clone()),
- ("signer", job.signer.clone()),
+ ("signer mode", job.signer.clone()),
+ (
+ "signer session",
+ job.signer_session_id.clone().unwrap_or_else(|| "-".to_owned()),
+ ),
(
"requested",
crate::runtime::job::format_timestamp(job.requested_at_unix),
@@ -823,7 +828,7 @@ fn render_job_watch(stdout: &mut dyn Write, view: &JobWatchView) -> Result<(), R
}
} else {
let table = Table {
- headers: &["frame", "time", "state", "terminal", "summary"],
+ headers: &["frame", "time", "state", "signer", "session", "terminal", "summary"],
rows: view
.frames
.iter()
@@ -832,6 +837,8 @@ fn render_job_watch(stdout: &mut dyn Write, view: &JobWatchView) -> Result<(), R
frame.sequence.to_string(),
crate::runtime::job::format_clock(frame.observed_at_unix),
frame.state.clone(),
+ frame.signer.clone(),
+ frame.signer_session_id.clone().unwrap_or_default(),
yes_no(frame.terminal).to_owned(),
frame.summary.clone(),
]
@@ -1035,6 +1042,12 @@ fn render_order_submit(stdout: &mut dyn Write, view: &OrderSubmitView) -> Result
if let Some(idempotency_key) = &view.idempotency_key {
rows.push(("idempotency key", idempotency_key.as_str()));
}
+ if let Some(signer_mode) = &view.signer_mode {
+ rows.push(("signer mode", signer_mode.as_str()));
+ }
+ if let Some(signer_session_id) = &view.signer_session_id {
+ rows.push(("signer session", signer_session_id.as_str()));
+ }
if let Some(requested_signer_session_id) = &view.requested_signer_session_id {
rows.push((
"requested signer session",
@@ -1074,7 +1087,7 @@ fn render_order_watch(stdout: &mut dyn Write, view: &OrderWatchView) -> Result<(
render_owned_pairs(stdout, "watch", rows.as_slice())?;
if !view.frames.is_empty() {
let table = Table {
- headers: &["frame", "time", "state", "terminal", "summary"],
+ headers: &["frame", "time", "state", "signer", "session", "terminal", "summary"],
rows: view
.frames
.iter()
@@ -1083,6 +1096,8 @@ fn render_order_watch(stdout: &mut dyn Write, view: &OrderWatchView) -> Result<(
frame.sequence.to_string(),
crate::runtime::job::format_clock(frame.observed_at_unix),
frame.state.clone(),
+ frame.signer_mode.clone(),
+ frame.signer_session_id.clone().unwrap_or_default(),
yes_no(frame.terminal).to_owned(),
frame.summary.clone(),
]
@@ -1214,6 +1229,12 @@ fn render_order_job(stdout: &mut dyn Write, job: &OrderJobView) -> Result<(), Ru
if let Some(command) = &job.command {
rows.push(("command", command.as_str()));
}
+ if let Some(signer_mode) = &job.signer_mode {
+ rows.push(("signer mode", signer_mode.as_str()));
+ }
+ if let Some(signer_session_id) = &job.signer_session_id {
+ rows.push(("signer session", signer_session_id.as_str()));
+ }
if let Some(requested_signer_session_id) = &job.requested_signer_session_id {
rows.push((
"requested signer session",
@@ -1429,7 +1450,10 @@ fn render_listing_mutation(
rows.push(("event id", event_id.as_str()));
}
if let Some(signer_mode) = &view.signer_mode {
- rows.push(("signer", signer_mode.as_str()));
+ rows.push(("signer mode", signer_mode.as_str()));
+ }
+ if let Some(signer_session_id) = &view.signer_session_id {
+ rows.push(("signer session", signer_session_id.as_str()));
}
if let Some(requested_signer_session_id) = &view.requested_signer_session_id {
rows.push((
diff --git a/src/runtime/daemon.rs b/src/runtime/daemon.rs
@@ -89,6 +89,8 @@ struct BridgeJobRemote {
completed_at_unix: Option<u64>,
signer_mode: String,
#[serde(default)]
+ signer_session_id: Option<String>,
+ #[serde(default)]
event_kind: Option<u32>,
event_id: Option<String>,
event_addr: Option<String>,
@@ -132,6 +134,7 @@ pub struct BridgeListingPublishResult {
pub idempotency_key: Option<String>,
pub status: String,
pub signer_mode: String,
+ pub signer_session_id: Option<String>,
pub event_kind: Option<u32>,
pub event_id: Option<String>,
pub event_addr: Option<String>,
@@ -144,6 +147,7 @@ pub struct BridgeOrderRequestResult {
pub idempotency_key: Option<String>,
pub status: String,
pub signer_mode: String,
+ pub signer_session_id: Option<String>,
pub event_id: Option<String>,
pub event_addr: Option<String>,
}
@@ -393,6 +397,7 @@ pub fn bridge_listing_publish(
idempotency_key: response.job.idempotency_key,
status: response.job.status,
signer_mode: response.job.signer_mode,
+ signer_session_id: response.job.signer_session_id,
event_kind: response.job.event_kind,
event_id: response.job.event_id,
event_addr: response.job.event_addr,
@@ -421,6 +426,7 @@ pub fn bridge_order_request(
idempotency_key: response.job.idempotency_key,
status: response.job.status,
signer_mode: response.job.signer_mode,
+ signer_session_id: response.job.signer_session_id,
event_id: response.job.event_id,
event_addr: response.job.event_addr,
})
@@ -624,6 +630,7 @@ fn map_job_summary_view(job: BridgeJobRemote) -> JobSummaryView {
state: job.status,
terminal: job.terminal,
signer: job.signer_mode,
+ signer_session_id: job.signer_session_id,
requested_at_unix: job.requested_at_unix,
completed_at_unix: job.completed_at_unix,
recovered_after_restart: job.recovered_after_restart,
@@ -637,6 +644,7 @@ fn map_job_detail_view(job: BridgeJobRemote) -> JobDetailView {
state: job.status,
terminal: job.terminal,
signer: job.signer_mode,
+ signer_session_id: job.signer_session_id,
requested_at_unix: job.requested_at_unix,
completed_at_unix: job.completed_at_unix,
recovered_after_restart: job.recovered_after_restart,
diff --git a/src/runtime/job.rs b/src/runtime/job.rs
@@ -71,6 +71,8 @@ pub fn watch(config: &RuntimeConfig, args: &JobWatchArgs) -> Result<CommandOutpu
observed_at_unix: job.completed_at_unix.unwrap_or(job.requested_at_unix),
state: job.state.clone(),
terminal: job.terminal,
+ signer: job.signer.clone(),
+ signer_session_id: job.signer_session_id.clone(),
summary: job.relay_outcome_summary.clone(),
});
if job.terminal || frames.len() >= max_frames {
diff --git a/src/runtime/listing.rs b/src/runtime/listing.rs
@@ -522,6 +522,7 @@ fn mutate(
event_id: None,
event_addr: Some(listing_addr.clone()),
idempotency_key: args.idempotency_key.clone(),
+ signer_session_id: None,
requested_signer_session_id: args.signer_session_id.clone(),
reason: Some("dry run requested; daemon publish skipped".to_owned()),
job: args.print_job.then(|| ListingMutationJobView {
@@ -531,6 +532,7 @@ fn mutate(
idempotency_key: args.idempotency_key.clone(),
requested_signer_session_id: args.signer_session_id.clone(),
signer_mode: Some(config.signer.backend.as_str().to_owned()),
+ signer_session_id: None,
}),
event: args.print_event.then_some(event_preview),
actions: vec![format!(
@@ -602,6 +604,7 @@ fn mutate(
job_id: Some(result.job_id.clone()),
job_status: Some(result.status.clone()),
signer_mode: Some(result.signer_mode.clone()),
+ signer_session_id: result.signer_session_id.clone(),
event_id: result.event_id.clone(),
event_addr: result
.event_addr
@@ -619,6 +622,7 @@ fn mutate(
idempotency_key: result.idempotency_key,
requested_signer_session_id: args.signer_session_id.clone(),
signer_mode: Some(result.signer_mode),
+ signer_session_id: result.signer_session_id,
}),
event: args.print_event.then(|| ListingMutationEventView {
event_id: result.event_id,
@@ -997,6 +1001,7 @@ fn daemon_error_view(
job_id: None,
job_status: None,
signer_mode: None,
+ signer_session_id: None,
event_id: None,
event_addr: None,
idempotency_key: args.idempotency_key.clone(),
@@ -1009,6 +1014,7 @@ fn daemon_error_view(
idempotency_key: args.idempotency_key.clone(),
requested_signer_session_id: args.signer_session_id.clone(),
signer_mode: Some(config.signer.backend.as_str().to_owned()),
+ signer_session_id: None,
}),
event: args.print_event.then_some(event_preview),
actions: vec![
@@ -1030,6 +1036,7 @@ fn daemon_error_view(
job_id: None,
job_status: None,
signer_mode: None,
+ signer_session_id: None,
event_id: None,
event_addr: None,
idempotency_key: args.idempotency_key.clone(),
@@ -1042,6 +1049,7 @@ fn daemon_error_view(
idempotency_key: args.idempotency_key.clone(),
requested_signer_session_id: args.signer_session_id.clone(),
signer_mode: Some(config.signer.backend.as_str().to_owned()),
+ signer_session_id: None,
}),
event: args.print_event.then_some(event_preview),
actions: vec!["start radrootsd and verify the rpc url".to_owned()],
@@ -1062,6 +1070,7 @@ fn daemon_error_view(
job_id: None,
job_status: None,
signer_mode: None,
+ signer_session_id: None,
event_id: None,
event_addr: None,
idempotency_key: args.idempotency_key.clone(),
@@ -1074,6 +1083,7 @@ fn daemon_error_view(
idempotency_key: args.idempotency_key.clone(),
requested_signer_session_id: args.signer_session_id.clone(),
signer_mode: Some(config.signer.backend.as_str().to_owned()),
+ signer_session_id: None,
}),
event: args.print_event.then_some(event_preview),
actions: vec!["inspect the daemon rpc response contract".to_owned()],
diff --git a/src/runtime/order.rs b/src/runtime/order.rs
@@ -74,6 +74,8 @@ struct OrderDraftSubmission {
#[serde(default, skip_serializing_if = "Option::is_none")]
signer_mode: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
+ signer_session_id: Option<String>,
+ #[serde(default, skip_serializing_if = "Option::is_none")]
command: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
event_id: Option<String>,
@@ -280,6 +282,8 @@ pub fn submit(
dry_run: false,
deduplicated: false,
idempotency_key: args.idempotency_key.clone(),
+ signer_mode: None,
+ signer_session_id: None,
requested_signer_session_id: args.signer_session_id.clone(),
reason: Some(format!("order draft `{}` was not found", args.key)),
job: None,
@@ -307,6 +311,8 @@ pub fn submit(
dry_run: false,
deduplicated: false,
idempotency_key: args.idempotency_key.clone(),
+ signer_mode: None,
+ signer_session_id: None,
requested_signer_session_id: args.signer_session_id.clone(),
reason: Some(reason),
job: None,
@@ -335,6 +341,8 @@ pub fn submit(
dry_run: false,
deduplicated: false,
idempotency_key: args.idempotency_key.clone(),
+ signer_mode: job.signer_mode.clone(),
+ signer_session_id: job.signer_session_id.clone(),
requested_signer_session_id: args.signer_session_id.clone(),
reason: Some("order draft already has a recorded submission job".to_owned()),
job: Some(job),
@@ -363,6 +371,8 @@ pub fn submit(
dry_run: false,
deduplicated: false,
idempotency_key: args.idempotency_key.clone(),
+ signer_mode: None,
+ signer_session_id: None,
requested_signer_session_id: args.signer_session_id.clone(),
reason: Some("order draft is not ready for durable submit".to_owned()),
job: None,
@@ -385,12 +395,16 @@ pub fn submit(
dry_run: true,
deduplicated: false,
idempotency_key: args.idempotency_key.clone(),
+ signer_mode: None,
+ signer_session_id: None,
requested_signer_session_id: args.signer_session_id.clone(),
reason: Some("dry run requested; daemon order submission skipped".to_owned()),
job: Some(OrderJobView {
job_id: "not_submitted".to_owned(),
state: "not_submitted".to_owned(),
command: Some("order.submit".to_owned()),
+ signer_mode: Some(config.signer.backend.as_str().to_owned()),
+ signer_session_id: None,
requested_signer_session_id: args.signer_session_id.clone(),
event_id: None,
event_addr: None,
@@ -428,6 +442,7 @@ pub fn submit(
job_id: result.job_id.clone(),
state: Some(result.status.clone()),
signer_mode: Some(result.signer_mode.clone()),
+ signer_session_id: result.signer_session_id.clone(),
command: Some("order.submit".to_owned()),
event_id: result.event_id.clone(),
event_addr: result.event_addr.clone(),
@@ -466,6 +481,8 @@ pub fn submit(
dry_run: false,
deduplicated: result.deduplicated,
idempotency_key: result.idempotency_key.clone(),
+ signer_mode: Some(result.signer_mode.clone()),
+ signer_session_id: result.signer_session_id.clone(),
requested_signer_session_id: args.signer_session_id.clone(),
reason: failed.then(|| {
"daemon order request failed before relay delivery completed".to_owned()
@@ -474,6 +491,8 @@ pub fn submit(
job_id: result.job_id,
state: result.status,
command: Some("order.submit".to_owned()),
+ signer_mode: Some(result.signer_mode),
+ signer_session_id: result.signer_session_id,
requested_signer_session_id: args.signer_session_id.clone(),
event_id: result.event_id,
event_addr: result.event_addr,
@@ -554,6 +573,8 @@ pub fn watch(
observed_at_unix: job.completed_at_unix.unwrap_or(job.requested_at_unix),
state: job.state.clone(),
terminal: job.terminal,
+ signer_mode: job.signer.clone(),
+ signer_session_id: job.signer_session_id.clone(),
summary: job.relay_outcome_summary.clone(),
});
if job.terminal || frames.len() >= max_frames {
@@ -1031,6 +1052,8 @@ fn submission_job_view(
job_id,
state: job.state,
command: Some(job.command),
+ signer_mode: Some(job.signer.clone()),
+ signer_session_id: job.signer_session_id,
requested_signer_session_id: None,
event_id: job.event_id,
event_addr: job.event_addr,
@@ -1040,6 +1063,8 @@ fn submission_job_view(
job_id,
state: "missing".to_owned(),
command: submission.command.clone(),
+ signer_mode: submission.signer_mode.clone(),
+ signer_session_id: submission.signer_session_id.clone(),
requested_signer_session_id: None,
event_id: submission.event_id.clone(),
event_addr: submission.event_addr.clone(),
@@ -1057,6 +1082,8 @@ fn recorded_job_view(submission: &OrderDraftSubmission, job_id: String) -> Order
.clone()
.unwrap_or_else(|| "recorded".to_owned()),
command: submission.command.clone(),
+ signer_mode: submission.signer_mode.clone(),
+ signer_session_id: submission.signer_session_id.clone(),
requested_signer_session_id: None,
event_id: submission.event_id.clone(),
event_addr: submission.event_addr.clone(),
@@ -1072,6 +1099,8 @@ fn job_view_from_error(job_id: String, error: DaemonRpcError) -> OrderJobView {
job_id,
state: "unconfigured".to_owned(),
command: None,
+ signer_mode: None,
+ signer_session_id: None,
requested_signer_session_id: None,
event_id: None,
event_addr: None,
@@ -1081,6 +1110,8 @@ fn job_view_from_error(job_id: String, error: DaemonRpcError) -> OrderJobView {
job_id,
state: "unavailable".to_owned(),
command: None,
+ signer_mode: None,
+ signer_session_id: None,
requested_signer_session_id: None,
event_id: None,
event_addr: None,
@@ -1092,6 +1123,8 @@ fn job_view_from_error(job_id: String, error: DaemonRpcError) -> OrderJobView {
job_id,
state: "error".to_owned(),
command: None,
+ signer_mode: None,
+ signer_session_id: None,
requested_signer_session_id: None,
event_id: None,
event_addr: None,
@@ -1143,6 +1176,8 @@ fn order_submit_error_view(
dry_run: false,
deduplicated: false,
idempotency_key: args.idempotency_key.clone(),
+ signer_mode: None,
+ signer_session_id: None,
requested_signer_session_id: args.signer_session_id.clone(),
reason: Some(reason),
job: None,
@@ -1415,6 +1450,7 @@ mod tests {
job_id: "job_01".to_owned(),
state: Some("accepted".to_owned()),
signer_mode: Some("embedded_service_identity".to_owned()),
+ signer_session_id: None,
command: Some("order.submit".to_owned()),
event_id: None,
event_addr: None,
diff --git a/tests/job_rpc.rs b/tests/job_rpc.rs
@@ -289,7 +289,8 @@ fn sample_job(job_id: &str, state: &str, terminal: bool, completed_at_unix: Opti
"recovered_after_restart": false,
"requested_at_unix": 1_712_720_000,
"completed_at_unix": completed_at_unix,
- "signer_mode": "embedded_service_identity",
+ "signer_mode": "nip46_session",
+ "signer_session_id": "session-1",
"event_id": "event-123",
"event_addr": "30023:npub1seller:listing-123",
"delivery_policy": "best_effort",
@@ -487,6 +488,8 @@ fn job_ls_and_get_report_retained_bridge_jobs() {
assert_eq!(list_json["count"], 1);
assert_eq!(list_json["jobs"][0]["id"], "job-123");
assert_eq!(list_json["jobs"][0]["command"], "listing.publish");
+ assert_eq!(list_json["jobs"][0]["signer"], "nip46_session");
+ assert_eq!(list_json["jobs"][0]["signer_session_id"], "session-1");
let get = job_rpc_command_in(dir.path())
.env("RADROOTS_RPC_URL", server.url())
@@ -498,6 +501,8 @@ fn job_ls_and_get_report_retained_bridge_jobs() {
let get_json: Value = serde_json::from_slice(get.stdout.as_slice()).expect("get json");
assert_eq!(get_json["state"], "ready");
assert_eq!(get_json["job"]["id"], "job-123");
+ assert_eq!(get_json["job"]["signer"], "nip46_session");
+ assert_eq!(get_json["job"]["signer_session_id"], "session-1");
assert_eq!(
get_json["job"]["relay_outcome_summary"],
"published to 2 relays"
@@ -569,6 +574,9 @@ fn job_watch_ndjson_emits_one_frame_per_poll_until_terminal() {
assert_eq!(lines.len(), 2);
assert!(lines[0].contains("\"sequence\":1"));
assert!(lines[0].contains("\"state\":\"publishing\""));
+ assert!(lines[0].contains("\"signer\":\"nip46_session\""));
+ assert!(lines[0].contains("\"signer_session_id\":\"session-1\""));
assert!(lines[1].contains("\"sequence\":2"));
assert!(lines[1].contains("\"terminal\":true"));
+ assert!(lines[1].contains("\"signer_session_id\":\"session-1\""));
}
diff --git a/tests/listing.rs b/tests/listing.rs
@@ -331,7 +331,13 @@ fn listing_publish_and_update_use_durable_bridge_publish() {
assert_eq!(auth_header.as_deref(), Some("Bearer bridge-secret"));
MockRpcResponse::success(json!({
"deduplicated": false,
- "job": sample_listing_job("job_listing_01", "published", "event_listing_01", "30402:deadbeef:AAAAAAAAAAAAAAAAAAAAAg")
+ "job": sample_listing_job(
+ "job_listing_01",
+ "published",
+ "event_listing_01",
+ "30402:deadbeef:AAAAAAAAAAAAAAAAAAAAAg",
+ "sess_publish_01"
+ )
}))
}
other => MockRpcResponse::rpc_error(-32601, &format!("unexpected method: {other}")),
@@ -363,7 +369,11 @@ fn listing_publish_and_update_use_durable_bridge_publish() {
assert_eq!(publish_json["job_status"], "published");
assert_eq!(publish_json["event_id"], "event_listing_01");
assert_eq!(publish_json["event"]["kind"], 30402);
+ assert_eq!(publish_json["signer_mode"], "nip46_session");
+ assert_eq!(publish_json["signer_session_id"], "sess_publish_01");
assert_eq!(publish_json["job"]["rpc_method"], "bridge.listing.publish");
+ assert_eq!(publish_json["job"]["signer_mode"], "nip46_session");
+ assert_eq!(publish_json["job"]["signer_session_id"], "sess_publish_01");
assert_eq!(
publish_json["requested_signer_session_id"],
"sess_publish_01"
@@ -471,7 +481,13 @@ fn listing_archive_and_dry_run_are_truthful() {
)])),
"bridge.listing.publish" => MockRpcResponse::success(json!({
"deduplicated": false,
- "job": sample_listing_job("job_listing_archive", "published", "event_listing_archive", "30402:deadbeef:AAAAAAAAAAAAAAAAAAAAAg")
+ "job": sample_listing_job(
+ "job_listing_archive",
+ "published",
+ "event_listing_archive",
+ "30402:deadbeef:AAAAAAAAAAAAAAAAAAAAAg",
+ "sess_archive_01"
+ )
})),
other => MockRpcResponse::rpc_error(-32601, &format!("unexpected method: {other}")),
}
@@ -495,6 +511,8 @@ fn listing_archive_and_dry_run_are_truthful() {
serde_json::from_slice(archive_output.stdout.as_slice()).expect("archive json");
assert_eq!(archive_json["operation"], "archive");
assert_eq!(archive_json["job_status"], "published");
+ assert_eq!(archive_json["signer_mode"], "nip46_session");
+ assert_eq!(archive_json["signer_session_id"], "sess_archive_01");
assert_eq!(
archive_json["requested_signer_session_id"],
"sess_archive_01"
@@ -520,6 +538,10 @@ fn listing_archive_and_dry_run_are_truthful() {
assert_eq!(dry_run_json["state"], "dry_run");
assert_eq!(dry_run_json["dry_run"], true);
assert_eq!(dry_run_json["job"]["state"], "not_submitted");
+ assert!(dry_run_json["signer_mode"].is_null());
+ assert!(dry_run_json["signer_session_id"].is_null());
+ assert_eq!(dry_run_json["job"]["signer_mode"], "local");
+ assert!(dry_run_json["job"]["signer_session_id"].is_null());
assert_eq!(dry_run_json["event"]["kind"], 30402);
assert!(dry_run_json["event"]["event_id"].is_null());
assert_eq!(
@@ -944,7 +966,13 @@ fn write_response(stream: &mut TcpStream, response: &MockRpcResponse) -> Result<
.map_err(|error| format!("flush mock rpc response: {error}"))
}
-fn sample_listing_job(job_id: &str, status: &str, event_id: &str, event_addr: &str) -> Value {
+fn sample_listing_job(
+ job_id: &str,
+ status: &str,
+ event_id: &str,
+ event_addr: &str,
+ signer_session_id: &str,
+) -> Value {
json!({
"job_id": job_id,
"command": "bridge.listing.publish",
@@ -954,7 +982,8 @@ fn sample_listing_job(job_id: &str, status: &str, event_id: &str, event_addr: &s
"recovered_after_restart": false,
"requested_at_unix": 1_712_720_000,
"completed_at_unix": 1_712_720_010,
- "signer_mode": "local",
+ "signer_mode": "nip46_session",
+ "signer_session_id": signer_session_id,
"event_kind": 30402,
"event_id": event_id,
"event_addr": event_addr,
diff --git a/tests/order.rs b/tests/order.rs
@@ -256,7 +256,8 @@ fn sample_bridge_job(job_id: &str, state: &str, terminal: bool) -> Value {
"recovered_after_restart": false,
"requested_at_unix": 1_712_720_000,
"completed_at_unix": terminal.then_some(1_712_720_030),
- "signer_mode": "embedded_service_identity",
+ "signer_mode": "nip46_session",
+ "signer_session_id": "sess_order_01",
"event_kind": 30420,
"event_id": "evt_order_01",
"event_addr": "30402:deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef:AAAAAAAAAAAAAAAAAAAAAg",
@@ -529,8 +530,12 @@ fn order_submit_persists_submission_metadata_and_reports_job() {
let submit_json: Value =
serde_json::from_slice(submit_output.stdout.as_slice()).expect("submit json");
assert_eq!(submit_json["state"], "accepted");
+ assert_eq!(submit_json["signer_mode"], "nip46_session");
+ assert_eq!(submit_json["signer_session_id"], "sess_order_01");
assert_eq!(submit_json["job"]["job_id"], "job_order_01");
assert_eq!(submit_json["job"]["command"], "order.submit");
+ assert_eq!(submit_json["job"]["signer_mode"], "nip46_session");
+ assert_eq!(submit_json["job"]["signer_session_id"], "sess_order_01");
assert_eq!(submit_json["requested_signer_session_id"], "sess_order_01");
assert_eq!(
submit_json["job"]["requested_signer_session_id"],
@@ -632,6 +637,10 @@ job_id = "job_watch_01"
assert_eq!(json["frames"].as_array().map(Vec::len), Some(2));
assert_eq!(json["frames"][0]["state"], "accepted");
assert_eq!(json["frames"][1]["state"], "completed");
+ assert_eq!(json["frames"][0]["signer_mode"], "nip46_session");
+ assert_eq!(json["frames"][0]["signer_session_id"], "sess_order_01");
+ assert_eq!(json["frames"][1]["signer_mode"], "nip46_session");
+ assert_eq!(json["frames"][1]["signer_session_id"], "sess_order_01");
}
#[test]