Skip to content

Commit

Permalink
Improve error handling (#210)
Browse files Browse the repository at this point in the history
* improve error handling

* convert provider to signal

* error handlers

* remove unreachable condition

* rename from account to session in contexts

* Update app/ts/components/TokenPicker.tsx

Co-authored-by: KillariDev <[email protected]>

* Update app/ts/context/Notification.tsx

Co-authored-by: KillariDev <[email protected]>

* Update app/ts/library/errors.ts

Co-authored-by: KillariDev <[email protected]>

* token amount render

---------

Co-authored-by: KillariDev <[email protected]>
  • Loading branch information
jubalm and KillariDev authored Oct 16, 2023
1 parent 9395a69 commit 6c98987
Show file tree
Hide file tree
Showing 36 changed files with 816 additions and 744 deletions.
69 changes: 32 additions & 37 deletions app/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -526,16 +526,12 @@ input[type='password']:autofill {
inset: 0px;
}

.left-4 {
left: 1rem;
.bottom-4 {
bottom: 1rem;
}

.left-auto {
left: auto;
}

.right-0 {
right: 0px;
.left-4 {
left: 1rem;
}

.right-2 {
Expand All @@ -562,6 +558,10 @@ input[type='password']:autofill {
grid-column: 1 / -1;
}

.row-span-2 {
grid-row: span 2 / span 2;
}

.row-start-2 {
grid-row-start: 2;
}
Expand Down Expand Up @@ -610,18 +610,6 @@ input[type='password']:autofill {
margin-bottom: 2rem;
}

.mb-auto {
margin-bottom: auto;
}

.ml-auto {
margin-left: auto;
}

.mr-8 {
margin-right: 2rem;
}

.mt-8 {
margin-top: 2rem;
}
Expand Down Expand Up @@ -874,6 +862,10 @@ input[type='password']:autofill {
grid-template-rows: 1fr min-content;
}

.grid-rows-\[min-content\2c min-content\] {
grid-template-rows: min-content min-content;
}

.flex-col {
flex-direction: column;
}
Expand Down Expand Up @@ -946,6 +938,10 @@ input[type='password']:autofill {
row-gap: 0.25rem;
}

.gap-y-2 {
row-gap: 0.5rem;
}

.gap-y-3 {
row-gap: 0.75rem;
}
Expand Down Expand Up @@ -1002,6 +998,10 @@ input[type='password']:autofill {
border-style: dashed;
}

.border-amber-500\/50 {
border-color: rgb(245 158 11 / 0.5);
}

.border-lime-400\/40 {
border-color: rgb(163 230 53 / 0.4);
}
Expand All @@ -1015,6 +1015,10 @@ input[type='password']:autofill {
border-color: rgb(248 113 113 / 0.2);
}

.border-red-400\/50 {
border-color: rgb(248 113 113 / 0.5);
}

.border-transparent {
border-color: transparent;
}
Expand Down Expand Up @@ -1044,6 +1048,10 @@ input[type='password']:autofill {
border-bottom-color: rgb(255 255 255 / 0.1);
}

.bg-amber-500\/10 {
background-color: rgb(245 158 11 / 0.1);
}

.bg-black {
--tw-bg-opacity: 1;
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
Expand Down Expand Up @@ -1075,6 +1083,10 @@ input[type='password']:autofill {
background-color: rgb(23 23 23 / var(--tw-bg-opacity));
}

.bg-red-400\/10 {
background-color: rgb(248 113 113 / 0.1);
}

.bg-red-400\/5 {
background-color: rgb(248 113 113 / 0.05);
}
Expand Down Expand Up @@ -1108,10 +1120,6 @@ input[type='password']:autofill {
background-color: rgb(255 255 255 / 0.5);
}

.p-10 {
padding: 2.5rem;
}

.p-2 {
padding: 0.5rem;
}
Expand Down Expand Up @@ -1148,11 +1156,6 @@ input[type='password']:autofill {
padding-right: 1rem;
}

.px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}

.py-1 {
padding-top: 0.25rem;
padding-bottom: 0.25rem;
Expand All @@ -1178,10 +1181,6 @@ input[type='password']:autofill {
padding-bottom: 1rem;
}

.pb-4 {
padding-bottom: 1rem;
}

.pl-4 {
padding-left: 1rem;
}
Expand All @@ -1194,10 +1193,6 @@ input[type='password']:autofill {
padding-top: 1.25rem;
}

.pt-6 {
padding-top: 1.5rem;
}

.text-left {
text-align: left;
}
Expand Down
32 changes: 32 additions & 0 deletions app/ts/components/AccountReconnect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useSignalEffect } from '@preact/signals'
import { useEffect } from 'preact/hooks'
import { useWallet } from '../context/Wallet.js'
import { useEthereumProvider } from '../context/Ethereum.js'
import { useAsyncState } from '../library/preact-utilities.js'
import { EthereumAddress } from '../schema.js'

export const AccountReconnect = () => {
const { browserProvider } = useEthereumProvider()
const { account } = useWallet()
const { value: query, waitFor } = useAsyncState<EthereumAddress>()

const attemptToConnect = () => {
if (!browserProvider.value) return
const provider = browserProvider.value
waitFor(async () => {
const [signer] = await provider.listAccounts()
return EthereumAddress.parse(signer.address)
})
}

const listenForQueryChanges = () => {
// do not reset shared state for other instances of this hooks
if (query.value.state === 'inactive') return
account.value = query.value
}

useSignalEffect(listenForQueryChanges)
useEffect(attemptToConnect, [])

return <></>
}
33 changes: 16 additions & 17 deletions app/ts/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
import { Route, Router } from './HashRouter.js'
import { Notices } from './Notice.js'
import { SplashScreen } from './SplashScreen.js'
import { TransactionPage } from './TransactionPage/index.js'
import { ErrorAlert } from './ErrorAlert.js'
import { TransferPage } from './TransferPage/index.js'
import { EthereumProvider } from '../context/Ethereum.js'
import { WalletProvider } from '../context/Wallet.js'
import { AccountProvider } from '../context/Account.js'
import { NotificationProvider } from '../context/Notification.js'

export function App() {
return (
<SplashScreen>
<WalletProvider>
<AccountProvider>
<Router>
<Route path=''>
<TransferPage />
</Route>
<Route path='#tx/:transaction_hash'>
<TransactionPage />
</Route>
</Router>
<Notices />
<ErrorAlert />
</AccountProvider>
</WalletProvider>
<NotificationProvider>
<EthereumProvider>
<WalletProvider>
<Router>
<Route path=''>
<TransferPage />
</Route>
<Route path='#tx/:transaction_hash'>
<TransactionPage />
</Route>
</Router>
</WalletProvider>
</EthereumProvider>
</NotificationProvider>
</SplashScreen>
)
}
51 changes: 36 additions & 15 deletions app/ts/components/ConnectAccount.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
import { useSignalEffect } from '@preact/signals'
import { makeError } from 'ethers'
import { useAsyncState } from '../library/preact-utilities.js'
import { EthereumAddress } from '../schema.js'
import { useEthereumProvider } from '../context/Ethereum.js'
import { useWallet } from '../context/Wallet.js'
import { useAccount } from '../context/Account.js'
import { useNotice } from '../store/notice.js'
import { useNotification } from '../context/Notification.js'
import { AsyncText } from './AsyncText.js'
import SVGBlockie from './SVGBlockie.js'
import { humanReadableEthersError, isJsonRpcError, isEthersError, humanReadableJsonRpcError } from '../library/errors.js'

export const ConnectAccount = () => {
const { browserProvider } = useWallet()
const { account } = useAccount()
const { browserProvider } = useEthereumProvider()
const { account } = useWallet()
const { value: query, waitFor } = useAsyncState<EthereumAddress>()
const { notify } = useNotice()
const { notify } = useNotification()

const connect = () => {
if (!browserProvider) {
notify({ message: 'No compatible web3 wallet detected.', title: 'Failed to connect' })
return
}
waitFor(async () => {
const signer = await browserProvider.getSigner()
if (!browserProvider.value) {
throw makeError('No compatible web3 wallet detected.', 'UNKNOWN_ERROR', { error: { code: 4900 } })
}
const signer = await browserProvider.value.getSigner()
return EthereumAddress.parse(signer.address)
})
}
Expand All @@ -33,8 +34,28 @@ export const ConnectAccount = () => {
useSignalEffect(listenForQueryChanges)

switch (account.value.state) {
case 'inactive':
case 'rejected':
const accountError = account.value.error
if (isEthersError(accountError)) {
let message = humanReadableEthersError(accountError).message
if (accountError.code === 'UNKNOWN_ERROR' && isJsonRpcError(accountError.error)) {
message = humanReadableJsonRpcError(accountError.error).message
}
notify({ message, title: 'Notice' })
}

return (
<div class='grid grid-cols-[1fr,auto] gap-3 px-4 lg:px-0 h-20 border border-white/20 lg:border-none lg:place-items-end place-content-center items-center'>
<div class='grid lg:place-items-end'>
<span class='font-bold'>Get started quickly</span>
<span class='text-sm text-white/50'>by connecting your wallet</span>
</div>
<button class='h-12 px-4 border border-white/50 bg-white/20' onClick={connect}>
Connect
</button>
</div>
)
case 'inactive':
return (
<div class='grid grid-cols-[1fr,auto] gap-3 px-4 lg:px-0 h-20 border border-white/20 lg:border-none lg:place-items-end place-content-center items-center'>
<div class='grid lg:place-items-end'>
Expand All @@ -61,7 +82,7 @@ export const ConnectAccount = () => {
}

const AccountAddress = () => {
const { account } = useAccount()
const { account } = useWallet()

switch (account.value.state) {
case 'inactive':
Expand All @@ -82,7 +103,7 @@ const NetworkIcon = () => (
)

const AccountAvatar = () => {
const { account } = useAccount()
const { account } = useWallet()

switch (account.value.state) {
case 'inactive':
Expand All @@ -100,7 +121,7 @@ const AccountAvatar = () => {
}

const WalletNetwork = () => {
const { account } = useAccount()
const { account } = useWallet()

switch (account.value.state) {
case 'inactive':
Expand All @@ -119,7 +140,7 @@ const WalletNetwork = () => {
}

const NetworkName = () => {
const { network } = useWallet()
const { network } = useEthereumProvider()

switch (network.value.state) {
case 'inactive':
Expand Down
35 changes: 0 additions & 35 deletions app/ts/components/ErrorAlert.tsx

This file was deleted.

18 changes: 0 additions & 18 deletions app/ts/components/ErrorPage/index.tsx

This file was deleted.

Loading

0 comments on commit 6c98987

Please sign in to comment.