Skip to content

Commit

Permalink
feat: cheats (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
jxom authored Oct 16, 2023
1 parent c6ff9f8 commit df65fd8
Show file tree
Hide file tree
Showing 15 changed files with 235 additions and 139 deletions.
35 changes: 33 additions & 2 deletions src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,21 @@ import { getTheme, setTheme } from '~/design-system'
import '~/design-system/styles/global.css'
import { useClient } from '~/hooks/useClient'
import { useNetworkStatus } from '~/hooks/useNetworkStatus'
import { usePendingBlock } from '~/hooks/usePendingBlock'
import {
getPendingBlockQueryKey,
usePendingBlock,
} from '~/hooks/usePendingBlock'
import { getPendingTransactionsQueryKey } from '~/hooks/usePendingTransactions'
import { usePrevious } from '~/hooks/usePrevious'
import { getTxpoolQueryKey } from '~/hooks/useTxpool'
import { getMessenger } from '~/messengers'
import { QueryClientProvider, queryClient } from '~/react-query'
import { deepEqual } from '~/utils'
import { getClient } from '~/viem'
import {
type AccountState,
type NetworkState,
networkStore,
syncStores,
useAccountStore,
useNetworkStore,
Expand All @@ -40,6 +47,7 @@ import OnboardingDownload from './screens/onboarding/download'
import OnboardingRun from './screens/onboarding/run'
import OnboardingStart from './screens/onboarding/start'
import Session from './screens/session'
import Settings from './screens/settings'
import TransactionDetails from './screens/transaction-details'

export function init({ type = 'standalone' }: { type?: AppMeta['type'] } = {}) {
Expand Down Expand Up @@ -87,6 +95,10 @@ export function init({ type = 'standalone' }: { type?: AppMeta['type'] } = {}) {
path: 'session',
element: <Session />,
},
{
path: 'settings',
element: <Settings />,
},
{
path: 'onboarding',
children: [
Expand All @@ -112,14 +124,33 @@ export function init({ type = 'standalone' }: { type?: AppMeta['type'] } = {}) {
},
])

// Handle requests from background to toggle the theme.
const backgroundMessenger = getMessenger('background:wallet')

// Handle requests from background to toggle the theme.
backgroundMessenger.reply('toggleTheme', async () => {
const { storageTheme, systemTheme } = getTheme()
const theme = storageTheme || systemTheme
setTheme(theme === 'dark' ? 'light' : 'dark')
})

// Handle executed transactions to invalidate stale queries.
backgroundMessenger.reply('transactionExecuted', async () => {
const {
network: { rpcUrl },
} = networkStore.getState()
const client = getClient({ rpcUrl })

queryClient.invalidateQueries({
queryKey: getPendingBlockQueryKey([client.key]),
})
queryClient.invalidateQueries({
queryKey: getPendingTransactionsQueryKey([client.key]),
})
queryClient.invalidateQueries({
queryKey: getTxpoolQueryKey([client.key]),
})
})

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<AppMetaContext.Provider value={{ type }}>
<QueryClientProvider>
Expand Down
62 changes: 19 additions & 43 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type ReactNode, useCallback, useMemo } from 'react'
import { Link, useLocation, useNavigate } from 'react-router-dom'
import { Link } from 'react-router-dom'
import { formatGwei } from 'viem'

import { Tooltip } from '~/components'
Expand Down Expand Up @@ -30,7 +30,6 @@ import { useAccountStore, useNetworkStore, useSessionsStore } from '~/zustand'
import * as styles from './Header.css'

const contentMessenger = getMessenger('wallet:contentScript')
const inpageMessenger = getMessenger('wallet:inpage')

export function Header({ isNetworkOffline }: { isNetworkOffline?: boolean }) {
const { type } = useAppMeta()
Expand Down Expand Up @@ -59,8 +58,7 @@ export function Header({ isNetworkOffline }: { isNetworkOffline?: boolean }) {
<Separator orientation="vertical" />
</Column>
<Column width="content">
{/** TODO: Remove this once EIP-6963 is widely adopted across wallets & dapps. */}
<ReinjectButton />
<SettingsButton />
</Column>
<Column width="content">
<Separator orientation="vertical" />
Expand Down Expand Up @@ -219,27 +217,24 @@ function CollapseButton() {
)
}

function ReinjectButton() {
const handleInject = useCallback(() => {
inpageMessenger.send('injectProvider', undefined)
}, [])

function SettingsButton() {
return (
<Tooltip label="Re-inject Wallet into Dapp" height="full">
<Box
alignItems="center"
as="button"
backgroundColor={{
hover: 'surface/fill/quarternary',
}}
display="flex"
justifyContent="center"
height="full"
onClick={handleInject}
style={{ width: '28px' }}
>
<SFSymbol size="14px" symbol="square.and.arrow.down" weight="medium" />
</Box>
<Tooltip label="Settings" height="full">
<Link to="/settings">
<Box
alignItems="center"
as="button"
backgroundColor={{
hover: 'surface/fill/quarternary',
}}
display="flex"
justifyContent="center"
height="full"
style={{ width: '28px' }}
>
<SFSymbol size="14px" symbol="gear" weight="medium" />
</Box>
</Link>
</Tooltip>
)
}
Expand All @@ -248,9 +243,6 @@ function ReinjectButton() {
// Middle Bar

function Network() {
const { pathname } = useLocation()
const navigate = useNavigate()
const { network } = useNetworkStore()
return (
<Link to="networks" style={{ height: '100%', width: '100%' }}>
<Box
Expand All @@ -273,22 +265,6 @@ function Network() {
<Chain />
</Inset>
</Column>
<Column width="content">
<Button.Symbol
label="Network Settings"
onClick={(e) => {
e.preventDefault()
navigate(`/networks/${encodeURIComponent(network.rpcUrl)}`, {
replace: pathname.includes(
`/networks/${encodeURIComponent(network.rpcUrl)}`,
),
})
}}
variant="ghost primary"
height="24px"
symbol="gearshape.fill"
/>
</Column>
</Columns>
</Inset>
</Box>
Expand Down
2 changes: 1 addition & 1 deletion src/design-system/symbols/generated/index.ts

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/design-system/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ export const symbolNames = [
'gearshape.fill',
'square.and.pencil',
'plus',
'gear',
] as const
export type SymbolName = typeof symbolNames[number]

Expand Down
35 changes: 21 additions & 14 deletions src/entries/background/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ import {
networkStore,
pendingRequestsStore,
sessionsStore,
settingsStore,
} from '~/zustand'

const inpageMessenger = getMessenger('background:inpage')
const walletMessenger = getMessenger('background:wallet')

const clientCache = new Map()
export function getRpcClient({
rpcUrl: rpcUrl_,
Expand Down Expand Up @@ -49,12 +53,17 @@ export function getRpcClient({
},
timeout: 5_000,
})

if (method === 'eth_sendTransaction')
walletMessenger.send('transactionExecuted', undefined)

if ((response as { success?: boolean }).success === false)
return {
id,
jsonrpc: '2.0',
error: 'An unknown error occurred.',
} as RpcResponse

return response
},
}),
Expand All @@ -63,9 +72,6 @@ export function getRpcClient({
return client
}

const inpageMessenger = getMessenger('background:inpage')
const walletMessenger = getMessenger('background:wallet')

export function setupRpcHandler({ messenger }: { messenger: Messenger }) {
messenger.reply('request', async ({ request, rpcUrl }, meta) => {
const isInpage =
Expand All @@ -74,7 +80,6 @@ export function setupRpcHandler({ messenger }: { messenger: Messenger }) {
const rpcClient = getRpcClient({ rpcUrl })

const hasOnboarded = isInpage ? networkStore.getState().onboarded : rpcUrl

if (!hasOnboarded)
return {
id: request.id,
Expand All @@ -85,12 +90,14 @@ export function setupRpcHandler({ messenger }: { messenger: Messenger }) {
},
} as RpcResponse

const { bypassSignatureAuth, bypassTransactionAuth } =
settingsStore.getState()
// If the method is a "signable" method, request approval from the user.
if (
request.method === 'eth_sendTransaction' ||
request.method === 'eth_sign' ||
request.method === 'eth_signTypedData_v4' ||
request.method === 'personal_sign'
(request.method === 'eth_sendTransaction' && !bypassTransactionAuth) ||
(request.method === 'eth_sign' && !bypassSignatureAuth) ||
(request.method === 'eth_signTypedData_v4' && !bypassSignatureAuth) ||
(request.method === 'personal_sign' && !bypassSignatureAuth)
) {
const { addPendingRequest, removePendingRequest } =
pendingRequestsStore.getState()
Expand Down Expand Up @@ -136,14 +143,10 @@ export function setupRpcHandler({ messenger }: { messenger: Messenger }) {
}

if (isInpage && request.method === 'eth_requestAccounts') {
const { addPendingRequest, removePendingRequest } =
pendingRequestsStore.getState()

const { addSession, instantAuth } = sessionsStore.getState()

const authorize = () => {
const { accountsForRpcUrl } = accountStore.getState()
const { network } = networkStore.getState()
const { addSession } = sessionsStore.getState()

const accounts = accountsForRpcUrl({
activeFirst: true,
Expand All @@ -165,7 +168,11 @@ export function setupRpcHandler({ messenger }: { messenger: Messenger }) {
} as RpcResponse
}

if (instantAuth) return authorize()
const { bypassConnectAuth } = settingsStore.getState()
if (bypassConnectAuth) return authorize()

const { addPendingRequest, removePendingRequest } =
pendingRequestsStore.getState()

addPendingRequest({ ...request, sender: meta.sender })

Expand Down
1 change: 1 addition & 0 deletions src/messengers/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@ export type Schema = {
| undefined,
response: void,
]
transactionExecuted: [payload: void, response: void]
}
34 changes: 15 additions & 19 deletions src/screens/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,15 @@ import type { Account } from '~/zustand/account'
import OnboardingStart from './onboarding/start'

export default function Index() {
const defaultTab = 'accounts'

const { setPosition } = useScrollPositionStore()
const [params, setParams] = useSearchParams({ tab: 'accounts' })
const [params, setParams] = useSearchParams({ tab: defaultTab })
const { onboarded } = useNetworkStore()
if (!onboarded) return <OnboardingStart />
return (
<Container scrollable={false} verticalInset={false}>
<Tabs.Root asChild value={params.get('tab')!}>
<Tabs.Root asChild value={params.get('tab') || defaultTab}>
<Box display="flex" flexDirection="column" height="full">
<TabsList
items={[
Expand Down Expand Up @@ -823,7 +825,6 @@ function Contracts() {
const contracts = contracts_.filter((contract) => contract.visible)

const VirtualList = useVirtualList({
// rome-ignore lint/nursery/useExhaustiveDependencies:
layout: useMemo(
() => [
{ size: 40, sticky: true, type: 'search' },
Expand All @@ -837,7 +838,7 @@ function Contracts() {
}) as const,
),
],
[contracts.length],
[contracts],
),
})

Expand Down Expand Up @@ -911,9 +912,15 @@ function Contracts() {
>
<Columns alignHorizontal="justify" gap="4px" width="full">
<Column alignVertical="center">
<Text size="11px" wrap={false}>
{contract.address}
</Text>
{contract.address !== '0x' ? (
<Text size="11px" wrap={false}>
{contract.address}
</Text>
) : (
<Text color="text/tertiary" size="11px" wrap={false}>
Deploying...
</Text>
)}
</Column>
<Column alignVertical="center" width="content">
<Button.Symbol
Expand Down Expand Up @@ -1001,24 +1008,13 @@ function ImportContract() {
if (bytecode) {
if (!account?.address) throw new Error()

const hash = await client.deployContract({
await client.deployContract({
abi: [],
bytecode,
account: account.address,
chain: null,
})
await client.mine({ blocks: 1 })
const receipt = await client.getTransactionReceipt({ hash })

if (!receipt.contractAddress) throw new Error()

updateContract({
address: receipt.contractAddress,
bytecode,
key,
receipt,
state: 'loaded',
})
return
}
} catch {
Expand Down
Loading

0 comments on commit df65fd8

Please sign in to comment.