auths_cli/commands/
keri_emit.rs1use anyhow::{Result, anyhow};
13use auths_keri::{
14 CesrKey, DipEvent, DipEventInit, Event, IxnEvent, KeriSequence, Prefix, Said, Seal, Threshold,
15 VersionString, finalize_dip_event, finalize_ixn_event,
16};
17use clap::Parser;
18
19use crate::config::CliConfig;
20
21#[derive(Parser, Debug, Clone)]
23#[command(
24 about = "Emit a raw KERI event (dip/ixn) as JSON from deterministic inputs (interop surface)",
25 after_help = "Examples:
26 auths keri-emit dip --key DA... --delegator EAbc... [--next EN...]
27 auths keri-emit ixn --pre EAbc... --sn 1 --prev EPrev... --seal-digest EDev..."
28)]
29pub struct KeriEmitCommand {
30 #[command(subcommand)]
31 pub kind: KeriEmitKind,
32}
33
34#[derive(clap::Subcommand, Debug, Clone)]
36pub enum KeriEmitKind {
37 Dip(DipArgs),
39 Ixn(IxnArgs),
41}
42
43#[derive(Parser, Debug, Clone)]
45pub struct DipArgs {
46 #[clap(long, value_name = "CESR")]
48 pub key: String,
49 #[clap(long, value_name = "PREFIX")]
51 pub delegator: String,
52 #[clap(long, value_name = "SAID")]
54 pub next: Option<String>,
55}
56
57#[derive(Parser, Debug, Clone)]
59pub struct IxnArgs {
60 #[clap(long, value_name = "PREFIX")]
62 pub pre: String,
63 #[clap(long)]
65 pub sn: u64,
66 #[clap(long, value_name = "SAID")]
68 pub prev: String,
69 #[clap(long, value_name = "SAID")]
71 pub seal_digest: String,
72}
73
74impl KeriEmitCommand {
75 pub fn execute(&self, _ctx: &CliConfig) -> Result<()> {
77 let json = match &self.kind {
78 KeriEmitKind::Dip(args) => emit_dip(args)?,
79 KeriEmitKind::Ixn(args) => emit_ixn(args)?,
80 };
81 println!("{json}");
82 Ok(())
83 }
84}
85
86fn emit_dip(args: &DipArgs) -> Result<String> {
88 let (nt, n) = match &args.next {
89 Some(next) => (
90 Threshold::Simple(1),
91 vec![Said::new_unchecked(next.clone())],
92 ),
93 None => (Threshold::Simple(0), vec![]),
94 };
95 let dip = finalize_dip_event(DipEvent::new(DipEventInit {
96 v: VersionString::placeholder(),
97 d: Said::default(),
98 i: Prefix::default(),
99 s: KeriSequence::new(0),
100 kt: Threshold::Simple(1),
101 k: vec![CesrKey::new_unchecked(args.key.clone())],
102 nt,
103 n,
104 bt: Threshold::Simple(0),
105 b: vec![],
106 c: vec![],
107 a: vec![],
108 di: Prefix::new_unchecked(args.delegator.clone()),
109 }))
110 .map_err(|e| anyhow!("finalize dip: {e}"))?;
111 serde_json::to_string(&Event::Dip(dip)).map_err(|e| anyhow!("serialize dip: {e}"))
112}
113
114fn emit_ixn(args: &IxnArgs) -> Result<String> {
116 let ixn = finalize_ixn_event(IxnEvent {
117 v: VersionString::placeholder(),
118 d: Said::default(),
119 i: Prefix::new_unchecked(args.pre.clone()),
120 s: KeriSequence::new(args.sn as u128),
121 p: Said::new_unchecked(args.prev.clone()),
122 a: vec![Seal::Digest {
123 d: Said::new_unchecked(args.seal_digest.clone()),
124 }],
125 })
126 .map_err(|e| anyhow!("finalize ixn: {e}"))?;
127 serde_json::to_string(&Event::Ixn(ixn)).map_err(|e| anyhow!("serialize ixn: {e}"))
128}