Skip to content

Commit

Permalink
Merge branch 'viem-test' of https://github.com/ensdomains/ens-app-v3
Browse files Browse the repository at this point in the history
…into viem-test
  • Loading branch information
storywithoutend committed Jan 24, 2024
2 parents 64acd65 + 608fede commit ba221e4
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 16 deletions.
4 changes: 1 addition & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,5 @@
"editor.defaultFormatter": "jock.svg"
},
"jest.jestCommandLine": "pnpm run test",
"cSpell.words": [
"ensjs"
]
"cSpell.words": ["ensjs"]
}
15 changes: 14 additions & 1 deletion src/components/@molecules/ProfileEditor/Avatar/AvatarNFT.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import MagnifyingGlassSVG from '@app/assets/MagnifyingGlass.svg'
import { InnerDialog } from '@app/components/@atoms/InnerDialog'
import { ScrollBoxWithSpinner, SpinnerRow } from '@app/components/@molecules/ScrollBoxWithSpinner'
import { useChainName } from '@app/hooks/chain/useChainName'
import { usePublicClient } from '@app/hooks/usePublicClient'
import { getSupportedChainContractAddress } from '@app/utils/getSupportedChainContractAddress'

type OwnedNFT = {
contract: {
Expand Down Expand Up @@ -168,6 +170,8 @@ export const AvatarNFT = ({
const { address: _address } = useAccount()
const address = _address!

const publicClient = usePublicClient()

const {
data: NFTPages,
fetchNextPage,
Expand All @@ -191,7 +195,16 @@ export const AvatarNFT = ({
ownedNfts: response.ownedNfts.filter(
(nft) =>
(nft.media[0].thumbnail || nft.media[0].gateway) &&
nft.contract.address !== '0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85',
nft.contract.address !==
getSupportedChainContractAddress({
client: publicClient,
contract: 'ensBaseRegistrarImplementation',
}) &&
nft.contract.address !==
getSupportedChainContractAddress({
client: publicClient,
contract: 'ensNameWrapper',
}),
),
} as NFTResponse
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ describe('<AvatarUpload />', () => {
mockHandleSubmit.mockClear()
global.fetch = jest.fn().mockImplementation(() =>
Promise.resolve({
json: () => ({ message: 'failed' }),
json: () => ({ error: 'failed', status: 500 }),
}),
)

Expand All @@ -128,4 +128,22 @@ describe('<AvatarUpload />', () => {
await waitFor(() => expect(global.fetch).toBeCalled())
await waitFor(() => expect(mockHandleSubmit).not.toHaveBeenCalled())
})
it('shows error when upload fails', async () => {
mockHandleSubmit.mockClear()
global.fetch = jest.fn().mockImplementation(() =>
Promise.resolve({
json: () => ({ error: 'failed', status: 500 }),
}),
)

render(<AvatarUpload {...props} />)
fireEvent.click(screen.getByTestId('continue-button'))
fireEvent.click(screen.getByTestId('upload-button'))

await waitFor(() => expect(global.fetch).toBeCalled())
await waitFor(() => expect(mockHandleSubmit).not.toHaveBeenCalled())

expect(screen.getByTestId('avatar-upload-error')).toBeVisible()
expect(screen.getByTestId('avatar-upload-error')).toHaveTextContent('failed')
})
})
44 changes: 37 additions & 7 deletions src/components/@molecules/ProfileEditor/Avatar/AvatarUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import styled, { css } from 'styled-components'
import { bytesToHex } from 'viem'
import { useMutation, useQueryClient, useSignTypedData } from 'wagmi'

import { Button, Dialog, mq } from '@ensdomains/thorin'
import { Button, Dialog, Helper, mq } from '@ensdomains/thorin'

import { useChainName } from '@app/hooks/chain/useChainName'

Expand Down Expand Up @@ -38,6 +38,15 @@ const dataURLToBytes = (dataURL: string) => {
return bytes
}

type AvatarUploadResult =
| {
message: string
}
| {
error: string
status: number
}

const UploadComponent = ({
dataURL,
handleCancel,
Expand Down Expand Up @@ -77,7 +86,11 @@ const UploadComponent = ({
},
})

const { mutate: signAndUpload, isLoading } = useMutation(async () => {
const {
mutate: signAndUpload,
isLoading,
error,
} = useMutation<void, Error>(async () => {
let baseURL = process.env.NEXT_PUBLIC_AVUP_ENDPOINT || `https://euc.li`
if (network !== 'mainnet') {
baseURL = `${baseURL}/${network}`
Expand All @@ -96,9 +109,9 @@ const UploadComponent = ({
dataURL,
sig,
}),
}).then((res) => res.json())) as any
}).then((res) => res.json())) as AvatarUploadResult

if (fetched.message === 'uploaded') {
if ('message' in fetched && fetched.message === 'uploaded') {
queryClient.invalidateQueries({
predicate: (query) => {
const {
Expand All @@ -112,7 +125,12 @@ const UploadComponent = ({
})
return handleSubmit('upload', endpoint, dataURL)
}
throw new Error(fetched.message)

if ('error' in fetched) {
throw new Error(fetched.error)
}

throw new Error('Unknown error')
})

return (
Expand All @@ -124,11 +142,23 @@ const UploadComponent = ({
<Container>
<CroppedImagePreview data-testid="cropped-image-preview" src={dataURL} />
</Container>
{error && (
<Helper data-testid="avatar-upload-error" type="error">
{error.message}
</Helper>
)}
<Dialog.Footer
leading={<AvCancelButton handleCancel={handleCancel} />}
trailing={
<Button disabled={isLoading} onClick={() => signAndUpload()} data-testid="upload-button">
{t('input.profileEditor.tabs.avatar.image.upload.action')}
<Button
disabled={isLoading}
colorStyle={error ? 'redSecondary' : undefined}
onClick={() => signAndUpload()}
data-testid="upload-button"
>
{error
? t('action.tryAgain', { ns: 'common' })
: t('input.profileEditor.tabs.avatar.image.upload.action')}
</Button>
}
/>
Expand Down
2 changes: 2 additions & 0 deletions src/constants/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,5 @@ export const localhostWithEns = {
export const mainnetWithEns = addEnsContracts(mainnet)
export const goerliWithEns = addEnsContracts(goerli)
export const sepoliaWithEns = addEnsContracts(sepolia)

export type SupportedChain = typeof mainnetWithEns | typeof goerliWithEns | typeof sepoliaWithEns
4 changes: 3 additions & 1 deletion src/hooks/usePublicClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { usePublicClient as usePublicClient_ } from 'wagmi'

import { PublicClientWithChain } from '@app/types'

export const usePublicClient = usePublicClient_ as <TPublicClient extends PublicClientWithChain>(
export const usePublicClient = usePublicClient_ as <
TPublicClient extends PublicClientWithChain = PublicClientWithChain,
>(
args?: Partial<GetPublicClientArgs>,
) => TPublicClient
4 changes: 3 additions & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
} from '@ensdomains/ensjs/utils'
import { Helper, Space } from '@ensdomains/thorin'

import { SupportedChain } from '@app/constants/chains'

export type Profile = Partial<
GetRecordsReturnType &
Pick<NonNullable<GetSubgraphRecordsReturnType>, 'isMigrated' | 'createdAt'> & {
Expand Down Expand Up @@ -161,7 +163,7 @@ export type Prettify<T> = {
[K in keyof T]: T[K]
} & {}

export type PublicClientWithChain = PublicClient<Transport, ChainWithEns>
export type PublicClientWithChain = PublicClient<Transport, SupportedChain>
export type WalletClientWithAccount = WalletClient<Transport, ChainWithEns, Account>

export type QueryConfig<TData, TError, TSelectData = TData> = Pick<
Expand Down
18 changes: 18 additions & 0 deletions src/utils/getSupportedChainContractAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Client, getChainContractAddress, Transport } from 'viem'

import { SupportedChain } from '@app/constants/chains'

export const getSupportedChainContractAddress = <
const TClient extends Client<Transport, SupportedChain>,
TContract extends Extract<keyof TClient['chain']['contracts'], string>,
>({
client,
contract,
}: {
client: TClient
contract: TContract
}) =>
getChainContractAddress({
chain: client.chain,
contract,
})
2 changes: 0 additions & 2 deletions src/validators/validateAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ export const validateCryptoAddress = ({
}) => {
try {
if (!address) return 'addressRequired'

const _address = normalizeCoinAddress({ coin, address })

const coinTypeInstance = getCoderByCoinName(coin)
coinTypeInstance.decode(_address)
return true
Expand Down

0 comments on commit ba221e4

Please sign in to comment.