Skip to content

Commit

Permalink
feat: add avatar to ipfs update
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr.Mao committed Mar 13, 2024
1 parent e3934fb commit 1fb44f0
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 59 deletions.
17 changes: 10 additions & 7 deletions .env
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
SECRET_WORDS="test test test test test test test test test test test junk"
PASSWORD=TestMetaMask
NETWORK_NAME=MXC
GRAPH_URL=http://mxc-graph.mxc.com:8000/subgraphs/name/mnsdomains/mns
GRAPH_URL=http://mxc-graph-node.mxc.com:8000/subgraphs/name/mnsdomains/mns

DATA_FOLDER=./data

NEXT_PUBLIC_ALCHEMY_KEY=sSpYuHmhlpuU7RVXq-IIdCdz4IuKF-gM

BLOCK_HEIGHT=17952336
SUBGRAPH_ID=QmQ8PKwc5a4Zv86TPPLvN9n7y3VAASiH5ptkffJHZm2pU1
SUBGRAPH_ID=QmXxAE7Urtv6TPa8o8XmPwLVQNbH6r35hRKHP63udTxTNa
LOCAL_SUBGRAPH_ID=QmSUnR4AUTQ8CuGH2fK7tFTSSfYGe8BUz6EeBRNavXbE1H
EPOCH_TIME=1660180306
NETWORK=mxc
NEXT_PUBLIC_NETWORK_CHAINID=18686
NETWORK=mxc_wannsee
NEXT_PUBLIC_NETWORK_CHAINID=5167003
ARCHIVE_URL=https://storage.googleapis.com/ens-manager-build-data

TRANSACTION_WAIT_TIME=5000
STABLE_MODE=500
NEXT_PUBLIC_PROVIDER=https://rpc.mxc.com
NEXT_PUBLIC_DEPLOYMENT_ADDRESSES={"ENSRegistry":"0xd241E9681B22Ae47e94c523d25CDdC1a4960cDC3","PublicResolver":"0x5325640Cc17A06a409d4f4b6af02A0120528c67E","BaseRegistrarImplementation":"0xCDFd5D9cEf780f751e5C653bFC9dFf0A4E55c39C","NameWrapper":"0xD1B70f92b310c3Fa95b83dB436E00a53e1f1f5d5","ETHRegistrarController":"0x8cFa2b92fcD0AEB6bD4EA056425C64f8638474d7","BulkRenewal":"0x032379fd3C71Fc100722CC98BC97803B7E01eAE6","DNSRegister":"0x74BF2E1290e24B99fCD244c34Da665Fd7FE17E08","ReverseRegistrar":"0x18c02bA5D8391b3CB49586C94454E44102252cFA","UniversalResolver":"0x7F0ca8F3bBC08eb712108Ae47D5A2c7D47075d6B","Multicall":"0xfA9eBcEd32BaB3EA062f9853ACA66cC9B666fBB9"}
NEXT_PUBLIC_GRAPH_URI=https://mxc-graph.mxc.com/subgraphs/name/mnsdomains/mns
NEXT_PUBLIC_PROVIDER=https://wannsee-rpc.mxc.com
NEXT_PUBLIC_DEPLOYMENT_ADDRESSES={"ENSRegistry":"0x4E7984fF74569a270765EE67792386cBA77D1b01","PublicResolver":"0x438b261bEb8D3C500153DD17588E6feC36535312","BaseRegistrarImplementation":"0x39c47d083364b4A23d085c7945Fac9d42457d8C7","NameWrapper":"0x2246EdAd0bc9212Bae82D43974619480A9D1f387","ETHRegistrarController":"0xD9EeC15002fF7467a6841EDF6ea2D1048BaBc7c4","BulkRenewal":"0xD879004149706a6156De08e9a571Bfa5Ac6eDa84","DNSRegister":"0xaCFb160C4356a89c0096aAd292c7300D5949F384","ReverseRegistrar":"0x3453c56D41A18147dcb4a92b0B08210F90740a87","UniversalResolver":"0x4dc508720f701882c0bBB2fa67aA5c6bfBcC9c3e","Multicall":"0x98b114269C2635ff2cB03F0526feb246d1082B4C"}
NEXT_PUBLIC_GRAPH_URI=https://mxc-graph-node.mxc.com/subgraphs/name/mnsdomains/mns

NEXT_PUBLIC_PINATA_SECRET_API_KEY = "e2888715c2e00be5b87664db8a797d11720db7f6014d51e15bfb6b62a922fe61"
NEXT_PUBLIC_PINATA_API_KEY = "52f5dffaa392c58db33d"
5 changes: 4 additions & 1 deletion .env.mainnet
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ TRANSACTION_WAIT_TIME=5000
STABLE_MODE=500
NEXT_PUBLIC_PROVIDER=https://rpc.mxc.com
NEXT_PUBLIC_DEPLOYMENT_ADDRESSES={"ENSRegistry":"0xd241E9681B22Ae47e94c523d25CDdC1a4960cDC3","PublicResolver":"0x5325640Cc17A06a409d4f4b6af02A0120528c67E","BaseRegistrarImplementation":"0xCDFd5D9cEf780f751e5C653bFC9dFf0A4E55c39C","NameWrapper":"0xD1B70f92b310c3Fa95b83dB436E00a53e1f1f5d5","ETHRegistrarController":"0x8cFa2b92fcD0AEB6bD4EA056425C64f8638474d7","BulkRenewal":"0x032379fd3C71Fc100722CC98BC97803B7E01eAE6","DNSRegister":"0x74BF2E1290e24B99fCD244c34Da665Fd7FE17E08","ReverseRegistrar":"0x18c02bA5D8391b3CB49586C94454E44102252cFA","UniversalResolver":"0x7F0ca8F3bBC08eb712108Ae47D5A2c7D47075d6B","Multicall":"0xfA9eBcEd32BaB3EA062f9853ACA66cC9B666fBB9"}
NEXT_PUBLIC_GRAPH_URI=https://mxc-graph.mxc.com/subgraphs/name/mnsdomains/mns
NEXT_PUBLIC_GRAPH_URI=https://mxc-graph.mxc.com/subgraphs/name/mnsdomains/mns

NEXT_PUBLIC_PINATA_SECRET_API_KEY = "e2888715c2e00be5b87664db8a797d11720db7f6014d51e15bfb6b62a922fe61"
NEXT_PUBLIC_PINATA_API_KEY = "52f5dffaa392c58db33d"
5 changes: 4 additions & 1 deletion .env.testnet
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ TRANSACTION_WAIT_TIME=5000
STABLE_MODE=500
NEXT_PUBLIC_PROVIDER=https://wannsee-rpc.mxc.com
NEXT_PUBLIC_DEPLOYMENT_ADDRESSES={"ENSRegistry":"0x4E7984fF74569a270765EE67792386cBA77D1b01","PublicResolver":"0x438b261bEb8D3C500153DD17588E6feC36535312","BaseRegistrarImplementation":"0x39c47d083364b4A23d085c7945Fac9d42457d8C7","NameWrapper":"0x2246EdAd0bc9212Bae82D43974619480A9D1f387","ETHRegistrarController":"0xD9EeC15002fF7467a6841EDF6ea2D1048BaBc7c4","BulkRenewal":"0xD879004149706a6156De08e9a571Bfa5Ac6eDa84","DNSRegister":"0xaCFb160C4356a89c0096aAd292c7300D5949F384","ReverseRegistrar":"0x3453c56D41A18147dcb4a92b0B08210F90740a87","UniversalResolver":"0x4dc508720f701882c0bBB2fa67aA5c6bfBcC9c3e","Multicall":"0x98b114269C2635ff2cB03F0526feb246d1082B4C"}
NEXT_PUBLIC_GRAPH_URI=https://mxc-graph-node.mxc.com/subgraphs/name/mnsdomains/mns
NEXT_PUBLIC_GRAPH_URI=https://mxc-graph-node.mxc.com/subgraphs/name/mnsdomains/mns

NEXT_PUBLIC_PINATA_SECRET_API_KEY = "e2888715c2e00be5b87664db8a797d11720db7f6014d51e15bfb6b62a922fe61"
NEXT_PUBLIC_PINATA_API_KEY = "52f5dffaa392c58db33d"
10 changes: 7 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"typescript.enablePromptUseWorkspaceTsdk": true,
"eslint.format.enable": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": false
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "never"
},
"stylelint.configFile": ".stylelintrc.json",
"stylelint.validate": ["css", "typescriptreact"],
Expand All @@ -18,5 +18,9 @@
"[svg]": {
"editor.defaultFormatter": "jock.svg"
},
"jest.jestCommandLine": "pnpm run test"
"jest.jestCommandLine": "pnpm run test",
"i18n-ally.localesPaths": [
"public/locales"
],
"i18n-ally.keystyle": "nested"
}
27 changes: 18 additions & 9 deletions src/components/@molecules/ProfileEditor/Avatar/AvatarButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { ComponentProps, useRef } from 'react'
// import { useTranslation } from 'react-i18next'
// import { DropdownItem } from '@ensdomains/thorin/dist/types/components/molecules/Dropdown/Dropdown'
// import { LegacyDropdown } from '@app/omponents/@molecules/LegacyDropdown/LegacyDropdown'
import { showOpenImagePicker } from '@hairy/browser-utils'
import styled, { css } from 'styled-components'

import { Avatar, Dropdown } from '@ensdomains/thorin'

import CameraIcon from '@app/assets/Camera.svg'
import func from 'deploy/00_deploy_bulk_renewal'

const Container = styled.button<{ $error?: boolean; $validated?: boolean; $dirty?: boolean }>(
({ theme, $validated, $dirty, $error }) => css`
Expand Down Expand Up @@ -128,16 +130,23 @@ Props) => {
// const dropdownProps = setIsOpen
// ? ({ isOpen, setIsOpen } as { isOpen: boolean; setIsOpen: Dispatch<SetStateAction<boolean>> })
// : ({} as { isOpen: never; setIsOpen: never })

async function onChange() {
const [file] = await showOpenImagePicker({multiple: false})
onSelectOption?.('upload')
onAvatarFileChange?.(file)
}
return (
<Container $validated={validated} $error={error} $dirty={dirty} type="button">
<Avatar label="profile-button-avatar" src={src} noBorder />
{!validated && !error && (
<IconMask>
<CameraIcon />
</IconMask>
)}
<input
<div onClick={onChange}>
<Avatar label="profile-button-avatar" src={src} noBorder />
{!validated && !error && (
<IconMask>
<CameraIcon />
</IconMask>
)}
</div>

{/* <input
disabled
type="file"
style={{ display: 'none' }}
Expand All @@ -149,7 +158,7 @@ Props) => {
onAvatarFileChange?.(e.target.files[0])
}
}}
/>
/> */}
</Container>
// <LegacyDropdown
// items={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ export const CropComponent = ({

useEffect(() => {
const image = imageRef.current
if (canvasRef && !image.src) {
if (canvasRef && !image.src && avatar) {
image.src = URL.createObjectURL(avatar)
image.onload = handleImageLoad
}
Expand Down
44 changes: 19 additions & 25 deletions src/components/@molecules/ProfileEditor/Avatar/AvatarUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useChainName } from '@app/hooks/useChainName'

import { useQueryKeys } from '../../../../utils/cacheKeyFactory'
import { AvCancelButton, CropComponent } from './AvatarCrop'
import { helperPostPinFileToIPFS } from './helperPostPinFileToIPFS'

const Container = styled.div(({ theme }) => [
css`
Expand Down Expand Up @@ -78,31 +79,12 @@ const UploadComponent = ({
})

const { mutate: signAndUpload, isLoading } = useMutation(async () => {
let baseURL = process.env.NEXT_PUBLIC_AVUP_ENDPOINT || `https://ens.xyz`
if (network !== 'mainnet') {
baseURL = `${baseURL}/${network}`
}
const endpoint = `${baseURL}/${name}`

const sig = await signTypedDataAsync()
const fetched = (await fetch(endpoint, {
method: 'PUT',
headers: {
// eslint-disable-next-line @typescript-eslint/naming-convention
'Content-Type': 'application/json',
},
body: JSON.stringify({
expiry,
dataURL,
sig,
}),
}).then((res) => res.json())) as any

if (fetched.message === 'uploaded') {
queryClient.invalidateQueries(queryKeys)
return handleSubmit('upload', endpoint, dataURL)
}
throw new Error(fetched.message)

await signTypedDataAsync()

const endpoint = await helperPostPinFileToIPFS({ file: base64ToFile(dataURL, name) })

handleSubmit('upload', endpoint, dataURL)
})

return (
Expand All @@ -126,6 +108,18 @@ const UploadComponent = ({
)
}

function base64ToFile(base64: string, fileName: string) {
let arr = base64.split(",");
let mime = arr[0].match(/:(.\*?);/)?.[1];
let bstr = window.atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], fileName, { type: mime });
}

export const AvatarUpload = ({
avatar,
handleCancel,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { erc721ABI } from 'wagmi'

export interface PostPinFileToIPFSData {
file: File
metadata?: Record<string, string>
}

const baseURL = 'https://api.pinata.cloud'
const headers = {
pinata_api_key: `${process.env.NEXT_PUBLIC_PINATA_API_KEY}`,
pinata_secret_api_key: `${process.env.NEXT_PUBLIC_PINATA_SECRET_API_KEY}`,
}

export async function helperPostPinFileToIPFS(data: PostPinFileToIPFSData) {
const metadata = data.metadata || { name: data.file.name }

const body = new FormData()

body.append('pinataMetadata', JSON.stringify(metadata))
body.append('file', data.file)

const response = await fetch(`${baseURL}/pinning/pinFileToIPFS`, {
method: 'POST',
body,
headers,
})
const result = await response.json() as any
return `https://gateway.pinata.cloud/ipfs/${result.IpfsHash}`
}
16 changes: 4 additions & 12 deletions src/hooks/useAvatar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useQueryKeys } from '@app/utils/cacheKeyFactory'
import { ensNftImageUrl, imageUrlUnknownRecord } from '@app/utils/utils'

import { useContractAddress } from './useContractAddress'
import { useProfile } from './useProfile'

const fetchImg = async (url: string) =>
new Promise<string | null>((resolve) => {
Expand Down Expand Up @@ -34,18 +35,9 @@ const fetchImg = async (url: string) =>
})

export const useAvatar = (name: string | null | undefined, network: number, noCache?: boolean) => {
const { data, isLoading, status } = useQuery(
useQueryKeys().avatar.avatar(name),
() => fetchImg(imageUrlUnknownRecord(name!, network)),
{
enabled: !!name,
cacheTime: noCache ? 0 : 60000,
staleTime: 60000,
refetchOnMount: false,
},
)

return { avatar: data, isLoading, status }
const {profile, loading, status} = useProfile(name!)
const avatar = profile?.records?.texts?.find(t => t.key === 'avatar')?.value
return { avatar: avatar, isLoading: loading, status }
}

export const useNFTImage = (name: string | undefined, network: number) => {
Expand Down

0 comments on commit 1fb44f0

Please sign in to comment.