Unverified Commit cd86900c authored by Andrei Eres's avatar Andrei Eres Committed by GitHub
Browse files

Separate ui and utils (#46)

* Move isPopup

* Move guards

* Move chains

* Move checkCameraAccess

* Move DEFAULT_TYPE

* Move registry

* Move startSettings

* Move routing

* Remove initAccountContext

* Move metadataCache

* Remove findAccountByAddress

* Move recodeAddress

* Move messaging

* Move buildHierarchy

* Move findSubstrateAccount

* Move getExtrinsicPayload

* Move getGenesisHashByAddress

* Move requestCameraAccess

* Move stores

* Move hooks

* Fix src/utils/recodeAddress.ts

* Simplify App

* Organize global components

* Organize ui types

* Rename themes

* Update buildHierarchy

* Update accounts store

* Update constants

* Update messaging
parent 87bc9a2c
......@@ -4,7 +4,7 @@ import { AccountsStore } from '@polkadot/extension-base/stores'
import keyring from '@polkadot/ui-keyring'
import { assert } from '@polkadot/util'
import { cryptoWaitReady } from '@polkadot/util-crypto'
import chrome from './utils/chrome'
import chrome from '@polkadot/extension-inject/chrome'
// setup the notification (same a FF default background, white text)
void chrome.browserAction.setBadgeBackgroundColor({ color: '#d90000' })
......
import { PORT_CONTENT } from '@polkadot/extension-base/defaults'
import { Message } from '@polkadot/extension-base/types'
import chrome from './utils/chrome'
import chrome from '@polkadot/extension-inject/chrome'
import { isMessageAllowed } from './utils/isMessageAllowed'
const port = chrome.runtime.connect({ name: PORT_CONTENT })
......
import { Chain } from '@polkadot/extension-chains/types'
import { getMetadata } from '../utils/messaging'
import { getMetadata } from '../utils/getMetadata'
import { useEffect, useState } from 'react'
export default function useMetadata(
......
import {
AccountJson,
AllowedPath,
AuthorizeRequest,
MetadataRequest,
SigningRequest,
} from '@polkadot/extension-base/background/types'
import { sendMessage } from './sendMessage'
export function forgetAccount(address: string): Promise<boolean> {
return sendMessage('pri(accounts.forget)', { address })
}
export function approveAuthRequest(id: string): Promise<boolean> {
return sendMessage('pri(authorize.approve)', { id })
}
export function approveMetaRequest(id: string): Promise<boolean> {
return sendMessage('pri(metadata.approve)', { id })
}
export function cancelSignRequest(id: string): Promise<boolean> {
return sendMessage('pri(signing.cancel)', { id })
}
export function approveSignSignature(
id: string,
signature: string
): Promise<boolean> {
return sendMessage('pri(signing.approve.signature)', { id, signature })
}
export function createAccountExternal(
name: string,
address: string,
genesisHash: string
): Promise<boolean> {
return sendMessage('pri(accounts.create.external)', {
address,
genesisHash,
name,
})
}
export function rejectAuthRequest(id: string): Promise<boolean> {
return sendMessage('pri(authorize.reject)', { id })
}
export function rejectMetaRequest(id: string): Promise<boolean> {
return sendMessage('pri(metadata.reject)', { id })
}
export function subscribeAccounts(
cb: (accounts: AccountJson[]) => void
): Promise<boolean> {
return sendMessage('pri(accounts.subscribe)', null, cb)
}
export function subscribeAuthorizeRequests(
cb: (accounts: AuthorizeRequest[]) => void
): Promise<boolean> {
return sendMessage('pri(authorize.requests)', null, cb)
}
export function subscribeMetadataRequests(
cb: (accounts: MetadataRequest[]) => void
): Promise<boolean> {
return sendMessage('pri(metadata.requests)', null, cb)
}
export function subscribeSigningRequests(
cb: (accounts: SigningRequest[]) => void
): Promise<boolean> {
return sendMessage('pri(signing.requests)', null, cb)
}
export function windowOpen(path: AllowedPath): Promise<boolean> {
return sendMessage('pri(window.open)', path)
}
export function getMeta(genesisHash: string | null) {
return sendMessage('pri(metadata.get)', genesisHash)
}
import { Message } from '@polkadot/extension-base/types'
export type Handler = {
resolve: (data: Message['data']['response']) => void
reject: (error: Error) => void
subscriber?: (data: Message['data']['subscription']) => void
}
type Handlers = Record<string, Handler>
export const handlers: Handlers = {}
import { Message } from '@polkadot/extension-base/types'
import { MESSAGING_PORT } from '../utils/constants'
import { handlers } from './handlers'
// setup a listener for messages, any incoming resolves the promise
MESSAGING_PORT.onMessage.addListener((data: Message['data']) => {
const handler = handlers[data.id]
if (!handler)
return console.error(`Unknown response: ${JSON.stringify(data)}`)
if (!handler.subscriber) delete handlers[data.id]
if (data.subscription) {
handler.subscriber && handler.subscriber(data.subscription)
} else if (data.error) {
handler.reject(new Error(data.error))
} else {
handler.resolve(data.response)
}
})
import {
MessageTypes,
MessageTypesWithNoSubscriptions,
MessageTypesWithNullRequest,
MessageTypesWithSubscriptions,
RequestTypes,
ResponseTypes,
SubscriptionMessageTypes,
} from '@polkadot/extension-base/background/types'
import { MESSAGING_PORT } from '../utils/constants'
import { Handler, handlers } from './handlers'
let idCounter = 0
export function sendMessage<TMessageType extends MessageTypesWithNullRequest>(
message: TMessageType
): Promise<ResponseTypes[TMessageType]>
export function sendMessage<
TMessageType extends MessageTypesWithNoSubscriptions
>(
message: TMessageType,
request: RequestTypes[TMessageType]
): Promise<ResponseTypes[TMessageType]>
export function sendMessage<TMessageType extends MessageTypesWithSubscriptions>(
message: TMessageType,
request: RequestTypes[TMessageType],
subscriber: (data: SubscriptionMessageTypes[TMessageType]) => void
): Promise<ResponseTypes[TMessageType]>
export function sendMessage<TMessageType extends MessageTypes>(
message: TMessageType,
request?: RequestTypes[TMessageType],
subscriber?: (data: unknown) => void
): Promise<ResponseTypes[TMessageType]> {
return new Promise((resolve, reject) => {
const id = `${Date.now()}.${++idCounter}`
handlers[id] = {
reject,
subscriber,
resolve: resolve as Handler['resolve'],
}
MESSAGING_PORT.postMessage({ id, message, request: request || {} })
})
}
import { AccountJson } from '@polkadot/extension-base/background/types'
import { canDerive } from '@polkadot/extension-base/utils'
import { createDerived, createStore } from 'nanostores'
import { buildHierarchy } from '../utils/buildHierarchy'
import { subscribeAccounts } from '../utils/messaging'
import { subscribeAccounts } from '../messaging/actions'
export const accounts = createStore<AccountJson[]>(() => {
accounts.set([])
......@@ -11,14 +10,6 @@ export const accounts = createStore<AccountJson[]>(() => {
export const hasAccounts = createDerived(accounts, (list) => list.length > 0)
export const hierarchy = createDerived(accounts, (list) =>
buildHierarchy(list as AccountJson[])
)
export const masterAccount = createDerived(hierarchy, (list) =>
list.find(({ isExternal, type }) => !isExternal && canDerive(type))
)
export const setAccounts = (list: AccountJson[]) => {
accounts.set(list)
accounts.set(buildHierarchy(list))
}
import { AuthorizeRequest } from '@polkadot/extension-base/background/types'
import { createStore } from 'nanostores'
import { subscribeAuthorizeRequests } from '../utils/messaging'
import { subscribeAuthorizeRequests } from '../messaging/actions'
/**
* [
......
import { MetadataRequest } from '@polkadot/extension-base/background/types'
import { createStore } from 'nanostores'
import { subscribeMetadataRequests } from '../utils/messaging'
import { subscribeMetadataRequests } from '../messaging/actions'
export const metaRequests = createStore<MetadataRequest[]>(() => {
metaRequests.set([])
......
import { SigningRequest } from '@polkadot/extension-base/background/types'
import { createStore } from 'nanostores'
import { subscribeSigningRequests } from '../utils/messaging'
import { subscribeSigningRequests } from '../messaging/actions'
/**
* [
......
import React, { Suspense } from 'react'
import React from 'react'
import { ErrorBoundary } from 'react-error-boundary'
import { ThemeProvider } from 'styled-components'
import { goHome } from '../utils/routing'
import ErrorFallback from './components/ErrorFallback'
import Loading from './components/Loading'
import Main from './components/Main'
import { GlobalStyle } from './GlobalStyle'
import Router from './Router'
import { theme } from './themes'
import { goHome } from './utils/routing'
import { GlobalStyle } from './global/GlobalStyle'
import Main from './global/Main'
import Router from './global/Router'
import { theme } from './theme'
export const App: React.FC = () => (
<Suspense fallback={'...'}>
<Loading>
<ThemeProvider theme={theme}>
<GlobalStyle theme={theme} />
<Main>
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={goHome}>
<Router />
</ErrorBoundary>
</Main>
</ThemeProvider>
</Loading>
</Suspense>
<ThemeProvider theme={theme}>
<GlobalStyle theme={theme} />
<Main>
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={goHome}>
<Router />
</ErrorBoundary>
</Main>
</ThemeProvider>
)
......@@ -2,29 +2,29 @@ import { useStore } from 'nanostores/react'
import React, { useEffect } from 'react'
import styled from 'styled-components'
import Key from '../components/Key'
import { hierarchy as hierarchyStore } from '../stores/accounts'
import { accounts as accountsStore } from '../../stores/accounts'
import {
addHeaderAction,
importHeaderAction,
resetHeaderActions,
} from '../stores/headerActions'
} from '../../stores/headerActions'
import { BaseProps } from '../types'
import NoAccounts from './NoAccounts'
const Accounts: React.FC<BaseProps> = ({ className }) => {
const hierarchy = useStore(hierarchyStore)
const accounts = useStore(accountsStore)
useEffect(() => {
if (hierarchy.length > 0) addHeaderAction(importHeaderAction)
if (accounts.length > 0) addHeaderAction(importHeaderAction)
return () => resetHeaderActions()
}, [hierarchy.length])
}, [accounts.length])
if (hierarchy.length === 0) return <NoAccounts />
if (accounts.length === 0) return <NoAccounts />
return (
<div className={className}>
<h1>All keys</h1>
{hierarchy.map((account) => (
{accounts.map((account) => (
<Key
address={account.address}
genesisHash={account.genesisHash}
......
......@@ -6,9 +6,9 @@ import {
addHeaderAction,
goHomeHeaderAction,
resetHeaderActions,
} from '../stores/headerActions'
} from '../../stores/headerActions'
import { BaseProps } from '../types'
import { createAccountExternal } from '../utils/messaging'
import { createAccountExternal } from '../../messaging/actions'
interface QrAccount {
isAddress: boolean
......
......@@ -2,7 +2,7 @@ import React from 'react'
import styled from 'styled-components'
import { Button } from '../components/Button'
import { BaseProps } from '../types'
import { goToImport } from '../utils/routing'
import { goToImport } from '../../utils/routing'
const NoAccounts: React.FC<BaseProps> = ({ className }) => (
<div className={className}>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment