Skip to content

Commit

Permalink
Merge pull request #1079 from oasisprotocol/buberdds/extLedgerAccess
Browse files Browse the repository at this point in the history
Fix extension WebUSB permission issue
  • Loading branch information
buberdds committed Nov 8, 2022
2 parents ab36d1e + e07f288 commit 401a13b
Show file tree
Hide file tree
Showing 26 changed files with 1,205 additions and 85 deletions.
13 changes: 6 additions & 7 deletions extension/src/popup/popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,28 @@ import { createRoot } from 'react-dom/client'
import { Provider } from 'react-redux'
import { HelmetProvider } from 'react-helmet-async'
import { Store } from 'webext-redux'
import { HashRouter } from 'react-router-dom'
import { createHashRouter, RouterProvider } from 'react-router-dom'

import { ThemeProvider } from 'styles/theme/ThemeProvider'
import { App } from 'app'

import 'locales/i18n'
import 'sanitize.css/sanitize.css'
import 'styles/main.css'
import { routes } from './routes'

const container = document.getElementById('root') as HTMLElement
const root = createRoot(container!)
const store = new Store()
const router = createHashRouter(routes)

store.ready().then(() => {
root.render(
<Provider store={store}>
<ThemeProvider>
<HelmetProvider>
<HashRouter>
<React.StrictMode>
<App />
</React.StrictMode>
</HashRouter>
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
</HelmetProvider>
</ThemeProvider>
</Provider>,
Expand Down
23 changes: 23 additions & 0 deletions extension/src/popup/routes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react'
import { App } from 'app'
import { ConnectDevicePage } from 'app/pages/ConnectDevicePage'
import { OpenWalletPageWebExtension } from 'app/pages/OpenWalletPage/webextension'
import { commonRoutes, Route } from '../../../src/commonRoutes'

export const routes: Route[] = [
{
path: '/*',
element: <App />,
children: [
...commonRoutes,
{
path: 'open-wallet',
element: <OpenWalletPageWebExtension />,
},
],
},
{
path: 'open-wallet/connect-device',
element: <ConnectDevicePage />,
},
]
4 changes: 3 additions & 1 deletion internals/jest/jest.base-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ const config = {
transform: {
'^.+\\.(js|jsx|mjs|cjs|ts|tsx)$': '<rootDir>/internals/jest/babelTransform.js',
},
transformIgnorePatterns: ['/node_modules/(?!(cborg|grommet/es6|grommet-icons/es6)/)'],
transformIgnorePatterns: [
'/node_modules/(?!(@ledgerhq/hw-transport-webusb|cborg|grommet/es6|grommet-icons/es6)/)',
],
watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],
}

Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@
"tweetnacl": "1.0.3",
"typed-redux-saga": "1.5.0",
"valid-url": "1.0.9",
"webext-redux": "2.1.9"
"webext-redux": "2.1.9",
"webextension-polyfill": "0.10.0"
},
"devDependencies": {
"@cypress/code-coverage": "3.10.0",
Expand Down Expand Up @@ -115,6 +116,7 @@
"@types/testing-library__jest-dom": "5.14.5",
"@types/valid-url": "1.0.3",
"@types/w3c-web-usb": "1.0.6",
"@types/webextension-polyfill": "0.9.1",
"@typescript-eslint/eslint-plugin": "5.42.0",
"@typescript-eslint/parser": "5.42.0",
"babel-jest": "29.2.2",
Expand Down
19 changes: 1 addition & 18 deletions src/app/__tests__/__snapshots__/index.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,7 @@ exports[`<App /> should render and match the snapshot 1`] = `
<Styled(Main)>
<FatalErrorHandler />
<Toolbar />
<Routes>
<Route
element={<HomePage />}
path="/"
/>
<Route
element={<CreateWalletPage />}
path="/create-wallet"
/>
<Route
element={<OpenWalletPage />}
path="/open-wallet/*"
/>
<Route
element={<AccountPage />}
path="/account/:address/*"
/>
</Routes>
<Outlet />
<Memo />
</Styled(Main)>
</Box>
Expand Down
8 changes: 7 additions & 1 deletion src/app/components/Header/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { render } from '@testing-library/react'
import { render, screen } from '@testing-library/react'

import { Header, ModalHeader } from '..'

Expand All @@ -9,6 +9,12 @@ describe('<Header />', () => {

expect(container).toMatchSnapshot()
})

it('should render header with text align property', () => {
render(<Header textAlign="center">Title</Header>)

expect(screen.queryByRole('heading')).toHaveStyle('text-align: center')
})
})

describe('<ModalHeader />', () => {
Expand Down
5 changes: 3 additions & 2 deletions src/app/components/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import { Heading, HeadingProps } from 'grommet'

interface HeaderProps extends Pick<HeadingProps, 'level' | 'size' | 'margin'> {
interface HeaderProps extends Pick<HeadingProps, 'level' | 'size' | 'margin' | 'textAlign'> {
children: React.ReactNode
}

Expand All @@ -10,9 +10,10 @@ export const Header = ({
level = 1,
size = 'small',
margin = { top: 'none' },
textAlign,
...props
}: HeaderProps) => (
<Heading level={level} size={size} margin={margin} {...props}>
<Heading level={level} size={size} margin={margin} textAlign={textAlign} {...props}>
{children}
</Heading>
)
Expand Down
13 changes: 2 additions & 11 deletions src/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,12 @@ import * as React from 'react'
import { useContext } from 'react'
import { Helmet } from 'react-helmet-async'
import { useTranslation } from 'react-i18next'
import { Route, Routes } from 'react-router-dom'
import { Outlet } from 'react-router-dom'
import styled from 'styled-components'
import { FatalErrorHandler } from './components/FatalErrorHandler'
import { Footer } from './components/Footer'
import { Navigation } from './components/Sidebar'
import { Toolbar } from './components/Toolbar'
import { AccountPage } from './pages/AccountPage'
import { CreateWalletPage } from './pages/CreateWalletPage'
import { HomePage } from './pages/HomePage'
import { OpenWalletPage } from './pages/OpenWalletPage'
import { ModalProvider } from './components/Modal'
import { useRouteRedirects } from './useRouteRedirects'

Expand Down Expand Up @@ -47,12 +43,7 @@ export function App() {
<AppMain>
<FatalErrorHandler />
<Toolbar />
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/create-wallet" element={<CreateWalletPage />} />
<Route path="/open-wallet/*" element={<OpenWalletPage />} />
<Route path="/account/:address/*" element={<AccountPage />} />
</Routes>
<Outlet />
<Footer />
</AppMain>
</Box>
Expand Down
15 changes: 14 additions & 1 deletion src/app/lib/ledger.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { Ledger, LedgerSigner } from './ledger'
import { Ledger, LedgerSigner, requestDevice } from './ledger'
import OasisApp from '@oasisprotocol/ledger'
import { WalletError, WalletErrors } from 'types/errors'
import { Wallet, WalletType } from 'app/state/wallet/types'
import { isSupported, requestLedgerDevice } from '@ledgerhq/hw-transport-webusb/lib-es/webusb'

jest.mock('@ledgerhq/hw-transport-webusb/lib-es/webusb')

jest.mock('@oasisprotocol/ledger', () => ({
...(jest.createMockFromModule('@oasisprotocol/ledger') as any),
Expand All @@ -13,6 +16,16 @@ function mockAppIsOpen(appName: string) {
appInfo.mockResolvedValueOnce({ appName: appName, return_code: 0x9000, error_message: '' })
}

describe('Extension access', () => {
it('should return a ledger device when web usb is supported', async () => {
const device = {} as USBDevice
jest.mocked(isSupported).mockResolvedValue(true)
jest.mocked(requestLedgerDevice).mockResolvedValue(device)
const result = await requestDevice()
expect(result).toBe(device)
})
})

describe('Ledger Library', () => {
afterEach(() => {
jest.resetAllMocks()
Expand Down
11 changes: 11 additions & 0 deletions src/app/lib/ledger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,23 @@ import { Wallet, WalletType } from 'app/state/wallet/types'
import { WalletError, WalletErrors } from 'types/errors'
import { hex2uint } from './helpers'
import type Transport from '@ledgerhq/hw-transport'
import { isSupported, requestLedgerDevice } from '@ledgerhq/hw-transport-webusb/lib-es/webusb'

interface LedgerAccount {
publicKey: Uint8Array
path: number[]
}

export async function canAccessNavigatorUsb(): Promise<boolean> {
return await isSupported()
}

export async function requestDevice(): Promise<USBDevice | undefined> {
if (await isSupported()) {
return await requestLedgerDevice()
}
}

function successOrThrowWalletError<T>(response: Response<T>, message: string) {
try {
return successOrThrow(response)
Expand Down
5 changes: 4 additions & 1 deletion src/app/pages/AccountPage/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { LocationDescriptor } from 'history'
import { configureAppStore } from 'store/configureStore'

import { AccountPage } from '..'
import { AccountDetails } from '../Features/AccountDetails'
import { DeepPartialRootState } from 'types/RootState'
import { stakingActions } from 'app/state/staking'
import { WalletErrors } from 'types/errors'
Expand All @@ -26,7 +27,9 @@ const renderPage = (store: any, initialEntries: LocationDescriptor[]) =>
<ThemeProvider>
<MemoryRouter initialEntries={initialEntries}>
<Routes>
<Route path="/account/:address/*" element={<AccountPage />} />
<Route path="/account/:address/*" element={<AccountPage />}>
<Route path="" element={<AccountDetails />}></Route>
</Route>
</Routes>
</MemoryRouter>
</ThemeProvider>
Expand Down
15 changes: 2 additions & 13 deletions src/app/pages/AccountPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import * as React from 'react'
import { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
import { NavLink, Route, Routes, useParams } from 'react-router-dom'
import { NavLink, Outlet, useParams } from 'react-router-dom'
import styled from 'styled-components'
import { normalizeColor } from 'grommet/es6/utils'

Expand All @@ -29,14 +29,9 @@ import {
selectWallets,
selectWalletsPublicKeys,
} from '../../state/wallet/selectors'
import { ActiveDelegationList } from '../StakingPage/Features/DelegationList/ActiveDelegationList'
import { DebondingDelegationList } from '../StakingPage/Features/DelegationList/DebondingDelegationList'
import { mobileHeaderZIndex } from '../../components/Sidebar'
import { ValidatorList } from '../StakingPage/Features/ValidatorList'
import { AccountDetails } from './Features/AccountDetails'
import { AccountSummary } from './Features/AccountSummary'
import { isValidAddress } from '../../lib/helpers'
import { ParaTimes } from '../ParaTimesPage'

const StyledNavItem = styled(NavLink)`
display: flex;
Expand Down Expand Up @@ -208,13 +203,7 @@ function AccountPageInternal(props: AccountPageProps) {
route="debonding-delegations"
/>
</Nav>
<Routes>
<Route path="/" element={<AccountDetails />} />
<Route path="/stake" element={<ValidatorList />} />
<Route path="/paratimes" element={<ParaTimes />} />
<Route path="/active-delegations" element={<ActiveDelegationList />} />
<Route path="/debonding-delegations" element={<DebondingDelegationList />} />
</Routes>
<Outlet />
</>
)}
</Box>
Expand Down

0 comments on commit 401a13b

Please sign in to comment.