use anyhow::{Result, anyhow};
use auths_keri::{
CesrKey, DipEvent, DipEventInit, Event, IxnEvent, KeriSequence, Prefix, Said, Seal, Threshold,
VersionString, finalize_dip_event, finalize_ixn_event,
};
use clap::Parser;
use crate::config::CliConfig;
#[derive(Parser, Debug, Clone)]
#[command(
about = "Emit a raw KERI event (dip/ixn) as JSON from deterministic inputs (interop surface)",
after_help = "Examples:
auths keri-emit dip --key DA... --delegator EAbc... [--next EN...]
auths keri-emit ixn --pre EAbc... --sn 1 --prev EPrev... --seal-digest EDev..."
)]
pub struct KeriEmitCommand {
#[command(subcommand)]
pub kind: KeriEmitKind,
}
#[derive(clap::Subcommand, Debug, Clone)]
pub enum KeriEmitKind {
Dip(DipArgs),
Ixn(IxnArgs),
}
#[derive(Parser, Debug, Clone)]
pub struct DipArgs {
#[clap(long, value_name = "CESR")]
pub key: String,
#[clap(long, value_name = "PREFIX")]
pub delegator: String,
#[clap(long, value_name = "SAID")]
pub next: Option<String>,
}
#[derive(Parser, Debug, Clone)]
pub struct IxnArgs {
#[clap(long, value_name = "PREFIX")]
pub pre: String,
#[clap(long)]
pub sn: u64,
#[clap(long, value_name = "SAID")]
pub prev: String,
#[clap(long, value_name = "SAID")]
pub seal_digest: String,
}
impl KeriEmitCommand {
pub fn execute(&self, _ctx: &CliConfig) -> Result<()> {
let json = match &self.kind {
KeriEmitKind::Dip(args) => emit_dip(args)?,
KeriEmitKind::Ixn(args) => emit_ixn(args)?,
};
println!("{json}");
Ok(())
}
}
fn emit_dip(args: &DipArgs) -> Result<String> {
let (nt, n) = match &args.next {
Some(next) => (
Threshold::Simple(1),
vec![Said::new_unchecked(next.clone())],
),
None => (Threshold::Simple(0), vec![]),
};
let dip = finalize_dip_event(DipEvent::new(DipEventInit {
v: VersionString::placeholder(),
d: Said::default(),
i: Prefix::default(),
s: KeriSequence::new(0),
kt: Threshold::Simple(1),
k: vec![CesrKey::new_unchecked(args.key.clone())],
nt,
n,
bt: Threshold::Simple(0),
b: vec![],
c: vec![],
a: vec![],
di: Prefix::new_unchecked(args.delegator.clone()),
}))
.map_err(|e| anyhow!("finalize dip: {e}"))?;
serde_json::to_string(&Event::Dip(dip)).map_err(|e| anyhow!("serialize dip: {e}"))
}
fn emit_ixn(args: &IxnArgs) -> Result<String> {
let ixn = finalize_ixn_event(IxnEvent {
v: VersionString::placeholder(),
d: Said::default(),
i: Prefix::new_unchecked(args.pre.clone()),
s: KeriSequence::new(args.sn as u128),
p: Said::new_unchecked(args.prev.clone()),
a: vec![Seal::Digest {
d: Said::new_unchecked(args.seal_digest.clone()),
}],
})
.map_err(|e| anyhow!("finalize ixn: {e}"))?;
serde_json::to_string(&Event::Ixn(ixn)).map_err(|e| anyhow!("serialize ixn: {e}"))
}