diff --git a/app-sdk/src/curve.rs b/app-sdk/src/curve.rs index 50e7f7d..5b6e4e0 100644 --- a/app-sdk/src/curve.rs +++ b/app-sdk/src/curve.rs @@ -229,6 +229,16 @@ where } } +impl AsRef> + for EcfpPublicKey +where + C: Curve, +{ + fn as_ref(&self) -> &Point { + &self.public_key + } +} + pub struct EcfpPrivateKey where C: Curve, @@ -546,10 +556,7 @@ mod tests { let signature = privkey.ecdsa_sign_hash(&msg_hash).unwrap(); - println!("Signature: {:?}", signature); - let pubkey = privkey.to_public_key(); - println!("Public key: {:?}", pubkey.public_key.to_bytes()); pubkey.ecdsa_verify_hash(&msg_hash, &signature).unwrap(); } @@ -564,11 +571,8 @@ mod tests { let msg = "If you don't believe me or don't get it, I don't have time to try to convince you, sorry."; let signature = privkey.schnorr_sign(msg.as_bytes()).unwrap(); - println!("Signature: {:?}", signature); let pubkey = privkey.to_public_key(); pubkey.schnorr_verify(msg.as_bytes(), &signature).unwrap(); - - println!("pubkey: {:?}", pubkey.public_key.to_bytes()); } } diff --git a/apps/bitcoin/README.md b/apps/bitcoin/README.md index 51f0351..eccda9a 100644 --- a/apps/bitcoin/README.md +++ b/apps/bitcoin/README.md @@ -1,7 +1,8 @@ -This is a test V-App, with a few simple computations and functionalities to test various aspects of the Vanadium VM. +This is the Bitcoin app for Vanadium. It is composed of the following crates: -- [app](app) contains the Risc-V app, based on the V-app Sdk. -- [client](client) folder contains the client of the app, based on the V-app Client Sdk. +- [app](app) contains the V-app. +- [client](client) contains the client of the V-app. +- [common](common) contains the code shared between the V-App and the client. The `client` is a library crate (see [lib.rs](client/src/lib.rs)), but it also has a test executable ([main.rs](client/src/main.rs)) to interact with the app from the command line. @@ -50,12 +51,4 @@ If you want to run the V-app natively, after building it for the native target, ### Client commands -Once the client is running, these are the available commands: - -- `reverse ` - Reverses the given buffer. -- `sha256 ` - Computes the sha256 hash of the given buffer. -- `b58enc ` - Computes the base58 encoding of the given buffer (the output is in hex as well). -- `addnumbers ` - Computes the sum of the numbers between `1` and `n`. -- `nprimes ` - Counts the number of primes up to `n` using the Sieve of Eratosthenes. -- `panic ` - Cause the V-App to panic. Everything written after 'panic' is the panic message. -- An empty command will exit the V-App. +TODO diff --git a/apps/bitcoin/app/Cargo.toml b/apps/bitcoin/app/Cargo.toml index ef82833..7fac292 100644 --- a/apps/bitcoin/app/Cargo.toml +++ b/apps/bitcoin/app/Cargo.toml @@ -8,4 +8,7 @@ common = { package = "vnd-bitcoin-common", path = "../common"} quick-protobuf = { version = "0.8.1", default-features = false } sdk = { package = "vanadium-app-sdk", path = "../../../app-sdk"} +[dev-dependencies] +bs58 = { version = "0.5.1"} + [workspace] diff --git a/apps/bitcoin/app/src/handlers/get_extended_pubkey.rs b/apps/bitcoin/app/src/handlers/get_extended_pubkey.rs new file mode 100644 index 0000000..2e32069 --- /dev/null +++ b/apps/bitcoin/app/src/handlers/get_extended_pubkey.rs @@ -0,0 +1,156 @@ +use std::borrow::Cow; + +use common::message::{RequestGetExtendedPubkey, ResponseGetExtendedPubkey}; +use sdk::{ + curve::{Curve, EcfpPrivateKey, EcfpPublicKey, Secp256k1, ToPublicKey}, + hash::{Hasher, Ripemd160, Sha256}, +}; + +const BIP32_TESTNET_PUBKEY_VERSION: u32 = 0x043587CFu32; + +fn get_pubkey_fingerprint(pubkey: &EcfpPublicKey) -> u32 { + let pk_bytes = pubkey.as_ref().to_bytes(); + let mut sha256hasher = Sha256::new(); + sha256hasher.update(&[pk_bytes[64] % 2 + 0x02]); + sha256hasher.update(&pk_bytes[1..33]); + let mut sha256 = [0u8; 32]; + sha256hasher.digest(&mut sha256); + + let hash = Ripemd160::hash(&sha256); + + u32::from_be_bytes([hash[0], hash[1], hash[2], hash[3]]) +} + +pub fn handle_get_extended_pubkey<'a, 'b>( + req: &'a RequestGetExtendedPubkey, +) -> Result, &'static str> { + if req.bip32_path.len() > 256 { + return Err("Derivation path is too long"); + } + + if req.display { + todo!("Display is not yet implemented") + } + + let hd_node = sdk::curve::Secp256k1::derive_hd_node(&req.bip32_path)?; + let privkey: EcfpPrivateKey = EcfpPrivateKey::new(*hd_node.privkey); + let pubkey = privkey.to_public_key(); + let pubkey_bytes = pubkey.as_ref().to_bytes(); + + let depth = req.bip32_path.len() as u8; + + let parent_fpr: u32 = if req.bip32_path.is_empty() { + 0 + } else { + let hd_node = + sdk::curve::Secp256k1::derive_hd_node(&req.bip32_path[..req.bip32_path.len() - 1])?; + let parent_privkey: EcfpPrivateKey = EcfpPrivateKey::new(*hd_node.privkey); + let parent_pubkey = parent_privkey.to_public_key(); + get_pubkey_fingerprint(&parent_pubkey) + }; + + let child_number: u32 = if req.bip32_path.is_empty() { + 0 + } else { + req.bip32_path[req.bip32_path.len() - 1] + }; + + let mut xpub = Vec::with_capacity(78); + xpub.extend_from_slice(&BIP32_TESTNET_PUBKEY_VERSION.to_be_bytes()); + xpub.push(depth); + xpub.extend_from_slice(&parent_fpr.to_be_bytes()); + xpub.extend_from_slice(&child_number.to_be_bytes()); + xpub.extend_from_slice(&hd_node.chaincode); + xpub.push(pubkey_bytes[64] % 2 + 0x02); + xpub.extend_from_slice(&pubkey_bytes[1..33]); + + Ok(ResponseGetExtendedPubkey { + pubkey: Cow::Owned(xpub), + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use bs58; + + use std::num::ParseIntError; + + // TODO: this should be implemented and tested elsewhere + /// Parse a Bitcoin-style derivation path (e.g., "m/48'/1'/4'/1'/0/7") into a list of + /// child indices as `u32`. Hardened indices are marked by an apostrophe (`'`). + pub fn parse_derivation_path(path: &str) -> Result, String> { + // Split by '/' to get each component. e.g. "m/48'/1'/4'/1'/0/7" -> ["m", "48'", "1'", "4'", "1'", "0", "7"] + let mut components = path.split('/').collect::>(); + + // The first component should be "m". Remove it if present. + if let Some(first) = components.first() { + if *first == "m" { + components.remove(0); + } + } + + let mut indices = Vec::new(); + for comp in components { + // Check if this component is hardened + let hardened = comp.ends_with('\''); + + // Remove the apostrophe if hardened + let raw_index = if hardened { + &comp[..comp.len() - 1] + } else { + comp + }; + + // Parse the numeric portion + let index: u32 = raw_index.parse::().map_err(|e: ParseIntError| { + format!("Invalid derivation index '{}': {}", comp, e) + })?; + + // If hardened, add the 0x80000000 mask + let child_number = if hardened { + 0x80000000_u32 + .checked_add(index) + .ok_or_else(|| format!("Invalid hardened index '{}': overflowed", comp))? + } else { + index + }; + + indices.push(child_number); + } + + Ok(indices) + } + + #[test] + fn test_handle_get_extended_pubkey() { + let testcases = vec![ + ("m/44'/1'/0'", "tpubDCwYjpDhUdPGP5rS3wgNg13mTrrjBuG8V9VpWbyptX6TRPbNoZVXsoVUSkCjmQ8jJycjuDKBb9eataSymXakTTaGifxR6kmVsfFehH1ZgJT"), + ("m/44'/1'/10'", "tpubDCwYjpDhUdPGp21gSpVay2QPJVh6WNySWMXPhbcu1DsxH31dF7mY18oibbu5RxCLBc1Szerjscuc3D5HyvfYqfRvc9mesewnFqGmPjney4d"), + ("m/44'/1'/2'/1/42", "tpubDGF9YgHKv6qh777rcqVhpmDrbNzgophJM9ec7nHiSfrbss7fVBXoqhmZfohmJSvhNakDHAspPHjVVNL657tLbmTXvSeGev2vj5kzjMaeupT"), + ("m/48'/1'/4'/1'/0/7", "tpubDK8WPFx4WJo1R9mEL7Wq325wBiXvkAe8ipgb9Q1QBDTDUD2YeCfutWtzY88NPokZqJyRPKHLGwTNLT7jBG59aC6VH8q47LDGQitPB6tX2d7"), + ("m/49'/1'/1'/1/3", "tpubDGnetmJDCL18TyaaoyRAYbkSE9wbHktSdTS4mfsR6inC8c2r6TjdBt3wkqEQhHYPtXpa46xpxDaCXU2PRNUGVvDzAHPG6hHRavYbwAGfnFr"), + ("m/84'/1'/2'/0/10", "tpubDG9YpSUwScWJBBSrhnAT47NcT4NZGLcY18cpkaiWHnkUCi19EtCh8Heeox268NaFF6o56nVeSXuTyK6jpzTvV1h68Kr3edA8AZp27MiLUNt"), + ("m/86'/1'/4'/1/12", "tpubDHTZ815MvTaRmo6Qg1rnU6TEU4ZkWyA56jA1UgpmMcBGomnSsyo34EZLoctzZY9MTJ6j7bhccceUeXZZLxZj5vgkVMYfcZ7DNPsyRdFpS3f"), + ]; + + for (path, expected_xpub) in testcases { + // decode the derivation path into a Vec + + let req = RequestGetExtendedPubkey { + bip32_path: parse_derivation_path(path).unwrap(), + display: false, + }; + + let response = handle_get_extended_pubkey(&req).unwrap(); + + assert_eq!( + response.pubkey, + bs58::decode(expected_xpub) + .with_check(None) + .into_vec() + .unwrap() + ); + } + } +} diff --git a/apps/bitcoin/app/src/handlers/get_master_fingerprint.rs b/apps/bitcoin/app/src/handlers/get_master_fingerprint.rs new file mode 100644 index 0000000..a53ba7d --- /dev/null +++ b/apps/bitcoin/app/src/handlers/get_master_fingerprint.rs @@ -0,0 +1,19 @@ +use common::message::ResponseGetMasterFingerprint; +use sdk::curve::Curve; + +pub fn handle_get_master_fingerprint() -> Result { + Ok(ResponseGetMasterFingerprint { + fingerprint: sdk::curve::Secp256k1::get_master_fingerprint(), + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_handle_get_master_fingerprint() { + let response = handle_get_master_fingerprint().unwrap(); + assert_eq!(response.fingerprint, 0xf5acc2fdu32); + } +} diff --git a/apps/bitcoin/app/src/handlers/mod.rs b/apps/bitcoin/app/src/handlers/mod.rs index 0324db5..5c4ae8c 100644 --- a/apps/bitcoin/app/src/handlers/mod.rs +++ b/apps/bitcoin/app/src/handlers/mod.rs @@ -1,8 +1,5 @@ -use common::message::ResponseGetMasterFingerprint; +mod get_extended_pubkey; +mod get_master_fingerprint; -pub fn handle_get_master_fingerprint() -> Result { - // TODO: replace with proper sdk call - Ok(ResponseGetMasterFingerprint { - fingerprint: 0xf5acc2fd, - }) -} +pub use get_extended_pubkey::handle_get_extended_pubkey; +pub use get_master_fingerprint::handle_get_master_fingerprint; diff --git a/apps/bitcoin/app/src/main.rs b/apps/bitcoin/app/src/main.rs index 0553c44..b2e263d 100644 --- a/apps/bitcoin/app/src/main.rs +++ b/apps/bitcoin/app/src/main.rs @@ -53,26 +53,26 @@ fn handle_req_<'a>(buffer: &'a [u8]) -> Result, &'static str> { let request: Request = Request::from_reader(&mut reader, buffer).map_err(|_| "Failed to parse request")?; // TODO: proper error handling - let response = Response { - response: match request.request { - OneOfrequest::get_version(_) => OneOfresponse::get_version(todo!()), - OneOfrequest::exit(_) => { - sdk::exit(0); - } - OneOfrequest::get_master_fingerprint(_) => { - OneOfresponse::get_master_fingerprint(handle_get_master_fingerprint()?) - } - OneOfrequest::get_extended_pubkey(req) => OneOfresponse::get_extended_pubkey(todo!()), - OneOfrequest::register_wallet(req) => OneOfresponse::register_wallet(todo!()), - OneOfrequest::get_wallet_address(req) => OneOfresponse::get_wallet_address(todo!()), - OneOfrequest::sign_psbt(req) => OneOfresponse::sign_psbt(todo!()), - OneOfrequest::None => OneOfresponse::error(ResponseError { - error_msg: Cow::Borrowed("Invalid command"), - }), - }, + let response = match request.request { + OneOfrequest::get_version(_) => OneOfresponse::get_version(todo!()), + OneOfrequest::exit(_) => { + sdk::exit(0); + } + OneOfrequest::get_master_fingerprint(_) => { + OneOfresponse::get_master_fingerprint(handle_get_master_fingerprint()?) + } + OneOfrequest::get_extended_pubkey(req) => { + OneOfresponse::get_extended_pubkey(handle_get_extended_pubkey(&req)?) + } + OneOfrequest::register_wallet(_req) => OneOfresponse::register_wallet(todo!()), + OneOfrequest::get_wallet_address(_req) => OneOfresponse::get_wallet_address(todo!()), + OneOfrequest::sign_psbt(_req) => OneOfresponse::sign_psbt(todo!()), + OneOfrequest::None => OneOfresponse::error(ResponseError { + error_msg: Cow::Borrowed("Invalid command"), + }), }; - Ok(response) + Ok(Response { response }) } fn handle_req(buffer: &[u8]) -> Vec { diff --git a/apps/bitcoin/common/.gitignore b/apps/bitcoin/common/.gitignore new file mode 100644 index 0000000..e5bdc6a --- /dev/null +++ b/apps/bitcoin/common/.gitignore @@ -0,0 +1,2 @@ +src/message/message.rs + diff --git a/apps/bitcoin/common/Cargo.toml b/apps/bitcoin/common/Cargo.toml index 822c3d8..75226c0 100644 --- a/apps/bitcoin/common/Cargo.toml +++ b/apps/bitcoin/common/Cargo.toml @@ -6,4 +6,7 @@ edition = "2021" [dependencies] quick-protobuf = { version = "0.8.1", default-features = false } +[build-dependencies] +pb-rs = "0.10.0" + [workspace] diff --git a/apps/bitcoin/common/build.rs b/apps/bitcoin/common/build.rs new file mode 100644 index 0000000..342c765 --- /dev/null +++ b/apps/bitcoin/common/build.rs @@ -0,0 +1,19 @@ +use std::process::Command; + +fn main() { + let proto_files = &["src/message/message.proto"]; + + for proto_file in proto_files { + let output = Command::new("pb-rs") + .args(&["--nostd", proto_file]) + .output() + .expect("Failed to execute pb-rs"); + + if !output.status.success() { + panic!( + "pb-rs failed with error: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + } +} diff --git a/apps/bitcoin/common/src/message/README.md b/apps/bitcoin/common/src/message/README.md index c31b255..202c608 100644 --- a/apps/bitcoin/common/src/message/README.md +++ b/apps/bitcoin/common/src/message/README.md @@ -1,4 +1,6 @@ -Generate rust modules from protobuf with: +The module corresponding to `message.proto` is automatically generated at build time via [build.rs](../../build.rs). + +You can generate it manually with: $ cargo install pb-rs $ pb-rs --nostd ./message.proto diff --git a/apps/bitcoin/common/src/message/message.proto b/apps/bitcoin/common/src/message/message.proto index 308192a..6c4fb2a 100644 --- a/apps/bitcoin/common/src/message/message.proto +++ b/apps/bitcoin/common/src/message/message.proto @@ -23,7 +23,7 @@ message RequestGetExtendedPubkey { } message ResponseGetExtendedPubkey { - string pubkey = 1; + bytes pubkey = 1; } message RequestRegisterWallet { diff --git a/apps/bitcoin/common/src/message/message.rs b/apps/bitcoin/common/src/message/message.rs deleted file mode 100644 index e0f17b3..0000000 --- a/apps/bitcoin/common/src/message/message.rs +++ /dev/null @@ -1,768 +0,0 @@ -// Automatically generated rust module for 'message.proto' file - -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(non_camel_case_types)] -#![allow(unused_imports)] -#![allow(unknown_lints)] -#![allow(clippy::all)] -#![cfg_attr(rustfmt, rustfmt_skip)] - - -use alloc::vec::Vec; -use alloc::borrow::Cow; -use quick_protobuf::{MessageInfo, MessageRead, MessageWrite, BytesReader, Writer, WriterBackend, Result}; -use quick_protobuf::sizeofs::*; -use super::*; - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct RequestGetVersion { } - -impl<'a> MessageRead<'a> for RequestGetVersion { - fn from_reader(r: &mut BytesReader, _: &[u8]) -> Result { - r.read_to_end(); - Ok(Self::default()) - } -} - -impl MessageWrite for RequestGetVersion { } - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct ResponseGetVersion<'a> { - pub version: Cow<'a, str>, -} - -impl<'a> MessageRead<'a> for ResponseGetVersion<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(10) => msg.version = r.read_string(bytes).map(Cow::Borrowed)?, - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for ResponseGetVersion<'a> { - fn get_size(&self) -> usize { - 0 - + if self.version == "" { 0 } else { 1 + sizeof_len((&self.version).len()) } - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.version != "" { w.write_with_tag(10, |w| w.write_string(&**&self.version))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct RequestExit { } - -impl<'a> MessageRead<'a> for RequestExit { - fn from_reader(r: &mut BytesReader, _: &[u8]) -> Result { - r.read_to_end(); - Ok(Self::default()) - } -} - -impl MessageWrite for RequestExit { } - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct RequestGetMasterFingerprint { } - -impl<'a> MessageRead<'a> for RequestGetMasterFingerprint { - fn from_reader(r: &mut BytesReader, _: &[u8]) -> Result { - r.read_to_end(); - Ok(Self::default()) - } -} - -impl MessageWrite for RequestGetMasterFingerprint { } - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct ResponseGetMasterFingerprint { - pub fingerprint: u32, -} - -impl<'a> MessageRead<'a> for ResponseGetMasterFingerprint { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(8) => msg.fingerprint = r.read_uint32(bytes)?, - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl MessageWrite for ResponseGetMasterFingerprint { - fn get_size(&self) -> usize { - 0 - + if self.fingerprint == 0u32 { 0 } else { 1 + sizeof_varint(*(&self.fingerprint) as u64) } - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.fingerprint != 0u32 { w.write_with_tag(8, |w| w.write_uint32(*&self.fingerprint))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct RequestGetExtendedPubkey { - pub display: bool, - pub bip32_path: Vec, -} - -impl<'a> MessageRead<'a> for RequestGetExtendedPubkey { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(8) => msg.display = r.read_bool(bytes)?, - Ok(18) => msg.bip32_path = r.read_packed(bytes, |r, bytes| Ok(r.read_uint32(bytes)?))?, - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl MessageWrite for RequestGetExtendedPubkey { - fn get_size(&self) -> usize { - 0 - + if self.display == false { 0 } else { 1 + sizeof_varint(*(&self.display) as u64) } - + if self.bip32_path.is_empty() { 0 } else { 1 + sizeof_len(self.bip32_path.iter().map(|s| sizeof_varint(*(s) as u64)).sum::()) } - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.display != false { w.write_with_tag(8, |w| w.write_bool(*&self.display))?; } - w.write_packed_with_tag(18, &self.bip32_path, |w, m| w.write_uint32(*m), &|m| sizeof_varint(*(m) as u64))?; - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct ResponseGetExtendedPubkey<'a> { - pub pubkey: Cow<'a, str>, -} - -impl<'a> MessageRead<'a> for ResponseGetExtendedPubkey<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(10) => msg.pubkey = r.read_string(bytes).map(Cow::Borrowed)?, - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for ResponseGetExtendedPubkey<'a> { - fn get_size(&self) -> usize { - 0 - + if self.pubkey == "" { 0 } else { 1 + sizeof_len((&self.pubkey).len()) } - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.pubkey != "" { w.write_with_tag(10, |w| w.write_string(&**&self.pubkey))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct RequestRegisterWallet<'a> { - pub name: Cow<'a, str>, - pub descriptor_template: Cow<'a, str>, - pub keys_info: Vec>, -} - -impl<'a> MessageRead<'a> for RequestRegisterWallet<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(10) => msg.name = r.read_string(bytes).map(Cow::Borrowed)?, - Ok(18) => msg.descriptor_template = r.read_string(bytes).map(Cow::Borrowed)?, - Ok(26) => msg.keys_info.push(r.read_string(bytes).map(Cow::Borrowed)?), - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for RequestRegisterWallet<'a> { - fn get_size(&self) -> usize { - 0 - + if self.name == "" { 0 } else { 1 + sizeof_len((&self.name).len()) } - + if self.descriptor_template == "" { 0 } else { 1 + sizeof_len((&self.descriptor_template).len()) } - + self.keys_info.iter().map(|s| 1 + sizeof_len((s).len())).sum::() - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.name != "" { w.write_with_tag(10, |w| w.write_string(&**&self.name))?; } - if self.descriptor_template != "" { w.write_with_tag(18, |w| w.write_string(&**&self.descriptor_template))?; } - for s in &self.keys_info { w.write_with_tag(26, |w| w.write_string(&**s))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct ResponseRegisterWallet<'a> { - pub wallet_id: Cow<'a, [u8]>, - pub wallet_hmac: Cow<'a, [u8]>, -} - -impl<'a> MessageRead<'a> for ResponseRegisterWallet<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(10) => msg.wallet_id = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(18) => msg.wallet_hmac = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for ResponseRegisterWallet<'a> { - fn get_size(&self) -> usize { - 0 - + if self.wallet_id == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.wallet_id).len()) } - + if self.wallet_hmac == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.wallet_hmac).len()) } - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.wallet_id != Cow::Borrowed(b"") { w.write_with_tag(10, |w| w.write_bytes(&**&self.wallet_id))?; } - if self.wallet_hmac != Cow::Borrowed(b"") { w.write_with_tag(18, |w| w.write_bytes(&**&self.wallet_hmac))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct RequestGetWalletAddress<'a> { - pub display: bool, - pub name: Cow<'a, str>, - pub descriptor_template: Cow<'a, str>, - pub keys_info: Vec>, - pub wallet_hmac: Cow<'a, [u8]>, - pub change: bool, - pub address_index: u32, -} - -impl<'a> MessageRead<'a> for RequestGetWalletAddress<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(8) => msg.display = r.read_bool(bytes)?, - Ok(18) => msg.name = r.read_string(bytes).map(Cow::Borrowed)?, - Ok(26) => msg.descriptor_template = r.read_string(bytes).map(Cow::Borrowed)?, - Ok(34) => msg.keys_info.push(r.read_string(bytes).map(Cow::Borrowed)?), - Ok(42) => msg.wallet_hmac = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(48) => msg.change = r.read_bool(bytes)?, - Ok(56) => msg.address_index = r.read_uint32(bytes)?, - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for RequestGetWalletAddress<'a> { - fn get_size(&self) -> usize { - 0 - + if self.display == false { 0 } else { 1 + sizeof_varint(*(&self.display) as u64) } - + if self.name == "" { 0 } else { 1 + sizeof_len((&self.name).len()) } - + if self.descriptor_template == "" { 0 } else { 1 + sizeof_len((&self.descriptor_template).len()) } - + self.keys_info.iter().map(|s| 1 + sizeof_len((s).len())).sum::() - + if self.wallet_hmac == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.wallet_hmac).len()) } - + if self.change == false { 0 } else { 1 + sizeof_varint(*(&self.change) as u64) } - + if self.address_index == 0u32 { 0 } else { 1 + sizeof_varint(*(&self.address_index) as u64) } - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.display != false { w.write_with_tag(8, |w| w.write_bool(*&self.display))?; } - if self.name != "" { w.write_with_tag(18, |w| w.write_string(&**&self.name))?; } - if self.descriptor_template != "" { w.write_with_tag(26, |w| w.write_string(&**&self.descriptor_template))?; } - for s in &self.keys_info { w.write_with_tag(34, |w| w.write_string(&**s))?; } - if self.wallet_hmac != Cow::Borrowed(b"") { w.write_with_tag(42, |w| w.write_bytes(&**&self.wallet_hmac))?; } - if self.change != false { w.write_with_tag(48, |w| w.write_bool(*&self.change))?; } - if self.address_index != 0u32 { w.write_with_tag(56, |w| w.write_uint32(*&self.address_index))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct ResponseGetWalletAddress<'a> { - pub address: Cow<'a, str>, -} - -impl<'a> MessageRead<'a> for ResponseGetWalletAddress<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(10) => msg.address = r.read_string(bytes).map(Cow::Borrowed)?, - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for ResponseGetWalletAddress<'a> { - fn get_size(&self) -> usize { - 0 - + if self.address == "" { 0 } else { 1 + sizeof_len((&self.address).len()) } - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.address != "" { w.write_with_tag(10, |w| w.write_string(&**&self.address))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct RequestSignPsbt<'a> { - pub psbt: Cow<'a, [u8]>, - pub name: Cow<'a, str>, - pub descriptor_template: Cow<'a, str>, - pub keys_info: Vec>, - pub wallet_hmac: Cow<'a, [u8]>, -} - -impl<'a> MessageRead<'a> for RequestSignPsbt<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(10) => msg.psbt = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(18) => msg.name = r.read_string(bytes).map(Cow::Borrowed)?, - Ok(26) => msg.descriptor_template = r.read_string(bytes).map(Cow::Borrowed)?, - Ok(34) => msg.keys_info.push(r.read_string(bytes).map(Cow::Borrowed)?), - Ok(42) => msg.wallet_hmac = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for RequestSignPsbt<'a> { - fn get_size(&self) -> usize { - 0 - + if self.psbt == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.psbt).len()) } - + if self.name == "" { 0 } else { 1 + sizeof_len((&self.name).len()) } - + if self.descriptor_template == "" { 0 } else { 1 + sizeof_len((&self.descriptor_template).len()) } - + self.keys_info.iter().map(|s| 1 + sizeof_len((s).len())).sum::() - + if self.wallet_hmac == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.wallet_hmac).len()) } - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.psbt != Cow::Borrowed(b"") { w.write_with_tag(10, |w| w.write_bytes(&**&self.psbt))?; } - if self.name != "" { w.write_with_tag(18, |w| w.write_string(&**&self.name))?; } - if self.descriptor_template != "" { w.write_with_tag(26, |w| w.write_string(&**&self.descriptor_template))?; } - for s in &self.keys_info { w.write_with_tag(34, |w| w.write_string(&**s))?; } - if self.wallet_hmac != Cow::Borrowed(b"") { w.write_with_tag(42, |w| w.write_bytes(&**&self.wallet_hmac))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct PartialSignature<'a> { - pub input_index: u32, - pub signature: Cow<'a, [u8]>, - pub public_key: Cow<'a, [u8]>, - pub leaf_hash: Cow<'a, [u8]>, -} - -impl<'a> MessageRead<'a> for PartialSignature<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(8) => msg.input_index = r.read_uint32(bytes)?, - Ok(18) => msg.signature = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(26) => msg.public_key = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(34) => msg.leaf_hash = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for PartialSignature<'a> { - fn get_size(&self) -> usize { - 0 - + if self.input_index == 0u32 { 0 } else { 1 + sizeof_varint(*(&self.input_index) as u64) } - + if self.signature == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.signature).len()) } - + if self.public_key == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.public_key).len()) } - + if self.leaf_hash == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.leaf_hash).len()) } - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.input_index != 0u32 { w.write_with_tag(8, |w| w.write_uint32(*&self.input_index))?; } - if self.signature != Cow::Borrowed(b"") { w.write_with_tag(18, |w| w.write_bytes(&**&self.signature))?; } - if self.public_key != Cow::Borrowed(b"") { w.write_with_tag(26, |w| w.write_bytes(&**&self.public_key))?; } - if self.leaf_hash != Cow::Borrowed(b"") { w.write_with_tag(34, |w| w.write_bytes(&**&self.leaf_hash))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct MusigPublicNonce<'a> { - pub input_index: u32, - pub pubnonce: Cow<'a, [u8]>, - pub participant_public_key: Cow<'a, [u8]>, - pub xonly_key: Cow<'a, [u8]>, - pub leaf_hash: Cow<'a, [u8]>, -} - -impl<'a> MessageRead<'a> for MusigPublicNonce<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(8) => msg.input_index = r.read_uint32(bytes)?, - Ok(18) => msg.pubnonce = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(26) => msg.participant_public_key = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(34) => msg.xonly_key = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(42) => msg.leaf_hash = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for MusigPublicNonce<'a> { - fn get_size(&self) -> usize { - 0 - + if self.input_index == 0u32 { 0 } else { 1 + sizeof_varint(*(&self.input_index) as u64) } - + if self.pubnonce == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.pubnonce).len()) } - + if self.participant_public_key == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.participant_public_key).len()) } - + if self.xonly_key == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.xonly_key).len()) } - + if self.leaf_hash == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.leaf_hash).len()) } - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.input_index != 0u32 { w.write_with_tag(8, |w| w.write_uint32(*&self.input_index))?; } - if self.pubnonce != Cow::Borrowed(b"") { w.write_with_tag(18, |w| w.write_bytes(&**&self.pubnonce))?; } - if self.participant_public_key != Cow::Borrowed(b"") { w.write_with_tag(26, |w| w.write_bytes(&**&self.participant_public_key))?; } - if self.xonly_key != Cow::Borrowed(b"") { w.write_with_tag(34, |w| w.write_bytes(&**&self.xonly_key))?; } - if self.leaf_hash != Cow::Borrowed(b"") { w.write_with_tag(42, |w| w.write_bytes(&**&self.leaf_hash))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct MusigPartialSignature<'a> { - pub input_index: u32, - pub signature: Cow<'a, [u8]>, - pub participant_public_key: Cow<'a, [u8]>, - pub xonly_key: Cow<'a, [u8]>, - pub leaf_hash: Cow<'a, [u8]>, -} - -impl<'a> MessageRead<'a> for MusigPartialSignature<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(8) => msg.input_index = r.read_uint32(bytes)?, - Ok(18) => msg.signature = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(26) => msg.participant_public_key = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(34) => msg.xonly_key = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(42) => msg.leaf_hash = r.read_bytes(bytes).map(Cow::Borrowed)?, - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for MusigPartialSignature<'a> { - fn get_size(&self) -> usize { - 0 - + if self.input_index == 0u32 { 0 } else { 1 + sizeof_varint(*(&self.input_index) as u64) } - + if self.signature == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.signature).len()) } - + if self.participant_public_key == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.participant_public_key).len()) } - + if self.xonly_key == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.xonly_key).len()) } - + if self.leaf_hash == Cow::Borrowed(b"") { 0 } else { 1 + sizeof_len((&self.leaf_hash).len()) } - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.input_index != 0u32 { w.write_with_tag(8, |w| w.write_uint32(*&self.input_index))?; } - if self.signature != Cow::Borrowed(b"") { w.write_with_tag(18, |w| w.write_bytes(&**&self.signature))?; } - if self.participant_public_key != Cow::Borrowed(b"") { w.write_with_tag(26, |w| w.write_bytes(&**&self.participant_public_key))?; } - if self.xonly_key != Cow::Borrowed(b"") { w.write_with_tag(34, |w| w.write_bytes(&**&self.xonly_key))?; } - if self.leaf_hash != Cow::Borrowed(b"") { w.write_with_tag(42, |w| w.write_bytes(&**&self.leaf_hash))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct ResponseSignPsbt<'a> { - pub partial_signatures: Vec>, - pub musig_public_nonces: Vec>, - pub musig_partial_signatures: Vec>, -} - -impl<'a> MessageRead<'a> for ResponseSignPsbt<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(10) => msg.partial_signatures.push(r.read_message::(bytes)?), - Ok(18) => msg.musig_public_nonces.push(r.read_message::(bytes)?), - Ok(26) => msg.musig_partial_signatures.push(r.read_message::(bytes)?), - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for ResponseSignPsbt<'a> { - fn get_size(&self) -> usize { - 0 - + self.partial_signatures.iter().map(|s| 1 + sizeof_len((s).get_size())).sum::() - + self.musig_public_nonces.iter().map(|s| 1 + sizeof_len((s).get_size())).sum::() - + self.musig_partial_signatures.iter().map(|s| 1 + sizeof_len((s).get_size())).sum::() - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - for s in &self.partial_signatures { w.write_with_tag(10, |w| w.write_message(s))?; } - for s in &self.musig_public_nonces { w.write_with_tag(18, |w| w.write_message(s))?; } - for s in &self.musig_partial_signatures { w.write_with_tag(26, |w| w.write_message(s))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct ResponseError<'a> { - pub error_msg: Cow<'a, str>, -} - -impl<'a> MessageRead<'a> for ResponseError<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(10) => msg.error_msg = r.read_string(bytes).map(Cow::Borrowed)?, - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for ResponseError<'a> { - fn get_size(&self) -> usize { - 0 - + if self.error_msg == "" { 0 } else { 1 + sizeof_len((&self.error_msg).len()) } - } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - if self.error_msg != "" { w.write_with_tag(10, |w| w.write_string(&**&self.error_msg))?; } - Ok(()) - } -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct Request<'a> { - pub request: mod_Request::OneOfrequest<'a>, -} - -impl<'a> MessageRead<'a> for Request<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(10) => msg.request = mod_Request::OneOfrequest::get_version(r.read_message::(bytes)?), - Ok(18) => msg.request = mod_Request::OneOfrequest::exit(r.read_message::(bytes)?), - Ok(26) => msg.request = mod_Request::OneOfrequest::get_master_fingerprint(r.read_message::(bytes)?), - Ok(34) => msg.request = mod_Request::OneOfrequest::get_extended_pubkey(r.read_message::(bytes)?), - Ok(42) => msg.request = mod_Request::OneOfrequest::register_wallet(r.read_message::(bytes)?), - Ok(50) => msg.request = mod_Request::OneOfrequest::get_wallet_address(r.read_message::(bytes)?), - Ok(58) => msg.request = mod_Request::OneOfrequest::sign_psbt(r.read_message::(bytes)?), - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for Request<'a> { - fn get_size(&self) -> usize { - 0 - + match self.request { - mod_Request::OneOfrequest::get_version(ref m) => 1 + sizeof_len((m).get_size()), - mod_Request::OneOfrequest::exit(ref m) => 1 + sizeof_len((m).get_size()), - mod_Request::OneOfrequest::get_master_fingerprint(ref m) => 1 + sizeof_len((m).get_size()), - mod_Request::OneOfrequest::get_extended_pubkey(ref m) => 1 + sizeof_len((m).get_size()), - mod_Request::OneOfrequest::register_wallet(ref m) => 1 + sizeof_len((m).get_size()), - mod_Request::OneOfrequest::get_wallet_address(ref m) => 1 + sizeof_len((m).get_size()), - mod_Request::OneOfrequest::sign_psbt(ref m) => 1 + sizeof_len((m).get_size()), - mod_Request::OneOfrequest::None => 0, - } } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - match self.request { mod_Request::OneOfrequest::get_version(ref m) => { w.write_with_tag(10, |w| w.write_message(m))? }, - mod_Request::OneOfrequest::exit(ref m) => { w.write_with_tag(18, |w| w.write_message(m))? }, - mod_Request::OneOfrequest::get_master_fingerprint(ref m) => { w.write_with_tag(26, |w| w.write_message(m))? }, - mod_Request::OneOfrequest::get_extended_pubkey(ref m) => { w.write_with_tag(34, |w| w.write_message(m))? }, - mod_Request::OneOfrequest::register_wallet(ref m) => { w.write_with_tag(42, |w| w.write_message(m))? }, - mod_Request::OneOfrequest::get_wallet_address(ref m) => { w.write_with_tag(50, |w| w.write_message(m))? }, - mod_Request::OneOfrequest::sign_psbt(ref m) => { w.write_with_tag(58, |w| w.write_message(m))? }, - mod_Request::OneOfrequest::None => {}, - } Ok(()) - } -} - -pub mod mod_Request { - -use alloc::vec::Vec; -use super::*; - -#[derive(Debug, PartialEq, Clone)] -pub enum OneOfrequest<'a> { - get_version(RequestGetVersion), - exit(RequestExit), - get_master_fingerprint(RequestGetMasterFingerprint), - get_extended_pubkey(RequestGetExtendedPubkey), - register_wallet(RequestRegisterWallet<'a>), - get_wallet_address(RequestGetWalletAddress<'a>), - sign_psbt(RequestSignPsbt<'a>), - None, -} - -impl<'a> Default for OneOfrequest<'a> { - fn default() -> Self { - OneOfrequest::None - } -} - -} - -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Debug, Default, PartialEq, Clone)] -pub struct Response<'a> { - pub response: mod_Response::OneOfresponse<'a>, -} - -impl<'a> MessageRead<'a> for Response<'a> { - fn from_reader(r: &mut BytesReader, bytes: &'a [u8]) -> Result { - let mut msg = Self::default(); - while !r.is_eof() { - match r.next_tag(bytes) { - Ok(10) => msg.response = mod_Response::OneOfresponse::get_version(r.read_message::(bytes)?), - Ok(18) => msg.response = mod_Response::OneOfresponse::get_master_fingerprint(r.read_message::(bytes)?), - Ok(26) => msg.response = mod_Response::OneOfresponse::get_extended_pubkey(r.read_message::(bytes)?), - Ok(34) => msg.response = mod_Response::OneOfresponse::register_wallet(r.read_message::(bytes)?), - Ok(42) => msg.response = mod_Response::OneOfresponse::get_wallet_address(r.read_message::(bytes)?), - Ok(50) => msg.response = mod_Response::OneOfresponse::sign_psbt(r.read_message::(bytes)?), - Ok(58) => msg.response = mod_Response::OneOfresponse::error(r.read_message::(bytes)?), - Ok(t) => { r.read_unknown(bytes, t)?; } - Err(e) => return Err(e), - } - } - Ok(msg) - } -} - -impl<'a> MessageWrite for Response<'a> { - fn get_size(&self) -> usize { - 0 - + match self.response { - mod_Response::OneOfresponse::get_version(ref m) => 1 + sizeof_len((m).get_size()), - mod_Response::OneOfresponse::get_master_fingerprint(ref m) => 1 + sizeof_len((m).get_size()), - mod_Response::OneOfresponse::get_extended_pubkey(ref m) => 1 + sizeof_len((m).get_size()), - mod_Response::OneOfresponse::register_wallet(ref m) => 1 + sizeof_len((m).get_size()), - mod_Response::OneOfresponse::get_wallet_address(ref m) => 1 + sizeof_len((m).get_size()), - mod_Response::OneOfresponse::sign_psbt(ref m) => 1 + sizeof_len((m).get_size()), - mod_Response::OneOfresponse::error(ref m) => 1 + sizeof_len((m).get_size()), - mod_Response::OneOfresponse::None => 0, - } } - - fn write_message(&self, w: &mut Writer) -> Result<()> { - match self.response { mod_Response::OneOfresponse::get_version(ref m) => { w.write_with_tag(10, |w| w.write_message(m))? }, - mod_Response::OneOfresponse::get_master_fingerprint(ref m) => { w.write_with_tag(18, |w| w.write_message(m))? }, - mod_Response::OneOfresponse::get_extended_pubkey(ref m) => { w.write_with_tag(26, |w| w.write_message(m))? }, - mod_Response::OneOfresponse::register_wallet(ref m) => { w.write_with_tag(34, |w| w.write_message(m))? }, - mod_Response::OneOfresponse::get_wallet_address(ref m) => { w.write_with_tag(42, |w| w.write_message(m))? }, - mod_Response::OneOfresponse::sign_psbt(ref m) => { w.write_with_tag(50, |w| w.write_message(m))? }, - mod_Response::OneOfresponse::error(ref m) => { w.write_with_tag(58, |w| w.write_message(m))? }, - mod_Response::OneOfresponse::None => {}, - } Ok(()) - } -} - -pub mod mod_Response { - -use alloc::vec::Vec; -use super::*; - -#[derive(Debug, PartialEq, Clone)] -pub enum OneOfresponse<'a> { - get_version(ResponseGetVersion<'a>), - get_master_fingerprint(ResponseGetMasterFingerprint), - get_extended_pubkey(ResponseGetExtendedPubkey<'a>), - register_wallet(ResponseRegisterWallet<'a>), - get_wallet_address(ResponseGetWalletAddress<'a>), - sign_psbt(ResponseSignPsbt<'a>), - error(ResponseError<'a>), - None, -} - -impl<'a> Default for OneOfresponse<'a> { - fn default() -> Self { - OneOfresponse::None - } -} - -} -