commit d8e31b37518205781dc3d80b757e6d977868fd7c
parent 3f856c6368cf5841c4ceac5e4860b042a38bcb1d
Author: triesap <tyson@radroots.org>
Date: Wed, 8 Apr 2026 18:29:46 +0000
cli: add signer-session selection surface
Diffstat:
7 files changed, 175 insertions(+), 69 deletions(-)
diff --git a/src/cli.rs b/src/cli.rs
@@ -349,6 +349,8 @@ pub struct ListingMutationArgs {
pub file: PathBuf,
#[arg(long)]
pub idempotency_key: Option<String>,
+ #[arg(long = "signer-session-id")]
+ pub signer_session_id: Option<String>,
#[arg(long = "print-job", action = ArgAction::SetTrue)]
pub print_job: bool,
#[arg(long = "print-event", action = ArgAction::SetTrue)]
@@ -423,6 +425,8 @@ pub struct OrderSubmitArgs {
pub key: String,
#[arg(long)]
pub idempotency_key: Option<String>,
+ #[arg(long = "signer-session-id")]
+ pub signer_session_id: Option<String>,
}
#[derive(Debug, Clone, Args)]
@@ -705,6 +709,7 @@ mod tests {
ListingCommand::Publish(file) => {
assert_eq!(file.file.to_str(), Some("draft.toml"));
assert!(file.idempotency_key.is_none());
+ assert!(file.signer_session_id.is_none());
assert!(!file.print_job);
assert!(!file.print_event);
}
@@ -728,6 +733,7 @@ mod tests {
ListingCommand::Archive(file) => {
assert_eq!(file.file.to_str(), Some("draft.toml"));
assert_eq!(file.idempotency_key.as_deref(), Some("archive-key"));
+ assert!(file.signer_session_id.is_none());
assert!(file.print_job);
assert!(file.print_event);
}
@@ -736,6 +742,25 @@ mod tests {
_ => panic!("unexpected command variant"),
}
+ let listing_update = CliArgs::parse_from([
+ "radroots",
+ "listing",
+ "update",
+ "--signer-session-id",
+ "sess_123",
+ "draft.toml",
+ ]);
+ match listing_update.command {
+ Command::Listing(args) => match args.command {
+ ListingCommand::Update(file) => {
+ assert_eq!(file.file.to_str(), Some("draft.toml"));
+ assert_eq!(file.signer_session_id.as_deref(), Some("sess_123"));
+ }
+ _ => panic!("unexpected listing subcommand"),
+ },
+ _ => panic!("unexpected command variant"),
+ }
+
let listing_get = CliArgs::parse_from(["radroots", "listing", "get", "lst_123"]);
match listing_get.command {
Command::Listing(args) => match args.command {
@@ -843,12 +868,15 @@ mod tests {
"ord_demo",
"--idempotency-key",
"submit-1",
+ "--signer-session-id",
+ "sess_456",
]);
match order_submit.command {
Command::Order(args) => match args.command {
OrderCommand::Submit(submit) => {
assert_eq!(submit.key, "ord_demo");
assert_eq!(submit.idempotency_key.as_deref(), Some("submit-1"));
+ assert_eq!(submit.signer_session_id.as_deref(), Some("sess_456"));
}
_ => panic!("unexpected order subcommand"),
},
@@ -885,21 +913,15 @@ mod tests {
#[test]
fn command_contract_helpers_report_supported_modes() {
let config_show = CliArgs::parse_from(["radroots", "config", "show"]);
- assert!(
- config_show
- .command
- .supports_output_format(OutputFormat::Human)
- );
- assert!(
- config_show
- .command
- .supports_output_format(OutputFormat::Json)
- );
- assert!(
- !config_show
- .command
- .supports_output_format(OutputFormat::Ndjson)
- );
+ assert!(config_show
+ .command
+ .supports_output_format(OutputFormat::Human));
+ assert!(config_show
+ .command
+ .supports_output_format(OutputFormat::Json));
+ assert!(!config_show
+ .command
+ .supports_output_format(OutputFormat::Ndjson));
assert!(config_show.command.supports_dry_run());
let account_new = CliArgs::parse_from(["radroots", "account", "new"]);
@@ -910,18 +932,14 @@ mod tests {
assert!(find.command.supports_output_format(OutputFormat::Ndjson));
let sync_watch = CliArgs::parse_from(["radroots", "sync", "watch", "--frames", "1"]);
- assert!(
- sync_watch
- .command
- .supports_output_format(OutputFormat::Ndjson)
- );
+ assert!(sync_watch
+ .command
+ .supports_output_format(OutputFormat::Ndjson));
let order_watch = CliArgs::parse_from(["radroots", "order", "watch", "ord_demo"]);
- assert!(
- order_watch
- .command
- .supports_output_format(OutputFormat::Ndjson)
- );
+ assert!(order_watch
+ .command
+ .supports_output_format(OutputFormat::Ndjson));
let order_submit = CliArgs::parse_from(["radroots", "order", "submit", "ord_demo"]);
assert_eq!(order_submit.command.display_name(), "order submit");
diff --git a/src/domain/runtime.rs b/src/domain/runtime.rs
@@ -615,6 +615,8 @@ pub struct OrderSubmitView {
#[serde(skip_serializing_if = "Option::is_none")]
pub idempotency_key: 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>,
#[serde(skip_serializing_if = "Option::is_none")]
pub job: Option<OrderJobView>,
@@ -777,6 +779,8 @@ pub struct OrderJobView {
#[serde(skip_serializing_if = "Option::is_none")]
pub command: 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>,
#[serde(skip_serializing_if = "Option::is_none")]
pub event_addr: Option<String>,
@@ -890,6 +894,8 @@ pub struct ListingMutationView {
#[serde(skip_serializing_if = "Option::is_none")]
pub idempotency_key: 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>,
#[serde(skip_serializing_if = "Option::is_none")]
pub job: Option<ListingMutationJobView>,
@@ -919,6 +925,8 @@ pub struct ListingMutationJobView {
#[serde(skip_serializing_if = "Option::is_none")]
pub idempotency_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
+ pub requested_signer_session_id: Option<String>,
+ #[serde(skip_serializing_if = "Option::is_none")]
pub signer_mode: Option<String>,
}
diff --git a/src/render/mod.rs b/src/render/mod.rs
@@ -8,8 +8,8 @@ use crate::domain::runtime::{
OrderHistoryView, OrderJobView, OrderListView, OrderNewView, OrderSubmitView, OrderWatchView,
RelayListView, RpcSessionsView, RpcStatusView, SyncActionView, SyncStatusView, SyncWatchView,
};
-use crate::runtime::RuntimeError;
use crate::runtime::config::{OutputConfig, OutputFormat};
+use crate::runtime::RuntimeError;
const THIN_RULE: &str = "────────────────────────────────────────────────────";
@@ -435,11 +435,19 @@ fn render_ndjson_to(stdout: &mut dyn Write, output: &CommandOutput) -> Result<()
}
fn yes_no(value: bool) -> &'static str {
- if value { "yes" } else { "no" }
+ if value {
+ "yes"
+ } else {
+ "no"
+ }
}
fn present_absent(value: bool) -> &'static str {
- if value { "present" } else { "absent" }
+ if value {
+ "present"
+ } else {
+ "absent"
+ }
}
fn render_account_list(stdout: &mut dyn Write, view: &AccountListView) -> Result<(), RuntimeError> {
@@ -548,7 +556,10 @@ fn render_config_show(
("secrets dir", view.account.secrets_dir.as_str()),
(
"contract default secret backend",
- view.account.secret_backend.contract_default_backend.as_str(),
+ view.account
+ .secret_backend
+ .contract_default_backend
+ .as_str(),
),
(
"configured secret backend",
@@ -1032,6 +1043,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(requested_signer_session_id) = &view.requested_signer_session_id {
+ rows.push((
+ "requested signer session",
+ requested_signer_session_id.as_str(),
+ ));
+ }
render_pairs(stdout, "order", rows.as_slice())?;
if let Some(job) = &view.job {
render_order_job(stdout, job)?;
@@ -1205,6 +1222,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(requested_signer_session_id) = &job.requested_signer_session_id {
+ rows.push((
+ "requested signer session",
+ requested_signer_session_id.as_str(),
+ ));
+ }
if let Some(event_id) = &job.event_id {
rows.push(("event id", event_id.as_str()));
}
@@ -1416,6 +1439,12 @@ fn render_listing_mutation(
if let Some(signer_mode) = &view.signer_mode {
rows.push(("signer", signer_mode.as_str()));
}
+ if let Some(requested_signer_session_id) = &view.requested_signer_session_id {
+ rows.push((
+ "requested signer session",
+ requested_signer_session_id.as_str(),
+ ));
+ }
render_pairs(stdout, "listing", rows.as_slice())?;
if let Some(reason) = &view.reason {
writeln!(stdout, "reason: {reason}")?;
@@ -2079,7 +2108,7 @@ fn human_command_name(view: &CommandView) -> &'static str {
#[cfg(test)]
mod tests {
- use super::{Table, render_human_to, render_ndjson_to, render_table};
+ use super::{render_human_to, render_ndjson_to, render_table, Table};
use crate::commands::runtime;
use crate::domain::runtime::{
AccountListView, CommandOutput, CommandView, DoctorCheckView, DoctorView, MycStatusView,
@@ -2184,19 +2213,20 @@ mod tests {
"/workspace/.radroots/config.toml"
);
assert_eq!(view.account.selector.as_deref(), Some("acct_demo"));
- assert!(
- view.account
- .store_path
- .ends_with(".radroots/data/shared/accounts/store.json")
- );
+ assert!(view
+ .account
+ .store_path
+ .ends_with(".radroots/data/shared/accounts/store.json"));
assert_eq!(view.relay.count, 2);
assert_eq!(view.relay.publish_policy, "any");
- assert_eq!(view.account.secret_backend.contract_default_backend, "host_vault");
- assert!(
- view.local
- .replica_db_path
- .ends_with(".radroots/data/apps/cli/replica/replica.sqlite")
+ assert_eq!(
+ view.account.secret_backend.contract_default_backend,
+ "host_vault"
);
+ assert!(view
+ .local
+ .replica_db_path
+ .ends_with(".radroots/data/apps/cli/replica/replica.sqlite"));
}
#[test]
@@ -2309,11 +2339,9 @@ mod tests {
));
let mut buffer = Vec::new();
let error = render_ndjson_to(&mut buffer, &output).expect_err("unsupported ndjson");
- assert!(
- error
- .to_string()
- .contains("`config show` does not support --ndjson")
- );
+ assert!(error
+ .to_string()
+ .contains("`config show` does not support --ndjson"));
}
#[test]
diff --git a/src/runtime/listing.rs b/src/runtime/listing.rs
@@ -7,7 +7,6 @@ use radroots_core::{
RadrootsCoreCurrency, RadrootsCoreDecimal, RadrootsCoreMoney, RadrootsCoreQuantity,
RadrootsCoreQuantityPrice, RadrootsCoreUnit,
};
-use radroots_events::RadrootsNostrEvent;
use radroots_events::kinds::{KIND_LISTING, KIND_LISTING_DRAFT};
use radroots_events::listing::{
RadrootsListing, RadrootsListingAvailability, RadrootsListingBin,
@@ -15,9 +14,10 @@ use radroots_events::listing::{
RadrootsListingProduct, RadrootsListingStatus,
};
use radroots_events::trade::RadrootsTradeListingValidationError;
+use radroots_events::RadrootsNostrEvent;
use radroots_events_codec::d_tag::is_d_tag_base64url;
use radroots_events_codec::listing::encode::to_wire_parts_with_kind;
-use radroots_sql_core::{SqlExecutor, SqliteExecutor, utils};
+use radroots_sql_core::{utils, SqlExecutor, SqliteExecutor};
use radroots_trade::listing::validation::validate_listing_event;
use serde::{Deserialize, Serialize};
use serde_json::Value;
@@ -28,12 +28,12 @@ use crate::domain::runtime::{
ListingMutationEventView, ListingMutationJobView, ListingMutationView, ListingNewView,
ListingValidateView, ListingValidationIssueView, SyncFreshnessView,
};
-use crate::runtime::RuntimeError;
use crate::runtime::accounts;
use crate::runtime::config::RuntimeConfig;
use crate::runtime::daemon;
use crate::runtime::daemon::DaemonRpcError;
use crate::runtime::sync::freshness_from_executor;
+use crate::runtime::RuntimeError;
const DRAFT_KIND: &str = "listing_draft_v1";
const LISTING_SOURCE: &str = "local draft · local first";
@@ -522,12 +522,14 @@ fn mutate(
event_id: None,
event_addr: Some(listing_addr.clone()),
idempotency_key: args.idempotency_key.clone(),
+ 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 {
rpc_method: "bridge.listing.publish".to_owned(),
state: "not_submitted".to_owned(),
job_id: None,
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()),
}),
event: args.print_event.then_some(event_preview),
@@ -584,6 +586,7 @@ fn mutate(
.clone()
.or_else(|| Some(listing_addr.clone())),
idempotency_key: result.idempotency_key.clone(),
+ requested_signer_session_id: args.signer_session_id.clone(),
reason: failed.then(|| {
"daemon publish job failed before relay delivery completed".to_owned()
}),
@@ -592,6 +595,7 @@ fn mutate(
state: result.status,
job_id: Some(result.job_id),
idempotency_key: result.idempotency_key,
+ requested_signer_session_id: args.signer_session_id.clone(),
signer_mode: Some(result.signer_mode),
}),
event: args.print_event.then(|| ListingMutationEventView {
@@ -974,12 +978,14 @@ fn daemon_error_view(
event_id: None,
event_addr: None,
idempotency_key: args.idempotency_key.clone(),
+ requested_signer_session_id: args.signer_session_id.clone(),
reason: Some(reason),
job: args.print_job.then(|| ListingMutationJobView {
rpc_method: "bridge.listing.publish".to_owned(),
state: "unconfigured".to_owned(),
job_id: None,
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()),
}),
event: args.print_event.then_some(event_preview),
@@ -1005,12 +1011,14 @@ fn daemon_error_view(
event_id: None,
event_addr: None,
idempotency_key: args.idempotency_key.clone(),
+ requested_signer_session_id: args.signer_session_id.clone(),
reason: Some(reason),
job: args.print_job.then(|| ListingMutationJobView {
rpc_method: "bridge.listing.publish".to_owned(),
state: "unavailable".to_owned(),
job_id: None,
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()),
}),
event: args.print_event.then_some(event_preview),
@@ -1035,12 +1043,14 @@ fn daemon_error_view(
event_id: None,
event_addr: None,
idempotency_key: args.idempotency_key.clone(),
+ requested_signer_session_id: args.signer_session_id.clone(),
reason: Some(reason),
job: args.print_job.then(|| ListingMutationJobView {
rpc_method: "bridge.listing.publish".to_owned(),
state: "error".to_owned(),
job_id: None,
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()),
}),
event: args.print_event.then_some(event_preview),
@@ -1288,7 +1298,7 @@ fn encode_base64url_no_pad(bytes: [u8; 16]) -> String {
#[cfg(test)]
mod tests {
- use super::{DRAFT_KIND, ListingDraftDocument, encode_base64url_no_pad, generate_d_tag};
+ use super::{encode_base64url_no_pad, generate_d_tag, ListingDraftDocument, DRAFT_KIND};
use radroots_events_codec::d_tag::is_d_tag_base64url;
#[test]
diff --git a/src/runtime/order.rs b/src/runtime/order.rs
@@ -16,10 +16,10 @@ use crate::domain::runtime::{
OrderIssueView, OrderJobView, OrderListView, OrderNewView, OrderSubmitView, OrderSummaryView,
OrderWatchFrameView, OrderWatchView,
};
-use crate::runtime::RuntimeError;
use crate::runtime::accounts;
use crate::runtime::config::RuntimeConfig;
use crate::runtime::daemon::{self, DaemonRpcError};
+use crate::runtime::RuntimeError;
const ORDER_DRAFT_KIND: &str = "order_draft_v1";
const ORDER_SOURCE: &str = "local order drafts · local first";
@@ -278,6 +278,7 @@ pub fn submit(
dry_run: false,
deduplicated: false,
idempotency_key: args.idempotency_key.clone(),
+ requested_signer_session_id: args.signer_session_id.clone(),
reason: Some(format!("order draft `{}` was not found", args.key)),
job: None,
issues: Vec::new(),
@@ -304,6 +305,7 @@ pub fn submit(
dry_run: false,
deduplicated: false,
idempotency_key: args.idempotency_key.clone(),
+ requested_signer_session_id: args.signer_session_id.clone(),
reason: Some(reason),
job: None,
issues: Vec::new(),
@@ -331,6 +333,7 @@ pub fn submit(
dry_run: false,
deduplicated: false,
idempotency_key: args.idempotency_key.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),
issues: Vec::new(),
@@ -358,6 +361,7 @@ pub fn submit(
dry_run: false,
deduplicated: false,
idempotency_key: args.idempotency_key.clone(),
+ requested_signer_session_id: args.signer_session_id.clone(),
reason: Some("order draft is not ready for durable submit".to_owned()),
job: None,
issues,
@@ -379,11 +383,13 @@ pub fn submit(
dry_run: true,
deduplicated: false,
idempotency_key: args.idempotency_key.clone(),
+ 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()),
+ requested_signer_session_id: args.signer_session_id.clone(),
event_id: None,
event_addr: None,
reason: None,
@@ -442,6 +448,7 @@ pub fn submit(
dry_run: false,
deduplicated: result.deduplicated,
idempotency_key: result.idempotency_key.clone(),
+ requested_signer_session_id: args.signer_session_id.clone(),
reason: failed.then(|| {
"daemon order request failed before relay delivery completed".to_owned()
}),
@@ -449,6 +456,7 @@ pub fn submit(
job_id: result.job_id,
state: result.status,
command: Some("order.submit".to_owned()),
+ requested_signer_session_id: args.signer_session_id.clone(),
event_id: result.event_id,
event_addr: result.event_addr,
reason: None,
@@ -1005,6 +1013,7 @@ fn submission_job_view(
job_id,
state: job.state,
command: Some(job.command),
+ requested_signer_session_id: None,
event_id: job.event_id,
event_addr: job.event_addr,
reason: None,
@@ -1013,6 +1022,7 @@ fn submission_job_view(
job_id,
state: "missing".to_owned(),
command: submission.command.clone(),
+ requested_signer_session_id: None,
event_id: submission.event_id.clone(),
event_addr: submission.event_addr.clone(),
reason: Some("recorded job id was not found in radrootsd".to_owned()),
@@ -1029,6 +1039,7 @@ fn recorded_job_view(submission: &OrderDraftSubmission, job_id: String) -> Order
.clone()
.unwrap_or_else(|| "recorded".to_owned()),
command: submission.command.clone(),
+ requested_signer_session_id: None,
event_id: submission.event_id.clone(),
event_addr: submission.event_addr.clone(),
reason: None,
@@ -1043,6 +1054,7 @@ fn job_view_from_error(job_id: String, error: DaemonRpcError) -> OrderJobView {
job_id,
state: "unconfigured".to_owned(),
command: None,
+ requested_signer_session_id: None,
event_id: None,
event_addr: None,
reason: Some(reason),
@@ -1051,6 +1063,7 @@ fn job_view_from_error(job_id: String, error: DaemonRpcError) -> OrderJobView {
job_id,
state: "unavailable".to_owned(),
command: None,
+ requested_signer_session_id: None,
event_id: None,
event_addr: None,
reason: Some(reason),
@@ -1061,6 +1074,7 @@ fn job_view_from_error(job_id: String, error: DaemonRpcError) -> OrderJobView {
job_id,
state: "error".to_owned(),
command: None,
+ requested_signer_session_id: None,
event_id: None,
event_addr: None,
reason: Some(reason),
@@ -1111,6 +1125,7 @@ fn order_submit_error_view(
dry_run: false,
deduplicated: false,
idempotency_key: args.idempotency_key.clone(),
+ requested_signer_session_id: args.signer_session_id.clone(),
reason: Some(reason),
job: None,
issues: Vec::new(),
@@ -1350,8 +1365,8 @@ impl From<OrderGetView> for OrderNewView {
#[cfg(test)]
mod tests {
use super::{
- ORDER_DRAFT_KIND, OrderDraft, OrderDraftDocument, OrderDraftItem, OrderDraftSubmission,
- next_order_id,
+ next_order_id, OrderDraft, OrderDraftDocument, OrderDraftItem, OrderDraftSubmission,
+ ORDER_DRAFT_KIND,
};
#[test]
diff --git a/tests/listing.rs b/tests/listing.rs
@@ -10,7 +10,7 @@ use std::time::Duration;
use assert_cmd::prelude::*;
use radroots_sql_core::{SqlExecutor, SqliteExecutor};
-use serde_json::{Value, json};
+use serde_json::{json, Value};
use tempfile::tempdir;
fn data_root(workdir: &Path) -> std::path::PathBuf {
@@ -334,6 +334,8 @@ fn listing_publish_and_update_use_durable_bridge_publish() {
"publish",
"--idempotency-key",
"publish-key",
+ "--signer-session-id",
+ "sess_publish_01",
"--print-job",
"--print-event",
draft_path.to_str().expect("draft path"),
@@ -349,6 +351,14 @@ fn listing_publish_and_update_use_durable_bridge_publish() {
assert_eq!(publish_json["event_id"], "event_listing_01");
assert_eq!(publish_json["event"]["kind"], 30402);
assert_eq!(publish_json["job"]["rpc_method"], "bridge.listing.publish");
+ assert_eq!(
+ publish_json["requested_signer_session_id"],
+ "sess_publish_01"
+ );
+ assert_eq!(
+ publish_json["job"]["requested_signer_session_id"],
+ "sess_publish_01"
+ );
let update_output = cli_command_in(dir.path())
.env("RADROOTS_RPC_URL", server.url())
@@ -441,6 +451,8 @@ fn listing_archive_and_dry_run_are_truthful() {
"--json",
"listing",
"archive",
+ "--signer-session-id",
+ "sess_archive_01",
draft_path.to_str().expect("draft path"),
])
.output()
@@ -450,6 +462,10 @@ 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["requested_signer_session_id"],
+ "sess_archive_01"
+ );
let dry_run_output = cli_command_in(dir.path())
.args([
@@ -457,6 +473,8 @@ fn listing_archive_and_dry_run_are_truthful() {
"--dry-run",
"listing",
"publish",
+ "--signer-session-id",
+ "sess_dry_run_01",
"--print-event",
"--print-job",
draft_path.to_str().expect("draft path"),
@@ -471,6 +489,14 @@ fn listing_archive_and_dry_run_are_truthful() {
assert_eq!(dry_run_json["job"]["state"], "not_submitted");
assert_eq!(dry_run_json["event"]["kind"], 30402);
assert!(dry_run_json["event"]["event_id"].is_null());
+ assert_eq!(
+ dry_run_json["requested_signer_session_id"],
+ "sess_dry_run_01"
+ );
+ assert_eq!(
+ dry_run_json["job"]["requested_signer_session_id"],
+ "sess_dry_run_01"
+ );
let recorded = requests.lock().expect("requests");
assert_eq!(recorded.len(), 1);
diff --git a/tests/order.rs b/tests/order.rs
@@ -507,6 +507,8 @@ fn order_submit_persists_submission_metadata_and_reports_job() {
order_id,
"--idempotency-key",
"order-submit-1",
+ "--signer-session-id",
+ "sess_order_01",
])
.output()
.expect("run order submit");
@@ -516,6 +518,11 @@ fn order_submit_persists_submission_metadata_and_reports_job() {
assert_eq!(submit_json["state"], "accepted");
assert_eq!(submit_json["job"]["job_id"], "job_order_01");
assert_eq!(submit_json["job"]["command"], "order.submit");
+ assert_eq!(submit_json["requested_signer_session_id"], "sess_order_01");
+ assert_eq!(
+ submit_json["job"]["requested_signer_session_id"],
+ "sess_order_01"
+ );
let contents = fs::read_to_string(file).expect("read updated order draft");
assert!(contents.contains("job_id = \"job_order_01\""));
@@ -523,16 +530,12 @@ fn order_submit_persists_submission_metadata_and_reports_job() {
assert!(contents.contains("command = \"order.submit\""));
let recorded_requests = requests.lock().expect("requests lock");
- assert!(
- recorded_requests
- .iter()
- .any(|request| request.method == "bridge.order.request")
- );
- assert!(
- recorded_requests
- .iter()
- .any(|request| { request.auth_header.as_deref() == Some("Bearer test-token") })
- );
+ assert!(recorded_requests
+ .iter()
+ .any(|request| request.method == "bridge.order.request"));
+ assert!(recorded_requests
+ .iter()
+ .any(|request| { request.auth_header.as_deref() == Some("Bearer test-token") }));
}
#[test]
@@ -693,10 +696,8 @@ command = "order.submit"
assert_eq!(output.status.code(), Some(3));
let json: Value = serde_json::from_slice(output.stdout.as_slice()).expect("cancel json");
assert_eq!(json["state"], "unconfigured");
- assert!(
- json["reason"]
- .as_str()
- .expect("cancel reason")
- .contains("trade-chain")
- );
+ assert!(json["reason"]
+ .as_str()
+ .expect("cancel reason")
+ .contains("trade-chain"));
}