use super::{CommandApdu, ResponseApdu};
use core::fmt::{self, Formatter};
use bitcoin::secp256k1;
use bitcoin_hashes::hex::DisplayHex as _;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Clone, Debug, PartialEq, Eq)]
pub struct XpubCommand {
cmd: &'static str, master: bool, #[serde(with = "serde_bytes")]
epubkey: [u8; 33], #[serde(with = "serde_bytes")]
xcvc: Vec<u8>, }
impl CommandApdu for XpubCommand {
fn name() -> &'static str {
"xpub"
}
}
impl XpubCommand {
pub fn new(master: bool, epubkey: secp256k1::PublicKey, xcvc: Vec<u8>) -> Self {
Self {
cmd: Self::name(),
master,
epubkey: epubkey.serialize(),
xcvc,
}
}
}
#[derive(Deserialize, Clone)]
pub struct XpubResponse {
#[serde(with = "serde_bytes")]
pub xpub: Vec<u8>,
#[serde(with = "serde_bytes")]
pub card_nonce: [u8; 16],
}
impl ResponseApdu for XpubResponse {}
impl std::fmt::Debug for XpubResponse {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_struct("XpubResponse")
.field("xpub", &self.xpub.to_lower_hex_string())
.field("card_nonce", &self.card_nonce.to_lower_hex_string())
.finish()
}
}
#[derive(Serialize, Clone, Debug, PartialEq, Eq)]
pub struct ChangeCommand {
cmd: &'static str,
#[serde(with = "serde_bytes")]
data: Vec<u8>,
#[serde(with = "serde_bytes")]
epubkey: [u8; 33],
#[serde(with = "serde_bytes")]
xcvc: Vec<u8>,
}
impl CommandApdu for ChangeCommand {
fn name() -> &'static str {
"change"
}
}
impl ChangeCommand {
pub fn new(data: Vec<u8>, epubkey: secp256k1::PublicKey, xcvc: Vec<u8>) -> Self {
Self {
cmd: Self::name(),
data,
epubkey: epubkey.serialize(),
xcvc,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct ChangeResponse {
pub success: bool,
#[serde(with = "serde_bytes")]
pub card_nonce: [u8; 16],
}
impl ResponseApdu for ChangeResponse {}
#[derive(Serialize, Clone, Debug, PartialEq, Eq)]
pub struct BackupCommand {
cmd: &'static str,
#[serde(with = "serde_bytes")]
epubkey: [u8; 33],
#[serde(with = "serde_bytes")]
xcvc: Vec<u8>,
}
impl CommandApdu for BackupCommand {
fn name() -> &'static str {
"backup"
}
}
impl BackupCommand {
pub fn new(epubkey: secp256k1::PublicKey, xcvc: Vec<u8>) -> Self {
Self {
cmd: Self::name(),
epubkey: epubkey.serialize(),
xcvc,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct BackupResponse {
#[serde(with = "serde_bytes")]
pub data: Vec<u8>,
#[serde(with = "serde_bytes")]
pub card_nonce: [u8; 16],
}
impl ResponseApdu for BackupResponse {}