1use clap::{arg, Parser};
2use std::{fmt::Display, str::FromStr};
3
4#[derive(Debug, Clone)]
5pub struct HexString(pub Vec<u8>);
6
7impl FromStr for HexString {
8 type Err = hex::FromHexError;
9
10 fn from_str(s: &str) -> Result<Self, Self::Err> {
11 let stripped = s.strip_prefix("0x").unwrap_or(s);
12 Ok(HexString(hex::decode(stripped)?))
13 }
14}
15
16impl Display for HexString {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 write!(f, "0x{}", hex::encode(&self.0))
19 }
20}
21
22#[derive(Parser)]
23pub struct EncodeFileArgs {
24 #[arg(long, short = 'i', value_name = "FILE", help = "input file")]
25 pub input: String,
26
27 #[arg(
28 long,
29 short = 'o',
30 value_name = "FILE",
31 help = "output file (blob, encoded as field elements)"
32 )]
33 pub output: String,
34
35 #[arg(long = "srs-filepath", value_name = "SRS_FILEPATH")]
36 pub srs_cache: Option<String>,
37
38 #[arg(
39 long = "assert-commitment",
40 value_name = "COMMITMENT",
41 help = "hash of commitments (hex encoded)"
42 )]
43 pub assert_commitment: Option<HexString>,
44
45 #[arg(
46 long = "challenge-seed",
47 value_name = "CHALLENGE_SEED",
48 help = "challenge seed (hex encoded, used only if assert-commitment is provided)"
49 )]
50 pub challenge_seed: Option<HexString>,
51}
52
53#[derive(Parser)]
54pub struct DecodeFileArgs {
55 #[arg(
56 long,
57 short = 'i',
58 value_name = "FILE",
59 help = "input file (encoded as field elements)"
60 )]
61 pub input: String,
62
63 #[arg(long, short = 'o', value_name = "FILE", help = "output file")]
64 pub output: String,
65
66 #[arg(long = "srs-filepath", value_name = "SRS_FILEPATH")]
67 pub srs_cache: Option<String>,
68
69 #[arg(long = "truncate-to-bytes", value_name = "TRUNCATE_TO_BYTES")]
70 pub truncate_to_bytes: Option<u64>,
71}
72
73#[derive(Parser)]
74pub struct ComputeCommitmentArgs {
75 #[arg(long, short = 'i', value_name = "FILE", help = "input file")]
76 pub input: String,
77
78 #[arg(long, short = 'o', value_name = "FILE", help = "output file")]
79 pub output: String,
80
81 #[arg(long = "srs-filepath", value_name = "SRS_FILEPATH")]
82 pub srs_cache: Option<String>,
83
84 #[arg(
85 long = "challenge-seed",
86 value_name = "CHALLENGE_SEED",
87 help = "challenge seed (hex encoded)"
88 )]
89 pub challenge_seed: HexString,
90}
91
92#[derive(Parser)]
93pub struct StorageProofArgs {
94 #[arg(
95 long,
96 short = 'i',
97 value_name = "FILE",
98 help = "input file (blob, encoded as field elements)"
99 )]
100 pub input: String,
101
102 #[arg(long = "srs-filepath", value_name = "SRS_FILEPATH")]
103 pub srs_cache: Option<String>,
104
105 #[arg(
106 long = "challenge-seed",
107 value_name = "CHALLENGE_SEED",
108 help = "challenge seed (hex encoded)"
109 )]
110 pub challenge_seed: HexString,
111}
112
113#[derive(Parser)]
114pub struct VerifyStorageProofArgs {
115 #[arg(long = "srs-filepath", value_name = "SRS_FILEPATH")]
116 pub srs_cache: Option<String>,
117
118 #[arg(
119 long,
120 short = 'c',
121 value_name = "COMMITMENT",
122 help = "commitment (hex encoded)"
123 )]
124 pub commitment: HexString,
125
126 #[arg(
127 long = "challenge-seed",
128 value_name = "CHALLENGE_SEED",
129 help = "challenge seed (hex encoded)"
130 )]
131 pub challenge_seed: HexString,
132
133 #[arg(long, short = 'p', value_name = "PROOF", help = "proof (hex encoded)")]
134 pub proof: HexString,
135}
136
137#[derive(Parser)]
138#[command(
139 name = "saffron",
140 version = "0.1",
141 about = "saffron - a mutable state layer"
142)]
143pub enum Commands {
144 #[command(name = "encode")]
145 Encode(EncodeFileArgs),
146 #[command(name = "decode")]
147 Decode(DecodeFileArgs),
148 #[command(name = "compute-commitment")]
149 ComputeCommitment(ComputeCommitmentArgs),
150 #[command(name = "storage-proof")]
151 StorageProof(StorageProofArgs),
152 #[command(name = "verify-storage-proof")]
153 VerifyStorageProof(VerifyStorageProofArgs),
154}