Skip to content

wizardsardine/bhwi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BHWI, the Bitcoin Hardware Wallet Interface

This repository is a work in progress for a sans-io equivalent of HWI. The main idea is to implement for each hardware wallet an interface called the interpreter that takes care of encoding commands, decoding device responses and routing data to their recipients.

pub trait Interpreter {
    type Command;
    type Transmit;
    type Response;
    type Error;
    fn start(&mut self, command: Self::Command) -> Result<Self::Transmit, Self::Error>;
    fn exchange(&mut self, data: Vec<u8>) -> Result<Option<Self::Transmit>, Self::Error>;
    fn end(self) -> Result<Self::Response, Self::Error>;
}

Once this trait implemented, it is up to the developer to take care of the IO according to the targeted plateform with or without async/await. The data and its recipient are provided in the Transmit structure.

For example the code of bhwi-async to run a command from the common interpreter that currently manage commands for ledger and jade devices and the jade pin server:

async fn run_command<T, S, I>(
    transport: &T,
    http_client: &S,
    mut intpr: I,
    command: common::Command,
) -> Result<common::Response, Error<T::Error, S::Error>>
where
    T: Transport + ?Sized,
    S: HttpClient + ?Sized,
    I: Interpreter<
        Command = common::Command,
        Transmit = common::Transmit,
        Response = common::Response,
        Error = common::Error,
    >,
{
    let transmit = intpr.start(command)?;
    let exchange = transport
        .exchange(&transmit.payload)
        .await
        .map_err(Error::Transport)?;
    let mut transmit = intpr.exchange(exchange)?;
    while let Some(t) = &transmit {
        match &t.recipient {
            common::Recipient::PinServer { url } => {
                let res = http_client
                    .request(url, &t.payload)
                    .await
                    .map_err(Error::HttpClient)?;
                transmit = intpr.exchange(res)?;
            }
            common::Recipient::Device => {
                let exchange = transport
                    .exchange(&t.payload)
                    .await
                    .map_err(Error::Transport)?;
                transmit = intpr.exchange(exchange)?;
            }
        }
    }
    intpr.end().map_err(|e| e.into())
}

About

[WIP] Bitcoin Hardware Wallet Interface in rust [WIP]

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published