Chrome extension for Bitcoin TREZOR by SatoshiLabs.
TREZOR Chrome Extension has two different purposes.
First, it has a built-in device management functionality, for wiping/recovery/initialization/.... It doesn't connect to any outside sources, all the data (including TREZOR firmware) is bundled with the app, so it works completely offline (if you somehow manage to install Chrome without an internet connection).
Second, it's a transport layer between websites (such as our own webwallet TREZOR Wallet) and TREZOR devices. It's possible to send Chrome messages (see chrome messages API documentation) to the extension, and the extension resends it to TREZOR hardware and back.
The messages are encoded through protobuf.js library and sent to the actual hardware via Chrome USB HID API.
The API of the extensions is described below. For development of web apps for TREZOR, it is recommended to use trezor.js javascript API, which has separate javascript calls for most common usecases; or TREZOR Connect, which is even more high level. However, the end user still needs to install either the extension or trezord.
Extension is available for download at Google Web store (and is automatically offered on webwallet TREZOR Wallet).
If you don't trust Google Web store (or want to use an offline machine), you can download the ZIP file extension.zip, unzip it, go to chrome://extensions/ in Chrome, enable "Developer mode", click "Load upacked extension" and find the directory.
The ZIP file in the repo will be updated simultaneously with the updates in Google Web Store; it might not be up-to-date with the master branch.
git clone --recursive https://github.com/trezor/chrome-extension.git
Or, if you already cloned the repository but not the submodules
git submodule update --init --recursive
Building works on OS X and Linux and uses make
.
You need to have flow installed for type checking. If you don't want to install it, edit the flow-check
in Makefile to something like true
.
You also need python3 and npm and have them in $PATH
.
(You need to be online for the build because of npm install
and git update
that happen in the build.)
make npm-install # needed only the first time
make clear # if you built before
make zip
The source code of the transport layer is using flow type annotations and some features of ECMAScript 6.
Most of the logic is now in trezor-link npm package, the extension just do data validation and so on.
The source code of the device management is an angular app. If it seems a little "over-blown", it's because it was created as a clone of the whole myTREZOR app, which handles more than device management, and then functionality was stripped off.
On Mac OS X, Windows and Chrome OS, installing the extension should work without any root privileges. Unfortunately, on GNU/Linux, you have install so-called udev rules as a root.
If you are using wallet.trezor.io, we are trying to detect the errors and offer you an easy package for the two most popular packaging systems (DEB and RPM).
If you don't want to or can't install that, please refer to our documentation
http://doc.satoshilabs.com/trezor-user/settingupchromeonlinux.html
Connect to UDP TREZOR emulator (will be released soon-ish) by opening extension background page in chrome://extensions and typing into console
window.setUdp([21324, ...])
with the list of ports of the virtual devices. The devices are immediately added and are registered as connected; if an app (like myTREZOR) is running, it will see them and try to communicate with them. To simulate disconnect, just type
window.setUdp([])
and the device are marked as disconnected.
Allowed ports are 21324, 21325 and 21326.
Note: there is a known bug - if you set up UDP connection, but turn off the emulator, the HID device listing might get stuck on webpage reloads. If you notice this, set wuindow.setUdp([])
or turn on the emulator.
If installed using some of the described methods, the extension has an id jcjjhjgimijdkoamemaghajlhegmoclj
.
You send the messages to the extension using chrome messages API (read the note about whitelisting below).
The messages are javacript Objects with type
property and body
property; type
is always string, body
varies depending on the type.
The response is a javascript Object with type
property, which is either "response"
or "error"
; in the response
case, the object has body
with type depending on message; in the error
case, the object has message
with error message.
So, the code, communicating with the extension, might look like this:
chrome.runtime.sendMessage('jcjjhjgimijdkoamemaghajlhegmoclj', {type: "info"},
function(response) {
if (response.type === "error") {
handleError(response.type);
} else {
handleInfo(response.body);
}
}
);
The possible messages are:
type | body | response type | description |
---|---|---|---|
info |
{version : string,configured : boolean} |
Returns current version of bridge and info about configuration. See configure for more info. |
|
configure |
config, as hex string | "Success" |
Before any advanced call, configuration file needs to be loaded to extension. Configuration file is signed by SatoshiLabs and the validity of the signature is limited. Current config should be in this repo, or on AWS here. |
enumerate |
Array<{path : number, session : number | null}> |
Lists devices.path uniquely defines device between more connected devices. It usually increases on reconnect until restart of browser, but there is no guarantee.If session is null, nobody else is using the device; if it's number, it identifies who is using it. |
|
listen |
previous, as JSON | like enumerate |
Listen to changes and returns either on change or after 30 second timeout. Compares change from previous that is sent as a parameter. "Change" is both connecting/disconnecting and session change. previous must be exactly the output from the previous enumerate , even if the devices have additional properties that are not described above |
acquire |
{path : path of device,previous : previous session (or null ) |
{session : number} |
Acquires the device at path . By "acquiring" the device, you are claiming the device for yourself.Before acquiring, checks that the current session is previous .If two applications call acquire on a newly connected device at the same time, only one of them succeed. |
release |
{session : session to release} |
"Success" |
Releases the device with the given session. By "releasing" the device, you claim that you don't want to use the device anymore. |
call |
{id : session to call,type : string,message : object} |
{type : string, body : object} |
Calls the message and returns the response from TREZOR. Messages are defined in this protobuf file. type in request is, for example, GetFeatures ; type in response is, for example, Features |
You cannot connect to the extension from anywhere on the internet. Your URL needs to be specifically whitelisted; whitelist is baked-in in the extension manifest.
localhost
is specifically whitelisted, so you can experiment on http://localhost
. If you want to add your url in order to make a TREZOR web app, make a pull request to this file.
GPLv3
some code from sowbug/trhid and throughnothing/chrome-trezor