Skip to main content

bsv_wallet_cli/server/
types.rs

1use serde::{Deserialize, Serialize};
2
3/// MetaNet Client request for getPublicKey
4#[derive(Deserialize)]
5#[serde(rename_all = "camelCase")]
6pub struct McGetPublicKeyReq {
7    #[serde(default)]
8    pub identity_key: bool,
9    #[serde(default, alias = "protocolID")]
10    pub protocol_id: Option<serde_json::Value>,
11    #[serde(default, alias = "keyID")]
12    pub key_id: Option<String>,
13    #[serde(default)]
14    pub counterparty: Option<String>,
15    #[serde(default)]
16    pub for_self: Option<bool>,
17}
18
19/// MetaNet Client response for getPublicKey
20#[derive(Serialize)]
21#[serde(rename_all = "camelCase")]
22pub struct McGetPublicKeyRes {
23    pub public_key: String,
24}
25
26/// MetaNet Client request for createSignature
27#[derive(Deserialize)]
28#[serde(rename_all = "camelCase")]
29pub struct McCreateSignatureReq {
30    /// Raw data to hash-then-sign. Mutually exclusive with
31    /// `hash_to_directly_sign` (ts-sdk sends exactly one of the two).
32    #[serde(default)]
33    pub data: Option<Vec<u8>>,
34    /// A 32-byte digest to sign as-is (ts-sdk `hashToDirectlySign`).
35    #[serde(default)]
36    pub hash_to_directly_sign: Option<Vec<u8>>,
37    #[serde(alias = "protocolID")]
38    pub protocol_id: serde_json::Value,
39    #[serde(alias = "keyID")]
40    pub key_id: String,
41    pub counterparty: String,
42}
43
44/// MetaNet Client response for createSignature
45#[derive(Serialize)]
46pub struct McCreateSignatureRes {
47    pub signature: Vec<u8>,
48}
49
50/// MetaNet Client request for createAction
51#[derive(Deserialize)]
52#[serde(rename_all = "camelCase")]
53pub struct McCreateActionReq {
54    pub description: String,
55    /// Caller-provided explicit inputs (covenant spends carry a full
56    /// unlockingScript). Absent/empty => wallet auto-selects its own UTXOs.
57    #[serde(default)]
58    pub inputs: Option<Vec<McCreateActionInput>>,
59    /// BEEF (Byte[]) of the input transactions' source txs/ancestry, so the
60    /// wallet can validate explicit external inputs. `@bsv/sdk` sends this key
61    /// as `inputBEEF` (not camelCase `inputBeef`), as a raw JSON byte array.
62    #[serde(default, rename = "inputBEEF")]
63    pub input_beef: Option<Vec<u8>>,
64    #[serde(default)]
65    pub outputs: Option<Vec<McCreateActionOutput>>,
66    /// nLockTime for the spending tx (required by CLTV-gated covenants).
67    #[serde(default)]
68    pub lock_time: Option<u32>,
69    #[serde(default)]
70    pub options: Option<McCreateActionOptions>,
71    #[serde(default)]
72    pub labels: Option<Vec<String>>,
73}
74
75/// A single caller-provided input for createAction.
76#[derive(Deserialize)]
77#[serde(rename_all = "camelCase")]
78pub struct McCreateActionInput {
79    /// "txid.vout"
80    pub outpoint: String,
81    /// Fully-provided unlocking script (hex). Use this OR unlocking_script_length.
82    #[serde(default)]
83    pub unlocking_script: Option<String>,
84    /// Length of a to-be-signed unlocking script (deferred-signing flow).
85    #[serde(default)]
86    pub unlocking_script_length: Option<u32>,
87    #[serde(default)]
88    pub input_description: Option<String>,
89    /// nSequence for this input (e.g. 0xfffffffe to make a covenant timeLock non-final).
90    #[serde(default)]
91    pub sequence_number: Option<u32>,
92}
93
94#[derive(Deserialize)]
95#[serde(rename_all = "camelCase")]
96pub struct McCreateActionOutput {
97    pub locking_script: String,
98    pub satoshis: u64,
99    pub output_description: String,
100    #[serde(default)]
101    pub basket: Option<String>,
102    #[serde(default)]
103    pub custom_instructions: Option<String>,
104    #[serde(default)]
105    pub tags: Option<Vec<String>>,
106}
107
108#[derive(Deserialize)]
109#[serde(rename_all = "camelCase")]
110pub struct McCreateActionOptions {
111    #[serde(default)]
112    pub accept_delayed_broadcast: Option<bool>,
113    #[serde(default)]
114    pub randomize_outputs: Option<bool>,
115    #[serde(default)]
116    pub sign_and_process: Option<bool>,
117    #[serde(default)]
118    pub no_send: Option<bool>,
119    /// "known" => input source txs may omit validity proofs for TXIDs the wallet
120    /// already knows (needed when spending a self-created covenant output whose
121    /// inputBEEF is proof-incomplete).
122    #[serde(default)]
123    pub trust_self: Option<String>,
124}
125
126/// MetaNet Client response for createAction
127#[derive(Serialize)]
128#[serde(rename_all = "camelCase")]
129pub struct McCreateActionRes {
130    #[serde(skip_serializing_if = "Option::is_none")]
131    pub txid: Option<String>,
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub tx: Option<Vec<u8>>,
134    #[serde(skip_serializing_if = "Option::is_none")]
135    pub send_with_results: Option<serde_json::Value>,
136    /// For signAndProcess: false — contains the unsigned tx and reference for signAction/abortAction.
137    #[serde(skip_serializing_if = "Option::is_none")]
138    pub signable_transaction: Option<McSignableTransaction>,
139    /// Change outpoints for noSend transactions.
140    #[serde(skip_serializing_if = "Option::is_none")]
141    pub no_send_change: Option<serde_json::Value>,
142    /// The doors' word when the immediate post drew no accepting word
143    /// (`built`, the request's status, the toolbox's hint, the inputs
144    /// `locked`); absent when a broadcaster took it. See
145    /// [`crate::server::post_word`].
146    #[serde(skip_serializing_if = "Option::is_none")]
147    pub broadcast: Option<crate::server::post_word::PostWord>,
148}
149
150/// signAction response, in the SAME wire shape as `McCreateActionRes`:
151/// `tx` is AtomicBEEF as a plain number array. The toolbox's own
152/// `SignActionResult` serde hex-encodes byte fields, which no BRC-100 client
153/// expects (MetaNet and the TS toolbox both send number arrays); passing that
154/// struct straight to `Json(...)` handed callers a hex STRING they then read
155/// as bytes and failed to parse — after the transaction had already broadcast.
156#[derive(Serialize)]
157#[serde(rename_all = "camelCase")]
158pub struct McSignActionRes {
159    #[serde(skip_serializing_if = "Option::is_none")]
160    pub txid: Option<String>,
161    #[serde(skip_serializing_if = "Option::is_none")]
162    pub tx: Option<Vec<u8>>,
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub send_with_results: Option<serde_json::Value>,
165    /// The doors' word when the immediate post drew no accepting word
166    /// (`built`, the request's status, the toolbox's hint, the inputs
167    /// `locked`); absent when a broadcaster took it. See
168    /// [`crate::server::post_word`].
169    #[serde(skip_serializing_if = "Option::is_none")]
170    pub broadcast: Option<crate::server::post_word::PostWord>,
171}
172
173/// Unsigned transaction + reference for deferred signing flow.
174#[derive(Serialize)]
175#[serde(rename_all = "camelCase")]
176pub struct McSignableTransaction {
177    /// The unsigned transaction bytes (number array).
178    pub tx: Vec<u8>,
179    /// The reference string for signAction/abortAction.
180    /// NOTE: The SDK stores this as Vec<u8> (from String.into_bytes()) then hex-encodes it.
181    /// We reverse that: convert bytes back to the original String so signAction/abortAction
182    /// can look it up correctly in the wallet's pending transaction cache.
183    pub reference: String,
184}
185
186/// MetaNet Client request for internalizeAction
187#[derive(Deserialize)]
188#[serde(rename_all = "camelCase")]
189pub struct McInternalizeActionReq {
190    pub tx: Vec<u8>,
191    pub outputs: Vec<McInternalizeOutput>,
192    pub description: String,
193    #[serde(default)]
194    pub labels: Option<Vec<String>>,
195}
196
197#[derive(Deserialize)]
198#[serde(rename_all = "camelCase")]
199pub struct McInternalizeOutput {
200    pub output_index: u32,
201    pub protocol: String,
202    #[serde(default)]
203    pub payment_remittance: Option<McWalletPayment>,
204    #[serde(default)]
205    pub insertion_remittance: Option<McBasketInsertion>,
206}
207
208#[derive(Deserialize)]
209#[serde(rename_all = "camelCase")]
210pub struct McBasketInsertion {
211    pub basket: String,
212    #[serde(default)]
213    pub custom_instructions: Option<String>,
214    #[serde(default)]
215    pub tags: Option<Vec<String>>,
216}
217
218#[derive(Deserialize)]
219#[serde(rename_all = "camelCase")]
220pub struct McWalletPayment {
221    pub derivation_prefix: String,
222    pub derivation_suffix: String,
223    pub sender_identity_key: String,
224}
225
226/// MetaNet Client response for internalizeAction
227#[derive(Serialize)]
228pub struct McInternalizeActionRes {
229    pub accepted: bool,
230    /// The doors' word when the immediate post drew no accepting word
231    /// (`built`, the request's status, the toolbox's hint, the inputs
232    /// `locked`); absent when a broadcaster took it. See
233    /// [`crate::server::post_word`].
234    #[serde(skip_serializing_if = "Option::is_none")]
235    pub broadcast: Option<crate::server::post_word::PostWord>,
236}
237
238// =============================================================================
239// Batch 3: Crypto request types (SDK args lack serde)
240// =============================================================================
241
242/// MetaNet Client request for verifySignature
243#[derive(Deserialize)]
244#[serde(rename_all = "camelCase")]
245pub struct McVerifySignatureReq {
246    #[serde(default)]
247    pub data: Option<Vec<u8>>,
248    pub signature: Vec<u8>,
249    #[serde(alias = "protocolID")]
250    pub protocol_id: serde_json::Value,
251    #[serde(alias = "keyID")]
252    pub key_id: String,
253    #[serde(default)]
254    pub counterparty: Option<String>,
255    #[serde(default)]
256    pub for_self: Option<bool>,
257}
258
259/// MetaNet Client request for encrypt
260#[derive(Deserialize)]
261#[serde(rename_all = "camelCase")]
262pub struct McEncryptReq {
263    pub plaintext: Vec<u8>,
264    #[serde(alias = "protocolID")]
265    pub protocol_id: serde_json::Value,
266    #[serde(alias = "keyID")]
267    pub key_id: String,
268    #[serde(default)]
269    pub counterparty: Option<String>,
270}
271
272/// MetaNet Client request for decrypt
273#[derive(Deserialize)]
274#[serde(rename_all = "camelCase")]
275pub struct McDecryptReq {
276    pub ciphertext: Vec<u8>,
277    #[serde(alias = "protocolID")]
278    pub protocol_id: serde_json::Value,
279    #[serde(alias = "keyID")]
280    pub key_id: String,
281    #[serde(default)]
282    pub counterparty: Option<String>,
283}
284
285/// MetaNet Client request for createHmac
286#[derive(Deserialize)]
287#[serde(rename_all = "camelCase")]
288pub struct McCreateHmacReq {
289    pub data: Vec<u8>,
290    #[serde(alias = "protocolID")]
291    pub protocol_id: serde_json::Value,
292    #[serde(alias = "keyID")]
293    pub key_id: String,
294    #[serde(default)]
295    pub counterparty: Option<String>,
296}
297
298/// MetaNet Client request for verifyHmac
299#[derive(Deserialize)]
300#[serde(rename_all = "camelCase")]
301pub struct McVerifyHmacReq {
302    pub data: Vec<u8>,
303    pub hmac: Vec<u8>,
304    #[serde(alias = "protocolID")]
305    pub protocol_id: serde_json::Value,
306    #[serde(alias = "keyID")]
307    pub key_id: String,
308    #[serde(default)]
309    pub counterparty: Option<String>,
310}
311
312// =============================================================================
313// Batch 6: Key linkage request types (SDK args lack serde)
314// =============================================================================
315
316/// MetaNet Client request for revealCounterpartyKeyLinkage
317#[derive(Deserialize)]
318#[serde(rename_all = "camelCase")]
319pub struct McRevealCounterpartyKeyLinkageReq {
320    pub counterparty: String,
321    pub verifier: String,
322    #[serde(default)]
323    pub privileged: Option<bool>,
324    #[serde(default)]
325    pub privileged_reason: Option<String>,
326}
327
328/// MetaNet Client request for revealSpecificKeyLinkage
329#[derive(Deserialize)]
330#[serde(rename_all = "camelCase")]
331pub struct McRevealSpecificKeyLinkageReq {
332    pub counterparty: String,
333    pub verifier: String,
334    #[serde(alias = "protocolID")]
335    pub protocol_id: serde_json::Value,
336    #[serde(alias = "keyID")]
337    pub key_id: String,
338    #[serde(default)]
339    pub privileged: Option<bool>,
340    #[serde(default)]
341    pub privileged_reason: Option<String>,
342}