From e586c9d8ea9dcd782f3a7e12023eb9a09faeda7d Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Mon, 30 Mar 2020 15:27:01 +0200 Subject: [PATCH 01/21] update outdated flowtype npm declarations --- .flowconfig | 5 ++- src/flowtype/npm/bignumber.js | 58 -------------------------------- src/flowtype/npm/redux_v3.x.x.js | 6 ++-- 3 files changed, 6 insertions(+), 63 deletions(-) delete mode 100644 src/flowtype/npm/bignumber.js diff --git a/.flowconfig b/.flowconfig index 9b970efd..b92aa275 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,4 +1,5 @@ [include] +.*/node_modules/hd-wallet/lib [ignore] .*/node_modules/fbjs/.* @@ -7,6 +8,9 @@ .*/node_modules/redux/.* .*/node_modules/react-router/.* .*/node_modules/oboe/test/.* +.*/node_modules/trezor-link/lib/lowlevel/webusb.js.flow +.*/node_modules/hd-wallet/lib/utils/stream.js.flow +.*/node_modules/protobufjs-old-fixed-webpack/src/bower.json .*/_old/.* .*/scripts/solidity/.* .*/build/.* @@ -19,7 +23,6 @@ ./src/flowtype/npm/react-router-dom_v4.x.x.js ; ./src/flowtype/npm/react-intl_v2.x.x.js // TODO: uncomment to get proper flow support for intl (needs some flow fixing) ./src/flowtype/npm/connected-react-router.js -./src/flowtype/npm/bignumber.js ./src/flowtype/npm/ethereum-types.js ./src/flowtype/npm/web3.js ./src/flowtype/css.js diff --git a/src/flowtype/npm/bignumber.js b/src/flowtype/npm/bignumber.js deleted file mode 100644 index d7bca1a4..00000000 --- a/src/flowtype/npm/bignumber.js +++ /dev/null @@ -1,58 +0,0 @@ -/* @flow */ - -declare module 'bignumber.js' { - declare type $npm$big$number$object = number | string | T_BigNumber - declare type $npm$cmp$result = -1 | 0 | 1 - declare type DIGIT = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 - declare type ROUND_DOWN = 0 - declare type ROUND_HALF_UP = 1 - declare type ROUND_HALF_EVEN = 2 - declare type ROUND_UP = 3 - declare type RM = ROUND_DOWN | ROUND_HALF_UP | ROUND_HALF_EVEN | ROUND_UP - - declare class T_BigNumber { - // Properties - static DP: number; - static RM: RM; - static E_NEG: number; - static E_POS: number; - - c: Array; - e: number; - s: -1 | 1; - - // Constructors - static (value: $npm$big$number$object): T_BigNumber; - constructor(value: $npm$big$number$object): T_BigNumber; - - // Methods - abs(): T_BigNumber; - div(n: $npm$big$number$object): T_BigNumber; - dividedBy(n: $npm$big$number$object): T_BigNumber; - eq(n: $npm$big$number$object): boolean; - gt(n: $npm$big$number$object): boolean; - isGreaterThan(n: $npm$big$number$object): boolean; - gte(n: $npm$big$number$object): boolean; - lt(n: $npm$big$number$object): boolean; - isLessThan(n: $npm$big$number$object): boolean; - lte(n: $npm$big$number$object): boolean; - isLessThanOrEqualTo(n: $npm$big$number$object): boolean; - isNaN(): boolean; - minus(n: $npm$big$number$object): T_BigNumber; - mod(n: $npm$big$number$object): T_BigNumber; - plus(n: $npm$big$number$object): T_BigNumber; - pow(exp: number): BigNumber; - sqrt(): T_BigNumber; - times(n: $npm$big$number$object): T_BigNumber; - toExponential(dp: ?number): string; - toFixed(dp: ?number): string; - toPrecision(sd: ?number): string; - toString(format?: number): string; - toNumber(): number; - valueOf(): string; - toJSON(): string; - } - - //declare module.exports: typeof T_BigNumber - declare export default typeof T_BigNumber; -} \ No newline at end of file diff --git a/src/flowtype/npm/redux_v3.x.x.js b/src/flowtype/npm/redux_v3.x.x.js index a6b06010..c71ef20a 100644 --- a/src/flowtype/npm/redux_v3.x.x.js +++ b/src/flowtype/npm/redux_v3.x.x.js @@ -1,5 +1,3 @@ -/* @flow */ - declare module 'redux' { /* S = State @@ -10,7 +8,7 @@ declare module 'redux' { declare export type DispatchAPI = (action: A) => A; // old Dispatch needs to stay as it is, because also "react-redux" is using this type - declare export type Dispatch }> = DispatchAPI; + declare export type Dispatch = DispatchAPI; declare export type ThunkAction = (dispatch: ReduxDispatch, getState: () => S) => void; declare export type AsyncAction = (dispatch: ReduxDispatch, getState: () => S) => Promise; @@ -21,7 +19,7 @@ declare module 'redux' { declare export type AsyncDispatch = (action: AsyncAction) => Promise; declare export type PromiseDispatch = (action: PromiseAction) => Promise; declare export type PayloadDispatch = (action: PayloadAction) => R; - declare export type PlainDispatch}> = DispatchAPI; + declare export type PlainDispatch = DispatchAPI; /* NEW: Dispatch is now a combination of these different dispatch types */ declare export type ReduxDispatch = PlainDispatch & ThunkDispatch & AsyncDispatch & PromiseDispatch & PayloadDispatch; From 486bfff3975f15969d435eae49d769c5c1fa2061 Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Mon, 30 Mar 2020 15:50:55 +0200 Subject: [PATCH 02/21] update TrezorDevice from trezor-connect@8 --- src/actions/LocalStorageActions.js | 3 +- src/actions/ModalActions.js | 2 +- src/actions/RouterActions.js | 33 ++++--- src/actions/TrezorConnectActions.js | 72 +++------------- src/actions/WalletActions.js | 2 +- src/flowtype/index.js | 86 ++++--------------- src/reducers/DevicesReducer.js | 25 +++--- src/reducers/ModalReducer.js | 6 +- src/reducers/NotificationReducer.js | 2 +- src/reducers/TrezorConnectReducer.js | 30 ++----- src/reducers/WalletReducer.js | 2 +- src/services/LogService.js | 4 +- src/services/TrezorConnectService.js | 4 +- src/services/WalletService.js | 2 +- src/utils/url.js | 4 +- .../Landing/views/InstallBridge/index.js | 9 +- .../components/CoinMenu/index.js | 4 +- src/views/Wallet/views/Dashboard/index.js | 4 +- 18 files changed, 87 insertions(+), 207 deletions(-) diff --git a/src/actions/LocalStorageActions.js b/src/actions/LocalStorageActions.js index 1148ed8e..bad2cd02 100644 --- a/src/actions/LocalStorageActions.js +++ b/src/actions/LocalStorageActions.js @@ -454,9 +454,8 @@ export const removeImportedAccounts = (device: TrezorDevice): ThunkAction => ( const importedAccounts: ?Array = getImportedAccounts(); if (!importedAccounts) return; - const deviceId = device.features ? device.features.device_id : null; const filteredImportedAccounts = importedAccounts.filter( - account => account.deviceID !== deviceId + account => account.deviceID !== device.id ); storageUtils.remove(TYPE, KEY_IMPORTED_ACCOUNTS); filteredImportedAccounts.forEach(account => { diff --git a/src/actions/ModalActions.js b/src/actions/ModalActions.js index f665762c..dce67072 100644 --- a/src/actions/ModalActions.js +++ b/src/actions/ModalActions.js @@ -144,7 +144,7 @@ export const onDeviceConnect = (device: Device): ThunkAction => ( device.features && modal.device && modal.device.features && - modal.device.features.device_id === device.features.device_id + modal.device.id === device.id ) { dispatch({ type: MODAL.CLOSE, diff --git a/src/actions/RouterActions.js b/src/actions/RouterActions.js index f8f10877..143a0f7d 100644 --- a/src/actions/RouterActions.js +++ b/src/actions/RouterActions.js @@ -65,14 +65,14 @@ export const paramsValidation = (params: RouterLocationState): PayloadAction d.features && - d.features.device_id === params.device && + d.id === params.device && d.instance === parseInt(params.deviceInstance, 10) ); } else { device = devices.find( d => ((!d.features || d.mode === 'bootloader') && d.path === params.device) || - (d.features && d.features.device_id === params.device) + (d.features && d.id === params.device) ); } @@ -218,21 +218,22 @@ const getDeviceUrl = (device: TrezorDevice | Device): PayloadAction => getState: GetState ): ?string => { let url: ?string; + const prefix = `/device/${device.id || device.path}`; if (!device.features) { - url = `/device/${device.path}/${device.type === 'unreadable' ? 'unreadable' : 'acquire'}`; + url = `${prefix}/${device.type === 'unreadable' ? 'unreadable' : 'acquire'}`; } else if (device.mode === 'bootloader') { // device in bootloader doesn't have device_id - url = `/device/${device.path}/bootloader`; + url = `${prefix}/bootloader`; } else if (device.mode === 'initialize') { - url = `/device/${device.features.device_id}/initialize`; + url = `${prefix}/initialize`; } else if (device.mode === 'seedless') { - url = `/device/${device.features.device_id}/seedless`; + url = `${prefix}/seedless`; } else if (device.firmware === 'required') { - url = `/device/${device.features.device_id}/firmware-update`; + url = `${prefix}/firmware-update`; } else if (typeof device.instance === 'number') { - url = `/device/${device.features.device_id}:${device.instance}`; + url = `${prefix}:${device.instance}`; } else { - url = `/device/${device.features.device_id}`; + url = `${prefix}`; // make sure that device is not TrezorDevice type if (!device.hasOwnProperty('ts')) { // it is device from trezor-connect triggered by DEVICE.CONNECT event @@ -379,10 +380,8 @@ export const gotoLandingPage = (): ThunkAction => (dispatch: Dispatch): void => export const gotoDeviceSettings = (device: TrezorDevice): ThunkAction => ( dispatch: Dispatch ): void => { - if (device.features) { - const devUrl: string = `${device.features.device_id}${ - device.instance ? `:${device.instance}` : '' - }`; + if (device.id) { + const devUrl: string = `${device.id}${device.instance ? `:${device.instance}` : ''}`; dispatch(goto(`/device/${devUrl}/settings`)); } }; @@ -403,8 +402,8 @@ export const gotoFirmwareUpdate = (): ThunkAction => ( getState: GetState ): void => { const { selectedDevice } = getState().wallet; - if (!selectedDevice || !selectedDevice.features) return; - const devUrl: string = `${selectedDevice.features.device_id}${ + if (!selectedDevice || !selectedDevice.id) return; + const devUrl: string = `${selectedDevice.id}${ selectedDevice.instance ? `:${selectedDevice.instance}` : '' }`; dispatch(goto(`/device/${devUrl}/firmware-update`)); @@ -415,8 +414,8 @@ export const gotoFirmwareUpdate = (): ThunkAction => ( */ export const gotoBackup = (): ThunkAction => (dispatch: Dispatch, getState: GetState): void => { const { selectedDevice } = getState().wallet; - if (!selectedDevice || !selectedDevice.features) return; - const devUrl: string = `${selectedDevice.features.device_id}${ + if (!selectedDevice || !selectedDevice.id) return; + const devUrl: string = `${selectedDevice.id}${ selectedDevice.instance ? `:${selectedDevice.instance}` : '' }`; dispatch(goto(`/device/${devUrl}/backup`)); diff --git a/src/actions/TrezorConnectActions.js b/src/actions/TrezorConnectActions.js index b80ff891..8d8aebb7 100644 --- a/src/actions/TrezorConnectActions.js +++ b/src/actions/TrezorConnectActions.js @@ -17,16 +17,6 @@ import * as RouterActions from 'actions/RouterActions'; import * as deviceUtils from 'utils/device'; import * as buildUtils from 'utils/build'; -import type { - DeviceMessage, - DeviceMessageType, - UiMessage, - UiMessageType, - TransportMessage, - TransportMessageType, - BlockchainEvent, -} from 'trezor-connect'; - import type { Dispatch, GetState, @@ -113,56 +103,27 @@ export const init = (): AsyncAction => async ( getState: GetState ): Promise => { // set listeners - TrezorConnect.on( - DEVICE_EVENT, - (event: DeviceMessage): void => { - // post event to reducers - const type: DeviceMessageType = event.type; // eslint-disable-line prefer-destructuring - dispatch({ - type, - device: event.payload, - }); - } - ); + TrezorConnect.on(DEVICE_EVENT, event => { + dispatch(event); + }); - TrezorConnect.on( - UI_EVENT, - (event: UiMessage): void => { - // post event to reducers - const type: UiMessageType = event.type; // eslint-disable-line prefer-destructuring - dispatch({ - type, - payload: event.payload, - }); - } - ); + TrezorConnect.on(UI_EVENT, event => { + dispatch(event); + }); - TrezorConnect.on( - TRANSPORT_EVENT, - (event: TransportMessage): void => { - // post event to reducers - const type: TransportMessageType = event.type; // eslint-disable-line prefer-destructuring - dispatch({ - type, - payload: event.payload, - }); - } - ); + TrezorConnect.on(TRANSPORT_EVENT, event => { + dispatch(event); + }); // post event to reducers - TrezorConnect.on( - BLOCKCHAIN_EVENT, - (event: BlockchainEvent): void => { - dispatch(event); - } - ); + TrezorConnect.on(BLOCKCHAIN_EVENT, event => { + dispatch(event); + }); if (buildUtils.isDev()) { // eslint-disable-next-line window.__TREZOR_CONNECT_SRC = - typeof LOCAL === 'string' - ? LOCAL - : 'https://connect.corp.sldev.cz/fix/v7-ripple-lib-error/'; // eslint-disable-line no-underscore-dangle + typeof LOCAL === 'string' ? LOCAL : 'https://connect.corp.sldev.cz/develop/'; // eslint-disable-line no-underscore-dangle // window.__TREZOR_CONNECT_SRC = typeof LOCAL === 'string' ? LOCAL : 'https://localhost:8088/'; // eslint-disable-line no-underscore-dangle window.TrezorConnect = TrezorConnect; } @@ -298,12 +259,7 @@ export const deviceDisconnect = (device: Device): AsyncAction => async ( ): Promise => { if (device.features) { const instances = getState().devices.filter( - d => - d.features && - device.features && - d.state && - !d.remember && - d.features.device_id === device.features.device_id + d => d.features && device.features && d.state && !d.remember && d.id === device.id ); if (instances.length > 0) { const isSelected = deviceUtils.isSelectedDevice( diff --git a/src/actions/WalletActions.js b/src/actions/WalletActions.js index ed84b5e8..5dd0b33d 100644 --- a/src/actions/WalletActions.js +++ b/src/actions/WalletActions.js @@ -144,7 +144,7 @@ export const clearUnavailableDevicesData = (prevState: State, device: Device): T d => d.features && device.features && - d.features.device_id === device.features.device_id && + d.id === device.id && d.features.passphrase_protection !== device.features.passphrase_protection ); diff --git a/src/flowtype/index.js b/src/flowtype/index.js index e56564df..fc23ae2b 100644 --- a/src/flowtype/index.js +++ b/src/flowtype/index.js @@ -36,33 +36,19 @@ import type { ImportAccountAction } from 'actions/ImportAccountActions'; import type { FiatRateAction } from 'services/CoingeckoService'; // this service has no action file, all is written inside one file import type { - Device, - Features, - DeviceStatus, - FirmwareRelease, - DeviceFirmwareStatus, - DeviceMode, - DeviceMessageType, - TransportMessageType, - UiMessageType, + KnownDevice, + UnknownDevice, + TransportEvent, BlockchainEvent, - BlockchainLinkTransaction, + UiEvent, + DeviceEvent, + AccountTransaction, } from 'trezor-connect'; import type { RouterAction, LocationState } from 'connected-react-router'; -export type AcquiredDevice = $Exact<{ - +type: 'acquired', - path: string, - +label: string, - +features: Features, - +firmware: DeviceFirmwareStatus, - +firmwareRelease: ?FirmwareRelease, - status: DeviceStatus, - +mode: DeviceMode, - state: ?string, +export type ExtendedDevice = {| useEmptyPassphrase: boolean, - remember: boolean, // device should be remembered connected: boolean, // device is connected available: boolean, // device cannot be used because of features.passphrase_protection is different then expected @@ -70,29 +56,16 @@ export type AcquiredDevice = $Exact<{ instanceLabel: string, instanceName: ?string, ts: number, -}>; - -export type UnknownDevice = $Exact<{ - +type: 'unacquired' | 'unreadable', - path: string, - +label: string, - +features: null, - state: ?string, - useEmptyPassphrase: boolean, +|}; - remember: boolean, // device should be remembered - connected: boolean, // device is connected - available: boolean, // device cannot be used because of features.passphrase_protection is different then expected - instance?: number, - instanceLabel: string, - instanceName: ?string, - ts: number, -}>; +export type AcquiredDevice = {| ...KnownDevice, ...ExtendedDevice |}; +export type UnacquiredDevice = {| ...UnknownDevice, ...ExtendedDevice |}; export type { Device } from 'trezor-connect'; -export type TrezorDevice = AcquiredDevice | UnknownDevice; +export type TrezorDevice = AcquiredDevice | UnacquiredDevice; -export type Transaction = BlockchainLinkTransaction & { +export type Transaction = AccountTransaction & { + descriptor: string, deviceState: string, network: string, rejected?: boolean, @@ -100,38 +73,11 @@ export type Transaction = BlockchainLinkTransaction & { export type RouterLocationState = LocationState; -// Cast event from TrezorConnect event listener to react Action -type DeviceEventAction = { - type: DeviceMessageType, - device: Device, -}; - -type TransportEventAction = { - type: TransportMessageType, - payload: any, -}; - -type UiEventAction = { - type: UiMessageType, - payload: any, - // payload: { - // device: Device; - // code?: string; - // }, -}; - -// TODO: join this message with uiMessage -type IFrameHandshake = { - type: 'iframe_handshake', - payload: any, -}; - export type Action = | RouterAction - | IFrameHandshake - | TransportEventAction - | DeviceEventAction - | UiEventAction + | TransportEvent + | DeviceEvent + | UiEvent | BlockchainEvent | SelectedAccountAction | AccountAction diff --git a/src/reducers/DevicesReducer.js b/src/reducers/DevicesReducer.js index 34dd677c..02e59e4b 100644 --- a/src/reducers/DevicesReducer.js +++ b/src/reducers/DevicesReducer.js @@ -62,8 +62,9 @@ const mergeDevices = (current: TrezorDevice, upcoming: Device | TrezorDevice): T } return { ...upcoming, - features: null, ...extended, + features: null, + state: null, }; }; @@ -79,9 +80,7 @@ const addDevice = (state: State, device: Device): State => { } otherDevices = state.filter(d => affectedDevices.indexOf(d) === -1); } else { - affectedDevices = state.filter( - d => d.features && device.features && d.features.device_id === device.features.device_id - ); + affectedDevices = state.filter(d => d.features && device.features && d.id === device.id); const unacquiredDevices = state.filter(d => d.path.length > 0 && d.path === device.path); otherDevices = state.filter( d => affectedDevices.indexOf(d) < 0 && unacquiredDevices.indexOf(d) < 0 @@ -191,7 +190,7 @@ const changeDevice = (state: State, device: Device | TrezorDevice, extended: Obj d => (d.features && device.features && - d.features.device_id === device.features.device_id && + d.id === device.id && d.features.passphrase_protection === device.features.passphrase_protection) || (d.features && d.path.length > 0 && d.path === device.path) ); @@ -247,7 +246,7 @@ const forgetDevice = (state: State, device: TrezorDevice): State => state.filter( d => d.remember || - (d.features && device.features && d.features.device_id !== device.features.device_id) || + (d.features && device.features && d.id !== device.id) || (!d.features && d.path !== device.path) ); @@ -261,9 +260,7 @@ const forgetSingleDevice = (state: State, device: TrezorDevice): State => { const disconnectDevice = (state: State, device: Device): State => { const affectedDevices: State = state.filter( - d => - d.path === device.path || - (d.features && device.features && d.features.device_id === device.features.device_id) + d => d.path === device.path || (d.features && device.features && d.id === device.id) ); const otherDevices: State = state.filter(d => affectedDevices.indexOf(d) === -1); @@ -308,9 +305,7 @@ const onSelectedDevice = (state: State, device: ?TrezorDevice): State => { const onChangeWalletType = (state: State, device: TrezorDevice, hidden: boolean): State => { const affectedDevices: State = state.filter( - d => - d.path === device.path || - (d.features && device.features && d.features.device_id === device.features.device_id) + d => d.path === device.path || (d.features && device.features && d.id === device.id) ); const otherDevices: State = state.filter(d => affectedDevices.indexOf(d) === -1); if (affectedDevices.length > 0) { @@ -354,16 +349,16 @@ export default function devices(state: State = initialState, action: Action): St case DEVICE.CONNECT: case DEVICE.CONNECT_UNACQUIRED: - return addDevice(state, action.device); + return addDevice(state, action.payload); case DEVICE.CHANGED: // return changeDevice(state, { ...action.device, connected: true, available: true }); - return changeDevice(state, action.device, { connected: true, available: true }); + return changeDevice(state, action.payload, { connected: true, available: true }); // TODO: check if available will propagate to unavailable case DEVICE.DISCONNECT: // case DEVICE.DISCONNECT_UNACQUIRED: - return disconnectDevice(state, action.device); + return disconnectDevice(state, action.payload); case WALLET.SET_SELECTED_DEVICE: return onSelectedDevice(state, action.device); diff --git a/src/reducers/ModalReducer.js b/src/reducers/ModalReducer.js index ee3c993d..f72fd0f7 100644 --- a/src/reducers/ModalReducer.js +++ b/src/reducers/ModalReducer.js @@ -67,7 +67,7 @@ export default function modal(state: State = initialState, action: Action): Stat case DEVICE.DISCONNECT: if ( state.context === MODAL.CONTEXT_DEVICE && - action.device.path === state.device.path + action.payload.path === state.device.path ) { return initialState; } @@ -78,14 +78,14 @@ export default function modal(state: State = initialState, action: Action): Stat case UI.REQUEST_PASSPHRASE: return { context: MODAL.CONTEXT_DEVICE, - device: action.payload.device, + device: (action.payload.device: any), // should be TrezorDevice, but ath this point it doesn't matter, Device is enough windowType: action.type, }; case UI.REQUEST_BUTTON: return { context: MODAL.CONTEXT_DEVICE, - device: action.payload.device, + device: (action.payload.device: any), // should be TrezorDevice, but ath this point it doesn't matter, Device is enough windowType: action.payload.code, }; diff --git a/src/reducers/NotificationReducer.js b/src/reducers/NotificationReducer.js index 4e387698..5ae86fe9 100644 --- a/src/reducers/NotificationReducer.js +++ b/src/reducers/NotificationReducer.js @@ -66,7 +66,7 @@ const closeNotification = (state: State, payload: any): State => { export default function notification(state: State = initialState, action: Action): State { switch (action.type) { case DEVICE.DISCONNECT: { - const { path } = action.device; // Flow warning + const { path } = action.payload; return state.filter(entry => entry.devicePath !== path); } diff --git a/src/reducers/TrezorConnectReducer.js b/src/reducers/TrezorConnectReducer.js index 7d087f18..a35f442f 100644 --- a/src/reducers/TrezorConnectReducer.js +++ b/src/reducers/TrezorConnectReducer.js @@ -1,7 +1,7 @@ /* @flow */ -import { TRANSPORT, UI } from 'trezor-connect'; +import { TRANSPORT, IFRAME } from 'trezor-connect'; import * as CONNECT from 'actions/constants/TrezorConnect'; - +import type { TransportInfo, BridgeInfo } from 'trezor-connect'; import type { Action } from 'flowtype'; export type SelectedDevice = { @@ -9,26 +9,14 @@ export type SelectedDevice = { instance: ?number, }; -export type LatestBridge = { - version: Array, - directory: string, - packages: Array<{ name: string, url: string, signature?: string, preferred: boolean }>, - changelog: Array, -}; - export type State = { initialized: boolean, error: ?string, transport: - | { - type: string, - version: string, - outdated: boolean, - bridge: LatestBridge, - } + | TransportInfo | { type: null, - bridge: LatestBridge, + bridge: ?BridgeInfo, }, // browserState: { // name: string; @@ -46,12 +34,7 @@ const initialState: State = { error: null, transport: { type: null, - bridge: { - version: [], - directory: '', - packages: [], - changelog: [], - }, + bridge: null, }, browserState: {}, acquiringDevice: false, @@ -66,11 +49,10 @@ export default function connect(state: State = initialState, action: Action): St error: action.error, }; // trezor-connect iframe loaded - case UI.IFRAME_HANDSHAKE: + case IFRAME.LOADED: return { ...state, initialized: true, - browserState: action.payload.browser, }; // trezor-connect (trezor-link) initialized case TRANSPORT.START: diff --git a/src/reducers/WalletReducer.js b/src/reducers/WalletReducer.js index 04d3a15e..f3ce5ad0 100644 --- a/src/reducers/WalletReducer.js +++ b/src/reducers/WalletReducer.js @@ -98,7 +98,7 @@ export default function wallet(state: State = initialState, action: Action): Sta }; case DEVICE.DISCONNECT: - if (state.disconnectRequest && action.device.path === state.disconnectRequest.path) { + if (state.disconnectRequest && action.payload.path === state.disconnectRequest.path) { return { ...state, disconnectRequest: null, diff --git a/src/services/LogService.js b/src/services/LogService.js index ee9d7d31..55f395d6 100644 --- a/src/services/LogService.js +++ b/src/services/LogService.js @@ -34,10 +34,10 @@ const LogService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispatch ); break; case DEVICE.CONNECT: - api.dispatch(LogActions.add('Device connected', action.device)); + api.dispatch(LogActions.add('Device connected', action.payload)); break; case DEVICE.DISCONNECT: - api.dispatch(LogActions.add('Device disconnected', action.device)); + api.dispatch(LogActions.add('Device disconnected', action.payload)); break; case DISCOVERY.START: api.dispatch(LogActions.add('Discovery started', action)); diff --git a/src/services/TrezorConnectService.js b/src/services/TrezorConnectService.js index d327ab5a..608b83f3 100644 --- a/src/services/TrezorConnectService.js +++ b/src/services/TrezorConnectService.js @@ -30,7 +30,7 @@ const TrezorConnectService: Middleware = (api: MiddlewareAPI) => (next: Middlewa } else if (action.type === BLOCKCHAIN_READY) { api.dispatch(TrezorConnectActions.postInit()); } else if (action.type === DEVICE.DISCONNECT) { - api.dispatch(TrezorConnectActions.deviceDisconnect(action.device)); + api.dispatch(TrezorConnectActions.deviceDisconnect(action.payload)); } else if (action.type === CONNECT.REMEMBER_REQUEST) { api.dispatch(ModalActions.onRememberRequest(prevModalState)); } else if (action.type === CONNECT.FORGET) { @@ -48,7 +48,7 @@ const TrezorConnectService: Middleware = (api: MiddlewareAPI) => (next: Middlewa api.dispatch(RouterActions.selectFirstAvailableDevice()); } } else if (action.type === DEVICE.CONNECT || action.type === DEVICE.CONNECT_UNACQUIRED) { - api.dispatch(ModalActions.onDeviceConnect(action.device)); + api.dispatch(ModalActions.onDeviceConnect(action.payload)); } else if (action.type === CONNECT.DUPLICATE) { api.dispatch(RouterActions.selectDevice(action.device)); } else if (action.type === BLOCKCHAIN.BLOCK) { diff --git a/src/services/WalletService.js b/src/services/WalletService.js index 1e42ab55..095356fe 100644 --- a/src/services/WalletService.js +++ b/src/services/WalletService.js @@ -56,7 +56,7 @@ const WalletService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispa api.dispatch(TrezorConnectActions.requestWalletType()); break; case DEVICE.CONNECT: - api.dispatch(WalletActions.clearUnavailableDevicesData(prevState, action.device)); + api.dispatch(WalletActions.clearUnavailableDevicesData(prevState, action.payload)); break; default: { break; diff --git a/src/utils/url.js b/src/utils/url.js index 44bc38cf..1e427f83 100644 --- a/src/utils/url.js +++ b/src/utils/url.js @@ -4,7 +4,7 @@ import type { TrezorDevice } from 'flowtype'; const getOldWalletUrl = (device: ?TrezorDevice): string => { if (!device || !device.firmwareRelease) return urlConstants.OLD_WALLET_BETA; - const release = device.firmwareRelease; + const { release } = device.firmwareRelease; const url = release.channel === 'beta' ? urlConstants.OLD_WALLET_BETA : urlConstants.OLD_WALLET; return url; }; @@ -12,7 +12,7 @@ const getOldWalletUrl = (device: ?TrezorDevice): string => { // TODO: use uri template to build urls const getOldWalletReleaseUrl = (device: ?TrezorDevice): string => { if (!device || !device.firmwareRelease) return urlConstants.OLD_WALLET_BETA; - const release = device.firmwareRelease; + const { release } = device.firmwareRelease; const url = getOldWalletUrl(device); const version = release.version.join('.'); return `${url}?fw=${version}`; diff --git a/src/views/Landing/views/InstallBridge/index.js b/src/views/Landing/views/InstallBridge/index.js index 268f57fa..fca506a4 100644 --- a/src/views/Landing/views/InstallBridge/index.js +++ b/src/views/Landing/views/InstallBridge/index.js @@ -117,12 +117,15 @@ const GoBack = styled.span` class InstallBridge extends PureComponent { constructor(props: Props) { super(props); + const { transport } = props; + const packages = transport.bridge ? transport.bridge.packages : []; + const version = transport.bridge ? transport.bridge.packages : []; - const installers = props.transport.bridge.packages.map(p => ({ + const installers = packages.map(p => ({ label: p.name, value: p.url, signature: p.signature, - preferred: p.preferred, + preferred: !!p.preferred, })); const currentTarget: ?InstallTarget = installers.find(i => i.preferred === true); @@ -131,7 +134,7 @@ class InstallBridge extends PureComponent { props.transport.type && props.transport.type === 'bridge' ? `Your version ${props.transport.version}` : 'Not installed', - latestVersion: props.transport.bridge.version.join('.'), + latestVersion: version.join('.'), installers, target: currentTarget || installers[0], uri: 'https://wallet.trezor.io/data/', diff --git a/src/views/Wallet/components/LeftNavigation/components/CoinMenu/index.js b/src/views/Wallet/components/LeftNavigation/components/CoinMenu/index.js index f6896513..534d2ef0 100644 --- a/src/views/Wallet/components/LeftNavigation/components/CoinMenu/index.js +++ b/src/views/Wallet/components/LeftNavigation/components/CoinMenu/index.js @@ -46,8 +46,8 @@ class CoinMenu extends PureComponent { getBaseUrl() { const { selectedDevice } = this.props.wallet; let baseUrl = ''; - if (selectedDevice && selectedDevice.features) { - baseUrl = `/device/${selectedDevice.features.device_id}`; + if (selectedDevice && selectedDevice.id) { + baseUrl = `/device/${selectedDevice.id}`; if (selectedDevice.instance) { baseUrl += `:${selectedDevice.instance}`; } diff --git a/src/views/Wallet/views/Dashboard/index.js b/src/views/Wallet/views/Dashboard/index.js index 2fbc8120..6baa0f1e 100644 --- a/src/views/Wallet/views/Dashboard/index.js +++ b/src/views/Wallet/views/Dashboard/index.js @@ -63,8 +63,8 @@ const StyledH4 = styled(H4)` const getBaseUrl = device => { let baseUrl = ''; - if (device && device.features) { - baseUrl = `/device/${device.features.device_id}`; + if (device && device.id) { + baseUrl = `/device/${device.id}`; if (device.instance) { baseUrl += `:${device.instance}`; } From 2231f42b372efc7c0bcbcbf3a5ee92a1516ef7f5 Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Mon, 30 Mar 2020 20:44:17 +0200 Subject: [PATCH 03/21] update Blockchain and Discovery using trezor-connect@8 --- public/data/appConfig.json | 14 +- src/actions/BlockchainActions.js | 33 +++-- src/actions/ImportAccountActions.js | 144 +++++-------------- src/actions/ethereum/BlockchainActions.js | 137 +++++++----------- src/actions/ethereum/DiscoveryActions.js | 95 ++++--------- src/actions/ripple/BlockchainActions.js | 164 ++++++---------------- src/actions/ripple/DiscoveryActions.js | 34 +---- src/reducers/AccountsReducer.js | 47 ++++--- src/reducers/BlockchainReducer.js | 27 ++-- src/reducers/DiscoveryReducer.js | 29 ---- 10 files changed, 227 insertions(+), 497 deletions(-) diff --git a/public/data/appConfig.json b/public/data/appConfig.json index 1703c331..48221a88 100644 --- a/public/data/appConfig.json +++ b/public/data/appConfig.json @@ -15,7 +15,7 @@ "name": "Ethereum", "symbol": "ETH", "shortcut": "eth", - "bip44": "m/44'/60'/0'/0", + "bip44": "m/44'/60'/0'/0/a", "chainId": 1, "defaultGasPrice": 64, "defaultGasLimit": 21000, @@ -26,8 +26,8 @@ "wss://eth2.trezor.io/geth" ], "explorer": { - "tx": "https://etherscan.io/tx/", - "address": "https://etherscan.io/address/" + "tx": "https://eth1.trezor.io/tx/", + "address": "https://eth1.trezor.io/tx/" }, "hasSignVerify": true }, @@ -38,7 +38,7 @@ "symbol": "ETC", "shortcut": "etc", "chainId": 61, - "bip44": "m/44'/61'/0'/0", + "bip44": "m/44'/61'/0'/0/a", "defaultGasPrice": 64, "defaultGasLimit": 21000, "defaultGasLimitTokens": 200000, @@ -61,7 +61,7 @@ "symbol": "tROP", "shortcut": "trop", "chainId": 3, - "bip44": "m/44'/60'/0'/0", + "bip44": "m/44'/60'/0'/0/a", "defaultGasPrice": 64, "defaultGasLimit": 21000, "defaultGasLimitTokens": 200000, @@ -83,8 +83,8 @@ "wss://ropsten1.trezor.io/geth" ], "explorer": { - "tx": "https://ropsten.etherscan.io/tx/", - "address": "https://ropsten.etherscan.io/address/" + "tx": "https://ropsten1.trezor.io/tx/", + "address": "https://ropsten1.trezor.io/address/" }, "hasSignVerify": true }, diff --git a/src/actions/BlockchainActions.js b/src/actions/BlockchainActions.js index 1e5e12c7..cf38efa6 100644 --- a/src/actions/BlockchainActions.js +++ b/src/actions/BlockchainActions.js @@ -76,32 +76,31 @@ export const subscribe = (networkName: string): PromiseAction => async ( } }; -export const onBlockMined = ( - payload: $ElementType -): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { +export const onBlockMined = (payload: BlockchainBlock): PromiseAction => async ( + dispatch: Dispatch, + getState: GetState +): Promise => { const shortcut = payload.coin.shortcut.toLowerCase(); - const { block } = payload; - if (getState().router.location.state.network !== shortcut) return; - const { config } = getState().localStorage; const network = config.networks.find(c => c.shortcut === shortcut); if (!network) return; switch (network.type) { case 'ethereum': - await dispatch(EthereumBlockchainActions.onBlockMined(shortcut)); + await dispatch(EthereumBlockchainActions.onBlockMined(network)); break; case 'ripple': - await dispatch(RippleBlockchainActions.onBlockMined(shortcut, block)); + await dispatch(RippleBlockchainActions.onBlockMined(network)); break; default: break; } }; -export const onNotification = ( - payload: $ElementType -): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { +export const onNotification = (payload: BlockchainNotification): PromiseAction => async ( + dispatch: Dispatch, + getState: GetState +): Promise => { const shortcut = payload.coin.shortcut.toLowerCase(); const { config } = getState().localStorage; const network = config.networks.find(c => c.shortcut === shortcut); @@ -109,11 +108,10 @@ export const onNotification = ( switch (network.type) { case 'ethereum': - // this is not working until blockchain-link will start support blockbook backends - await dispatch(EthereumBlockchainActions.onNotification(payload)); + await dispatch(EthereumBlockchainActions.onNotification(payload, network)); break; case 'ripple': - await dispatch(RippleBlockchainActions.onNotification(payload)); + await dispatch(RippleBlockchainActions.onNotification(payload, network)); break; default: break; @@ -122,9 +120,10 @@ export const onNotification = ( // Handle BLOCKCHAIN.ERROR event from TrezorConnect // disconnect and remove Web3 websocket instance if exists -export const onError = ( - payload: $ElementType -): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { +export const onError = (payload: BlockchainError): PromiseAction => async ( + dispatch: Dispatch, + getState: GetState +): Promise => { const shortcut = payload.coin.shortcut.toLowerCase(); const { config } = getState().localStorage; const network = config.networks.find(c => c.shortcut === shortcut); diff --git a/src/actions/ImportAccountActions.js b/src/actions/ImportAccountActions.js index 91a16277..9e779279 100644 --- a/src/actions/ImportAccountActions.js +++ b/src/actions/ImportAccountActions.js @@ -4,10 +4,9 @@ import * as ACCOUNT from 'actions/constants/account'; import * as IMPORT from 'actions/constants/importAccount'; import * as NOTIFICATION from 'actions/constants/notification'; import type { AsyncAction, Account, TrezorDevice, Network, Dispatch, GetState } from 'flowtype'; -import * as BlockchainActions from 'actions/ethereum/BlockchainActions'; import * as LocalStorageActions from 'actions/LocalStorageActions'; import TrezorConnect from 'trezor-connect'; -import { toDecimalAmount } from 'utils/formatUtils'; +import { enhanceAccount } from 'utils/accountUtils'; export type ImportAccountAction = | { @@ -23,10 +22,7 @@ export type ImportAccountAction = const findIndex = (accounts: Array, network: Network, device: TrezorDevice): number => { return accounts.filter( - a => - a.imported === true && - a.network === network.shortcut && - a.deviceID === (device.features || {}).device_id + a => a.imported === true && a.network === network.shortcut && a.deviceID === device.id ).length; }; @@ -35,113 +31,22 @@ export const importAddress = ( network: Network, device: ?TrezorDevice ): AsyncAction => async (dispatch: Dispatch, getState: GetState): Promise => { - if (!device) return; + if (!device || !device.features) return; dispatch({ type: IMPORT.START, }); - let payload; - try { - if (network.type === 'ethereum') { - const account = await dispatch( - BlockchainActions.discoverAccount(device, address, network.shortcut) - ); - - const index = findIndex(getState().accounts, network, device); - - const empty = account.nonce <= 0 && account.balance === '0'; - payload = { - imported: true, - index, - network: network.shortcut, - deviceID: device.features ? device.features.device_id : '0', - deviceState: device.state || '0', - accountPath: account.path || [], - descriptor: account.descriptor, - - balance: account.balance, - availableBalance: account.balance, - block: account.block, - transactions: account.transactions, - empty, - - networkType: 'ethereum', - nonce: account.nonce, - }; - dispatch({ - type: ACCOUNT.CREATE, - payload, - }); - dispatch({ - type: IMPORT.SUCCESS, - }); - dispatch(LocalStorageActions.setImportedAccount(payload)); - dispatch({ - type: NOTIFICATION.ADD, - payload: { - variant: 'success', - title: 'The account has been successfully imported', - cancelable: true, - }, - }); - } else if (network.type === 'ripple') { - const response = await TrezorConnect.rippleGetAccountInfo({ - account: { - descriptor: address, - }, - coin: network.shortcut, - }); - - // handle TREZOR response error - if (!response.success) { - throw new Error(response.payload.error); - } - - const account = response.payload; - const empty = account.sequence <= 0 && account.balance === '0'; - const index = findIndex(getState().accounts, network, device); - - payload = { - imported: true, - index, - network: network.shortcut, - deviceID: device.features ? device.features.device_id : '0', - deviceState: device.state || '0', - accountPath: account.path || [], - descriptor: account.descriptor, - - balance: toDecimalAmount(account.balance, network.decimals), - availableBalance: toDecimalAmount(account.availableBalance, network.decimals), - block: account.block, - transactions: account.transactions, - empty, + const response = await TrezorConnect.getAccountInfo({ + descriptor: address, + coin: network.shortcut, + }); - networkType: 'ripple', - sequence: account.sequence, - reserve: toDecimalAmount(account.reserve, network.decimals), - }; - dispatch({ - type: ACCOUNT.CREATE, - payload, - }); - dispatch({ - type: IMPORT.SUCCESS, - }); - dispatch(LocalStorageActions.setImportedAccount(payload)); - dispatch({ - type: NOTIFICATION.ADD, - payload: { - variant: 'success', - title: 'The account has been successfully imported', - cancelable: true, - }, - }); - } - } catch (error) { + // handle TREZOR response error + if (!response.success) { dispatch({ type: IMPORT.FAIL, - error: error.message, + error: response.payload.error, }); dispatch({ @@ -149,9 +54,36 @@ export const importAddress = ( payload: { variant: 'error', title: 'Import account error', - message: error.message, + message: response.payload.error, cancelable: true, }, }); + + return; } + + const index = findIndex(getState().accounts, network, device); + const account = enhanceAccount(response.payload, { + imported: true, + index, + network, + device, + }); + + dispatch({ + type: ACCOUNT.CREATE, + payload: account, + }); + dispatch({ + type: IMPORT.SUCCESS, + }); + dispatch(LocalStorageActions.setImportedAccount(account)); + dispatch({ + type: NOTIFICATION.ADD, + payload: { + variant: 'success', + title: 'The account has been successfully imported', + cancelable: true, + }, + }); }; diff --git a/src/actions/ethereum/BlockchainActions.js b/src/actions/ethereum/BlockchainActions.js index 9ceb83e4..ac299de1 100644 --- a/src/actions/ethereum/BlockchainActions.js +++ b/src/actions/ethereum/BlockchainActions.js @@ -3,47 +3,14 @@ import TrezorConnect from 'trezor-connect'; import BigNumber from 'bignumber.js'; import * as PENDING from 'actions/constants/pendingTx'; +import * as AccountsActions from 'actions/AccountsActions'; +import * as Web3Actions from 'actions/Web3Actions'; +import { mergeAccount, enhanceTransaction } from 'utils/accountUtils'; -import type { TrezorDevice, Dispatch, GetState, PromiseAction } from 'flowtype'; -import type { EthereumAccount, BlockchainNotification } from 'trezor-connect'; +import type { Dispatch, GetState, PromiseAction, Network } from 'flowtype'; +import type { BlockchainNotification } from 'trezor-connect'; import type { Token } from 'reducers/TokensReducer'; import type { NetworkToken } from 'reducers/LocalStorageReducer'; -import * as Web3Actions from 'actions/Web3Actions'; -import * as AccountsActions from 'actions/AccountsActions'; - -export const discoverAccount = ( - device: TrezorDevice, - descriptor: string, - network: string -): PromiseAction => async (dispatch: Dispatch): Promise => { - // get data from connect - const txs = await TrezorConnect.ethereumGetAccountInfo({ - account: { - descriptor, - block: 0, - transactions: 0, - balance: '0', - availableBalance: '0', - nonce: 0, - }, - coin: network, - }); - - if (!txs.success) { - throw new Error(txs.payload.error); - } - - // blockbook web3 fallback - const web3account = await dispatch(Web3Actions.discoverAccount(descriptor, network)); - return { - descriptor, - transactions: txs.payload.transactions, - block: txs.payload.block, - balance: web3account.balance, - availableBalance: web3account.balance, - nonce: web3account.nonce, - }; -}; export const getTokenInfo = (input: string, network: string): PromiseAction => async ( dispatch: Dispatch @@ -103,9 +70,9 @@ export const subscribe = (network: string): PromiseAction => async ( dispatch: Dispatch, getState: GetState ): Promise => { - const accounts: Array = getState() + const accounts = getState() .accounts.filter(a => a.network === network) - .map(a => a.descriptor); // eslint-disable-line no-unused-vars + .map(a => ({ descriptor: a.descriptor })); const response = await TrezorConnect.blockchainSubscribe({ accounts, coin: network, @@ -115,7 +82,7 @@ export const subscribe = (network: string): PromiseAction => async ( await dispatch(Web3Actions.initWeb3(network)); }; -export const onBlockMined = (network: string): PromiseAction => async ( +export const onBlockMined = (network: Network): PromiseAction => async ( dispatch: Dispatch, getState: GetState ): Promise => { @@ -123,56 +90,52 @@ export const onBlockMined = (network: string): PromiseAction => async ( // check latest saved transaction blockhash against blockhheight // try to resolve pending transactions - await dispatch(Web3Actions.resolvePendingTransactions(network)); - - await dispatch(Web3Actions.updateGasPrice(network)); - - const accounts: Array = getState().accounts.filter(a => a.network === network); - if (accounts.length > 0) { - // find out which account changed - const response = await TrezorConnect.ethereumGetAccountInfo({ - accounts, - coin: network, - }); - - if (response.success) { - response.payload.forEach((a, i) => { - if (a.transactions > 0) { - // load additional data from Web3 (balance, nonce, tokens) - dispatch(Web3Actions.updateAccount(accounts[i], a, network)); - } else { - // there are no new txs, just update block - // TODO: There still could be internal transactions as a result of contract - // If that's the case, account balance won't be updated - // Currently waiting for deprecating web3 and utilising new blockbook - dispatch(AccountsActions.update({ ...accounts[i], block: a.block })); - - // HACK: since blockbook can't work with smart contracts for now - // try to update tokens balances added to this account using Web3 - dispatch(Web3Actions.updateAccountTokens(accounts[i])); - } - }); - } - } + await dispatch(Web3Actions.resolvePendingTransactions(network.shortcut)); + + await dispatch(Web3Actions.updateGasPrice(network.shortcut)); + + const accounts = getState().accounts.filter(a => a.network === network.shortcut); + if (accounts.length === 0) return; + const blockchain = getState().blockchain.find(b => b.shortcut === network.shortcut); + if (!blockchain) return; // flowtype fallback + + // find out which account changed + const bundle = accounts.map(a => ({ descriptor: a.descriptor, coin: network.shortcut })); + const response = await TrezorConnect.getAccountInfo({ bundle }); + + if (!response.success) return; + + response.payload.forEach((info, i) => { + dispatch( + AccountsActions.update(mergeAccount(info, accounts[i], network, blockchain.block)) + ); + dispatch(Web3Actions.updateAccountTokens(accounts[i])); + }); }; export const onNotification = ( - payload: $ElementType + payload: BlockchainNotification, + network: Network ): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const { notification } = payload; - const account = getState().accounts.find(a => a.descriptor === notification.descriptor); - if (!account) return; - - if (!notification.blockHeight) { - dispatch({ - type: PENDING.ADD, - payload: { - ...notification, - deviceState: account.deviceState, - network: account.network, - }, - }); - } + const { descriptor, tx } = payload.notification; + const account = getState().accounts.find(a => a.descriptor === descriptor); + const blockchain = getState().blockchain.find(b => b.shortcut === network.shortcut); + if (!account || !blockchain) return; + dispatch({ + type: PENDING.ADD, + payload: enhanceTransaction(account, tx, network), + }); + + const response = await TrezorConnect.getAccountInfo({ + descriptor: account.descriptor, + coin: account.network, + }); + + if (!response.success) return; + + dispatch( + AccountsActions.update(mergeAccount(response.payload, account, network, blockchain.block)) + ); }; export const onError = (network: string): PromiseAction => async ( diff --git a/src/actions/ethereum/DiscoveryActions.js b/src/actions/ethereum/DiscoveryActions.js index d7b8bc03..85864a31 100644 --- a/src/actions/ethereum/DiscoveryActions.js +++ b/src/actions/ethereum/DiscoveryActions.js @@ -1,10 +1,8 @@ /* @flow */ import TrezorConnect from 'trezor-connect'; -import EthereumjsUtil from 'ethereumjs-util'; import * as DISCOVERY from 'actions/constants/discovery'; -import * as BlockchainActions from 'actions/ethereum/BlockchainActions'; - +import { enhanceAccount } from 'utils/accountUtils'; import type { PromiseAction, Dispatch, GetState, TrezorDevice, Network, Account } from 'flowtype'; import type { Discovery } from 'reducers/DiscoveryReducer'; @@ -13,30 +11,41 @@ export type DiscoveryStartAction = { networkType: 'ethereum', network: Network, device: TrezorDevice, - publicKey: string, - chainCode: string, - basePath: Array, }; -// first iteration -// generate public key for this account -// start discovery process export const begin = ( device: TrezorDevice, network: Network -): PromiseAction => async (): Promise => { - // get xpub from TREZOR - const response = await TrezorConnect.getPublicKey({ +): PromiseAction => async (): Promise => ({ + type: DISCOVERY.START, + networkType: 'ethereum', + network, + device, +}); + +export const discoverAccount = ( + device: TrezorDevice, + discoveryProcess: Discovery +): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { + const { config } = getState().localStorage; + const network = config.networks.find(c => c.shortcut === discoveryProcess.network); + if (!network) throw new Error('Discovery network not found'); + + const { accountIndex } = discoveryProcess; + const path = network.bip44.slice(0).replace('a', accountIndex.toString()); + + const response = await TrezorConnect.getAccountInfo({ device: { path: device.path, instance: device.instance, state: device.state, }, - path: network.bip44, + path, + // details: 'tokenBalances', TODO: load ERC20 + pageSize: 1, keepSession: true, // acquire and hold session - //useEmptyPassphrase: !device.instance, useEmptyPassphrase: device.useEmptyPassphrase, - network: network.name, + coin: network.shortcut, }); // handle TREZOR response error @@ -44,59 +53,9 @@ export const begin = ( throw new Error(response.payload.error); } - const basePath: Array = response.payload.path; - - return { - type: DISCOVERY.START, - networkType: 'ethereum', + return enhanceAccount(response.payload, { + index: discoveryProcess.accountIndex, network, device, - publicKey: response.payload.publicKey, - chainCode: response.payload.chainCode, - basePath, - }; -}; - -export const discoverAccount = ( - device: TrezorDevice, - discoveryProcess: Discovery -): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const { config } = getState().localStorage; - const network = config.networks.find(c => c.shortcut === discoveryProcess.network); - if (!network) throw new Error('Discovery network not found'); - - const derivedKey = discoveryProcess.hdKey.derive(`m/${discoveryProcess.accountIndex}`); - const path = discoveryProcess.basePath.concat(discoveryProcess.accountIndex); - const publicAddress: string = EthereumjsUtil.publicToAddress( - derivedKey.publicKey, - true - ).toString('hex'); - const ethAddress: string = EthereumjsUtil.toChecksumAddress(publicAddress); - - // TODO: check if address was created before - const account = await dispatch( - BlockchainActions.discoverAccount(device, ethAddress, network.shortcut) - ); - - // const accountIsEmpty = account.transactions <= 0 && account.nonce <= 0 && account.balance === '0'; - const empty = account.nonce <= 0 && account.balance === '0'; - - return { - imported: false, - index: discoveryProcess.accountIndex, - network: network.shortcut, - deviceID: device.features ? device.features.device_id : '0', - deviceState: device.state || '0', - accountPath: path, - descriptor: ethAddress, - - balance: account.balance, - availableBalance: account.balance, - block: account.block, - transactions: account.transactions, - empty, - - networkType: 'ethereum', - nonce: account.nonce, - }; + }); }; diff --git a/src/actions/ripple/BlockchainActions.js b/src/actions/ripple/BlockchainActions.js index 8d19b9af..70d3ab87 100644 --- a/src/actions/ripple/BlockchainActions.js +++ b/src/actions/ripple/BlockchainActions.js @@ -4,7 +4,7 @@ import TrezorConnect from 'trezor-connect'; import * as BLOCKCHAIN from 'actions/constants/blockchain'; import * as PENDING from 'actions/constants/pendingTx'; import * as AccountsActions from 'actions/AccountsActions'; -import { toDecimalAmount } from 'utils/formatUtils'; +import { mergeAccount, enhanceTransaction } from 'utils/accountUtils'; import { observeChanges } from 'reducers/utils'; import type { BlockchainNotification } from 'trezor-connect'; @@ -20,10 +20,10 @@ import type { export const subscribe = (network: string): PromiseAction => async ( dispatch: Dispatch, getState: GetState -): Promise => { - const accounts: Array = getState() +) => { + const accounts = getState() .accounts.filter(a => a.network === network) - .map(a => a.descriptor); + .map(a => ({ descriptor: a.descriptor })); await TrezorConnect.blockchainSubscribe({ accounts, coin: network, @@ -47,161 +47,81 @@ export const getFeeLevels = (network: Network): PayloadAction => async ( +export const onBlockMined = (network: Network): PromiseAction => async ( dispatch: Dispatch, getState: GetState ): Promise => { - const blockchain = getState().blockchain.find(b => b.shortcut === networkShortcut); + const blockchain = getState().blockchain.find(b => b.shortcut === network.shortcut); if (!blockchain) return; // flowtype fallback // if last update was more than 5 minutes ago const now = new Date().getTime(); if (blockchain.feeTimestamp < now - 300000) { const feeRequest = await TrezorConnect.blockchainEstimateFee({ - coin: networkShortcut, + request: { + feeLevels: 'smart', + }, + coin: network.shortcut, }); if (feeRequest.success && observeChanges(blockchain.feeLevels, feeRequest.payload)) { // check if downloaded fee levels are different dispatch({ type: BLOCKCHAIN.UPDATE_FEE, - shortcut: networkShortcut, - feeLevels: feeRequest.payload, + shortcut: network.shortcut, + feeLevels: feeRequest.payload.levels.map(l => ({ + name: 'Normal', + value: l.feePerUnit, + })), }); } } // TODO: check for blockchain rollbacks here! - const accounts: Array = getState().accounts.filter(a => a.network === networkShortcut); + const accounts = getState().accounts.filter(a => a.network === network.shortcut); if (accounts.length === 0) return; - const { networks } = getState().localStorage.config; - const network = networks.find(c => c.shortcut === networkShortcut); - if (!network) return; - - // HACK: Since Connect always returns account.transactions as 0 - // we don't have info about new transactions for the account since last update. - // Untill there is a better solution compare accounts block. - // If we missed some blocks (wallet was offline) we'll update the account - // If we are update to date with the last block that means wallet was online - // and we would get Blockchain notification about new transaction if needed - accounts.forEach(async account => { - const missingBlocks = account.block !== block - 1; - if (!missingBlocks) { - // account was last updated on account.block, current block is +1, we didn't miss single block - // if there was new tx, blockchain notification would let us know - // so just update the block for the account - dispatch( - AccountsActions.update({ - ...account, - block, - }) - ); - } else { - // we missed some blocks (wallet was offline). get updated account info from connect - const response = await TrezorConnect.rippleGetAccountInfo({ - account: { - descriptor: account.descriptor, - }, - level: 'transactions', - coin: networkShortcut, - }); - if (!response.success) return; - - const updatedAccount = response.payload; - - // new txs - dispatch( - AccountsActions.update({ - ...account, - balance: toDecimalAmount(updatedAccount.balance, network.decimals), - availableBalance: toDecimalAmount( - updatedAccount.availableBalance, - network.decimals - ), - block: updatedAccount.block, - sequence: updatedAccount.sequence, - }) - ); - } + const bundle = accounts.map(a => ({ descriptor: a.descriptor, coin: network.shortcut })); + const response = await TrezorConnect.getAccountInfo({ bundle }); + + if (!response.success) return; + + response.payload.forEach((info, i) => { + dispatch( + AccountsActions.update(mergeAccount(info, accounts[i], network, blockchain.block)) + ); }); }; export const onNotification = ( - payload: $ElementType + payload: BlockchainNotification, + network: Network ): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const { notification } = payload; - const account = getState().accounts.find(a => a.descriptor === notification.descriptor); - if (!account) return; - const { network } = getState().selectedAccount; - if (!network) return; // flowtype fallback + const { descriptor, tx } = payload.notification; + const account = getState().accounts.find(a => a.descriptor === descriptor); + const blockchain = getState().blockchain.find(b => b.shortcut === network.shortcut); + if (!account || !blockchain) return; - if (!notification.blockHeight) { + if (!tx.blockHeight) { dispatch({ type: PENDING.ADD, - payload: { - ...notification, - deviceState: account.deviceState, - network: account.network, - - amount: toDecimalAmount(notification.amount, network.decimals), - total: - notification.type === 'send' - ? toDecimalAmount(notification.total, network.decimals) - : toDecimalAmount(notification.amount, network.decimals), - fee: toDecimalAmount(notification.fee, network.decimals), - }, + payload: enhanceTransaction(account, tx, network), }); - - // todo: replace "send success" notification with link to explorer } else { dispatch({ type: PENDING.TX_RESOLVED, - hash: notification.hash, + hash: tx.txid, }); } - // In case of tx sent between two Trezor accounts there is a possibility that only 1 notification will be received - // therefore we need to find target account and update data for it as well - const accountsToUpdate = [account]; - const targetAddress = - notification.type === 'send' - ? notification.outputs[0].addresses[0] - : notification.inputs[0].addresses[0]; - - const targetAccount = getState().accounts.find(a => a.descriptor === targetAddress); - if (targetAccount) { - accountsToUpdate.push(targetAccount); - } + const response = await TrezorConnect.getAccountInfo({ + descriptor: account.descriptor, + coin: account.network, + }); - accountsToUpdate.forEach(async a => { - const response = await TrezorConnect.rippleGetAccountInfo({ - account: { - descriptor: a.descriptor, - from: a.block, - history: false, - }, - coin: a.network, - }); + if (!response.success) return; - if (response.success) { - const updatedAccount = response.payload; - const empty = updatedAccount.sequence <= 0 && updatedAccount.balance === '0'; - dispatch( - AccountsActions.update({ - networkType: 'ripple', - ...a, - balance: toDecimalAmount(updatedAccount.balance, network.decimals), - availableBalance: toDecimalAmount( - updatedAccount.availableBalance, - network.decimals - ), - block: updatedAccount.block, - sequence: updatedAccount.sequence, - reserve: toDecimalAmount(updatedAccount.reserve, network.decimals), - empty, - }) - ); - } - }); + dispatch( + AccountsActions.update(mergeAccount(response.payload, account, network, blockchain.block)) + ); }; diff --git a/src/actions/ripple/DiscoveryActions.js b/src/actions/ripple/DiscoveryActions.js index 6ae2a332..0683b3da 100644 --- a/src/actions/ripple/DiscoveryActions.js +++ b/src/actions/ripple/DiscoveryActions.js @@ -2,7 +2,7 @@ import TrezorConnect from 'trezor-connect'; import * as DISCOVERY from 'actions/constants/discovery'; -import { toDecimalAmount } from 'utils/formatUtils'; +import { enhanceAccount } from 'utils/accountUtils'; import type { PromiseAction, GetState, Dispatch, TrezorDevice, Network, Account } from 'flowtype'; import type { Discovery } from 'reducers/DiscoveryReducer'; @@ -35,16 +35,13 @@ export const discoverAccount = ( const { accountIndex } = discoveryProcess; const path = network.bip44.slice(0).replace('a', accountIndex.toString()); - const response = await TrezorConnect.rippleGetAccountInfo({ + const response = await TrezorConnect.getAccountInfo({ device: { path: device.path, instance: device.instance, state: device.state, }, - account: { - path, - block: 0, - }, + path, keepSession: true, // acquire and hold session useEmptyPassphrase: device.useEmptyPassphrase, coin: network.shortcut, @@ -55,26 +52,9 @@ export const discoverAccount = ( throw new Error(response.payload.error); } - const account = response.payload; - const empty = account.sequence <= 0 && account.balance === '0'; - - return { - imported: false, + return enhanceAccount(response.payload, { index: discoveryProcess.accountIndex, - network: network.shortcut, - deviceID: device.features ? device.features.device_id : '0', - deviceState: device.state || '0', - accountPath: account.path || [], - descriptor: account.descriptor, - - balance: toDecimalAmount(account.balance, network.decimals), - availableBalance: toDecimalAmount(account.availableBalance, network.decimals), - block: account.block, - transactions: account.transactions, - empty, - - networkType: 'ripple', - sequence: account.sequence, - reserve: toDecimalAmount(account.reserve, network.decimals), - }; + network, + device, + }); }; diff --git a/src/reducers/AccountsReducer.js b/src/reducers/AccountsReducer.js index 22994c3f..2b643aba 100644 --- a/src/reducers/AccountsReducer.js +++ b/src/reducers/AccountsReducer.js @@ -6,13 +6,13 @@ import * as ACCOUNT from 'actions/constants/account'; import type { Action, TrezorDevice } from 'flowtype'; -type AccountCommon = { +type AccountCommon = {| +imported: boolean, +index: number, +network: string, // network id (shortcut) +deviceID: string, // empty for imported accounts +deviceState: string, // empty for imported accounts - +accountPath: Array, // empty for imported accounts + +accountPath: string, // empty for imported accounts +descriptor: string, // address or xpub balance: string, @@ -21,22 +21,31 @@ type AccountCommon = { empty: boolean, // account without transactions transactions: number, // deprecated -}; +|}; export type Account = - | (AccountCommon & { - networkType: 'ethereum', - nonce: number, - }) - | (AccountCommon & { - networkType: 'ripple', - sequence: number, - reserve: string, - }) - | (AccountCommon & { - networkType: 'bitcoin', - addressIndex: number, - }); + | {| + ...AccountCommon, + ...{| + networkType: 'ethereum', + nonce: string, + |}, + |} + | {| + ...AccountCommon, + ...{| + networkType: 'ripple', + sequence: number, + reserve: string, + |}, + |} + | {| + ...AccountCommon, + ...{| + networkType: 'bitcoin', + addressIndex: number, + |}, + |}; export type State = Array; @@ -51,14 +60,12 @@ export const findDeviceAccounts = ( return state.filter( addr => (addr.deviceState === device.state || - (addr.imported && addr.deviceID === (device.features || {}).device_id)) && + (addr.imported && addr.deviceID === device.id)) && addr.network === network ); } return state.filter( - addr => - addr.deviceState === device.state || - (addr.imported && addr.deviceID === (device.features || {}).device_id) + addr => addr.deviceState === device.state || (addr.imported && addr.deviceID === device.id) ); }; diff --git a/src/reducers/BlockchainReducer.js b/src/reducers/BlockchainReducer.js index d6a1e029..fd545ab4 100644 --- a/src/reducers/BlockchainReducer.js +++ b/src/reducers/BlockchainReducer.js @@ -4,7 +4,7 @@ import { BLOCKCHAIN as BLOCKCHAIN_EVENT } from 'trezor-connect'; import * as BLOCKCHAIN_ACTION from 'actions/constants/blockchain'; import type { Action } from 'flowtype'; -import type { BlockchainConnect, BlockchainError, BlockchainBlock } from 'trezor-connect'; +import type { BlockchainInfo, BlockchainError, BlockchainBlock } from 'trezor-connect'; export type BlockchainFeeLevel = { name: string, @@ -50,16 +50,15 @@ const onStartSubscribe = (state: State, shortcut: string): State => { ]); }; -const onConnect = (state: State, action: BlockchainConnect): State => { - const shortcut = action.payload.coin.shortcut.toLowerCase(); +const onConnect = (state: State, info: BlockchainInfo): State => { + const shortcut = info.coin.shortcut.toLowerCase(); const network = state.find(b => b.shortcut === shortcut); - const { info } = action.payload; if (network) { const others = state.filter(b => b !== network); return others.concat([ { ...network, - block: info.block, + block: info.blockHeight, connected: true, connecting: false, reconnectionAttempts: 0, @@ -73,15 +72,15 @@ const onConnect = (state: State, action: BlockchainConnect): State => { connected: true, connecting: false, reconnectionAttempts: 0, - block: info.block, + block: info.blockHeight, feeTimestamp: 0, feeLevels: [], }, ]); }; -const onError = (state: State, action: BlockchainError): State => { - const shortcut = action.payload.coin.shortcut.toLowerCase(); +const onError = (state: State, payload: BlockchainError): State => { + const shortcut = payload.coin.shortcut.toLowerCase(); const network = state.find(b => b.shortcut === shortcut); if (network) { const others = state.filter(b => b !== network); @@ -108,15 +107,15 @@ const onError = (state: State, action: BlockchainError): State => { ]); }; -const onBlock = (state: State, action: BlockchainBlock): State => { - const shortcut = action.payload.coin.shortcut.toLowerCase(); +const onBlock = (state: State, payload: BlockchainBlock): State => { + const shortcut = payload.coin.shortcut.toLowerCase(); const network = state.find(b => b.shortcut === shortcut); if (network) { const others = state.filter(b => b !== network); return others.concat([ { ...network, - block: action.payload.block, + block: payload.blockHeight, }, ]); } @@ -143,11 +142,11 @@ export default (state: State = initialState, action: Action): State => { case BLOCKCHAIN_ACTION.START_SUBSCRIBE: return onStartSubscribe(state, action.shortcut); case BLOCKCHAIN_EVENT.CONNECT: - return onConnect(state, action); + return onConnect(state, action.payload); case BLOCKCHAIN_EVENT.ERROR: - return onError(state, action); + return onError(state, action.payload); case BLOCKCHAIN_EVENT.BLOCK: - return onBlock(state, action); + return onBlock(state, action.payload); case BLOCKCHAIN_ACTION.UPDATE_FEE: return updateFee(state, action.shortcut, action.feeLevels); diff --git a/src/reducers/DiscoveryReducer.js b/src/reducers/DiscoveryReducer.js index 30b42061..ec7acb81 100644 --- a/src/reducers/DiscoveryReducer.js +++ b/src/reducers/DiscoveryReducer.js @@ -1,7 +1,5 @@ /* @flow */ -import HDKey from 'hdkey'; - import * as DISCOVERY from 'actions/constants/discovery'; import * as ACCOUNT from 'actions/constants/account'; import * as CONNECT from 'actions/constants/TrezorConnect'; @@ -27,10 +25,6 @@ export type Discovery = { waitingForBlockchain: boolean, fwNotSupported: boolean, fwOutdated: boolean, - - publicKey: string, // used in ethereum only - chainCode: string, // used in ethereum only - hdKey: HDKey, // used in ethereum only }; export type State = Array; @@ -46,10 +40,6 @@ const defaultDiscovery: Discovery = { waitingForBlockchain: false, fwNotSupported: false, fwOutdated: false, - - publicKey: '', - chainCode: '', - hdKey: null, }; const findIndex = (state: State, network: string, deviceState: string): number => @@ -63,18 +53,6 @@ const start = (state: State, action: DiscoveryStartAction): State => { deviceState, }; - if (action.networkType === 'ethereum') { - const hdKey = new HDKey(); - hdKey.publicKey = Buffer.from(action.publicKey, 'hex'); - hdKey.chainCode = Buffer.from(action.chainCode, 'hex'); - - instance.hdKey = hdKey; - instance.publicKey = action.publicKey; - instance.chainCode = action.chainCode; - - instance.basePath = action.basePath; - } - const newState: State = [...state]; const index: number = findIndex(state, action.network.shortcut, deviceState); if (index >= 0) { @@ -202,15 +180,8 @@ export default function discovery(state: State = initialState, action: Action): return notSupported(state, action); case DISCOVERY.FROM_STORAGE: return action.payload.map(d => { - if (d.publicKey.length < 1) return d; - // recreate ethereum discovery HDKey - // deprecated: will be removed after switching to blockbook - const hdKey: HDKey = new HDKey(); - hdKey.publicKey = Buffer.from(d.publicKey, 'hex'); - hdKey.chainCode = Buffer.from(d.chainCode, 'hex'); return { ...d, - hdKey, interrupted: false, waitingForDevice: false, waitingForBlockchain: false, From 11bf91b093ced19347dc7876cb5714cbb63d3396 Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Mon, 30 Mar 2020 20:46:07 +0200 Subject: [PATCH 04/21] update SendForm and PendingTx using trezor-connect@8 --- src/actions/SignVerifyActions.js | 2 +- src/actions/TxActions.js | 5 +- src/actions/Web3Actions.js | 93 +++++++------- src/actions/ethereum/SendFormActions.js | 78 +++--------- src/actions/ripple/SendFormActions.js | 11 +- .../ripple/SendFormValidationActions.js | 12 +- src/components/Transaction/index.js | 43 ++++--- src/reducers/PendingTxReducer.js | 6 +- src/reducers/utils/index.js | 25 ++-- src/utils/accountUtils.js | 114 ++++++++++++++++++ .../components/PendingTransactions/index.js | 2 +- .../views/Account/Send/ethereum/index.js | 15 ++- 12 files changed, 232 insertions(+), 174 deletions(-) create mode 100644 src/utils/accountUtils.js diff --git a/src/actions/SignVerifyActions.js b/src/actions/SignVerifyActions.js index a0722196..383592f5 100644 --- a/src/actions/SignVerifyActions.js +++ b/src/actions/SignVerifyActions.js @@ -39,7 +39,7 @@ export type SignVerifyAction = message: ?string, }; -const sign = (path: Array, message: string, hex: boolean = false): AsyncAction => async ( +const sign = (path: string, message: string, hex: boolean = false): AsyncAction => async ( dispatch: Dispatch, getState: GetState ): Promise => { diff --git a/src/actions/TxActions.js b/src/actions/TxActions.js index 07f62753..6e947572 100644 --- a/src/actions/TxActions.js +++ b/src/actions/TxActions.js @@ -21,7 +21,7 @@ type EthereumTxRequest = { data: string, gasLimit: string, gasPrice: string, - nonce: number, + nonce: string, }; export const prepareEthereumTx = ( @@ -54,9 +54,6 @@ export const prepareEthereumTx = ( nonce: toHex(tx.nonce), gasLimit: toHex(tx.gasLimit), gasPrice: toHex(EthereumjsUnits.convert(tx.gasPrice, 'gwei', 'wei')), - r: '', - s: '', - v: '', }; }; diff --git a/src/actions/Web3Actions.js b/src/actions/Web3Actions.js index 599bc1e8..3c6bcb6f 100644 --- a/src/actions/Web3Actions.js +++ b/src/actions/Web3Actions.js @@ -11,13 +11,11 @@ import * as ethUtils from 'utils/ethUtils'; import type { Dispatch, GetState, ThunkAction, PromiseAction } from 'flowtype'; -import type { EthereumAccount } from 'trezor-connect'; import type { Account } from 'reducers/AccountsReducer'; import type { Web3Instance } from 'reducers/Web3Reducer'; import type { Token } from 'reducers/TokensReducer'; import type { NetworkToken } from 'reducers/LocalStorageReducer'; import * as TokenActions from './TokenActions'; -import * as AccountsActions from './AccountsActions'; export type Web3UpdateBlockAction = { type: typeof WEB3.BLOCK_UPDATED, @@ -127,22 +125,22 @@ export const initWeb3 = ( web3.currentProvider.on('error', onEnd); }); -export const discoverAccount = ( - descriptor: string, - network: string -): PromiseAction => async (dispatch: Dispatch): Promise => { - const instance: Web3Instance = await dispatch(initWeb3(network)); - const balance = await instance.web3.eth.getBalance(descriptor); - const nonce = await instance.web3.eth.getTransactionCount(descriptor); - return { - descriptor, - transactions: 0, - block: 0, - balance: EthereumjsUnits.convert(balance, 'wei', 'ether'), - availableBalance: EthereumjsUnits.convert(balance, 'wei', 'ether'), - nonce, - }; -}; +// not used since connect@8 +// export const discoverAccount = (descriptor: string, network: string): PromiseAction => async ( +// dispatch: Dispatch +// ): Promise => { +// const instance: Web3Instance = await dispatch(initWeb3(network)); +// const balance = await instance.web3.eth.getBalance(descriptor); +// const nonce = await instance.web3.eth.getTransactionCount(descriptor); +// return { +// descriptor, +// transactions: 0, +// block: 0, +// balance: EthereumjsUnits.convert(balance, 'wei', 'ether'), +// availableBalance: EthereumjsUnits.convert(balance, 'wei', 'ether'), +// nonce, +// }; +// }; export const resolvePendingTransactions = (network: string): PromiseAction => async ( dispatch: Dispatch, @@ -151,24 +149,24 @@ export const resolvePendingTransactions = (network: string): PromiseAction const instance: Web3Instance = await dispatch(initWeb3(network)); const pending = getState().pending.filter(p => p.network === network); pending.forEach(async tx => { - const status = await instance.web3.eth.getTransaction(tx.hash); + const status = await instance.web3.eth.getTransaction(tx.txid); if (!status) { dispatch({ type: PENDING.TX_REJECTED, - hash: tx.hash, + hash: tx.txid, }); } else { - const receipt = await instance.web3.eth.getTransactionReceipt(tx.hash); + const receipt = await instance.web3.eth.getTransactionReceipt(tx.txid); if (receipt) { if (status.gas !== receipt.gasUsed) { dispatch({ type: PENDING.TX_TOKEN_ERROR, - hash: tx.hash, + hash: tx.txid, }); } dispatch({ type: PENDING.TX_RESOLVED, - hash: tx.hash, + hash: tx.txid, }); } } @@ -205,30 +203,31 @@ export const getTxInput = (): PromiseAction => async (dispatch: Dispatch): }; */ -export const updateAccount = ( - account: Account, - newAccount: EthereumAccount, - network: string -): PromiseAction => async (dispatch: Dispatch): Promise => { - const instance: Web3Instance = await dispatch(initWeb3(network)); - const balance = await instance.web3.eth.getBalance(account.descriptor); - const nonce = await instance.web3.eth.getTransactionCount(account.descriptor); - const empty = nonce <= 0 && balance === '0'; - dispatch( - AccountsActions.update({ - networkType: 'ethereum', - ...account, - ...newAccount, - empty, - nonce, - balance: EthereumjsUnits.convert(balance, 'wei', 'ether'), - availableBalance: EthereumjsUnits.convert(balance, 'wei', 'ether'), - }) - ); - - // update tokens for this account - dispatch(updateAccountTokens(account)); -}; +// not used since connect@8 +// export const updateAccount = ( +// account: Account, +// newAccount: any, +// network: string +// ): PromiseAction => async (dispatch: Dispatch): Promise => { +// const instance: Web3Instance = await dispatch(initWeb3(network)); +// const balance = await instance.web3.eth.getBalance(account.descriptor); +// const nonce = await instance.web3.eth.getTransactionCount(account.descriptor); +// const empty = nonce <= 0 && balance === '0'; +// dispatch( +// AccountsActions.update({ +// networkType: 'ethereum', +// ...account, +// ...newAccount, +// empty, +// nonce, +// balance: EthereumjsUnits.convert(balance, 'wei', 'ether'), +// availableBalance: EthereumjsUnits.convert(balance, 'wei', 'ether'), +// }) +// ); + +// // update tokens for this account +// dispatch(updateAccountTokens(account)); +// }; export const updateAccountTokens = (account: Account): PromiseAction => async ( dispatch: Dispatch, diff --git a/src/actions/ethereum/SendFormActions.js b/src/actions/ethereum/SendFormActions.js index 471c8ede..f4b9c07d 100644 --- a/src/actions/ethereum/SendFormActions.js +++ b/src/actions/ethereum/SendFormActions.js @@ -486,7 +486,7 @@ export const onGasPriceChange = (gasPrice: string): ThunkAction => ( ): void => { const state: State = getState().sendFormEthereum; // switch to custom fee level - let newSelectedFeeLevel = state.selectedFeeLevel; + let newSelectedFeeLevel; if (state.selectedFeeLevel.value !== 'Custom') newSelectedFeeLevel = state.feeLevels.find(f => f.value === 'Custom'); @@ -498,7 +498,7 @@ export const onGasPriceChange = (gasPrice: string): ThunkAction => ( untouched: false, touched: { ...state.touched, gasPrice: true }, gasPrice, - selectedFeeLevel: newSelectedFeeLevel, + selectedFeeLevel: newSelectedFeeLevel || state.selectedFeeLevel, }, }); }; @@ -673,9 +673,12 @@ export const onSend = (): AsyncAction => async ( const currentState: State = getState().sendFormEthereum; - const isToken: boolean = currentState.currency !== currentState.networkSymbol; - const pendingNonce: number = reducerUtils.getPendingSequence(pending); - const nonce = pendingNonce > 0 && pendingNonce >= account.nonce ? pendingNonce : account.nonce; + const isToken = currentState.currency !== currentState.networkSymbol; + const pendingNonce = new BigNumber(reducerUtils.getPendingSequence(pending)); + const nonce = + pendingNonce.gt(0) && pendingNonce.gt(account.nonce) + ? pendingNonce.toString() + : account.nonce; const txData = await dispatch( prepareEthereumTx({ @@ -727,12 +730,15 @@ export const onSend = (): AsyncAction => async ( return; } - txData.r = signedTransaction.payload.r; - txData.s = signedTransaction.payload.s; - txData.v = signedTransaction.payload.v; - try { - const serializedTx: string = await dispatch(serializeEthereumTx(txData)); + const serializedTx: string = await dispatch( + serializeEthereumTx({ + ...txData, + r: signedTransaction.payload.r, + s: signedTransaction.payload.s, + v: signedTransaction.payload.v, + }) + ); const push = await TrezorConnect.pushTransaction({ tx: serializedTx, coin: network.shortcut, @@ -746,58 +752,6 @@ export const onSend = (): AsyncAction => async ( dispatch({ type: SEND.TX_COMPLETE }); - // ugly blockbook workaround: - // since blockbook can't emit pending notifications - // need to trigger this event from here, where we know everything about this transaction - // blockchainNotification is 'trezor-connect' BlockchainLinkTransaction type - const fee = ValidationActions.calculateFee(currentState.gasLimit, currentState.gasPrice); - const blockchainNotification = { - type: 'send', - descriptor: account.descriptor, - inputs: [ - { - addresses: [account.descriptor], - amount: currentState.amount, - fee, - total: currentState.total, - }, - ], - outputs: [ - { - addresses: [currentState.address], - amount: currentState.amount, - }, - ], - hash: txid, - amount: currentState.amount, - fee, - total: currentState.total, - - sequence: nonce, - tokens: isToken - ? [ - { - name: currentState.currency, - shortcut: currentState.currency, - value: currentState.amount, - }, - ] - : undefined, - - blockHeight: 0, - blockHash: undefined, - timestamp: undefined, - }; - - dispatch( - BlockchainActions.onNotification({ - // $FlowIssue: missing coinInfo declaration - coin: {}, - notification: blockchainNotification, - }) - ); - // workaround end - // clear session storage dispatch(SessionStorageActions.clear()); diff --git a/src/actions/ripple/SendFormActions.js b/src/actions/ripple/SendFormActions.js index fce5ef8b..eefacdfe 100644 --- a/src/actions/ripple/SendFormActions.js +++ b/src/actions/ripple/SendFormActions.js @@ -1,6 +1,7 @@ /* @flow */ import React from 'react'; import { FormattedMessage } from 'react-intl'; +import { Link } from 'trezor-ui-components'; import TrezorConnect from 'trezor-connect'; import * as NOTIFICATION from 'actions/constants/notification'; import * as SEND from 'actions/constants/send'; @@ -374,7 +375,7 @@ export const onFeeChange = (fee: string): ThunkAction => ( const state: State = getState().sendFormRipple; // switch to custom fee level - let newSelectedFeeLevel = state.selectedFeeLevel; + let newSelectedFeeLevel; if (state.selectedFeeLevel.value !== 'Custom') newSelectedFeeLevel = state.feeLevels.find(f => f.value === 'Custom'); @@ -385,7 +386,7 @@ export const onFeeChange = (fee: string): ThunkAction => ( ...state, untouched: false, touched: { ...state.touched, fee: true }, - selectedFeeLevel: newSelectedFeeLevel, + selectedFeeLevel: newSelectedFeeLevel || state.selectedFeeLevel, fee, }, }); @@ -501,7 +502,11 @@ export const onSend = (): AsyncAction => async ( payload: { variant: 'success', title: , - message: txid, + message: ( + + + + ), cancelable: true, actions: [], }, diff --git a/src/actions/ripple/SendFormValidationActions.js b/src/actions/ripple/SendFormValidationActions.js index 33ddcc06..dbe651bf 100644 --- a/src/actions/ripple/SendFormValidationActions.js +++ b/src/actions/ripple/SendFormValidationActions.js @@ -173,16 +173,14 @@ const addressBalanceValidation = ($state: State): PromiseAction => async ( if (!network) return; let minAmount: string = '0'; - const response = await TrezorConnect.rippleGetAccountInfo({ - account: { - descriptor: $state.address, - }, + const response = await TrezorConnect.getAccountInfo({ + descriptor: $state.address, coin: network.shortcut, }); if (response.success) { - const empty = response.payload.sequence <= 0 && response.payload.balance === '0'; - if (empty) { - minAmount = toDecimalAmount(response.payload.reserve, network.decimals); + if (response.payload.empty) { + const reserve = response.payload.misc ? response.payload.misc.reserve : '0'; + minAmount = toDecimalAmount(reserve || '0', network.decimals); } } diff --git a/src/components/Transaction/index.js b/src/components/Transaction/index.js index 2e035b2a..2ede36df 100644 --- a/src/components/Transaction/index.js +++ b/src/components/Transaction/index.js @@ -63,7 +63,7 @@ const Value = styled.div` text-align: right; color: ${colors.GREEN_SECONDARY}; - &.send { + &.sent { color: ${colors.ERROR_PRIMARY}; } `; @@ -77,28 +77,27 @@ const Fee = styled.div` `; const TransactionItem = ({ tx, network }: Props) => { - const url = `${network.explorer.tx}${tx.hash}`; - const date = typeof tx.timestamp === 'string' ? tx.timestamp : undefined; // TODO: format date - const addresses = (tx.type === 'send' ? tx.outputs : tx.inputs).reduce( - (arr, item) => arr.concat(item.addresses), - [] - ); - - const operation = tx.type === 'send' ? '-' : '+'; - const amount = tx.tokens ? ( - tx.tokens.map(t => ( - + const url = `${network.explorer.tx}${tx.txid}`; + const date = typeof tx.blockTime === 'number' ? tx.blockTime : undefined; // TODO: format date + const addresses = tx.targets.reduce((arr, item) => arr.concat(item.addresses), []); + + const operation = tx.type === 'sent' ? '-' : '+'; + const amount = + tx.tokens.length > 0 ? ( + tx.tokens.map(t => ( + + {operation} + {t.amount} {t.symbol} + + )) + ) : ( + {operation} - {t.value} {t.shortcut} + {tx.amount} {network.symbol} - )) - ) : ( - - {operation} - {tx.total} {network.symbol} - - ); - const fee = tx.tokens && tx.type === 'send' ? `${tx.fee} ${network.symbol}` : undefined; + ); + const fee = + tx.tokens.length > 0 && tx.type === 'sent' ? `${tx.fee} ${network.symbol}` : undefined; return ( @@ -113,7 +112,7 @@ const TransactionItem = ({ tx, network }: Props) => { ))} {!tx.blockHeight && ( - Transaction hash: {tx.hash} + Transaction hash: {tx.txid} )} diff --git a/src/reducers/PendingTxReducer.js b/src/reducers/PendingTxReducer.js index 02bd2591..d8af632d 100644 --- a/src/reducers/PendingTxReducer.js +++ b/src/reducers/PendingTxReducer.js @@ -17,12 +17,12 @@ const add = (state: State, payload: Transaction): State => { const removeByDeviceState = (state: State, deviceState: ?string): State => state.filter(tx => tx.deviceState !== deviceState); -const removeByHash = (state: State, hash: string): State => state.filter(tx => tx.hash !== hash); +const removeByHash = (state: State, hash: string): State => state.filter(tx => tx.txid !== hash); const reject = (state: State, hash: string): State => state.map(tx => { - if (tx.hash === hash && !tx.rejected) { - return { ...tx, rejected: true }; + if (tx.txid === hash && !tx.rejected) { + return Object.assign({}, { rejected: true }, tx); } return tx; }); diff --git a/src/reducers/utils/index.js b/src/reducers/utils/index.js index e14862e9..8840dd4c 100644 --- a/src/reducers/utils/index.js +++ b/src/reducers/utils/index.js @@ -27,11 +27,7 @@ export const getSelectedDevice = (state: State): ?TrezorDevice => { if (d.mode === 'bootloader' && d.path === locationState.device) { return true; } - if ( - d.features && - d.features.device_id === locationState.device && - d.instance === instance - ) { + if (d.features && d.id === locationState.device && d.instance === instance) { return true; } return false; @@ -46,7 +42,7 @@ export const findDevice = ( ): ?TrezorDevice => devices.find(d => { // TODO: && (instance && d.instance === instance) - if (d.features && d.features.device_id === deviceId && d.state === deviceState) { + if (d.features && d.id === deviceId && d.state === deviceState) { return true; } return false; @@ -60,9 +56,7 @@ export const getDuplicateInstanceNumber = ( // find device(s) with the same features.device_id // and sort them by instance number const affectedDevices: Array = devices - .filter( - d => d.features && device.features && d.features.device_id === device.features.device_id - ) + .filter(d => d.features && device.features && d.id === device.id) .sort((a, b) => { if (!a.instance) { return -1; @@ -92,8 +86,7 @@ export const getSelectedAccount = (state: State): ?Account => { return state.accounts.find( a => a.imported === isImported && - (a.deviceState === device.state || - (a.imported && a.deviceID === (device.features || {}).device_id)) && + (a.deviceState === device.state || (a.imported && a.deviceID === device.id)) && a.index === index && a.network === locationState.network ); @@ -129,8 +122,8 @@ export const getAccountPendingTx = ( export const getPendingSequence = (pending: Array): number => pending.reduce((value: number, tx: Transaction): number => { - if (tx.rejected) return value; - return Math.max(value, tx.sequence + 1); + if (!tx.ethereumSpecific || tx.rejected) return value; + return Math.max(value, tx.ethereumSpecific.nonce + 1); }, 0); export const getPendingAmount = ( @@ -139,7 +132,7 @@ export const getPendingAmount = ( token: boolean = false ): BigNumber => pending.reduce((value: BigNumber, tx: Transaction): BigNumber => { - if (tx.type !== 'send') return value; + if (tx.type !== 'sent') return value; if (!token) { // regular transactions // add fees from token txs and amount from regular txs @@ -147,9 +140,9 @@ export const getPendingAmount = ( } if (tx.tokens) { // token transactions - const allTokens = tx.tokens.filter(t => t.shortcut === currency); + const allTokens = tx.tokens.filter(t => t.symbol === currency); const tokensValue: BigNumber = allTokens.reduce( - (tv, t) => new BigNumber(value).plus(t.value), + (tv, t) => new BigNumber(value).plus(t.amount), new BigNumber('0') ); return new BigNumber(value).plus(tokensValue); diff --git a/src/utils/accountUtils.js b/src/utils/accountUtils.js new file mode 100644 index 00000000..51eb6985 --- /dev/null +++ b/src/utils/accountUtils.js @@ -0,0 +1,114 @@ +/* @flow */ +import { toDecimalAmount } from 'utils/formatUtils'; +import type { AccountInfo, AccountTransaction } from 'trezor-connect'; +import type { Account, Transaction, Network, TrezorDevice } from 'flowtype'; + +// Merge fresh AccountInfo into existing Account +export const mergeAccount = ( + info: AccountInfo, + account: Account, + network: Network, + block: number +): Account => { + if (account.networkType === 'ethereum') { + const nonce = info.misc && info.misc.nonce ? info.misc.nonce : '0'; + return { + networkType: 'ethereum', + ...account, + balance: toDecimalAmount(info.balance, network.decimals), + availableBalance: toDecimalAmount(info.availableBalance, network.decimals), + block, + transactions: info.history.total, + empty: account.empty, + nonce, + }; + } + + if (account.networkType === 'ripple') { + const sequence = info.misc && info.misc.sequence ? info.misc.sequence : 0; + const reserve = info.misc && info.misc.reserve ? info.misc.reserve : '0'; + return { + ...account, + balance: toDecimalAmount(info.balance, network.decimals), + availableBalance: toDecimalAmount(info.availableBalance, network.decimals), + block, + empty: info.empty, + + networkType: 'ripple', + sequence, + reserve: toDecimalAmount(reserve || '0', network.decimals), + }; + } + + return account; +}; + +type EnhanceAccountOptions = { + index: number, + network: Network, + device: TrezorDevice, + imported?: boolean, + block?: number, +}; + +// Create Account from AccountInfo +export const enhanceAccount = (account: AccountInfo, options: EnhanceAccountOptions): Account => { + if (options.network.type === 'ethereum') { + const nonce = account.misc && account.misc.nonce ? account.misc.nonce : '0'; + return { + imported: !!options.imported, + index: options.index, + network: options.network.shortcut, + deviceID: options.device.id || '0', + deviceState: options.device.state || '0', + accountPath: account.path, + descriptor: account.descriptor, + + balance: toDecimalAmount(account.balance, options.network.decimals), + availableBalance: toDecimalAmount(account.availableBalance, options.network.decimals), + block: options.block || 0, + transactions: account.history.total, + empty: account.empty, + + networkType: 'ethereum', + nonce, + }; + } + + const sequence = account.misc && account.misc.sequence ? account.misc.sequence : 0; + const reserve = account.misc && account.misc.reserve ? account.misc.reserve : '0'; + return { + imported: !!options.imported, + index: options.index, + network: options.network.shortcut, + deviceID: options.device.id || '0', + deviceState: options.device.state || '0', + accountPath: account.path, + descriptor: account.descriptor, + + balance: toDecimalAmount(account.balance, options.network.decimals), + availableBalance: toDecimalAmount(account.availableBalance, options.network.decimals), + block: options.block || 0, + transactions: 0, + empty: account.empty, + + networkType: 'ripple', + sequence, + reserve: toDecimalAmount(reserve, options.network.decimals), + }; +}; + +export const enhanceTransaction = ( + account: Account, + tx: AccountTransaction, + network: Network +): Transaction => { + return { + ...tx, + descriptor: account.descriptor, + deviceState: account.deviceState, + network: account.network, + amount: toDecimalAmount(tx.amount, network.decimals), + fee: toDecimalAmount(tx.fee, network.decimals), + }; +}; diff --git a/src/views/Wallet/views/Account/Send/components/PendingTransactions/index.js b/src/views/Wallet/views/Account/Send/components/PendingTransactions/index.js index 6d0ab40b..66fffac0 100644 --- a/src/views/Wallet/views/Account/Send/components/PendingTransactions/index.js +++ b/src/views/Wallet/views/Account/Send/components/PendingTransactions/index.js @@ -31,7 +31,7 @@ const PendingTransactions = (props: Props) => { There are no pending transactions )} {pending.map(tx => ( - + ))} ); diff --git a/src/views/Wallet/views/Account/Send/ethereum/index.js b/src/views/Wallet/views/Account/Send/ethereum/index.js index 723bef68..7d0ff924 100644 --- a/src/views/Wallet/views/Account/Send/ethereum/index.js +++ b/src/views/Wallet/views/Account/Send/ethereum/index.js @@ -521,14 +521,13 @@ const AccountSend = (props: Props) => { )} - {props.selectedAccount.pending.length > 0 || - (account.imported && ( - - ))} + {props.selectedAccount.pending.length > 0 && ( + + )} ); }; From c5b4ae1350ffc3aca084368eb37747bdd71971cd Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Mon, 30 Mar 2020 20:47:20 +0200 Subject: [PATCH 05/21] flowtype fixes --- src/actions/ReceiveActions.js | 2 +- src/components/Header/index.js | 4 ++-- src/components/images/DeviceIcon/index.js | 12 +----------- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/actions/ReceiveActions.js b/src/actions/ReceiveActions.js index 7516d195..9d27fb8f 100644 --- a/src/actions/ReceiveActions.js +++ b/src/actions/ReceiveActions.js @@ -54,7 +54,7 @@ export const showUnverifiedAddress = (): Action => ({ }); //export const showAddress = (address_n: string): AsyncAction => { -export const showAddress = (path: Array): AsyncAction => async ( +export const showAddress = (path: string): AsyncAction => async ( dispatch: Dispatch, getState: GetState ): Promise => { diff --git a/src/components/Header/index.js b/src/components/Header/index.js index 622bc178..6f10760b 100644 --- a/src/components/Header/index.js +++ b/src/components/Header/index.js @@ -5,7 +5,7 @@ import { Header } from 'trezor-ui-components'; import { FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; -import type { toggleSidebar as toggleSidebarType } from 'actions/WalletActions'; +import { toggleSidebar as toggleSidebarAction } from 'actions/WalletActions'; import l10nMessages from './index.messages'; import LanguagePicker from './components/LanguagePicker/Container'; @@ -13,7 +13,7 @@ import LanguagePicker from './components/LanguagePicker/Container'; type MyProps = { sidebarEnabled?: boolean, sidebarOpened?: ?boolean, - toggleSidebar?: toggleSidebarType, + toggleSidebar?: typeof toggleSidebarAction, }; const MyHeader = ({ sidebarEnabled, sidebarOpened, toggleSidebar }: MyProps) => ( diff --git a/src/components/images/DeviceIcon/index.js b/src/components/images/DeviceIcon/index.js index 8ae997ad..853c8886 100644 --- a/src/components/images/DeviceIcon/index.js +++ b/src/components/images/DeviceIcon/index.js @@ -30,20 +30,10 @@ const DeviceIcon = ({ color = COLORS.TEXT_SECONDARY, hoverColor, onClick, - ...rest }: Props) => { const majorVersion = device.features ? device.features.major_version : 2; const icon = getDeviceIcon(majorVersion); - return ( - - ); + return ; }; DeviceIcon.propTypes = { From de6439e1af29b8157beb1593c8d867ad11e4b304 Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Mon, 30 Mar 2020 20:47:35 +0200 Subject: [PATCH 06/21] update localstorage version --- src/actions/LocalStorageActions.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/actions/LocalStorageActions.js b/src/actions/LocalStorageActions.js index bad2cd02..34a8bf82 100644 --- a/src/actions/LocalStorageActions.js +++ b/src/actions/LocalStorageActions.js @@ -213,7 +213,8 @@ const loadJSON = (): AsyncAction => async (dispatch: Dispatch): Promise => } }; -const VERSION: string = '2'; +// version 3 since trezor-connect@8 implementation +const VERSION: string = '3'; const loadStorageData = (): ThunkAction => (dispatch: Dispatch): void => { // validate version From 99802c59f7260297553ccbb689f8a3eed1ceabbc Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Mon, 30 Mar 2020 20:59:36 +0200 Subject: [PATCH 07/21] update trezor-connect@8 --- package.json | 9 +- yarn.lock | 715 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 668 insertions(+), 56 deletions(-) diff --git a/package.json b/package.json index e55673f6..79dd60e9 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "license": "SEE LICENSE IN LICENSE.md", "scripts": { - "dev": "yarn && npx webpack-dev-server --config webpack/dev.babel.js", + "dev": "npx webpack-dev-server --config webpack/dev.babel.js", "dev:local": "yarn && npx webpack-dev-server --config webpack/local.babel.js", "build": "rimraf build && run-s build:*", "build:stable": "rimraf build/stable && npx webpack --config webpack/production.babel.js --output-path build/stable --progress --bail", @@ -34,7 +34,7 @@ "dependencies": { "@babel/polyfill": "^7.2.5", "@hot-loader/react-dom": "16.8.6", - "bignumber.js": "8.0.2", + "bignumber.js": "9.0.0", "color-hash": "^1.0.3", "commander": "^2.19.0", "connected-react-router": "6.4.0", @@ -47,7 +47,6 @@ "ethereumjs-util": "^6.0.0", "express": "^4.16.4", "git-revision-webpack-plugin": "^3.0.3", - "hdkey": "^1.1.0", "history": "^4.7.2", "html-webpack-plugin": "^3.2.0", "jest-fetch-mock": "^2.1.0", @@ -81,7 +80,7 @@ "styled-components": "^4.1.3", "styled-normalize": "^8.0.6", "trezor-bridge-communicator": "1.0.2", - "trezor-connect": "7.0.2", + "trezor-connect": "8.1.0-beta.6", "trezor-ui-components": "^1.0.0-beta.20", "wallet-address-validator": "^0.2.4", "web3": "1.0.0-beta.36", @@ -124,7 +123,7 @@ "eslint-plugin-prettier": "^3.0.1", "eslint-plugin-react": "^7.12.4", "file-loader": "3.0.1", - "flow-bin": "0.90", + "flow-bin": "0.121.0", "jest": "^24.9.0", "prettier": "^1.16.4", "prettier-eslint": "^9.0.0", diff --git a/yarn.lock b/yarn.lock index 37c0391b..cbb68f89 100644 --- a/yarn.lock +++ b/yarn.lock @@ -784,7 +784,7 @@ pirates "^4.0.0" source-map-support "^0.5.9" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.3.1": +"@babel/runtime@^7.0.0": version "7.3.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.3.4.tgz#73d12ba819e365fcf7fd152aed56d6df97d21c83" integrity sha512-IvfvnMdSaLBateu0jfsYIpZTxAc2cKEXEMiezGGN75QcBcecDUKd3PgLAncT0oOgxKy8dd8hrJKj9MfzgfZd6g== @@ -804,6 +804,13 @@ dependencies: regenerator-runtime "^0.12.0" +"@babel/runtime@^7.8.7": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2": version "7.2.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" @@ -1190,6 +1197,47 @@ prop-types "^15.6.2" tippy.js "^4.2.1" +"@trezor/blockchain-link@^1.0.9": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@trezor/blockchain-link/-/blockchain-link-1.0.9.tgz#3993085f9a9b45f358f9212ead2476cae70c91eb" + integrity sha512-VLEnt5QGWPg7/wA4biVZwlryz/E1zY5vOefn47RqsEygz5YVmZT5XjtDEbZzrn2AEKaMynjfz2mu7wiaLUZYuQ== + dependencies: + es6-promise "^4.2.8" + events "^3.1.0" + +"@trezor/rollout@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@trezor/rollout/-/rollout-1.0.4.tgz#501238c4a0025014af5f3372ca3136b94292cb77" + integrity sha512-wqqnE2TqxOnzA9shqW0aS8dcJVCfu+7zc4x198dbJw8J9zLgP+gC/rIiS5knPAR+nIvsoPBKSWbrHy/TGjwHUw== + dependencies: + cross-fetch "^3.0.4" + runtypes "^4.2.0" + +"@trezor/utxo-lib@0.1.0", "@trezor/utxo-lib@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@trezor/utxo-lib/-/utxo-lib-0.1.0.tgz#f7a60d514ab75bef2f2206200cf0317d2d8523b2" + integrity sha512-jkqFRKL++xTga3xUgu5pWw1ArzTfraK0unXuj31V9g6wu+MKPbvcXW1+tMOVh+WNZZ3QUSGSQNNflSyh+qD0Vw== + dependencies: + bech32 "0.0.3" + bigi "^1.4.0" + bip66 "^1.1.0" + bitcoin-ops "^1.3.0" + blake2b "https://github.com/BitGo/blake2b#6268e6dd678661e0acc4359e9171b97eb1ebf8ac" + bs58check "^2.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.3" + debug "~3.1.0" + ecurve "^1.0.0" + merkle-lib "^2.0.10" + pushdata-bitcoin "^1.0.1" + randombytes "^2.0.1" + safe-buffer "^5.0.1" + typeforce "^1.11.3" + varuint-bitcoin "^1.0.4" + wif "^2.0.1" + optionalDependencies: + secp256k1 "^3.5.2" + "@types/babel__core@^7.1.0": version "7.1.2" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.2.tgz#608c74f55928033fce18b99b213c16be4b3d114f" @@ -1659,6 +1707,11 @@ aes-js@3.0.0: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" @@ -1874,6 +1927,11 @@ array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -1882,6 +1940,14 @@ asap@~2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" +ascli@~0.3: + version "0.3.0" + resolved "https://registry.yarnpkg.com/ascli/-/ascli-0.3.0.tgz#5e66230e5219fe3e8952a4efb4f20fae596a813a" + integrity sha1-XmYjDlIZ/j6JUqTvtPIPrllqgTo= + dependencies: + colour latest + optjs latest + asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" @@ -2534,6 +2600,11 @@ babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + bail@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.3.tgz#63cfb9ddbac829b02a3128cd53224be78e6c21a3" @@ -2543,6 +2614,13 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +base-x@^3.0.2: + version "3.0.8" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" + integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== + dependencies: + safe-buffer "^5.0.1" + base-x@^3.0.4: version "3.0.5" resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.5.tgz#d3ada59afed05b921ab581ec3112e6444ba0795a" @@ -2553,6 +2631,11 @@ base16@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70" +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= + base64-js@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" @@ -2583,6 +2666,22 @@ batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" +bchaddrjs@0.4.7: + version "0.4.7" + resolved "https://registry.yarnpkg.com/bchaddrjs/-/bchaddrjs-0.4.7.tgz#9d33e25816091e43a0cb4ce474d6210d6f006a37" + integrity sha512-+KAWllIzFDZUhaQqkzKEr2Nroh2v+63mdAtib2y7G+J0zoynFhFAV4tFr/HPEwWZPEAtK46LjenvN/o8P+JIiw== + dependencies: + bs58check "^2.1.2" + cashaddrjs "^0.3.10" + +bchaddrjs@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/bchaddrjs/-/bchaddrjs-0.3.2.tgz#62d4915f8f69012b7a16ae9fd0c99eca3a8ccf91" + integrity sha512-jpoq2GX6PphcCpuvvrQG4oQmEzn4nGQSm5dT208W72r9GDdbmNPi0hG9TY/dFF3r9sNtdl0qKwNsh8dNL3Q62g== + dependencies: + bs58check "^2.1.2" + cashaddrjs "^0.3.3" + bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" @@ -2590,6 +2689,18 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +bech32@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-0.0.3.tgz#736747c4a6531c5d8937d0400498de30e93b2f9c" + integrity sha512-O+K1w8P/aAOLcYwwQ4sbiPYZ51ZIW95lnS4/6nE8Aib/z+OOddQIIPdu2qi94qGDp4HhYy/wJotttXKkak1lXg== + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= + dependencies: + callsite "1.0.0" + bfj@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.1.tgz#05a3b7784fbd72cfa3c22e56002ef99336516c48" @@ -2600,6 +2711,11 @@ bfj@^6.1.1: hoopy "^0.1.2" tryer "^1.0.0" +big-integer@1.6.36: + version "1.6.36" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" + integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg== + big.js@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" @@ -2610,10 +2726,15 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== -bignumber.js@8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-8.0.2.tgz#d8c4e1874359573b1ef03011a2d861214aeef137" - integrity sha512-EiuvFrnbv0jFixEQ9f58jo7X0qI2lNGIr/MxntmVzQc5JUweDSh8y8hbTCAomFtqwUPIOWcLXP0VEOSZTG7FFw== +bigi@^1.1.0, bigi@^1.4.0, bigi@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/bigi/-/bigi-1.4.2.tgz#9c665a95f88b8b08fc05cfd731f561859d725825" + integrity sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU= + +bignumber.js@9.0.0, bignumber.js@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" + integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== bignumber.js@^2.3.0: version "2.4.0" @@ -2627,12 +2748,24 @@ bindings@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7" -bip66@^1.1.3: +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bip66@^1.1.0, bip66@^1.1.3, bip66@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" dependencies: safe-buffer "^5.0.1" +bitcoin-ops@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/bitcoin-ops/-/bitcoin-ops-1.4.1.tgz#e45de620398e22fd4ca6023de43974ff42240278" + integrity sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow== + bl@^1.0.0: version "1.2.2" resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" @@ -2640,6 +2773,24 @@ bl@^1.0.0: readable-stream "^2.3.5" safe-buffer "^5.1.1" +"blake2b-wasm@https://github.com/BitGo/blake2b-wasm#193cdb71656c1a6c7f89b05d0327bb9b758d071b": + version "2.0.0" + resolved "https://github.com/BitGo/blake2b-wasm#193cdb71656c1a6c7f89b05d0327bb9b758d071b" + dependencies: + nanoassert "^1.0.0" + +"blake2b@https://github.com/BitGo/blake2b#6268e6dd678661e0acc4359e9171b97eb1ebf8ac": + version "2.1.3" + resolved "https://github.com/BitGo/blake2b#6268e6dd678661e0acc4359e9171b97eb1ebf8ac" + dependencies: + blake2b-wasm "https://github.com/BitGo/blake2b-wasm#193cdb71656c1a6c7f89b05d0327bb9b758d071b" + nanoassert "^1.0.0" + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + block-stream@*: version "0.0.9" resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" @@ -2670,7 +2821,7 @@ bn.js@4.11.6: version "4.11.6" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.0, bn.js@^4.11.3, bn.js@^4.11.6, bn.js@^4.4.0, bn.js@^4.8.0: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.0, bn.js@^4.11.3, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.4.0, bn.js@^4.8.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" @@ -2704,6 +2855,11 @@ boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" +bowser@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.9.0.tgz#3bed854233b419b9a7422d9ee3e85504373821c9" + integrity sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -2836,9 +2992,21 @@ browserslist@^4.6.3: electron-to-chromium "^1.3.191" node-releases "^1.1.25" -bs58@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.1.tgz#55908d58f1982aba2008fa1bed8f91998a29bf8d" +bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= + dependencies: + base-x "^3.0.2" + +bs58check@<3.0.0, bs58check@^2.0.0, bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" bser@^2.0.0: version "2.0.0" @@ -2905,6 +3073,11 @@ buffer@^5.0.5: base64-js "^1.0.2" ieee754 "^1.1.4" +bufferview@~1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bufferview/-/bufferview-1.0.1.tgz#7afd74a45f937fa422a1d338c08bbfdc76cd725d" + integrity sha1-ev10pF+Tf6QiodM4wIu/3HbNcl0= + builtin-modules@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -2913,6 +3086,14 @@ builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" +bytebuffer-old-fixed-webpack@3.5.6: + version "3.5.6" + resolved "https://registry.yarnpkg.com/bytebuffer-old-fixed-webpack/-/bytebuffer-old-fixed-webpack-3.5.6.tgz#5adc419c6a9b4692f217206703ec7431c759aa3f" + integrity sha1-WtxBnGqbRpLyFyBnA+x0McdZqj8= + dependencies: + bufferview "~1" + long "~2 >=2.2.3" + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -2995,6 +3176,11 @@ caller-path@^2.0.0: dependencies: caller-callsite "^2.0.0" +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + callsites@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" @@ -3068,6 +3254,13 @@ caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" +cashaddrjs@^0.3.10, cashaddrjs@^0.3.3: + version "0.3.10" + resolved "https://registry.yarnpkg.com/cashaddrjs/-/cashaddrjs-0.3.10.tgz#8eb281573184e343cc9186c28fb95e65d5695ebc" + integrity sha512-x+r0TxRzLR7Z9wy9JBHCCe1d6Yong5BH//vjWB/uldNT/IEb8cMGo8HNY5/QZmCr3KYcsLIToM8u6whXfKFbRw== + dependencies: + big-integer "1.6.36" + ccount@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.3.tgz#f1cec43f332e2ea5a569fd46f9f5bde4e6102aff" @@ -3294,13 +3487,6 @@ code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" -coinstring@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/coinstring/-/coinstring-2.3.0.tgz#cdb63363a961502404a25afb82c2e26d5ff627a4" - dependencies: - bs58 "^2.0.1" - create-hash "^1.1.1" - collapse-white-space@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.4.tgz#ce05cf49e54c3277ae573036a26851ba430a0091" @@ -3332,6 +3518,11 @@ colors@^1.1.2: version "1.2.1" resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.1.tgz#f4a3d302976aaf042356ba1ade3b1a2c62d9d794" +colour@latest: + version "0.7.1" + resolved "https://registry.yarnpkg.com/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778" + integrity sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g= + combined-stream@1.0.6, combined-stream@~1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" @@ -3389,20 +3580,31 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + component-classes@^1.2.5: version "1.2.6" resolved "https://registry.yarnpkg.com/component-classes/-/component-classes-1.2.6.tgz#c642394c3618a4d8b0b8919efccbbd930e5cd691" dependencies: component-indexof "0.0.3" -component-emitter@^1.2.1: +component-emitter@1.2.1, component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= component-indexof@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/component-indexof/-/component-indexof-0.0.3.tgz#11d091312239eb8f32c8f25ae9cb002ffe8d3c24" +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + compressible@~2.0.13: version "2.0.13" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.13.tgz#0d1020ab924b2fdb4d6279875c7d6daba6baa7a9" @@ -3611,7 +3813,7 @@ create-emotion@^9.2.12: stylis "^3.5.0" stylis-rule-sheet "^0.0.10" -create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2: +create-hash@^1.1.0, create-hash@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd" dependencies: @@ -3620,9 +3822,21 @@ create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2: ripemd160 "^2.0.0" sha.js "^2.4.0" -create-hmac@^1.1.0, create-hmac@^1.1.2: +create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.3: version "1.1.7" resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== dependencies: cipher-base "^1.0.3" create-hash "^1.1.0" @@ -3665,6 +3879,14 @@ cross-fetch@^2.2.2: node-fetch "2.1.2" whatwg-fetch "2.0.4" +cross-fetch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.4.tgz#7bef7020207e684a7638ef5f2f698e24d9eb283c" + integrity sha512-MSHgpjQqgbT/94D4CyADeNoYh52zMkCX4pcJvPP5WqPsLFMKjr2TCMg381ox5qI0ii2dPwaLx/00477knXqXVw== + dependencies: + node-fetch "2.6.0" + whatwg-fetch "3.0.0" + cross-spawn@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" @@ -3862,9 +4084,10 @@ debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6. dependencies: ms "2.0.0" -debug@3.1.0, debug@^3.1.0: +debug@3.1.0, debug@^3.1.0, debug@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== dependencies: ms "2.0.0" @@ -3875,7 +4098,7 @@ debug@^3.2.5, debug@^3.2.6: dependencies: ms "^2.1.1" -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -3988,7 +4211,7 @@ default-gateway@^2.6.0: execa "^0.10.0" ip-regex "^2.1.0" -define-properties@^1.1.2: +define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== @@ -4268,6 +4491,14 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +ecurve@^1.0.0, ecurve@^1.0.3: + version "1.0.6" + resolved "https://registry.yarnpkg.com/ecurve/-/ecurve-1.0.6.tgz#dfdabbb7149f8d8b78816be5a7d5b83fcf6de797" + integrity sha512-/BzEjNfiSuB7jIWKcS/z8FK9jNjmEWvUV2YZ4RLSmcDtP7Lq0m6FvDuSnJpBlDpGRpfRQeTLGLBI8H+kEv0r+w== + dependencies: + bigi "^1.1.0" + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -4326,6 +4557,19 @@ elliptic@^6.4.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" +elliptic@^6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + emoji-regex@^7.0.1, emoji-regex@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -4365,6 +4609,34 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" +engine.io-client@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.0.tgz#82a642b42862a9b3f7a188f41776b2deab643700" + integrity sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~4.1.0" + engine.io-parser "~2.2.0" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~6.1.0" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-parser@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.0.tgz#312c4894f57d52a02b420868da7b5c1c84af80ed" + integrity sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + enhanced-resolve@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" @@ -4407,6 +4679,23 @@ es-abstract@^1.11.0, es-abstract@^1.5.1: is-regex "^1.0.4" object-keys "^1.0.12" +es-abstract@^1.17.0-next.1: + version "1.17.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" + integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.1.5" + is-regex "^1.0.5" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.1" + es-abstract@^1.4.3, es-abstract@^1.6.1: version "1.12.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" @@ -4436,6 +4725,20 @@ es-to-primitive@^1.1.1, es-to-primitive@^1.2.0: is-date-object "^1.0.1" is-symbol "^1.0.2" +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es6-promise@^4.2.8: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -4698,6 +5001,11 @@ eslint@^5.0.0, eslint@^5.16.0: table "^5.2.3" text-table "^0.2.0" +esm@^3.2.25: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + espree@^3.5.2: version "3.5.4" resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" @@ -4890,10 +5198,10 @@ events@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" -events@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" - integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== +events@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" + integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== eventsource@^1.0.7: version "1.0.7" @@ -5233,6 +5541,11 @@ file-type@^6.1.0: version "6.2.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + filesize@^3.6.1: version "3.6.1" resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" @@ -5352,10 +5665,10 @@ flatted@^2.0.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== -flow-bin@0.90: - version "0.90.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.90.0.tgz#733b6d29a8c8a22b9a5d273611d9a8402faf3445" - integrity sha512-/syDchjhLLL7nELK1ggyWJifGXuMCTz74kvkjR1t9DcmasMrilLl9qAAotsACcNb98etEEJpsCrvP7WL64kadw== +flow-bin@0.121.0: + version "0.121.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.121.0.tgz#e206bdc3d510277f9a847920540f72c49e87c130" + integrity sha512-QYRMs+AoMLj/OTaSo9+8c3kzM/u8YgvfrInp0qzhtzC02Sc2jb3BV/QZWZGjPo+XK3twyyqXrcI3s8MuL1UQRg== flush-write-stream@^1.0.0: version "1.0.2" @@ -5845,6 +6158,18 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + has-flag@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" @@ -5862,6 +6187,11 @@ has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" +has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + has-to-string-tag-x@^1.2.0: version "1.4.1" resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" @@ -5925,14 +6255,16 @@ hash.js@1.1.3, hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.0" -hdkey@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.0.tgz#e74e7b01d2c47f797fa65d1d839adb7a44639f29" - integrity sha512-E7aU8pNlWUJbXGjTz/+lKf1LkMcA3hUrC5ZleeizrmLSd++kvf8mSOe3q8CmBDA9j4hdfXO5iY6hGiTUCOV2jQ== +hd-wallet@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/hd-wallet/-/hd-wallet-9.0.0.tgz#94abbb95eed243a4bbae0cf12959e4dd6fc8b32c" + integrity sha512-WzzGwljUhA7Tc3a3U8JuAEXdFSowadYmAu6a+BmER0zQTah5bqPfSiVjhRpA57NloTdjFz+c2mJo3+wUaNII4g== dependencies: - coinstring "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" + "@trezor/utxo-lib" "0.1.0" + bchaddrjs "^0.3.2" + bignumber.js "^9.0.0" + queue "^6.0.1" + socket.io-client "^2.2.0" he@1.1.x: version "1.1.1" @@ -6433,6 +6765,11 @@ is-callable@^1.1.3, is-callable@^1.1.4: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== +is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== + is-ci@1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" @@ -6632,6 +6969,13 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" +is-regex@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + dependencies: + has "^1.0.3" + is-regexp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-2.1.0.tgz#cd734a56864e23b956bf4e7c66c396a4c0b22c2d" @@ -6684,6 +7028,11 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -7268,6 +7617,13 @@ json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -7353,6 +7709,14 @@ keccak@^1.0.2: nan "^2.2.1" safe-buffer "^5.1.0" +keccak@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.0.tgz#420d1de4a38a04f33ff8401f0535fb93756861d4" + integrity sha512-/4h4FIfFEpTEuySXi/nVFM5rqSKPnnhI7cL4K3MFSwoI3VyM7AhPSq3SsysARtnEBEeIKMBUWD8cTh9nHE8AkA== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + keccakjs@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/keccakjs/-/keccakjs-0.2.1.tgz#1d633af907ef305bbf9f2fa616d56c44561dfa4d" @@ -7666,6 +8030,11 @@ long@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" +"long@~2 >=2.2.3": + version "2.4.0" + resolved "https://registry.yarnpkg.com/long/-/long-2.4.0.tgz#9fa180bb1d9500cdc29c4156766a1995e1f4524f" + integrity sha1-n6GAux2VAM3CnEFWdmoZleH0Uk8= + longest-streak@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.2.tgz#2421b6ba939a443bb9ffebf596585a50b4c38e2e" @@ -7863,6 +8232,11 @@ merge2@^1.2.3: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== +merkle-lib@^2.0.10: + version "2.0.10" + resolved "https://registry.yarnpkg.com/merkle-lib/-/merkle-lib-2.0.10.tgz#82b8dbae75e27a7785388b73f9d7725d0f6f3326" + integrity sha1-grjbrnXieneFOItz+ddyXQ9vMyY= + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -8143,7 +8517,7 @@ nan@2.10.0, nan@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" -nan@^2.0.8, nan@^2.12.1, nan@^2.3.3: +nan@^2.0.8, nan@^2.12.1, nan@^2.14.0, nan@^2.3.3: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== @@ -8156,6 +8530,11 @@ nano-json-stream-parser@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" +nanoassert@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/nanoassert/-/nanoassert-1.1.0.tgz#4f3152e09540fde28c76f44b19bbcd1d5a42478d" + integrity sha1-TzFS4JVA/eKMdvRLGbvNHVpCR40= + nanomatch@^1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" @@ -8213,11 +8592,21 @@ no-case@^2.2.0: dependencies: lower-case "^1.1.1" +node-addon-api@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.0.tgz#f9afb8d777a91525244b01775ea0ddbe1125483b" + integrity sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA== + node-fetch@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= +node-fetch@2.6.0, node-fetch@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" + integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== + node-fetch@^1.0.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" @@ -8234,6 +8623,11 @@ node-forge@0.7.5: version "0.7.5" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" +node-gyp-build@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.1.tgz#f28f0d3d3ab268d48ab76c6f446f19bc3d0db9dc" + integrity sha512-XyCKXsqZfLqHep1hhsMncoXuUNt/cXCjg1+8CLbu69V1TKuPiOeSGbL9n+k/ByKH8UT0p4rdIX8XkTRZV0i7Sw== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -8451,6 +8845,11 @@ object-assign@4.x, object-assign@^4, object-assign@^4.0.0, object-assign@^4.0.1, version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= + object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" @@ -8464,6 +8863,11 @@ object-hash@^1.1.4: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== +object-inspect@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + object-keys@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" @@ -8473,6 +8877,11 @@ object-keys@^1.0.12: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -8521,6 +8930,16 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" +object.values@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" + integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + oboe@2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.3.tgz#2b4865dbd46be81225713f4e9bfe4bcf4f680a4f" @@ -8590,6 +9009,11 @@ optionator@^0.8.1, optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" +optjs@latest: + version "3.2.2" + resolved "https://registry.yarnpkg.com/optjs/-/optjs-3.2.2.tgz#69a6ce89c442a44403141ad2f9b370bd5bb6f4ee" + integrity sha1-aabOicRCpEQDFBrS+bNwvVu29O4= + ora@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" @@ -8802,10 +9226,29 @@ parse-passwd@^1.0.0: resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= +parse-uri@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-uri/-/parse-uri-1.0.0.tgz#2872dcc22f1a797acde1583d8a0ac29552ddac20" + integrity sha1-KHLcwi8aeXrN4Vg9igrClVLdrCA= + parse5@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= + dependencies: + better-assert "~1.0.0" + parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" @@ -9302,6 +9745,14 @@ prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.8.1" +protobufjs-old-fixed-webpack@3.8.5: + version "3.8.5" + resolved "https://registry.yarnpkg.com/protobufjs-old-fixed-webpack/-/protobufjs-old-fixed-webpack-3.8.5.tgz#5813c1af9f1d136bbf39f4f9f2e6f3e43c389d06" + integrity sha1-WBPBr58dE2u/OfT58ubz5Dw4nQY= + dependencies: + ascli "~0.3" + bytebuffer-old-fixed-webpack "3.5.6" + protobufjs@^6.8.8: version "6.8.8" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" @@ -9401,6 +9852,13 @@ pure-color@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" +pushdata-bitcoin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pushdata-bitcoin/-/pushdata-bitcoin-1.0.1.tgz#15931d3cd967ade52206f523aa7331aef7d43af7" + integrity sha1-FZMdPNlnreUiBvUjqnMxrvfUOvc= + dependencies: + bitcoin-ops "^1.3.0" + qr.js@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f" @@ -9429,6 +9887,13 @@ querystringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.0.0.tgz#fa3ed6e68eb15159457c89b37bc6472833195755" +queue@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.1.tgz#abd5a5b0376912f070a25729e0b6a7d565683791" + integrity sha512-AJBQabRCCNr9ANq8v77RJEv73DPbn55cdTb+Giq4X0AVnNVZvMHlYp7XlQiN+1npCZj1DuSmaA2hYVUUDgxFDg== + dependencies: + inherits "~2.0.3" + quick-lru@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" @@ -10009,6 +10474,11 @@ regenerator-runtime@^0.12.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== +regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" @@ -10404,6 +10874,11 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" +runtypes@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/runtypes/-/runtypes-4.2.0.tgz#6bb01a4683c1ac76015de8669df32a034c6cb0fe" + integrity sha512-s89DYbxI7qKSpDMmdKQCGg61nH45tYA5LJMR0pWfJ/1nwPdpww75fusQqGzXE7llpk+rwe8fNPSx78FRGKenJg== + rxjs@^5.0.0-beta.11: version "5.5.12" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" @@ -10529,6 +11004,20 @@ secp256k1@^3.0.1: nan "^2.2.1" safe-buffer "^5.1.0" +secp256k1@^3.5.2: + version "3.8.0" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.8.0.tgz#28f59f4b01dbee9575f56a47034b7d2e3b3b352d" + integrity sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw== + dependencies: + bindings "^1.5.0" + bip66 "^1.1.5" + bn.js "^4.11.8" + create-hash "^1.2.0" + drbg.js "^1.0.1" + elliptic "^6.5.2" + nan "^2.14.0" + safe-buffer "^5.1.2" + seek-bzip@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" @@ -10545,6 +11034,11 @@ selfsigned@^1.9.1: dependencies: node-forge "0.7.5" +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + "semver@2 || 3 || 4 || 5", semver@^5.3.0: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" @@ -10785,6 +11279,35 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" +socket.io-client@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.0.tgz#14d5ba2e00b9bcd145ae443ab96b3f86cbcc1bb4" + integrity sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~4.1.0" + engine.io-client "~3.4.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.3.0" + to-array "0.1.4" + +socket.io-parser@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f" + integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + sockjs-client@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177" @@ -11085,6 +11608,22 @@ string.prototype.padend@^3.0.0: es-abstract "^1.4.3" function-bind "^1.0.2" +string.prototype.trimleft@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" + integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string.prototype.trimright@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" + integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + string_decoder@^1.0.0, string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -11552,6 +12091,13 @@ tiny-warning@^1.0.0: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.2.tgz#1dfae771ee1a04396bdfde27a3adcebc6b648b28" integrity sha512-rru86D9CpQRLvsFG5XFdy0KdLAvjdQDyZCsRcuu60WtzFylDM3eAWSxEVz5kzL2Gp544XiUvPbVKtOA/txLi9Q== +tiny-worker@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tiny-worker/-/tiny-worker-2.3.0.tgz#715ae34304c757a9af573ae9a8e3967177e6011e" + integrity sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g== + dependencies: + esm "^3.2.25" + tippy.js@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-4.2.1.tgz#9e4939d976465f77229b05a3cb233b5dc28cf850" @@ -11576,6 +12122,11 @@ tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= + to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -11670,13 +12221,39 @@ trezor-bridge-communicator@1.0.2: request "^2.88.0" whatwg-fetch "^3.0.0" -trezor-connect@7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/trezor-connect/-/trezor-connect-7.0.2.tgz#8b1b0d1b3b6dc6564bc3d22fe8f54ba826f2a242" - integrity sha512-KAFOqxEHHaFvrG8NGLFlM/QxHcwIa3gwfXcgTjCYM0g0zRpwIQBwe35AKsjAQO5yiTJQGa0Cu5MZufGJRGYjjw== - dependencies: - "@babel/runtime" "^7.3.1" - events "^3.0.0" +trezor-connect@8.1.0-beta.6: + version "8.1.0-beta.6" + resolved "https://registry.yarnpkg.com/trezor-connect/-/trezor-connect-8.1.0-beta.6.tgz#9eacd20841d03028ebc617f59ac46fa2bf987352" + integrity sha512-lflOzbw+Ea5Pc5DAHen6P3zpbWliXd5njA0wfZ3k3lAdtMwPQNVR03f/+UBhIYBeWRAKrubWbMNs30YQK7xWnQ== + dependencies: + "@babel/runtime" "^7.8.7" + "@trezor/blockchain-link" "^1.0.9" + "@trezor/rollout" "^1.0.4" + "@trezor/utxo-lib" "^0.1.0" + bchaddrjs "0.4.7" + bignumber.js "^9.0.0" + bowser "^2.9.0" + events "^3.1.0" + hd-wallet "9.0.0" + keccak "^3.0.0" + node-fetch "^2.6.0" + parse-uri "^1.0.0" + tiny-worker "^2.3.0" + trezor-link "1.7.0" + whatwg-fetch "^3.0.0" + +trezor-link@1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/trezor-link/-/trezor-link-1.7.0.tgz#6119de00f4fc57fff0cd4d4d214353c761fad896" + integrity sha512-JJ4vVp5md8SVn3kLRkjMbxCUbqPTf78MH5fVXPa0yvUhsPKElCP0PjeEmCwJZ4f0tmnorkUE/9+ZlZDoUjLBKQ== + dependencies: + bigi "^1.4.1" + ecurve "^1.0.3" + json-stable-stringify "^1.0.1" + node-fetch "^2.6.0" + object.values "^1.1.0" + protobufjs-old-fixed-webpack "3.8.5" + semver-compare "^1.0.0" whatwg-fetch "^3.0.0" trezor-translations-manager@^1.0.5: @@ -11783,6 +12360,11 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" +typeforce@^1.11.3: + version "1.18.0" + resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" + integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== + typescript@^3.2.1: version "3.5.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977" @@ -12087,6 +12669,13 @@ value-equal@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7" +varuint-bitcoin@^1.0.4: + version "1.1.2" + resolved "https://registry.yarnpkg.com/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz#e76c138249d06138b480d4c5b40ef53693e24e92" + integrity sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw== + dependencies: + safe-buffer "^5.1.1" + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -12592,15 +13181,15 @@ whatwg-fetch@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" -whatwg-fetch@>=0.10.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" - -whatwg-fetch@^3.0.0: +whatwg-fetch@3.0.0, whatwg-fetch@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== +whatwg-fetch@>=0.10.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" + whatwg-mimetype@^2.0.0, whatwg-mimetype@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz#f0f21d76cbba72362eb609dbed2a30cd17fcc7d4" @@ -12635,6 +13224,13 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2" +wif@^2.0.1: + version "2.0.6" + resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" + integrity sha1-CNP1IFbGZnkplyb63g1DKudLRwQ= + dependencies: + bs58check "<3.0.0" + wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" @@ -12708,6 +13304,13 @@ ws@^6.0.0: dependencies: async-limiter "~1.0.0" +ws@~6.1.0: + version "6.1.4" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" + integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA== + dependencies: + async-limiter "~1.0.0" + x-is-string@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" @@ -12759,6 +13362,11 @@ xmldom@0.1.x: resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= + xmlhttprequest@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" @@ -12900,3 +13508,8 @@ yauzl@^2.4.2: dependencies: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= From b0983994cd68bcaa9e0df11b789cb4ce6fa3923b Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Mon, 30 Mar 2020 22:02:34 +0200 Subject: [PATCH 08/21] implement PassphraseOnDevice button --- src/actions/ModalActions.js | 11 ++--- src/components/modals/index.js | 5 +++ .../modals/passphrase/OnDevice/index.js | 43 +++++++++++++++++++ .../modals/passphrase/Passphrase/index.js | 23 +++++++++- src/reducers/ModalReducer.js | 1 + 5 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 src/components/modals/passphrase/OnDevice/index.js diff --git a/src/actions/ModalActions.js b/src/actions/ModalActions.js index dce67072..5c2f5eea 100644 --- a/src/actions/ModalActions.js +++ b/src/actions/ModalActions.js @@ -33,14 +33,14 @@ export const onPinSubmit = (value: string): Action => { }; }; -export const onPassphraseSubmit = (passphrase: string): AsyncAction => async ( - dispatch: Dispatch, - getState: GetState -): Promise => { +export const onPassphraseSubmit = ( + passphrase: string, + passphraseOnDevice: boolean = false +): AsyncAction => async (dispatch: Dispatch, getState: GetState): Promise => { const { modal } = getState(); if (modal.context !== MODAL.CONTEXT_DEVICE) return; - if (passphrase === '') { + if (passphrase === '' && !passphraseOnDevice) { // set standard wallet type if passphrase is blank dispatch({ type: CONNECT.UPDATE_WALLET_TYPE, @@ -54,6 +54,7 @@ export const onPassphraseSubmit = (passphrase: string): AsyncAction => async ( payload: { value: passphrase, save: true, + passphraseOnDevice, }, }); diff --git a/src/components/modals/index.js b/src/components/modals/index.js index 955fc467..522b2607 100644 --- a/src/components/modals/index.js +++ b/src/components/modals/index.js @@ -16,6 +16,7 @@ import Pin from 'components/modals/pin/Pin'; import InvalidPin from 'components/modals/pin/Invalid'; import Passphrase from 'components/modals/passphrase/Passphrase'; import PassphraseType from 'components/modals/passphrase/Type'; +import PassphraseOnDevice from 'components/modals/passphrase/OnDevice'; import ConfirmSignTx from 'components/modals/confirm/SignTx'; import ConfirmAction from 'components/modals/confirm/Action'; import ConfirmUnverifiedAddress from 'components/modals/confirm/UnverifiedAddress'; @@ -97,6 +98,10 @@ const getDeviceContextModal = (props: Props) => { } } + case UI.REQUEST_PASSPHRASE_ON_DEVICE: + case 'ButtonRequest_PassphraseEntry': + return ; + case 'ButtonRequest_ProtectCall': return ; diff --git a/src/components/modals/passphrase/OnDevice/index.js b/src/components/modals/passphrase/OnDevice/index.js new file mode 100644 index 00000000..23e9df77 --- /dev/null +++ b/src/components/modals/passphrase/OnDevice/index.js @@ -0,0 +1,43 @@ +/* @flow */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import styled from 'styled-components'; + +import { H5, P, colors } from 'trezor-ui-components'; +import DeviceIcon from 'components/images/DeviceIcon'; + +import type { TrezorDevice } from 'flowtype'; + +type Props = { + device: TrezorDevice, +}; + +const Wrapper = styled.div` + max-width: 360px; + padding: 30px 48px; +`; + +const StyledDeviceIcon = styled(DeviceIcon)` + margin-bottom: 10px; +`; + +const Header = styled.div``; + +const PassphraseType = (props: Props) => ( + +
+ +
Enter passphrase on {props.device.label} device
+

+ If you enter a wrong passphrase, you will not unlock the desired hidden wallet. +

+
+
+); + +PassphraseType.propTypes = { + device: PropTypes.object.isRequired, +}; + +export default PassphraseType; diff --git a/src/components/modals/passphrase/Passphrase/index.js b/src/components/modals/passphrase/Passphrase/index.js index 4377ce47..116a4f8c 100644 --- a/src/components/modals/passphrase/Passphrase/index.js +++ b/src/components/modals/passphrase/Passphrase/index.js @@ -73,6 +73,10 @@ const LinkButton = styled(Button)` } `; +const OnDeviceButton = styled(Button)` + margin: 10px 0 10px 0; +`; + class Passphrase extends PureComponent { constructor(props: Props) { super(props); @@ -169,7 +173,10 @@ class Passphrase extends PureComponent { })); } - submitPassphrase(shouldLeavePassphraseBlank: boolean = false) { + submitPassphrase( + shouldLeavePassphraseBlank: boolean = false, + passphraseOnDevice: boolean = false + ) { const { onPassphraseSubmit } = this.props; const passphrase = this.state.passphraseInputValue; @@ -181,7 +188,7 @@ class Passphrase extends PureComponent { isPassphraseHidden: true, }); - onPassphraseSubmit(shouldLeavePassphraseBlank ? '' : passphrase); + onPassphraseSubmit(shouldLeavePassphraseBlank ? '' : passphrase, passphraseOnDevice); } handleKeyPress(event: KeyboardEvent) { @@ -209,6 +216,13 @@ class Passphrase extends PureComponent { ); } + const { device } = this.props; + const onDeviceOffer = !!( + device.features && + device.features.capabilities && + device.features.capabilities.includes('Capability_PassphraseEntry') + ); + return (
@@ -270,6 +284,11 @@ class Passphrase extends PureComponent { + {onDeviceOffer && ( + this.submitPassphrase(false, true)}> + Enter passphrase on device + + )}