Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump trezor-connect from 7.0.5 to 8.1.2 #1504

Merged
merged 6 commits into from
May 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@

[untyped]
.*/node_modules/trezor-connect/lib/utils/networkUtils.js
.*/node_modules/trezor-connect/lib/index.js
.*/node_modules/trezor-connect/lib/env/browser/index.js
.*/node_modules/trezor-connect/lib/popup/PopupManager.js
.*/node_modules/react-polymorph/source/components/HOC/withTheme.js
.*/node_modules/react-polymorph/source/components/layout/Flex.js

Expand Down
4 changes: 2 additions & 2 deletions app/api/ada/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ import type {
LedgerSignTxPayload,
} from '../../domain/HWSignTx';
import Notice from '../../domain/Notice';
import type { $CardanoSignTransaction } from 'trezor-connect/lib/types/cardano';
import type { CardanoSignTransaction } from 'trezor-connect/lib/types/networks/cardano';
import {
createTrezorSignTxPayload,
broadcastTrezorSignedTx,
Expand Down Expand Up @@ -327,7 +327,7 @@ export type CreateTrezorSignTxDataRequest = {|
|};
export type CreateTrezorSignTxDataResponse = {|
// https://github.com/trezor/connect/blob/develop/docs/methods/cardanoSignTransaction.md
trezorSignTxPayload: $CardanoSignTransaction,
trezorSignTxPayload: $Exact<CardanoSignTransaction>,
|};
export type CreateTrezorSignTxDataFunc = (
request: CreateTrezorSignTxDataRequest
Expand Down
6 changes: 3 additions & 3 deletions app/api/ada/transactions/byron/hwTransactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ import type {
} from '@cardano-foundation/ledgerjs-hw-app-cardano';
import { toDerivationPathString } from '@emurgo/ledger-connect-handler';
import type {
$CardanoSignTransaction,
CardanoSignTransaction,
CardanoInput,
CardanoOutput,
} from 'trezor-connect/lib/types/cardano';
} from 'trezor-connect/lib/types/networks/cardano';
import type {
Address, Value, Addressing,
} from '../../lib/storage/models/PublicDeriver/interfaces';
Expand All @@ -53,7 +53,7 @@ declare var CONFIG: ConfigType;
export async function createTrezorSignTxPayload(
signRequest: BaseSignRequest<RustModule.WalletV2.Transaction>,
getTxsBodiesForUTXOs: TxBodiesFunc,
): Promise<$CardanoSignTransaction> {
): Promise<$Exact<CardanoSignTransaction>> {
const txJson = signRequest.unsignedTx.to_json();

const utxoMap = utxosToLookupMap(
Expand Down
57 changes: 23 additions & 34 deletions app/stores/ada/TrezorConnectStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
import { observable, action } from 'mobx';

import TrezorConnect, { UI_EVENT, DEVICE_EVENT } from 'trezor-connect';
import type { DeviceMessage, UiMessage } from 'trezor-connect';
import type { CardanoGetPublicKey$ } from 'trezor-connect/lib/types/cardano';
import type { DeviceEvent } from 'trezor-connect/lib/types/trezor/device';
import type { UiEvent } from 'trezor-connect/lib/types/events';
import type { CardanoPublicKey } from 'trezor-connect/lib/types/networks/cardano';
import type { Success, Unsuccessful, } from 'trezor-connect/lib/types/params';

import Config from '../../config';
import environment from '../../environment';

import Store from '../base/Store';
Expand All @@ -17,7 +18,7 @@ import globalMessages from '../../i18n/global-messages';
import LocalizableError, { UnexpectedError } from '../../i18n/LocalizableError';
import { CheckAdressesInUseApiError } from '../../api/ada/errors';
import { derivePathPrefix } from '../../api/ada/transactions/utils';
import { wrapWithFrame, wrapWithoutFrame } from '../lib/TrezorWrapper';
import { getTrezorManifest, wrapWithFrame, wrapWithoutFrame } from '../lib/TrezorWrapper';

// This is actually just an interface
import {
Expand All @@ -41,8 +42,8 @@ import { PublicDeriver } from '../../api/ada/lib/storage/models/PublicDeriver';
import { HARD_DERIVATION_START } from '../../config/numbersConfig';

type TrezorConnectionResponse = {|
trezorResp: CardanoGetPublicKey$,
trezorEventDevice: DeviceMessage,
trezorResp: Success<CardanoPublicKey> | Unsuccessful,
trezorEventDevice: DeviceEvent,
|};


Expand Down Expand Up @@ -78,7 +79,7 @@ export default class TrezorConnectStore

/** holds Trezor device DeviceMessage event object, device features will be fetched
* from this object and will be converted to TrezorDeviceInfo object */
trezorEventDevice: ?DeviceMessage;
trezorEventDevice: ?DeviceEvent;
// =================== VIEW RELATED =================== //

// =================== API RELATED =================== //
Expand All @@ -102,29 +103,15 @@ export default class TrezorConnectStore
trezorConnectAction.submitSave.listen(this._submitSave);

try {
/** Starting from v7 Trezor Connect Manifest has been made mandatory
* https://github.com/trezor/connect/blob/develop/docs/index.md#trezor-connect-manifest */
const { manifest } = Config.wallets.hardwareWallet.trezorT;

const trezorManifest = {};
trezorManifest.email = manifest.EMAIL;
if (environment.userAgentInfo.isFirefox) {
// Set appUrl for `moz-extension:` protocol using browser (like Firefox)
trezorManifest.appUrl = manifest.appURL.FIREFOX;
} else {
// For all other browser supported that uses `chrome-extension:` protocol
// In future if other non chrome like browser is supported them we can consider updating
trezorManifest.appUrl = manifest.appURL.CHROME;
}

const trezorManifest = getTrezorManifest();
wrapWithoutFrame(trezor => trezor.manifest(trezorManifest));
} catch (error) {
Logger.error(`TrezorConnectStore::setup:error: ${stringifyError(error)}`);
}
}

/** setup() is called when stores are being created
* _init() is called when connect dailog is about to show */
* _init() is called when connect dialog is about to show */
_init: void => void = () => {
Logger.debug(`${nameof(TrezorConnectStore)}::${nameof(this._init)} called`);
}
Expand Down Expand Up @@ -196,7 +183,10 @@ export default class TrezorConnectStore
path: derivePathPrefix(this.derivationIndex)
}));

const trezorEventDevice: DeviceMessage = { ...this.trezorEventDevice };
if (this.trezorEventDevice == null) {
throw new Error(`${nameof(this._checkAndStoreHWDeviceInfo)} no ${nameof(this.trezorEventDevice)}`);
}
const trezorEventDevice = this.trezorEventDevice;

/** Converts a valid hardware wallet response to a common storable format
* later the same format will be used to create wallet */
Expand Down Expand Up @@ -225,21 +215,20 @@ export default class TrezorConnectStore
const { trezorResp, trezorEventDevice } = resp;

/** This check already done in _validateHWResponse but flow needs this */
if (trezorEventDevice == null
|| trezorEventDevice.payload == null
|| trezorEventDevice.payload.features == null) {
const device = trezorEventDevice.payload;
const { features } = device;
if (features == null) {
throw new Error('Trezor device hardware info not valid');
}

const deviceFeatures = trezorEventDevice.payload.features;
return {
publicMasterKey: trezorResp.payload.publicKey,
hwFeatures: {
Vendor: deviceFeatures.vendor,
Model: deviceFeatures.model,
DeviceId: deviceFeatures.device_id,
Vendor: features.vendor,
Model: features.model,
DeviceId: features.device_id || '',
},
defaultName: deviceFeatures.label || '',
defaultName: device.label || '',
};
}

Expand Down Expand Up @@ -310,12 +299,12 @@ export default class TrezorConnectStore
}
};

_onTrezorDeviceEvent: DeviceMessage => void = (event) => {
_onTrezorDeviceEvent: DeviceEvent => void = (event) => {
Logger.debug(`TrezorConnectStore:: DEVICE_EVENT: ${event.type}`);
this.trezorEventDevice = event;
};

_onTrezorUIEvent: UiMessage => void = (event) => {
_onTrezorUIEvent: UiEvent => void = (event) => {
Logger.debug(`TrezorConnectStore:: UI_EVENT: ${event.type}`);
// TODO: [TREZOR] https://github.com/Emurgo/yoroi-frontend/issues/126
// if(event.type === CLOSE_UI_WINDOW &&
Expand Down
5 changes: 3 additions & 2 deletions app/stores/ada/TrezorSendStore.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @flow
import { action, observable } from 'mobx';
import type { CardanoSignTransaction$ } from 'trezor-connect/lib/types/cardano';
import type { CardanoSignedTx } from 'trezor-connect/lib/types/networks/cardano';
import type { Success, Unsuccessful } from 'trezor-connect/lib/types/params';

import Store from '../base/Store';
import environment from '../../environment';
Expand Down Expand Up @@ -105,7 +106,7 @@ export default class TrezorSendStore extends Store {
};

_brodcastSignedTx: (
CardanoSignTransaction$,
Success<CardanoSignedTx> | Unsuccessful,
PublicDeriver<>,
) => Promise<void> = async (
trezorSignTxResp,
Expand Down
39 changes: 37 additions & 2 deletions app/stores/lib/TrezorWrapper.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,50 @@
// @flow

import Config from '../../config';
import environment from '../../environment';
import TrezorConnect from 'trezor-connect';
import type { Manifest } from 'trezor-connect';

/* eslint-disable no-restricted-properties */

// TODO: explain why we want this file
/*
* Trezor needs to embed an iframe inside Yoroi to function (created by TrezorConnect.init)
* Some TrezorConnect functions depend on this iframe existing, while others don't
* Goal: want to only keep the Trezor iframe open for the least amount of time for safety & privacy
*
* To do this safely, do this, we disallow the usage of TrezorConnect in the whole codebase
* except for this function that exposes to wrapper functions
* that forces the user to explicitly decide to initialize the iframe or not
*/

export function getTrezorManifest(): Manifest {
/** Starting from v7 Trezor Connect Manifest has been made mandatory
* https://github.com/trezor/connect/blob/develop/docs/index.md#trezor-connect-manifest */
const { manifest } = Config.wallets.hardwareWallet.trezorT;

const trezorManifest: Manifest = {
email: manifest.EMAIL,
appUrl: (() => {
if (environment.userAgentInfo.isFirefox) {
// Set appUrl for `moz-extension:` protocol using browser (like Firefox)
return manifest.appURL.FIREFOX;
}
// For all other browser supported that uses `chrome-extension:` protocol
// In future if other non chrome like browser is supported them we can consider updating
return manifest.appURL.CHROME;
})(),
};

return trezorManifest;
}

export async function wrapWithFrame<T>(
func: (typeof TrezorConnect) => Promise<T>
): Promise<T> {
await TrezorConnect.init({});
const trezorManifest = getTrezorManifest();
await TrezorConnect.init({
manifest: trezorManifest,
});
const result = await func(TrezorConnect);
await TrezorConnect.dispose();
return result;
Expand Down
4 changes: 2 additions & 2 deletions app/utils/tabManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function addCloseListener() {

/**
* Notify any other Yoroi tabs to close before we initialize
* Note: for the listner to fire, the key much change values
* Note: for the listener to fire, the key much change values
* To generate a new value every time, we use the current time
*
* The precision of the clock may be of concern. Let's look at two scenarios:
Expand All @@ -60,7 +60,7 @@ export function addCloseListener() {
*
* 2) Manually entering the Yoroi URL into a page multiple times
* This bypasses above-mentioned restriction of only one copy loading at once
* Emperically, this doesn't seem to be an issue though.
* Empirically, this doesn't seem to be an issue though.
*
* WARNING: You should only call this AFTER the wasm bindings have loaded
* closing a different copy of Yoroi while loading WASM causes the load to hang
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ Passing messages from popup to background script

window.addEventListener('message', event => {
if (port && event.source === window && event.data) {
port.postMessage(event.data);
port.postMessage({ data: event.data });
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,5 @@
</style>
</head>
<body>
<iframe id="trezor-usb-permissions" src="https://connect.trezor.io/7/extension-permissions.html" allow="usb" frameborder="0" width="100%" height="100%"></iframe>
<script type="text/javascript" src="./js/trezor-usb-permissions.js"></script>
</body>
40 changes: 27 additions & 13 deletions chrome/content-scripts/3rd-party-trezor/trezor-usb-permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,37 @@ Handling messages from usb permissions iframe
declare var chrome;
*/

const switchToPopupTab = (event) => {
const VERSION = '8.1.5';
const versionN = VERSION.split('.').map(s => parseInt(s));
const DIRECTORY = `${ versionN[0] }${ (versionN[1] > 0 ? `.${versionN[1]}` : '') }/`;
const url = 'https://connect.trezor.io/' + 8;

/* Handling messages from usb permissions iframe */
function switchToPopupTab(event) {
window.removeEventListener('beforeunload', switchToPopupTab);

if (!event) {
// triggered from 'usb-permissions-close' message
// switch tab to previous index and close current
// close current tab
chrome.tabs.query({
currentWindow: true,
active: true,
}, (current) => {
if (current.length < 0) return;
chrome.tabs.query({
index: current[0].index - 1,
}, popup => {
if (popup.length < 0) return;
chrome.tabs.update(popup[0].id, { active: true });
});
chrome.tabs.remove(current[0].id);
});
return;
}

// triggered from 'beforeunload' event
// find tab by popup pattern and switch to it
chrome.tabs.query({
url: '*://connect.trezor.io/*/popup.html',
url: url + 'popup.html',
}, (tabs) => {
if (tabs.length < 0) return;
chrome.tabs.update(tabs[0].id, { active: true });
});
};
}

window.addEventListener('message', event => {
window.addEventListener('message', function (event) {
if (event.data === 'usb-permissions-init') {
const iframe = document.getElementById('trezor-usb-permissions');
if (!iframe || !(iframe instanceof HTMLIFrameElement)) {
Expand All @@ -55,3 +53,19 @@ window.addEventListener('message', event => {
});

window.addEventListener('beforeunload', switchToPopupTab);
window.addEventListener('load', function () {
const instance = document.createElement('iframe');
instance.id = 'trezor-usb-permissions';
instance.frameBorder = '0';
instance.width = '100%';
instance.height = '100%';
instance.style.border = '0px';
instance.style.width = '100%';
instance.style.height = '100%';
instance.setAttribute('src', url + 'extension-permissions.html');
instance.setAttribute('allow', 'usb');

if (document.body) {
document.body.appendChild(instance);
}
});
Loading