1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#[cfg(feature = "f_bitcoin")]
extern crate bitcoin;
#[cfg(feature = "f_bitcoin")]
extern crate bitcoin_bech32;
#[cfg(feature = "f_bitcoin")]
extern crate bitcoin_hashes;
#[cfg(feature = "f_bitcoin")]
extern crate secp256k1;
#[cfg(feature = "f_bitcoin")]
extern crate unicode_normalization;
#[cfg(feature = "f_ethereum")]
extern crate primitive_types;
extern crate byteorder;
extern crate hex;
extern crate hidapi_rusb;
extern crate rusb;
#[macro_use]
extern crate log;
extern crate protobuf;
mod messages;
mod transport;
pub mod client;
pub mod error;
pub mod protos;
#[cfg(feature = "f_bitcoin")]
pub mod utils;
mod flows {
#[cfg(feature = "f_bitcoin")]
pub mod sign_tx;
}
pub use client::{
ButtonRequest, ButtonRequestType, EntropyRequest, Features, InputScriptType, InteractionType,
PassphraseRequest, PinMatrixRequest, PinMatrixRequestType, Trezor, TrezorResponse, WordCount,
};
pub use error::{Error, Result};
#[cfg(feature = "f_bitcoin")]
pub use flows::sign_tx::SignTxProgress;
pub use messages::TrezorMessage;
use std::fmt;
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
pub enum Model {
Trezor1,
Trezor2,
Trezor2Bl,
}
impl fmt::Display for Model {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
Model::Trezor1 => "Trezor 1",
Model::Trezor2 => "Trezor 2",
Model::Trezor2Bl => "Trezor 2 Bootloader",
})
}
}
#[derive(Debug)]
pub struct AvailableDevice {
pub model: Model,
pub debug: bool,
transport: transport::AvailableDeviceTransport,
}
impl fmt::Display for AvailableDevice {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} (transport: {}) (debug: {})", self.model, &self.transport, self.debug)
}
}
impl AvailableDevice {
pub fn connect(self) -> Result<Trezor> {
let transport = transport::connect(&self).map_err(Error::TransportConnect)?;
Ok(client::trezor_with_transport(self.model, transport))
}
}
pub fn find_devices(debug: bool) -> Result<Vec<AvailableDevice>> {
let mut devices = Vec::new();
use transport::webusb::WebUsbTransport;
devices.extend(WebUsbTransport::find_devices(debug).map_err(Error::TransportConnect)?);
Ok(devices)
}
pub fn find_hid_devices() -> Result<Vec<AvailableDevice>> {
use transport::hid::HidTransport;
HidTransport::find_devices(true).map_err(Error::TransportConnect)
}
pub fn unique(debug: bool) -> Result<Trezor> {
let mut devices = find_devices(debug)?;
match devices.len() {
0 => Err(Error::NoDeviceFound),
1 => Ok(devices.remove(0).connect()?),
_ => {
debug!("Trezor devices found: {:?}", devices);
Err(Error::DeviceNotUnique)
}
}
}